]> git.sesse.net Git - stockfish/commitdiff
Extend move_is_legal() to work also when in check
authorMarco Costalba <mcostalba@gmail.com>
Thu, 5 Nov 2009 11:52:40 +0000 (12:52 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Thu, 5 Nov 2009 13:58:57 +0000 (14:58 +0100)
This patch is a prerequisite to use TT phase
during evasions.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/movegen.cpp
src/position.cpp
src/position.h

index 4784e95d93aa25b142d9244aa419bfdb196519e3..da619d1c605e17de1199aa99de245403d60adb79 100644 (file)
@@ -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);
 }
 
 
index c6c20dbce73d40c2e4f45270de6689c1e1eee8bd..412a7782462c3ee203bdbf296747896dba888f88 100644 (file)
@@ -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 {
index 2568563cb5d335147d700e509a6349ea14f250df..0e3c16c7f2dbac1d915fc28801f56ae8b623d645 100644 (file)
@@ -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;