Greatly speedup has_mate_threat()
authorMarco Costalba <mcostalba@gmail.com>
Mon, 20 Apr 2009 07:10:27 +0000 (09:10 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 26 Apr 2009 12:40:26 +0000 (13:40 +0100)
Instead of loop across all legal moves to find a mate
loop across possible check moves only.

This reduces more then 10 times the number of moves to
check for a possible mate.

Also rename generate_checks() in generate_non_capture_checks()
so to better clarify what the function does.

No functional change.

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

index dff9e8c..b3a2580 100644 (file)
@@ -176,10 +176,10 @@ int generate_noncaptures(const Position& pos, MoveStack* mlist) {
 }
 
 
-/// generate_checks() generates all pseudo-legal non-capturing, non-promoting
-/// checks. It returns the number of generated moves.
+/// generate_non_capture_checks() generates all pseudo-legal non-capturing,
+/// non-promoting checks. It returns the number of generated moves.
 
-int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) {
+int generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bitboard dc) {
 
   assert(pos.is_ok());
   assert(!pos.is_check());
index 1871568..c844efc 100644 (file)
@@ -34,7 +34,7 @@
 
 extern int generate_captures(const Position& pos, MoveStack* mlist);
 extern int generate_noncaptures(const Position& pos, MoveStack* mlist);
-extern int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc);
+extern int generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bitboard dc);
 extern int generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned);
 extern int generate_legal_moves(const Position& pos, MoveStack* mlist);
 extern bool move_is_legal(const Position& pos, const Move m, Bitboard pinned);
index 280a61a..6c3f426 100644 (file)
@@ -163,7 +163,7 @@ Move MovePicker::get_next_move() {
         break;
 
     case PH_QCHECKS:
-        numOfMoves = generate_checks(pos, moves, dc);
+        numOfMoves = generate_non_capture_checks(pos, moves, dc);
         movesPicked = 0;
         break;
 
index 3e72c0e..abe7580 100644 (file)
@@ -1903,20 +1903,13 @@ bool Position::is_mate() const {
 
 
 /// Position::has_mate_threat() tests whether a given color has a mate in one
-/// from the current position. This function is quite slow, but it doesn't
-/// matter, because it is currently only called from PV nodes, which are rare.
+/// from the current position.
 
 bool Position::has_mate_threat(Color c) {
 
   StateInfo st1, st2;
   Color stm = side_to_move();
 
-  // The following lines are useless and silly, but prevents gcc from
-  // emitting a stupid warning stating that u1.lastMove and u1.epSquare might
-  // be used uninitialized.
-  st1.lastMove = st->lastMove;
-  st1.epSquare = st->epSquare;
-
   if (is_check())
       return false;
 
@@ -1927,18 +1920,26 @@ bool Position::has_mate_threat(Color c) {
   MoveStack mlist[120];
   int count;
   bool result = false;
+  Bitboard dc = discovered_check_candidates(sideToMove);
+  Bitboard pinned = pinned_pieces(sideToMove);
 
-  // Generate legal moves
-  count = generate_legal_moves(*this, mlist);
+  // Generate pseudo-legal non-capture and capture check moves
+  count = generate_non_capture_checks(*this, mlist, dc);
+  count += generate_captures(*this, mlist + count);
 
   // Loop through the moves, and see if one of them is mate
   for (int i = 0; i < count; i++)
   {
-      do_move(mlist[i].move, st2);
+      Move move = mlist[i].move;
+
+      if (!pl_move_is_legal(move, pinned))
+          continue;
+
+      do_move(move, st2);
       if (is_mate())
           result = true;
 
-      undo_move(mlist[i].move);
+      undo_move(move);
   }
 
   // Undo null move, if necessary