1
0
Fork 0

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 <mcostalba@gmail.com>
sf_2.3.1_base
Marco Costalba 2009-02-19 16:28:35 +01:00
parent 7f4f18f959
commit 5f142ec209
2 changed files with 60 additions and 21 deletions

View File

@ -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<ROOK, true>(c, ksq) | hidden_checks<BISHOP, true>(c, ksq);
pinned[c] = hidden_checks<ROOK, true>(c, ksq, p1) | hidden_checks<BISHOP, true>(c, ksq, p2);
pinners[c] = p1 | p2;
return pinned[c];
}
Bitboard Position::pinned_pieces(Color c, Bitboard& p) const {
/// 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.
if (pinned[c] == ~EmptyBoardBB)
pinned_pieces(c);
p = pinners[c];
return pinned[c];
}
Bitboard Position::discovered_check_candidates(Color c) const {
Square ksq = king_square(opposite_color(c));
return hidden_checks<ROOK, false>(c, ksq) | hidden_checks<BISHOP, false>(c, ksq);
}
if (dcCandidates[c] != ~EmptyBoardBB)
return dcCandidates[c];
Bitboard dummy;
Square ksq = king_square(opposite_color(c));
dcCandidates[c] = hidden_checks<ROOK, false>(c, ksq, dummy) | hidden_checks<BISHOP, false>(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<PieceType Piece, bool FindPinned>
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<PAWN>(&checkersBB, ksq, from, to, dcCandidates); break;
case KNIGHT: update_checkers<KNIGHT>(&checkersBB, ksq, from, to, dcCandidates); break;
case BISHOP: update_checkers<BISHOP>(&checkersBB, ksq, from, to, dcCandidates); break;
case ROOK: update_checkers<ROOK>(&checkersBB, ksq, from, to, dcCandidates); break;
case QUEEN: update_checkers<QUEEN>(&checkersBB, ksq, from, to, dcCandidates); break;
case KING: update_checkers<KING>(&checkersBB, ksq, from, to, dcCandidates); break;
case PAWN: update_checkers<PAWN>(&checkersBB, ksq, from, to, dc); break;
case KNIGHT: update_checkers<KNIGHT>(&checkersBB, ksq, from, to, dc); break;
case BISHOP: update_checkers<BISHOP>(&checkersBB, ksq, from, to, dc); break;
case ROOK: update_checkers<ROOK>(&checkersBB, ksq, from, to, dc); break;
case QUEEN: update_checkers<QUEEN>(&checkersBB, ksq, from, to, dc); break;
case KING: update_checkers<KING>(&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;

View File

@ -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<PieceType Piece, bool FindPinned>
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];