]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Store node evaluation in SearchStack
[stockfish] / src / search.cpp
index 4a8dd17f81c4b8079ddc745322340a13e8a5691a..76db6d69217f4d53c3d007d808a0b1b952554111 100644 (file)
@@ -172,9 +172,9 @@ namespace {
   // best move from the previous iteration, Problem is set back to false.
   const Value NoProblemMargin = Value(0x14);
 
-  // Null move margin. A null move search will not be done if the approximate
+  // Null move margin. A null move search will not be done if the static
   // evaluation of the position is more than NullMoveMargin below beta.
-  const Value NullMoveMargin = Value(0x300);
+  const Value NullMoveMargin = Value(0x200);
 
   // If the TT move is at least SingleReplyMargin better then the
   // remaining ones we will extend it.
@@ -190,13 +190,6 @@ namespace {
   // Depth limit for razoring
   const Depth RazorDepth = 4 * OnePly;
 
-  // Remaining depth:                 1 ply         1.5 ply       2 ply         2.5 ply       3 ply         3.5 ply
-  const Value RazorMargins[6]     = { Value(0x180), Value(0x300), Value(0x300), Value(0x3C0), Value(0x3C0), Value(0x3C0) };
-
-  // Remaining depth:                 1 ply         1.5 ply       2 ply         2.5 ply       3 ply         3.5 ply
-  const Value RazorApprMargins[6] = { Value(0x520), Value(0x300), Value(0x300), Value(0x300), Value(0x300), Value(0x300) };
-
-
   /// Variables initialized by UCI options
 
   // Minimum number of full depth (i.e. non-reduced) moves at PV and non-PV nodes
@@ -231,7 +224,7 @@ namespace {
   int SearchStartTime;
   int MaxNodes, MaxDepth;
   int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime;
-  bool InfiniteSearch, PonderSearch, StopOnPonderhit;
+  bool UseTimeManagement, InfiniteSearch, PonderSearch, StopOnPonderhit;
   bool AbortSearch, Quit;
   bool FailHigh, FailLow, Problem;
 
@@ -373,8 +366,20 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
            int time[], int increment[], int movesToGo, int maxDepth,
            int maxNodes, int maxTime, Move searchMoves[]) {
 
-  // Look for a book move
-  if (!infinite && !ponder && get_option_value_bool("OwnBook"))
+  // Initialize global search variables
+  Idle = StopOnPonderhit = AbortSearch = Quit = false;
+  FailHigh = FailLow = Problem = false;
+  NodesSincePoll = 0;
+  SearchStartTime = get_system_time();
+  ExactMaxTime = maxTime;
+  MaxDepth = maxDepth;
+  MaxNodes = maxNodes;
+  InfiniteSearch = infinite;
+  PonderSearch = ponder;
+  UseTimeManagement = !ExactMaxTime && !MaxDepth && !MaxNodes && !InfiniteSearch;
+
+  // Look for a book move, only during games, not tests
+  if (UseTimeManagement && !ponder && get_option_value_bool("OwnBook"))
   {
       Move bookMove;
       if (get_option_value_string("Book File") != OpeningBook.file_name())
@@ -388,15 +393,6 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
       }
   }
 
-  // Initialize global search variables
-  Idle = StopOnPonderhit = AbortSearch = Quit = false;
-  FailHigh = FailLow = Problem = false;
-  SearchStartTime = get_system_time();
-  ExactMaxTime = maxTime;
-  NodesSincePoll = 0;
-  InfiniteSearch = infinite;
-  PonderSearch = ponder;
-
   for (int i = 0; i < THREAD_MAX; i++)
   {
       Threads[i].nodes = 0ULL;
@@ -464,51 +460,45 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
   // Set thinking time
   int myTime = time[side_to_move];
   int myIncrement = increment[side_to_move];
-
-  if (!movesToGo) // Sudden death time control
+  if (UseTimeManagement)
   {
-      if (myIncrement)
+      if (!movesToGo) // Sudden death time control
       {
-          MaxSearchTime = myTime / 30 + myIncrement;
-          AbsoluteMaxSearchTime = Max(myTime / 4, myIncrement - 100);
-      }
-      else // Blitz game without increment
-      {
-          MaxSearchTime = myTime / 30;
-          AbsoluteMaxSearchTime = myTime / 8;
+          if (myIncrement)
+          {
+              MaxSearchTime = myTime / 30 + myIncrement;
+              AbsoluteMaxSearchTime = Max(myTime / 4, myIncrement - 100);
+          }
+          else // Blitz game without increment
+          {
+              MaxSearchTime = myTime / 30;
+              AbsoluteMaxSearchTime = myTime / 8;
+          }
       }
-  }
-  else // (x moves) / (y minutes)
-  {
-      if (movesToGo == 1)
+      else // (x moves) / (y minutes)
       {
-          MaxSearchTime = myTime / 2;
-          AbsoluteMaxSearchTime = (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4);
+          if (movesToGo == 1)
+          {
+              MaxSearchTime = myTime / 2;
+              AbsoluteMaxSearchTime = (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4);
+          }
+          else
+          {
+              MaxSearchTime = myTime / Min(movesToGo, 20);
+              AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3);
+          }
       }
-      else
+
+      if (PonderingEnabled)
       {
-          MaxSearchTime = myTime / Min(movesToGo, 20);
-          AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3);
+          MaxSearchTime += MaxSearchTime / 4;
+          MaxSearchTime = Min(MaxSearchTime, AbsoluteMaxSearchTime);
       }
   }
 
-  if (PonderingEnabled)
-  {
-      MaxSearchTime += MaxSearchTime / 4;
-      MaxSearchTime = Min(MaxSearchTime, AbsoluteMaxSearchTime);
-  }
-
-  // Fixed depth or fixed number of nodes?
-  MaxDepth = maxDepth;
-  if (MaxDepth)
-      InfiniteSearch = true; // HACK
-
-  MaxNodes = maxNodes;
+  // Set best NodesBetweenPolls interval
   if (MaxNodes)
-  {
       NodesBetweenPolls = Min(MaxNodes, 30000);
-      InfiniteSearch = true; // HACK
-  }
   else if (myTime && myTime < 1000)
       NodesBetweenPolls = 1000;
   else if (myTime && myTime < 5000)
@@ -662,6 +652,7 @@ void SearchStack::init(int ply) {
   pv[ply] = pv[ply + 1] = MOVE_NONE;
   currentMove = threatMove = MOVE_NONE;
   reduction = Depth(0);
+  eval = VALUE_NONE;
 }
 
 void SearchStack::initKillers() {
@@ -791,7 +782,7 @@ namespace {
 
         Problem = false;
 
-        if (!InfiniteSearch)
+        if (UseTimeManagement)
         {
             // Time to stop?
             bool stopSearch = false;
@@ -845,9 +836,9 @@ namespace {
 
     rml.sort();
 
-    // If we are pondering, we shouldn't print the best move before we
-    // are told to do so
-    if (PonderSearch)
+    // If we are pondering or in infinite search, we shouldn't print the
+    // best move before we are told to do so.
+    if (!AbortSearch && (PonderSearch || InfiniteSearch))
         wait_for_stop_or_ponderhit();
     else
         // Print final search statistics
@@ -1401,6 +1392,7 @@ namespace {
     const int FutilityValueMargin = 112 * bitScanReverse32(int(depth) * int(depth) / 2);
 
     // Enhance score accuracy with TT value if possible
+    ss[ply].eval = staticValue;
     futilityValue = staticValue + FutilityValueMargin;
     staticValue = refine_eval(tte, staticValue, ply);
 
@@ -1456,12 +1448,12 @@ namespace {
     // Null move search not allowed, try razoring
     else if (   !value_is_mate(beta)
              && depth < RazorDepth
-             && staticValue < beta - RazorApprMargins[int(depth) - 2]
+             && staticValue < beta - (depth > OnePly ? NullMoveMargin + 16 * depth : 2*NullMoveMargin)
              && ss[ply - 1].currentMove != MOVE_NULL
              && ttMove == MOVE_NONE
              && !pos.has_pawn_on_7th(pos.side_to_move()))
     {
-        Value rbeta = beta - RazorMargins[int(depth) - 2];
+        Value rbeta = beta - (NullMoveMargin + 16 * depth);
         Value v = qsearch(pos, ss, rbeta-1, rbeta, Depth(0), ply, threadID);
         if (v < rbeta)
           return v;
@@ -2680,7 +2672,7 @@ namespace {
                      || stillAtFirstMove //FIXME: We are not checking any problem flags, BUG?
                      || noProblemFound;
 
-    if (   (Iteration >= 3 && !InfiniteSearch && noMoreTime)
+    if (   (Iteration >= 3 && UseTimeManagement && noMoreTime)
         || (ExactMaxTime && t >= ExactMaxTime)
         || (Iteration >= 3 && MaxNodes && nodes_searched() >= MaxNodes))
         AbortSearch = true;
@@ -2710,7 +2702,7 @@ namespace {
                      || stillAtFirstMove
                      || noProblemFound;
 
-    if (Iteration >= 3 && !InfiniteSearch && (noMoreTime || StopOnPonderhit))
+    if (Iteration >= 3 && UseTimeManagement && (noMoreTime || StopOnPonderhit))
         AbortSearch = true;
   }