X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=93c42291b658d6d90ec9236d2a8642c3073c6037;hp=ce48e33fb6fedd5721b7a890da8665c7cda85046;hb=3e40bd0648ab69c04e37da50fd3f3d4beb072df2;hpb=5c81602d14539f8259a715477315e28b5de7cb54 diff --git a/src/position.cpp b/src/position.cpp index ce48e33f..93c42291 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -35,13 +35,13 @@ #include "san.h" #include "ucioption.h" +using std::string; + //// //// Variables //// -extern SearchStack EmptySearchStack; - int Position::castleRightsMask[64]; Key Position::zobrist[2][8][64]; @@ -65,7 +65,7 @@ Position::Position(const Position& pos) { copy(pos); } -Position::Position(const std::string& fen) { +Position::Position(const string& fen) { from_fen(fen); } @@ -74,9 +74,9 @@ Position::Position(const std::string& 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 std::string& fen) { +void Position::from_fen(const string& fen) { - static const std::string pieceLetters = "KQRBNPkqrbnp"; + static const string pieceLetters = "KQRBNPkqrbnp"; static const Piece pieces[] = { WK, WQ, WR, WB, WN, WP, BK, BQ, BR, BB, BN, BP }; clear(); @@ -100,7 +100,7 @@ void Position::from_fen(const std::string& fen) { continue; } size_t idx = pieceLetters.find(fen[i]); - if (idx == std::string::npos) + if (idx == string::npos) { std::cout << "Error in FEN at character " << i << std::endl; return; @@ -213,18 +213,18 @@ void Position::from_fen(const std::string& fen) { st->materialKey = compute_material_key(); st->mgValue = compute_value(); st->egValue = compute_value(); - npMaterial[WHITE] = compute_non_pawn_material(WHITE); - npMaterial[BLACK] = compute_non_pawn_material(BLACK); + st->npMaterial[WHITE] = compute_non_pawn_material(WHITE); + st->npMaterial[BLACK] = compute_non_pawn_material(BLACK); } /// Position::to_fen() converts the position object to a FEN string. This is /// probably only useful for debugging. -const std::string Position::to_fen() const { +const string Position::to_fen() const { - static const std::string pieceLetters = " PNBRQK pnbrqk"; - std::string fen; + static const string pieceLetters = " PNBRQK pnbrqk"; + string fen; int skip; for (Rank rank = RANK_8; rank >= RANK_1; rank--) @@ -274,7 +274,7 @@ const std::string Position::to_fen() const { void Position::print(Move m) const { - static const std::string pieceLetters = " PNBRQK PNBRQK ."; + static const string pieceLetters = " PNBRQK PNBRQK ."; // Check for reentrancy, as example when called from inside // MovePicker that is used also here in move_to_san() @@ -286,7 +286,7 @@ void Position::print(Move m) const { std::cout << std::endl; if (m != MOVE_NONE) { - std::string col = (color_of_piece_on(move_from(m)) == BLACK ? ".." : ""); + string col = (color_of_piece_on(move_from(m)) == BLACK ? ".." : ""); std::cout << "Move is: " << col << move_to_san(*this, m) << std::endl; } for (Rank rank = RANK_8; rank >= RANK_1; rank--) @@ -377,9 +377,7 @@ Bitboard Position::discovered_check_candidates(Color c) const { } /// Position::attacks_to() computes a bitboard containing all pieces which -/// attacks a given square. There are two versions of this function: One -/// which finds attackers of both colors, and one which only finds the -/// attackers for one side. +/// attacks a given square. Bitboard Position::attacks_to(Square s) const { @@ -658,6 +656,7 @@ inline void Position::update_checkers(Bitboard* pCheckersBB, Square ksq, Square const bool Rook = (Piece == QUEEN || Piece == ROOK); const bool Slider = Bishop || Rook; + // Direct checks if ( ( (Bishop && bit_is_set(BishopPseudoAttacks[ksq], to)) || (Rook && bit_is_set(RookPseudoAttacks[ksq], to))) && bit_is_set(piece_attacks(ksq), to)) // slow, try to early skip @@ -668,6 +667,7 @@ inline void Position::update_checkers(Bitboard* pCheckersBB, Square ksq, Square && bit_is_set(piece_attacks(ksq), to)) set_bit(pCheckersBB, to); + // Discovery checks if (Piece != QUEEN && bit_is_set(dcCandidates, from)) { if (Piece != ROOK) @@ -701,6 +701,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { int castleRights, rule50; Square epSquare; Value mgValue, egValue; + Value npMaterial[2]; }; memcpy(&newSt, st, sizeof(ReducedStateInfo)); @@ -740,12 +741,11 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { do_capture_move(st->capture, them, to); // Move the piece - clear_bit(&(byColorBB[us]), from); - clear_bit(&(byTypeBB[piece]), from); - clear_bit(&(byTypeBB[0]), from); // HACK: byTypeBB[0] == occupied squares - set_bit(&(byColorBB[us]), to); - set_bit(&(byTypeBB[piece]), to); - set_bit(&(byTypeBB[0]), to); // HACK: byTypeBB[0] == occupied squares + Bitboard move_bb = make_move_bb(from, to); + do_move_bb(&(byColorBB[us]), move_bb); + do_move_bb(&(byTypeBB[piece]), move_bb); + do_move_bb(&(byTypeBB[0]), move_bb); // HACK: byTypeBB[0] == occupied squares + board[to] = board[from]; board[from] = EMPTY; @@ -837,6 +837,7 @@ void Position::do_capture_move(PieceType capture, Color them, Square to) { // Remove captured piece clear_bit(&(byColorBB[them]), to); clear_bit(&(byTypeBB[capture]), to); + clear_bit(&(byTypeBB[0]), to); // Update hash key st->key ^= zobrist[them][capture][to]; @@ -851,7 +852,7 @@ void Position::do_capture_move(PieceType capture, Color them, Square to) { // Update material if (capture != PAWN) - npMaterial[them] -= piece_value_midgame(capture); + st->npMaterial[them] -= piece_value_midgame(capture); // Update material hash key st->materialKey ^= zobMaterial[them][capture][pieceCount[them][capture]]; @@ -990,7 +991,7 @@ void Position::do_promotion_move(Move m) { st->capture = type_of_piece_on(to); if (st->capture) - do_capture_move(st->capture, them, to); + do_capture_move(st->capture, them, to); // Remove pawn clear_bit(&(byColorBB[us]), from); @@ -1033,7 +1034,7 @@ void Position::do_promotion_move(Move m) { st->egValue += pst(us, promotion, to); // Update material - npMaterial[us] += piece_value_midgame(promotion); + st->npMaterial[us] += piece_value_midgame(promotion); // Clear the en passant square if (st->epSquare != SQ_NONE) @@ -1169,17 +1170,13 @@ void Position::undo_move(Move m) { assert(color_of_piece_on(to) == us); // Put the piece back at the source square + Bitboard move_bb = make_move_bb(to, from); piece = type_of_piece_on(to); - set_bit(&(byColorBB[us]), from); - set_bit(&(byTypeBB[piece]), from); - set_bit(&(byTypeBB[0]), from); // HACK: byTypeBB[0] == occupied squares + do_move_bb(&(byColorBB[us]), move_bb); + do_move_bb(&(byTypeBB[piece]), move_bb); + do_move_bb(&(byTypeBB[0]), move_bb); // HACK: byTypeBB[0] == occupied squares board[from] = piece_of_color_and_type(us, piece); - // Clear the destination square - clear_bit(&(byColorBB[us]), to); - clear_bit(&(byTypeBB[piece]), to); - clear_bit(&(byTypeBB[0]), to); // HACK: byTypeBB[0] == occupied squares - // If the moving piece was a king, update the king square if (piece == KING) kingSquare[us] = from; @@ -1192,16 +1189,12 @@ void Position::undo_move(Move m) { { assert(st->capture != KING); - // Replace the captured piece + // Restore the captured piece set_bit(&(byColorBB[them]), to); set_bit(&(byTypeBB[st->capture]), to); set_bit(&(byTypeBB[0]), to); board[to] = piece_of_color_and_type(them, st->capture); - // Update material - if (st->capture != PAWN) - npMaterial[them] += piece_value_midgame(st->capture); - // Update piece list pieceList[them][st->capture][pieceCount[them][st->capture]] = to; index[to] = pieceCount[them][st->capture]; @@ -1323,9 +1316,6 @@ void Position::undo_promotion_move(Move m) { set_bit(&(byTypeBB[0]), from); // HACK: byTypeBB[0] == occupied squares board[from] = piece_of_color_and_type(us, PAWN); - // Update material - npMaterial[us] -= piece_value_midgame(promotion); - // Update piece list pieceList[us][PAWN][pieceCount[us][PAWN]] = from; index[from] = pieceCount[us][PAWN]; @@ -1347,11 +1337,6 @@ void Position::undo_promotion_move(Move m) { set_bit(&(byTypeBB[0]), to); // HACK: byTypeBB[0] == occupied squares board[to] = piece_of_color_and_type(them, st->capture); - // Update material. Because the move is a promotion move, we know - // that the captured piece cannot be a pawn. - assert(st->capture != PAWN); - npMaterial[them] += piece_value_midgame(st->capture); - // Update piece list pieceList[them][st->capture][pieceCount[them][st->capture]] = to; index[to] = pieceCount[them][st->capture]; @@ -1404,13 +1389,13 @@ void Position::undo_ep_move(Move m) { set_bit(&(byTypeBB[0]), from); board[from] = piece_of_color_and_type(us, PAWN); - // Update piece list: + // Update piece list pieceList[us][PAWN][index[to]] = from; index[from] = index[to]; pieceList[them][PAWN][pieceCount[them][PAWN]] = capsq; index[capsq] = pieceCount[them][PAWN]; - // Update piece count: + // Update piece count pieceCount[them][PAWN]++; } @@ -1424,12 +1409,13 @@ void Position::do_null_move(StateInfo& backupSt) { assert(!is_check()); // Back up the information necessary to undo the null move to the supplied - // StateInfo object. In the case of a null move, the only thing we need to - // remember is the last move made and the en passant square. + // StateInfo object. // Note that differently from normal case here backupSt is actually used as // a backup storage not as a new state to be used. - backupSt.lastMove = st->lastMove; backupSt.epSquare = st->epSquare; + backupSt.key = st->key; + backupSt.mgValue = st->mgValue; + backupSt.egValue = st->egValue; backupSt.previous = st->previous; st->previous = &backupSt; @@ -1462,21 +1448,16 @@ void Position::undo_null_move() { assert(!is_check()); // Restore information from the our backup StateInfo object - st->lastMove = st->previous->lastMove; st->epSquare = st->previous->epSquare; + st->key = st->previous->key; + st->mgValue = st->previous->mgValue; + st->egValue = st->previous->egValue; st->previous = st->previous->previous; - if (st->epSquare != SQ_NONE) - st->key ^= zobEp[st->epSquare]; - // Update the necessary information sideToMove = opposite_color(sideToMove); st->rule50--; gamePly--; - st->key ^= zobSideToMove; - - st->mgValue += (sideToMove == WHITE)? TempoValueMidgame : -TempoValueMidgame; - st->egValue += (sideToMove == WHITE)? TempoValueEndgame : -TempoValueEndgame; assert(is_ok()); } @@ -2043,8 +2024,8 @@ void Position::flipped_copy(const Position &pos) { st->egValue = compute_value(); // Material - npMaterial[WHITE] = compute_non_pawn_material(WHITE); - npMaterial[BLACK] = compute_non_pawn_material(BLACK); + st->npMaterial[WHITE] = compute_non_pawn_material(WHITE); + st->npMaterial[BLACK] = compute_non_pawn_material(BLACK); assert(is_ok()); } @@ -2180,10 +2161,10 @@ bool Position::is_ok(int* failedStep) const { if (failedStep) (*failedStep)++; if (debugNonPawnMaterial) { - if (npMaterial[WHITE] != compute_non_pawn_material(WHITE)) + if (st->npMaterial[WHITE] != compute_non_pawn_material(WHITE)) return false; - if (npMaterial[BLACK] != compute_non_pawn_material(BLACK)) + if (st->npMaterial[BLACK] != compute_non_pawn_material(BLACK)) return false; }