From: Marco Costalba Date: Thu, 19 Feb 2009 15:28:35 +0000 (+0100) Subject: Cache pinned and discovery check bitboards X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=5f142ec2098531bac1780f67579dedbd12d18dcc Cache pinned and discovery check bitboards After have been calculated cache their values so to avoid another expensive call to hidden_checks() if pinned_pieces() or discovered_check_candidates() are called with the same position. Add also interface to get pinners bitboard, we already have this value so save it instead of discard. Now that, after the first call to pinned_pieces() the following are very cheap we can rewrite and cleanup all the checking handling. So this patch is a prerequisite for future work. No functional change. Signed-off-by: Marco Costalba --- diff --git a/src/position.cpp b/src/position.cpp index 382073a7..a999b4c6 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -323,29 +323,42 @@ void Position::copy(const Position &pos) { /// king) pieces for the given color. Bitboard Position::pinned_pieces(Color c) const { + if (pinned[c] != ~EmptyBoardBB) + return pinned[c]; + + Bitboard p1, p2; Square ksq = king_square(c); - return hidden_checks(c, ksq) | hidden_checks(c, ksq); + pinned[c] = hidden_checks(c, ksq, p1) | hidden_checks(c, ksq, p2); + pinners[c] = p1 | p2; + return pinned[c]; } +Bitboard Position::pinned_pieces(Color c, Bitboard& p) const { + + if (pinned[c] == ~EmptyBoardBB) + pinned_pieces(c); -/// Position:discovered_check_candidates() returns a bitboard containing all -/// pieces for the given side which are candidates for giving a discovered -/// check. The code is almost the same as the function for finding pinned -/// pieces. + p = pinners[c]; + return pinned[c]; +} Bitboard Position::discovered_check_candidates(Color c) const { + if (dcCandidates[c] != ~EmptyBoardBB) + return dcCandidates[c]; + + Bitboard dummy; Square ksq = king_square(opposite_color(c)); - return hidden_checks(c, ksq) | hidden_checks(c, ksq); + dcCandidates[c] = hidden_checks(c, ksq, dummy) | hidden_checks(c, ksq, dummy); + return dcCandidates[c]; } - /// Position:hidden_checks<>() returns a bitboard of all pinned (against the /// king) pieces for the given color and for the given pinner type. Or, when /// template parameter FindPinned is false, the pinned pieces of opposite color /// that are, indeed, the pieces candidate for a discovery check. template -Bitboard Position::hidden_checks(Color c, Square ksq) const { +Bitboard Position::hidden_checks(Color c, Square ksq, Bitboard& pinners) const { Square s; Bitboard sliders, result = EmptyBoardBB; @@ -362,7 +375,7 @@ Bitboard Position::hidden_checks(Color c, Square ksq) const { // Pinners are sliders, not checkers, that give check when // candidate pinned are removed. - Bitboard pinners = (FindPinned ? sliders & ~checkersBB : sliders); + pinners = (FindPinned ? sliders & ~checkersBB : sliders); if (Piece == ROOK) pinners &= rook_attacks_bb(ksq, occupied_squares() ^ candidate_pinned); @@ -371,12 +384,16 @@ Bitboard Position::hidden_checks(Color c, Square ksq) const { // Finally for each pinner find the corresponding pinned piece (if same color of king) // or discovery checker (if opposite color) among the candidates. - while (pinners) + Bitboard p = pinners; + while (p) { - s = pop_1st_bit(&pinners); + s = pop_1st_bit(&p); result |= (squares_between(s, ksq) & candidate_pinned); } } + else + pinners = EmptyBoardBB; + return result; } @@ -692,6 +709,13 @@ void Position::backup(UndoInfo& u) const { u.mgValue = mgValue; u.egValue = egValue; u.capture = NO_PIECE_TYPE; + + for (Color c = WHITE; c <= BLACK; c++) + { + u.pinners[c] = pinners[c]; + u.pinned[c] = pinned[c]; + u.dcCandidates[c] = dcCandidates[c]; + } } @@ -711,6 +735,13 @@ void Position::restore(const UndoInfo& u) { mgValue = u.mgValue; egValue = u.egValue; // u.capture is restored in undo_move() + + for (Color c = WHITE; c <= BLACK; c++) + { + pinners[c] = u.pinners[c]; + pinned[c] = u.pinned[c]; + dcCandidates[c] = u.dcCandidates[c]; + } } @@ -748,7 +779,7 @@ void Position::do_move(Move m, UndoInfo& u) { do_move(m, u, discovered_check_candidates(side_to_move())); } -void Position::do_move(Move m, UndoInfo& u, Bitboard dcCandidates) { +void Position::do_move(Move m, UndoInfo& u, Bitboard dc) { assert(is_ok()); assert(move_is_ok(m)); @@ -765,6 +796,10 @@ void Position::do_move(Move m, UndoInfo& u, Bitboard dcCandidates) { // case of non-reversible moves is taken care of later. rule50++; + // Reset pinned bitboard and its friends + for (Color c = WHITE; c <= BLACK; c++) + pinners[c] = pinned[c] = dcCandidates[c] = ~EmptyBoardBB; + if (move_is_castle(m)) do_castle_move(m); else if (move_promotion(m)) @@ -856,12 +891,12 @@ void Position::do_move(Move m, UndoInfo& u, Bitboard dcCandidates) { Square ksq = king_square(them); switch (piece) { - case PAWN: update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; - case KNIGHT: update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; - case BISHOP: update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; - case ROOK: update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; - case QUEEN: update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; - case KING: update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; + case PAWN: update_checkers(&checkersBB, ksq, from, to, dc); break; + case KNIGHT: update_checkers(&checkersBB, ksq, from, to, dc); break; + case BISHOP: update_checkers(&checkersBB, ksq, from, to, dc); break; + case ROOK: update_checkers(&checkersBB, ksq, from, to, dc); break; + case QUEEN: update_checkers(&checkersBB, ksq, from, to, dc); break; + case KING: update_checkers(&checkersBB, ksq, from, to, dc); break; default: assert(false); break; } } @@ -1719,6 +1754,8 @@ void Position::clear() { } checkersBB = EmptyBoardBB; + for (Color c = WHITE; c <= BLACK; c++) + pinners[c] = pinned[c] = dcCandidates[c] = ~EmptyBoardBB; lastMove = MOVE_NONE; diff --git a/src/position.h b/src/position.h index ceebce1c..3fabf64c 100644 --- a/src/position.h +++ b/src/position.h @@ -82,7 +82,7 @@ enum CastleRights { struct UndoInfo { int castleRights; Square epSquare; - Bitboard checkersBB; + Bitboard checkersBB, pinners[2], pinned[2], dcCandidates[2]; Key key, pawnKey, materialKey; int rule50; Move lastMove; @@ -197,6 +197,7 @@ public: // Bitboards for pinned pieces and discovered check candidates Bitboard discovered_check_candidates(Color c) const; + Bitboard pinned_pieces(Color c, Bitboard& p) const; Bitboard pinned_pieces(Color c) const; // Checking pieces @@ -312,7 +313,7 @@ private: void update_checkers(Bitboard* pCheckersBB, Square ksq, Square from, Square to, Bitboard dcCandidates); template - Bitboard hidden_checks(Color c, Square ksq) const; + Bitboard hidden_checks(Color c, Square ksq, Bitboard& pinners) const; // Computing hash keys from scratch (for initialization and debugging) Key compute_key() const; @@ -329,6 +330,7 @@ private: // Bitboards Bitboard byColorBB[2], byTypeBB[8]; Bitboard checkersBB; + mutable Bitboard pinners[2], pinned[2], dcCandidates[2]; // Board Piece board[64];