]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Do not prune the move if we are still under mate
[stockfish] / src / search.cpp
index 58b60c878d872f986157e84a823386a40b33a0d5..53811de04701c4705053dc0d3ed1e52049db0aed 100644 (file)
@@ -299,6 +299,7 @@ namespace {
   void ponderhit();
   void print_current_line(SearchStack ss[], int ply, int threadID);
   void wait_for_stop_or_ponderhit();
+  void init_ss_array(SearchStack ss[]);
 
   void idle_loop(int threadID, SplitPoint* waitSp);
   void init_split_point_stack();
@@ -445,7 +446,8 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
       if (movesToGo == 1)
       {
           MaxSearchTime = myTime / 2;
-          AbsoluteMaxSearchTime = Min(myTime / 2, myTime - 500);
+          AbsoluteMaxSearchTime = 
+             (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4);
       } else {
           MaxSearchTime = myTime / Min(movesToGo, 20);
           AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3);
@@ -469,6 +471,10 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
       NodesBetweenPolls = Min(MaxNodes, 30000);
       InfiniteSearch = true; // HACK
   }
+  else if (myTime && myTime < 1000)
+      NodesBetweenPolls = 1000;
+  else if (myTime && myTime < 5000)
+      NodesBetweenPolls = 5000;
   else
       NodesBetweenPolls = 30000;
 
@@ -489,9 +495,9 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
   {
       Value v = id_loop(pos, searchMoves);
       loseOnTime = (   UseLSNFiltering
-                     && myTime < LSNTime
-                     && myIncrement == 0
-                     && v < -LSNValue);
+                    && myTime < LSNTime
+                    && myIncrement == 0
+                    && v < -LSNValue);
   }
   else
   {
@@ -636,11 +642,7 @@ namespace {
     // Initialize
     TT.new_search();
     H.clear();
-    for (int i = 0; i < 3; i++)
-    {
-        ss[i].init(i);
-        ss[i].initKillers();
-    }
+    init_ss_array(ss);
     IterationInfo[1] = IterationInfoType(rml.get_move_score(0), rml.get_move_score(0));
     Iteration = 1;
 
@@ -947,7 +949,7 @@ namespace {
             // Update PV
             rml.set_move_score(i, value);
             update_pv(ss, 0);
-            TT.extract_pv(pos, ss[0].pv);
+            TT.extract_pv(pos, ss[0].pv, PLY_MAX);
             rml.set_move_pv(i, ss[0].pv);
 
             if (MultiPV == 1)
@@ -974,7 +976,10 @@ namespace {
                 std::cout << std::endl;
 
                 if (UseLogFile)
-                    LogFile << pretty_pv(pos, current_search_time(), Iteration, nodes_searched(), value, ss[0].pv)
+                    LogFile << pretty_pv(pos, current_search_time(), Iteration, nodes_searched(), value, 
+                                         ((value >= beta)? VALUE_TYPE_LOWER
+                                          : ((value <= alpha)? VALUE_TYPE_UPPER : VALUE_TYPE_EXACT)),
+                                         ss[0].pv)
                             << std::endl;
 
                 if (value > alpha)
@@ -1043,7 +1048,7 @@ namespace {
     EvalInfo ei;
 
     if (ply >= PLY_MAX - 1)
-        return evaluate(pos, ei, threadID);
+        return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID);
 
     // Mate distance pruning
     Value oldAlpha = alpha;
@@ -1233,7 +1238,7 @@ namespace {
     EvalInfo ei;
 
     if (ply >= PLY_MAX - 1)
-        return evaluate(pos, ei, threadID);
+        return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID);
 
     // Mate distance pruning
     if (value_mated_in(ply) >= beta)
@@ -1333,6 +1338,10 @@ namespace {
     bool useFutilityPruning =   depth < SelectiveDepth
                              && !isCheck;
 
+    // Avoid calling evaluate() if we already have the score in TT
+    if (tte && (tte->type() & VALUE_TYPE_EVAL))
+        futilityValue = value_from_tt(tte->value(), ply) + FutilityMargins[int(depth) - 2];
+
     // Loop through all legal moves until no moves remain or a beta cutoff
     // occurs.
     while (   bestValue < beta
@@ -1360,7 +1369,8 @@ namespace {
       {
           // History pruning. See ok_to_prune() definition
           if (   moveCount >= 2 + int(depth)
-              && ok_to_prune(pos, move, ss[ply].threatMove, depth))
+              && ok_to_prune(pos, move, ss[ply].threatMove, depth)
+              && bestValue > value_mated_in(PLY_MAX))
               continue;
 
           // Value based pruning
@@ -1520,8 +1530,8 @@ namespace {
     else
         staticValue = evaluate(pos, ei, threadID);
 
-    if (ply == PLY_MAX - 1)
-        return evaluate(pos, ei, threadID);
+    if (ply >= PLY_MAX - 1)
+        return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID);
 
     // Initialize "stand pat score", and return it immediately if it is
     // at least beta.
@@ -1957,6 +1967,7 @@ namespace {
         // Find a quick score for the move
         StateInfo st;
         SearchStack ss[PLY_MAX_PLUS_2];
+        init_ss_array(ss);
 
         moves[count].move = cur->move;
         pos.do_move(moves[count].move, st);
@@ -2556,6 +2567,18 @@ namespace {
   }
 
 
+  // init_ss_array() does a fast reset of the first entries of a SearchStack array
+
+  void init_ss_array(SearchStack ss[]) {
+
+    for (int i = 0; i < 3; i++)
+    {
+        ss[i].init(i);
+        ss[i].initKillers();
+    }
+  }
+
+
   // wait_for_stop_or_ponderhit() is called when the maximum depth is reached
   // while the program is pondering.  The point is to work around a wrinkle in
   // the UCI protocol:  When pondering, the engine is not allowed to give a