]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Do not reset ss->eval in the beginning of the node
[stockfish] / src / search.cpp
index ab778ec15f959eedb1d4bf0016e285ff3ad8b67f..7249a113862f87ebe8cd6563f0bb3fa08e937ddb 100644 (file)
@@ -291,6 +291,8 @@ namespace {
 
   bool connected_moves(const Position& pos, Move m1, Move m2);
   bool value_is_mate(Value value);
+  Value value_to_tt(Value v, int ply);
+  Value value_from_tt(Value v, int ply);
   bool move_is_killer(Move m, SearchStack* ss);
   bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply);
   bool connected_threat(const Position& pos, Move m, Move threat);
@@ -300,6 +302,7 @@ namespace {
   void update_gains(const Position& pos, Move move, Value before, Value after);
 
   int current_search_time();
+  std::string value_to_uci(Value v);
   int nps();
   void poll();
   void ponderhit();
@@ -339,8 +342,8 @@ void init_search() {
   // Init reductions array
   for (hd = 1; hd < 64; hd++) for (mc = 1; mc < 64; mc++)
   {
-      double    pvRed = log(double(hd)) * log(double(mc)) / 3.0;
-      double nonPVRed = log(double(hd)) * log(double(mc)) / 1.5;
+      double    pvRed = 0.33 + log(double(hd)) * log(double(mc)) / 4.5;
+      double nonPVRed = 0.33 + log(double(hd)) * log(double(mc)) / 2.25;
       ReductionMatrix[PV][hd][mc]    = (int8_t) (   pvRed >= 1.0 ? floor(   pvRed * int(OnePly)) : 0);
       ReductionMatrix[NonPV][hd][mc] = (int8_t) (nonPVRed >= 1.0 ? floor(nonPVRed * int(OnePly)) : 0);
   }
@@ -361,7 +364,6 @@ void SearchStack::init() {
 
   currentMove = threatMove = bestMove = MOVE_NONE;
   reduction = Depth(0);
-  eval = VALUE_NONE;
 }
 
 // SearchStack::initKillers() initializes killers for a search stack entry
@@ -408,9 +410,8 @@ int perft(Position& pos, Depth depth)
 /// search-related global variables, and calls root_search(). It returns false
 /// when a quit command is received during the search.
 
-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[]) {
+bool think(const Position& pos, bool infinite, bool ponder, int time[], int increment[],
+           int movesToGo, int maxDepth, int maxNodes, int maxTime, Move searchMoves[]) {
 
   // Initialize global search variables
   StopOnPonderhit = AbortSearch = Quit = AspirationFailLow = false;
@@ -483,8 +484,8 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
   TM.wake_sleeping_threads();
 
   // Set thinking time
-  int myTime = time[side_to_move];
-  int myIncrement = increment[side_to_move];
+  int myTime = time[pos.side_to_move()];
+  int myIncrement = increment[pos.side_to_move()];
   if (UseTimeManagement)
   {
       if (!movesToGo) // Sudden death time control
@@ -584,7 +585,7 @@ namespace {
     // so to output information also for iteration 1.
     cout << "info depth " << 1
          << "\ninfo depth " << 1
-         << " score " << value_to_string(rml.get_move_score(0))
+         << " score " << value_to_uci(rml.get_move_score(0))
          << " time " << current_search_time()
          << " nodes " << TM.nodes_searched()
          << " nps " << nps()
@@ -769,8 +770,7 @@ namespace {
 
     // Step 5. Evaluate the position statically
     // At root we do this only to get reference value for child nodes
-    if (!isCheck)
-        ss->eval = evaluate(pos, ei);
+    ss->eval = isCheck ? VALUE_NONE : evaluate(pos, ei);
 
     // Step 6. Razoring (omitted at root)
     // Step 7. Static null move pruning (omitted at root)
@@ -960,7 +960,7 @@ namespace {
                     for (int j = 0; j < Min(MultiPV, rml.move_count()); j++)
                     {
                         cout << "info multipv " << j + 1
-                             << " score " << value_to_string(rml.get_move_score(j))
+                             << " score " << value_to_uci(rml.get_move_score(j))
                              << " depth " << (j <= i ? Iteration : Iteration - 1)
                              << " time " << current_search_time()
                              << " nodes " << TM.nodes_searched()
@@ -1095,6 +1095,8 @@ namespace {
         refinedValue = refine_eval(tte, ss->eval, ply); // Enhance accuracy with TT value if possible
         update_gains(pos, (ss-1)->currentMove, (ss-1)->eval, ss->eval);
     }
+    else
+        ss->eval = VALUE_NONE;
 
     // Step 6. Razoring (is omitted in PV nodes)
     if (   !PvNode
@@ -1448,7 +1450,6 @@ namespace {
 
     TM.incrementNodeCounter(pos.thread());
     ss->bestMove = ss->currentMove = MOVE_NONE;
-    ss->eval = VALUE_NONE;
 
     // Check for an instant draw or maximum ply reached
     if (pos.is_draw() || ply >= PLY_MAX - 1)
@@ -1471,6 +1472,7 @@ namespace {
     if (isCheck)
     {
         bestValue = futilityBase = -VALUE_INFINITE;
+        ss->eval = VALUE_NONE;
         deepChecks = enoughMaterial = false;
     }
     else
@@ -1824,8 +1826,8 @@ namespace {
   }
 
 
-  // value_is_mate() checks if the given value is a mate one
-  // eventually compensated for the ply.
+  // value_is_mate() checks if the given value is a mate one eventually
+  // compensated for the ply.
 
   bool value_is_mate(Value value) {
 
@@ -1836,8 +1838,38 @@ namespace {
   }
 
 
-  // move_is_killer() checks if the given move is among the
-  // killer moves of that ply.
+  // value_to_tt() adjusts a mate score from "plies to mate from the root" to
+  // "plies to mate from the current ply".  Non-mate scores are unchanged.
+  // The function is called before storing a value to the transposition table.
+
+  Value value_to_tt(Value v, int ply) {
+
+    if (v >= value_mate_in(PLY_MAX))
+      return v + ply;
+
+    if (v <= value_mated_in(PLY_MAX))
+      return v - ply;
+
+    return v;
+  }
+
+
+  // value_from_tt() is the inverse of value_to_tt(): It adjusts a mate score from
+  // the transposition table to a mate score corrected for the current ply.
+
+  Value value_from_tt(Value v, int ply) {
+
+    if (v >= value_mate_in(PLY_MAX))
+      return v - ply;
+
+    if (v <= value_mated_in(PLY_MAX))
+      return v + ply;
+
+    return v;
+  }
+
+
+  // move_is_killer() checks if the given move is among the killer moves
 
   bool move_is_killer(Move m, SearchStack* ss) {
 
@@ -2052,6 +2084,20 @@ namespace {
   }
 
 
+  // value_to_uci() converts a value to a string suitable for use with the UCI protocol
+
+  std::string value_to_uci(Value v) {
+
+    std::stringstream s;
+
+    if (abs(v) < VALUE_MATE - PLY_MAX * OnePly)
+      s << "cp " << int(v) * 100 / int(PawnValueMidgame); // Scale to pawn = 100
+    else
+      s << "mate " << (v > 0 ? (VALUE_MATE - v + 1) / 2 : -(VALUE_MATE + v) / 2 );
+
+    return s.str();
+  }
+
   // nps() computes the current nodes/second count.
 
   int nps() {
@@ -2209,7 +2255,7 @@ namespace {
   void print_pv_info(const Position& pos, Move pv[], Value alpha, Value beta, Value value) {
 
     cout << "info depth " << Iteration
-         << " score "     << value_to_string(value)
+         << " score "     << value_to_uci(value)
          << (value >= beta ? " lowerbound" : value <= alpha ? " upperbound" : "")
          << " time "  << current_search_time()
          << " nodes " << TM.nodes_searched()
@@ -2707,6 +2753,8 @@ namespace {
 
         // Find a quick score for the move
         init_ss_array(ss, PLY_MAX_PLUS_2);
+        ss[0].eval = VALUE_NONE;
+        ss[0].currentMove = cur->move;
         pos.do_move(cur->move, st);
         moves[count].move = cur->move;
         moves[count].score = -qsearch<PV>(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, Depth(0), 1);