- sliders = bishops_and_queens(c);
- if(sliders & BishopPseudoAttacks[ksq]) {
- b2 = bishop_attacks(ksq) & pieces_of_color(c);
- checkers = bishop_attacks_bb(ksq, b1 ^ b2) & sliders;
- while(checkers) {
- s = pop_1st_bit(&checkers);
- dc |= (squares_between(s, ksq) & b2);
- }
- }
+ Square ksq = king_square(opposite_color(c));
+ return hidden_checks<ROOK, false>(c, ksq) | hidden_checks<BISHOP, false>(c, ksq);
+}
+
+
+/// 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 {
+
+ Square s;
+ Bitboard sliders, result = EmptyBoardBB;
+
+ if (Piece == ROOK) // Resolved at compile time
+ sliders = rooks_and_queens(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq];
+ else
+ sliders = bishops_and_queens(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq];
+
+ if (sliders && (!FindPinned || (sliders & ~checkersBB)))
+ {
+ // 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 = (FindPinned ? sliders & ~checkersBB : sliders);
+
+ if (Piece == ROOK)
+ pinners &= rook_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);
+ else
+ pinners &= bishop_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);