From 1c73c1c15026766fb1b77b45d58a0c5b98139ae6 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Thu, 5 Nov 2009 12:52:40 +0100 Subject: [PATCH] Extend move_is_legal() to work also when in check This patch is a prerequisite to use TT phase during evasions. No functional change. Signed-off-by: Marco Costalba --- src/movegen.cpp | 10 ++++------ src/position.cpp | 26 ++++++++++++++++++++++++++ src/position.h | 1 + 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/movegen.cpp b/src/movegen.cpp index 4784e95d..da619d1c 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -296,12 +296,10 @@ bool move_is_legal(const Position& pos, const Move m) { /// Fast version of move_is_legal() that takes a position a move and a /// bitboard of pinned pieces as input, and tests whether the move is legal. -/// This version must only be used when the side to move is not in check. bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) { assert(pos.is_ok()); - assert(!pos.is_check()); assert(move_is_ok(m)); assert(pinned == pos.pinned_pieces(pos.side_to_move())); @@ -383,13 +381,13 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) { return false; } // The move is pseudo-legal, check if it is also legal - return pos.pl_move_is_legal(m, pinned); + return pos.is_check() ? pos.pl_move_is_evasion(m, pinned) : pos.pl_move_is_legal(m, pinned); } // Luckly we can handle all the other pieces in one go - return ( bit_is_set(pos.attacks_from(pc, from), to) - && pos.pl_move_is_legal(m, pinned) - && !move_is_promotion(m)); + return bit_is_set(pos.attacks_from(pc, from), to) + && (pos.is_check() ? pos.pl_move_is_evasion(m, pinned) : pos.pl_move_is_legal(m, pinned)) + && !move_is_promotion(m); } diff --git a/src/position.cpp b/src/position.cpp index c6c20dbc..412a7782 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -511,6 +511,32 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { } +/// Position::pl_move_is_evasion() tests whether a pseudo-legal move is a legal evasion + +bool Position::pl_move_is_evasion(Move m, Bitboard pinned) const +{ + assert(pos.is_check()); + + Color us = side_to_move(); + Square from = move_from(m); + Square to = move_to(m); + + // King moves and en-passant captures are verified in pl_move_is_legal() + if (type_of_piece_on(from) == KING || move_is_ep(m)) + return pl_move_is_legal(m, pinned); + + Bitboard target = checkers(); + Square checksq = pop_1st_bit(&target); + + if (target) // double check ? + return false; + + // Our move must be a blocking evasion or a capture of the checking piece + target = squares_between(checksq, king_square(us)) | checkers(); + return bit_is_set(target, to) && pl_move_is_legal(m, pinned); +} + + /// Position::move_is_check() tests whether a pseudo-legal move is a check bool Position::move_is_check(Move m) const { diff --git a/src/position.h b/src/position.h index 2568563c..0e3c16c7 100644 --- a/src/position.h +++ b/src/position.h @@ -203,6 +203,7 @@ public: // Properties of moves bool pl_move_is_legal(Move m, Bitboard pinned) const; + bool pl_move_is_evasion(Move m, Bitboard pinned) const; bool move_is_check(Move m) const; bool move_is_check(Move m, Bitboard dcCandidates) const; bool move_is_capture(Move m) const; -- 2.39.2