const bool Rook = (Piece == QUEEN || Piece == ROOK);
const bool Slider = Bishop || Rook;
+ assert(*pCheckersBB == EmptyBoardBB);
+
// Direct checks
- if ( ( (Bishop && bit_is_set(BishopPseudoAttacks[ksq], to))
+ if ( ( !Slider // try to early skip slide piece attacks
+ || (Bishop && bit_is_set(BishopPseudoAttacks[ksq], to))
|| (Rook && bit_is_set(RookPseudoAttacks[ksq], to)))
- && bit_is_set(attacks_from<Piece>(ksq), to)) // slow, try to early skip
- set_bit(pCheckersBB, to);
-
- else if ( Piece != KING
- && !Slider
- && bit_is_set(Piece == PAWN ? attacks_from<PAWN>(ksq, opposite_color(sideToMove))
- : attacks_from<Piece>(ksq), to))
- set_bit(pCheckersBB, to);
-
+ && bit_is_set(Piece == PAWN ? attacks_from<PAWN>(ksq, opposite_color(sideToMove)) : attacks_from<Piece>(ksq) , to))
+ {
+ *pCheckersBB = SetMaskBB[to];
+ }
// Discovery checks
- if (Piece != QUEEN && bit_is_set(dcCandidates, from))
+ if (Piece != QUEEN && dcCandidates && bit_is_set(dcCandidates, from))
{
if (Piece != ROOK)
(*pCheckersBB) |= (attacks_from<ROOK>(ksq) & pieces(ROOK, QUEEN, side_to_move()));
do_move(m, newSt, discovered_check_candidates(side_to_move()));
}
-void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
+void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates, bool moveCanBeCheck) {
assert(is_ok());
assert(move_is_ok(m));
st->key = key;
// Update checkers bitboard, piece must be already moved
- if (ep | pm)
- st->checkersBB = attackers_to(king_square(them)) & pieces_of_color(us);
- else
+ st->checkersBB = EmptyBoardBB;
+
+ if (moveCanBeCheck)
{
- st->checkersBB = EmptyBoardBB;
- Square ksq = king_square(them);
- switch (pt)
+ if (ep | pm)
+ st->checkersBB = attackers_to(king_square(them)) & pieces_of_color(us);
+ else
{
- case PAWN: update_checkers<PAWN>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
- case KNIGHT: update_checkers<KNIGHT>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
- case BISHOP: update_checkers<BISHOP>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
- case ROOK: update_checkers<ROOK>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
- case QUEEN: update_checkers<QUEEN>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
- case KING: update_checkers<KING>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
- default: assert(false); break;
+ Square ksq = king_square(them);
+ switch (pt)
+ {
+ case PAWN: update_checkers<PAWN>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
+ case KNIGHT: update_checkers<KNIGHT>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
+ case BISHOP: update_checkers<BISHOP>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
+ case ROOK: update_checkers<ROOK>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
+ case QUEEN: update_checkers<QUEEN>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
+ case KING: update_checkers<KING>(&(st->checkersBB), ksq, from, to, dcCandidates); break;
+ default: assert(false); break;
+ }
}
}