Do not null search when beta is a mate value
authorMarco Costalba <mcostalba@gmail.com>
Mon, 15 Dec 2008 10:50:01 +0000 (11:50 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 15 Dec 2008 21:19:25 +0000 (22:19 +0100)
Also do not return unproven mates in null search.

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

index ab3e6f66cdcf9d7988c4dd7e167216bc90b90751..cbb6ea0980a6f6c005c31ee62d45ef862dcb271f 100644 (file)
@@ -267,6 +267,7 @@ namespace {
   void update_pv(SearchStack ss[], int ply);
   void sp_update_pv(SearchStack *pss, SearchStack ss[], int ply);
   bool connected_moves(const Position &pos, Move m1, Move m2);
+  bool value_is_mate(Value value);
   bool move_is_killer(Move m, const SearchStack& ss);
   Depth extension(const Position &pos, Move m, bool pvNode, bool check, bool singleReply, bool mateThreat, bool* dangerous);
   bool ok_to_do_nullmove(const Position &pos);
@@ -1176,6 +1177,7 @@ namespace {
     if (    allowNullmove
         &&  depth > OnePly
         && !isCheck
+        && !value_is_mate(beta)
         &&  ok_to_do_nullmove(pos)
         &&  approximateEval >= beta - NullMoveMargin)
     {
@@ -1201,7 +1203,11 @@ namespace {
 
         pos.undo_null_move(u);
 
-        if (nullValue >= beta)
+        if (value_is_mate(nullValue))
+        {
+            /* Do not return unproven mates */
+        }
+        else if (nullValue >= beta)
         {
             if (depth < 6 * OnePly)
                 return beta;
@@ -1298,10 +1304,12 @@ namespace {
           && !moveIsCapture
           && !move_promotion(move))
       {
+          // History pruning. See ok_to_prune() definition.
           if (   moveCount >= 2 + int(depth)
               && ok_to_prune(pos, move, ss[ply].threatMove, depth))
               continue;
 
+          // Value based pruning.
           if (depth < 3 * OnePly && approximateEval < beta)
           {
               if (futilityValue == VALUE_NONE)
@@ -2120,6 +2128,18 @@ namespace {
   }
 
 
+  // value_is_mate() checks if the given value is a mate one
+  // eventually compensated for the ply.
+
+  bool value_is_mate(Value value) {
+
+    assert(abs(value) <= VALUE_INFINITE);
+
+    return   value <= value_mated_in(PLY_MAX)
+          || value >= value_mate_in(PLY_MAX);
+  }
+
+
   // move_is_killer() checks if the given move is among the
   // killer moves of that ply.