/// Functions for testing whether a given bit is set in a bitboard, and for
/// setting and clearing bits.
-inline Bitboard set_mask_bb(Square s) {
- // return 1ULL << s;
- return SetMaskBB[s];
-}
-
-inline Bitboard clear_mask_bb(Square s) {
- // return ~set_mask_bb(s);
- return ClearMaskBB[s];
-}
-
inline Bitboard bit_is_set(Bitboard b, Square s) {
- return b & set_mask_bb(s);
+ return b & SetMaskBB[s];
}
inline void set_bit(Bitboard *b, Square s) {
- *b |= set_mask_bb(s);
+ *b |= SetMaskBB[s];
}
inline void clear_bit(Bitboard *b, Square s) {
- *b &= clear_mask_bb(s);
+ *b &= ClearMaskBB[s];
}
while (b)
{
Square from, to = pop_1st_bit(&b);
- if (!(escapeSquares & ~queen_attacks_bb(to, occ & clear_mask_bb(s))))
+ if (!(escapeSquares & ~queen_attacks_bb(to, occ & ClearMaskBB[s])))
{
// We have a mate, unless the queen is pinned or there
// is an X-ray attack through the queen.
from = p.piece_list(them, QUEEN, i);
if ( bit_is_set(p.piece_attacks<QUEEN>(from), to)
&& !bit_is_set(p.pinned_pieces(them), from)
- && !(rook_attacks_bb(to, occ & clear_mask_bb(from)) & p.rooks_and_queens(us))
- && !(rook_attacks_bb(to, occ & clear_mask_bb(from)) & p.rooks_and_queens(us)))
+ && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.rooks_and_queens(us))
+ && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.rooks_and_queens(us)))
ei.mateThreat[them] = make_move(from, to);
}
}
-/// Position:pinned_pieces() returns a bitboard of all pinned (against the
-/// king) pieces for the given color.
+/// Position:pinned_pieces<>() returns a bitboard of all pinned (against the
+/// king) pieces for the given color and for the given pinner type.
+template<PieceType Piece>
+Bitboard Position::pinned_pieces(Color c, Square ksq) const {
-Bitboard Position::pinned_pieces(Color c) const {
- Bitboard b1, b2, pinned, pinners, sliders;
- Square ksq = king_square(c), s;
- Color them = opposite_color(c);
+ Square s;
+ Bitboard sliders, pinned = EmptyBoardBB;
+
+ if (Piece == ROOK) // Resolved at compile time
+ sliders = rooks_and_queens(opposite_color(c)) & RookPseudoAttacks[ksq];
+ else
+ sliders = bishops_and_queens(opposite_color(c)) & BishopPseudoAttacks[ksq];
- pinned = EmptyBoardBB;
- b1 = occupied_squares();
+ if (sliders && (sliders & ~checkersBB))
+ {
+ // Our king blockers are candidate pinned pieces
+ Bitboard candidate_pinned = piece_attacks<Piece>(ksq) & pieces_of_color(c);
+
+ // Pinners are sliders, not checkers, that give check when
+ // candidate pinned are removed.
+ Bitboard pinners = sliders & ~checkersBB;
+ if (Piece == ROOK)
+ pinners &= rook_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);
+ else
+ pinners &= bishop_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);
- sliders = rooks_and_queens(them) & ~checkers();
- if(sliders & RookPseudoAttacks[ksq]) {
- b2 = piece_attacks<ROOK>(ksq) & pieces_of_color(c);
- pinners = rook_attacks_bb(ksq, b1 ^ b2) & sliders;
- while(pinners) {
- s = pop_1st_bit(&pinners);
- pinned |= (squares_between(s, ksq) & b2);
- }
+ // Finally for each pinner find the corresponding pinned piece
+ // among the candidates.
+ while (pinners)
+ {
+ s = pop_1st_bit(&pinners);
+ pinned |= (squares_between(s, ksq) & candidate_pinned);
+ }
}
+ return pinned;
+}
- sliders = bishops_and_queens(them) & ~checkers();
- if(sliders & BishopPseudoAttacks[ksq]) {
- b2 = piece_attacks<BISHOP>(ksq) & pieces_of_color(c);
- pinners = bishop_attacks_bb(ksq, b1 ^ b2) & sliders;
- while(pinners) {
- s = pop_1st_bit(&pinners);
- pinned |= (squares_between(s, ksq) & b2);
- }
- }
- return pinned;
+/// Position:pinned_pieces() returns a bitboard of all pinned (against the
+/// king) pieces for the given color.
+Bitboard Position::pinned_pieces(Color c) const {
+
+ Square ksq = king_square(c);
+ return pinned_pieces<ROOK>(c, ksq) | pinned_pieces<BISHOP>(c, ksq);
}
+
/// 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
// Bitboards for pinned pieces and discovered check candidates
Bitboard discovered_check_candidates(Color c) const;
Bitboard pinned_pieces(Color c) const;
+ template<PieceType Piece>
+ Bitboard pinned_pieces(Color c, Square ksq) const;
// Checking pieces
Bitboard checkers() const;
}
inline bool Position::is_check() const {
- return checkers() != EmptyBoardBB;
+ return checkersBB != EmptyBoardBB;
}
inline bool Position::pawn_attacks_square(Color c, Square f, Square t) const {