X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fposition.cpp;h=2585ef3c84c0775d4d4a965ac69e5f9281fa5128;hb=f32992f88c16c6d4c2b72164c88fc4581f8faba7;hp=31176c9d42ead1a504a57c426b1b40c748a7f6c1;hpb=088ecc242f6ef35e7785577482535ebfad56b975;p=stockfish diff --git a/src/position.cpp b/src/position.cpp index 31176c9d..2585ef3c 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -118,7 +118,7 @@ void Position::from_fen(const std::string& fen) { } sideToMove = (fen[i] == 'w' ? WHITE : BLACK); - // Castling rights: + // Castling rights i++; if (fen[i] != ' ') { @@ -420,30 +420,44 @@ bool Position::piece_attacks_square(Square f, Square t) const { /// Position::move_attacks_square() tests whether a move from the current -/// position attacks a given square. Only attacks by the moving piece are -/// considered; the function does not handle X-ray attacks. +/// position attacks a given square. bool Position::move_attacks_square(Move m, Square s) const { assert(move_is_ok(m)); assert(square_is_ok(s)); + bool is_attack; Square f = move_from(m), t = move_to(m); assert(square_is_occupied(f)); switch (piece_on(f)) { - case WP: return pawn_attacks_square(WHITE, t, s); - case BP: return pawn_attacks_square(BLACK, t, s); - case WN: case BN: return piece_attacks_square(t, s); - case WB: case BB: return piece_attacks_square(t, s); - case WR: case BR: return piece_attacks_square(t, s); - case WQ: case BQ: return piece_attacks_square(t, s); - case WK: case BK: return piece_attacks_square(t, s); + case WP: is_attack = pawn_attacks_square(WHITE, t, s); break; + case BP: is_attack = pawn_attacks_square(BLACK, t, s); break; + case WN: case BN: is_attack = piece_attacks_square(t, s); break; + case WB: case BB: is_attack = piece_attacks_square(t, s); break; + case WR: case BR: is_attack = piece_attacks_square(t, s); break; + case WQ: case BQ: is_attack = piece_attacks_square(t, s); break; + case WK: case BK: is_attack = piece_attacks_square(t, s); break; default: break; } - return false; + + if (is_attack) + return true; + + // Move the piece and scan for X-ray attacks behind it + Bitboard occ = occupied_squares(); + Color us = color_of_piece_on(f); + clear_bit(&occ, f); + set_bit(&occ, t); + Bitboard xray = ( (rook_attacks_bb(s, occ) & rooks_and_queens()) + |(bishop_attacks_bb(s, occ) & bishops_and_queens())) & pieces_of_color(us); + + // If we have attacks we need to verify that are caused by our move + // and are not already existent ones. + return xray && (xray ^ (xray & piece_attacks(s))); } @@ -665,7 +679,7 @@ bool Position::move_is_capture(Move m) const { assert(m != MOVE_NONE); return ( !square_is_empty(move_to(m)) - && (color_of_piece_on(move_to(m)) == opposite_color(side_to_move())) + && (color_of_piece_on(move_to(m)) != color_of_piece_on(move_from(m))) ) || move_is_ep(m); }