X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=e89477ea534d654658244d890c53d9ead3e87b07;hp=57d6dc09bce917c7d9014f1d31340b6ed6134dd8;hb=e72b93e44fb95af6b3669e23a8fcd7702ea09ec1;hpb=0439a79566d03065317b2025b9b479b9ae9f2d65 diff --git a/src/position.cpp b/src/position.cpp index 57d6dc09..e89477ea 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -62,15 +62,8 @@ const Value PieceValueEndgame[17] = { RookValueEndgame, QueenValueEndgame }; - -namespace { - - // Bonus for having the side to move (modified by Joona Kiiski) - const Score Tempo = make_score(48, 22); - - // To convert a Piece to and from a FEN char - const string PieceToChar(" PNBRQK pnbrqk ."); -} +// To convert a Piece to and from a FEN char +static const string PieceToChar(" PNBRQK pnbrqk ."); /// CheckInfo c'tor @@ -92,33 +85,26 @@ CheckInfo::CheckInfo(const Position& pos) { } -/// Position c'tors. Here we always create a copy of the original position -/// or the FEN string, we want the new born Position object do not depend -/// on any external data so we detach state pointer from the source one. +/// Position::operator=() creates a copy of 'pos'. We want the new born Position +/// object do not depend on any external data so we detach state pointer from +/// the source one. -void Position::copy(const Position& pos, int th) { +void Position::operator=(const Position& pos) { memcpy(this, &pos, sizeof(Position)); startState = *st; st = &startState; - threadID = th; nodes = 0; assert(pos_is_ok()); } -Position::Position(const string& fen, bool isChess960, int th) { - - from_fen(fen, isChess960); - threadID = th; -} - /// Position::from_fen() initializes the position object with the given FEN /// 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. @@ -234,6 +220,7 @@ void Position::from_fen(const string& fenStr, bool isChess960) { 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()); } @@ -245,24 +232,24 @@ void Position::from_fen(const string& fenStr, bool isChess960) { 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; } @@ -306,16 +293,16 @@ const string Position::to_fen() const { 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 << '-'; @@ -336,7 +323,7 @@ void Position::print(Move move) const { if (move) { - Position p(*this, this_thread()); + Position p(*this); cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") << move_to_san(p, move); } @@ -836,7 +823,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI prefetch((char*)TT.first_entry(k)); // Move the piece - Bitboard from_to_bb = SquareBB[from] | SquareBB[to]; + Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to]; byTypeBB[ALL_PIECES] ^= from_to_bb; byTypeBB[pt] ^= from_to_bb; byColorBB[us] ^= from_to_bb; @@ -903,8 +890,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI } // Prefetch pawn and material hash tables - prefetch((char*)Threads[threadID].pawnTable.entries[st->pawnKey]); - prefetch((char*)Threads[threadID].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); @@ -940,9 +927,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI } } - // Finish sideToMove = ~sideToMove; - st->psqScore += (sideToMove == WHITE ? Tempo : -Tempo); assert(pos_is_ok()); } @@ -1001,7 +986,7 @@ void Position::undo_move(Move m) { } // Put the piece back at the source square - Bitboard from_to_bb = SquareBB[from] | SquareBB[to]; + Bitboard from_to_bb = SquareBB[from] ^ SquareBB[to]; byTypeBB[ALL_PIECES] ^= from_to_bb; byTypeBB[pt] ^= from_to_bb; byColorBB[us] ^= from_to_bb; @@ -1084,21 +1069,13 @@ void Position::do_castle_move(Move m) { assert(piece_on(kfrom) == make_piece(us, KING)); assert(piece_on(rfrom) == make_piece(us, ROOK)); - // Remove pieces from source squares - byTypeBB[ALL_PIECES] ^= kfrom; - byTypeBB[KING] ^= kfrom; - byColorBB[us] ^= kfrom; - byTypeBB[ALL_PIECES] ^= rfrom; - byTypeBB[ROOK] ^= rfrom; - byColorBB[us] ^= rfrom; - - // Put pieces on destination squares - byTypeBB[ALL_PIECES] |= kto; - byTypeBB[KING] |= kto; - byColorBB[us] |= kto; - byTypeBB[ALL_PIECES] |= rto; - byTypeBB[ROOK] |= rto; - byColorBB[us] |= rto; + // Move the pieces, with some care; in chess960 could be kto == rfrom + Bitboard k_from_to_bb = SquareBB[kfrom] ^ SquareBB[kto]; + Bitboard r_from_to_bb = SquareBB[rfrom] ^ SquareBB[rto]; + byTypeBB[KING] ^= k_from_to_bb; + byTypeBB[ROOK] ^= r_from_to_bb; + byTypeBB[ALL_PIECES] ^= k_from_to_bb ^ r_from_to_bb; + byColorBB[us] ^= k_from_to_bb ^ r_from_to_bb; // Update board Piece king = make_piece(us, KING); @@ -1141,9 +1118,7 @@ void Position::do_castle_move(Move m) { // Update checkers BB st->checkersBB = attackers_to(king_square(~us)) & pieces(us); - // Finish sideToMove = ~sideToMove; - st->psqScore += (sideToMove == WHITE ? Tempo : -Tempo); } else // Undo: point our state pointer back to the previous state @@ -1186,7 +1161,6 @@ void Position::do_null_move(StateInfo& backupSt) { st->epSquare = SQ_NONE; st->rule50++; st->pliesFromNull = 0; - st->psqScore += (sideToMove == WHITE ? Tempo : -Tempo); } assert(pos_is_ok()); @@ -1420,18 +1394,15 @@ Key Position::compute_material_key() const { /// updated by do_move and undo_move when the program is running in debug mode. Score Position::compute_psq_score() const { - Bitboard b; Score result = SCORE_ZERO; + Bitboard b = pieces(); - for (Color c = WHITE; c <= BLACK; c++) - for (PieceType pt = PAWN; pt <= KING; pt++) - { - b = pieces(pt, c); - while (b) - result += pieceSquareTable[make_piece(c, pt)][pop_1st_bit(&b)]; - } + while (b) + { + Square s = pop_1st_bit(&b); + result += pieceSquareTable[piece_on(s)][s]; + } - result += (sideToMove == WHITE ? Tempo / 2 : -Tempo / 2); return result; } @@ -1545,46 +1516,37 @@ void Position::init() { void Position::flip() { - // Make a copy of current position before to start changing - const Position pos(*this, threadID); + const Position pos(*this); clear(); - threadID = pos.this_thread(); - // 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); @@ -1741,17 +1703,16 @@ bool Position::pos_is_ok(int* failedStep) const { 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;