/// object do not depend on any external data so we detach state pointer from
/// the source one.
-Position& Position::operator=(const Position& pos) {
+void Position::operator=(const Position& pos) {
memcpy(this, &pos, sizeof(Position));
startState = *st;
st = &startState;
nodes = 0;
- return *this;
+
+ assert(pos_is_ok());
}
/// string. This function is not very robust - make sure that input FENs are
/// correct (this is assumed to be the responsibility of the GUI).
-void Position::from_fen(const string& fenStr, bool isChess960) {
+void Position::from_fen(const string& fenStr, bool isChess960, Thread* th) {
/*
A FEN string defines a particular position using only the ASCII character set.
st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
chess960 = isChess960;
+ thisThread = th;
assert(pos_is_ok());
}
void Position::set_castle_right(Color c, Square rfrom) {
Square kfrom = king_square(c);
- bool kingSide = kfrom < rfrom;
- int cr = (kingSide ? WHITE_OO : WHITE_OOO) << c;
+ CastlingSide cs = kfrom < rfrom ? KING_SIDE : QUEEN_SIDE;
+ CastleRight cr = make_castle_right(c, cs);
st->castleRights |= cr;
castleRightsMask[kfrom] |= cr;
castleRightsMask[rfrom] |= cr;
- castleRookSquare[cr] = rfrom;
+ castleRookSquare[c][cs] = rfrom;
- Square kto = relative_square(c, kingSide ? SQ_G1 : SQ_C1);
- Square rto = relative_square(c, kingSide ? SQ_F1 : SQ_D1);
+ Square kto = relative_square(c, cs == KING_SIDE ? SQ_G1 : SQ_C1);
+ Square rto = relative_square(c, cs == KING_SIDE ? SQ_F1 : SQ_D1);
for (Square s = std::min(rfrom, rto); s <= std::max(rfrom, rto); s++)
if (s != kfrom && s != rfrom)
- castlePath[cr] |= s;
+ castlePath[c][cs] |= s;
for (Square s = std::min(kfrom, kto); s <= std::max(kfrom, kto); s++)
if (s != kfrom && s != rfrom)
- castlePath[cr] |= s;
+ castlePath[c][cs] |= s;
}
fen << (sideToMove == WHITE ? " w " : " b ");
if (can_castle(WHITE_OO))
- fen << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE_OO))))) : 'K');
+ fen << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE, KING_SIDE))))) : 'K');
if (can_castle(WHITE_OOO))
- fen << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE_OOO))))) : 'Q');
+ fen << (chess960 ? char(toupper(file_to_char(file_of(castle_rook_square(WHITE, QUEEN_SIDE))))) : 'Q');
if (can_castle(BLACK_OO))
- fen << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK_OO))) : 'k');
+ fen << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK, KING_SIDE))) : 'k');
if (can_castle(BLACK_OOO))
- fen << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK_OOO))) : 'q');
+ fen << (chess960 ? file_to_char(file_of(castle_rook_square(BLACK, QUEEN_SIDE))) : 'q');
if (st->castleRights == CASTLES_NONE)
fen << '-';
}
// Prefetch pawn and material hash tables
- prefetch((char*)this_thread->pawnTable.entries[st->pawnKey]);
- prefetch((char*)this_thread->materialTable.entries[st->materialKey]);
+ prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]);
+ prefetch((char*)thisThread->materialTable.entries[st->materialKey]);
// Update incremental scores
st->psqScore += psq_delta(piece, from, to);
void Position::flip() {
- // Make a copy of current position before to start changing
const Position pos(*this);
clear();
- // Board
+ sideToMove = ~pos.side_to_move();
+ thisThread = pos.this_thread();
+ nodes = pos.nodes_searched();
+ chess960 = pos.is_chess960();
+ startPosPly = pos.startpos_ply_counter();
+
for (Square s = SQ_A1; s <= SQ_H8; s++)
if (!pos.square_empty(s))
put_piece(Piece(pos.piece_on(s) ^ 8), ~s);
- // Side to move
- sideToMove = ~pos.side_to_move();
-
- // Castling rights
if (pos.can_castle(WHITE_OO))
- set_castle_right(BLACK, ~pos.castle_rook_square(WHITE_OO));
+ set_castle_right(BLACK, ~pos.castle_rook_square(WHITE, KING_SIDE));
if (pos.can_castle(WHITE_OOO))
- set_castle_right(BLACK, ~pos.castle_rook_square(WHITE_OOO));
+ set_castle_right(BLACK, ~pos.castle_rook_square(WHITE, QUEEN_SIDE));
if (pos.can_castle(BLACK_OO))
- set_castle_right(WHITE, ~pos.castle_rook_square(BLACK_OO));
+ set_castle_right(WHITE, ~pos.castle_rook_square(BLACK, KING_SIDE));
if (pos.can_castle(BLACK_OOO))
- set_castle_right(WHITE, ~pos.castle_rook_square(BLACK_OOO));
+ set_castle_right(WHITE, ~pos.castle_rook_square(BLACK, QUEEN_SIDE));
- // En passant square
if (pos.st->epSquare != SQ_NONE)
st->epSquare = ~pos.st->epSquare;
- // Checkers
- st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
-
- // Hash keys
st->key = compute_key();
st->pawnKey = compute_pawn_key();
st->materialKey = compute_material_key();
-
- // Incremental scores
st->psqScore = compute_psq_score();
-
- // Material
+ st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
st->npMaterial[WHITE] = compute_non_pawn_material(WHITE);
st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
if (failedStep) (*failedStep)++;
if (debugCastleSquares)
- for (CastleRight f = WHITE_OO; f <= BLACK_OOO; f = CastleRight(f << 1))
- {
- if (!can_castle(f))
- continue;
-
- Piece rook = (f & (WHITE_OO | WHITE_OOO) ? W_ROOK : B_ROOK);
+ for (Color c = WHITE; c <= BLACK; c++)
+ for (CastlingSide s = KING_SIDE; s <= QUEEN_SIDE; s = CastlingSide(s + 1))
+ {
+ if (!can_castle(make_castle_right(c, s)))
+ continue;
- if ( piece_on(castleRookSquare[f]) != rook
- || castleRightsMask[castleRookSquare[f]] != f)
- return false;
- }
+ if ( piece_on(castleRookSquare[c][s]) != make_piece(c, ROOK)
+ || castleRightsMask[castleRookSquare[c][s]] != make_castle_right(c, s))
+ return false;
+ }
if (failedStep) *failedStep = 0;
return true;