From c6f497f09de59ce4889c2045e0e4b6efb3082899 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 30 Oct 2011 18:59:12 +0100 Subject: [PATCH 1/1] Fix small bug in move_attacks_square() We test if the piece moved in 'to' attacks the square 's' with: bit_is_set(attacks_from(piece, to), s)) But we should instead consider the new occupancy, changed after the piece is moved, and so test with: bit_is_set(attacks_from(piece, to, occ), s)) Otherwise we can miss some cases, for instance a queen in b1 that moves in c1 is not detected to attack a1 while instead she does. Signed-off-by: Marco Costalba --- src/position.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 4160822b..12485fbb 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -377,7 +377,7 @@ template Bitboard Position::hidden_checkers() const; template Bitboard Position::hidden_checkers() const; -/// Position::attackers_to() computes a bitboard of all pieces which attacks a +/// Position::attackers_to() computes a bitboard of all pieces which attack a /// given square. Slider attacks use occ bitboard as occupancy. Bitboard Position::attackers_to(Square s, Bitboard occ) const { @@ -417,22 +417,25 @@ bool Position::move_attacks_square(Move m, Square s) const { assert(square_is_ok(s)); Bitboard occ, xray; - Square f = move_from(m), t = move_to(m); + Square from = move_from(m); + Square to = move_to(m); + Piece piece = piece_on(from); - assert(!square_is_empty(f)); + assert(!square_is_empty(from)); - if (bit_is_set(attacks_from(piece_on(f), t), s)) + // Update occupancy as if the piece is moving + occ = occupied_squares(); + do_move_bb(&occ, make_move_bb(from, to)); + + // The piece moved in 'to' attacks the square 's' ? + if (bit_is_set(attacks_from(piece, to, occ), s)) return true; - // Move the piece and scan for X-ray attacks behind it - occ = occupied_squares(); - do_move_bb(&occ, make_move_bb(f, t)); - xray = ( (rook_attacks_bb(s, occ) & pieces(ROOK, QUEEN)) - |(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN))) - & pieces(color_of(piece_on(f))); + // Scan for possible X-ray attackers behind the moved piece + xray = (rook_attacks_bb(s, occ) & pieces(ROOK, QUEEN, color_of(piece))) + |(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN, color_of(piece))); - // If we have attacks we need to verify that are caused by our move - // and are not already existent ones. + // Verify attackers are triggered by our move and not already existing return xray && (xray ^ (xray & attacks_from(s))); } -- 2.39.2