]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Use MovePicker's move ordering also at root
[stockfish] / src / search.cpp
index 239cd3860ab77db1fd4f25c11e81d8250f0a1828..68b19cd34b116bf229e26e9e1dee9c1de7d728aa 100644 (file)
@@ -117,7 +117,7 @@ namespace {
 
   struct RootMove {
 
-    RootMove() { nodes = cumulativeNodes = ourBeta = theirBeta = 0ULL; }
+    RootMove() { mp_score = 0; nodes = cumulativeNodes = ourBeta = theirBeta = 0ULL; }
 
     // RootMove::operator<() is the comparison function used when
     // sorting the moves. A move m1 is considered to be better
@@ -125,11 +125,12 @@ namespace {
     // have equal score but m1 has the higher beta cut-off count.
     bool operator<(const RootMove& m) const {
 
-        return score != m.score ? score < m.score : theirBeta <= m.theirBeta;
+        return score != m.score ? score < m.score : mp_score <= m.mp_score;
     }
 
     Move move;
     Value score;
+    int mp_score;
     int64_t nodes, cumulativeNodes, ourBeta, theirBeta;
     Move pv[PLY_MAX_PLUS_2];
   };
@@ -143,6 +144,8 @@ namespace {
   public:
     RootMoveList(Position& pos, Move searchMoves[]);
 
+    void set_mp_scores(const Position &pos);
+
     int move_count() const { return count; }
     Move get_move(int moveNum) const { return moves[moveNum].move; }
     Value get_move_score(int moveNum) const { return moves[moveNum].score; }
@@ -739,6 +742,7 @@ namespace {
     while (1)
     {
         // Sort the moves before to (re)search
+        rml.set_mp_scores(pos);
         rml.sort();
 
         // Step 10. Loop through all moves in the root move list
@@ -824,7 +828,7 @@ namespace {
                             value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, 1);
                             doFullDepthSearch = (value > alpha);
                         }
-                        ss->reduction = Depth(0); // Restore original reduction
+                        ss->reduction = DEPTH_ZERO; // Restore original reduction
                     }
 
                     // Step 15. Full depth search
@@ -996,7 +1000,7 @@ namespace {
 
     // Step 2. Check for aborted search and immediate draw
     if (AbortSearch || ThreadsMgr.thread_should_stop(threadID))
-        return Value(0);
+        return VALUE_ZERO;
 
     if (pos.is_draw() || ply >= PLY_MAX - 1)
         return VALUE_DRAW;
@@ -1067,7 +1071,7 @@ namespace {
         && !pos.has_pawn_on_7th(pos.side_to_move()))
     {
         Value rbeta = beta - razor_margin(depth);
-        Value v = qsearch<NonPV>(pos, ss, rbeta-1, rbeta, Depth(0), ply);
+        Value v = qsearch<NonPV>(pos, ss, rbeta-1, rbeta, DEPTH_ZERO, ply);
         if (v < rbeta)
             // Logically we should return (v + razor_margin(depth)), but
             // surprisingly this did slightly weaker in tests.
@@ -1110,7 +1114,7 @@ namespace {
         pos.do_null_move(st);
         (ss+1)->skipNullMove = true;
 
-        nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -beta, -alpha, Depth(0), ply+1)
+        nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
                                               : - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY, ply+1);
         (ss+1)->skipNullMove = false;
         pos.undo_null_move();
@@ -1179,7 +1183,7 @@ namespace {
                            && tte
                            && tte->move()
                            && !excludedMove // Do not allow recursive singular extension search
-                           && is_lower_bound(tte->type())
+                           && (tte->type() & VALUE_TYPE_LOWER)
                            && tte->depth() >= depth - 3 * ONE_PLY;
 
     // Step 10. Loop through moves
@@ -1263,7 +1267,7 @@ namespace {
       // Step extra. pv search (only in PV nodes)
       // The first move in list is the expected PV
       if (PvNode && moveCount == 1)
-          value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, Depth(0), ply+1)
+          value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
                                      : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
       else
       {
@@ -1281,7 +1285,7 @@ namespace {
               if (ss->reduction)
               {
                   Depth d = newDepth - ss->reduction;
-                  value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, Depth(0), ply+1)
+                  value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
                                       : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, ply+1);
 
                   doFullDepthSearch = (value > alpha);
@@ -1298,20 +1302,20 @@ namespace {
                   value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, ply+1);
                   doFullDepthSearch = (value > alpha);
               }
-              ss->reduction = Depth(0); // Restore original reduction
+              ss->reduction = DEPTH_ZERO; // Restore original reduction
           }
 
           // Step 15. Full depth search
           if (doFullDepthSearch)
           {
-              value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, Depth(0), ply+1)
+              value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
                                          : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1);
 
               // Step extra. pv search (only in PV nodes)
               // Search only for possible new PV nodes, if instead value >= beta then
               // parent node fails low with value <= alpha and tries another move.
               if (PvNode && value > alpha && value < beta)
-                  value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, Depth(0), ply+1)
+                  value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
                                              : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
           }
       }
@@ -1471,7 +1475,7 @@ namespace {
     // to search the moves. Because the depth is <= 0 here, only captures,
     // queen promotions and checks (only if depth == 0 or depth == -ONE_PLY
     // and we are near beta) will be generated.
-    MovePicker mp = MovePicker(pos, ttMove, deepChecks ? Depth(0) : depth, H);
+    MovePicker mp = MovePicker(pos, ttMove, deepChecks ? DEPTH_ZERO : depth, H);
     CheckInfo ci(pos);
 
     // Loop through the moves until no moves remain or a beta cutoff occurs
@@ -1493,7 +1497,7 @@ namespace {
       {
           futilityValue =  futilityBase
                          + pos.endgame_value_of_piece_on(move_to(move))
-                         + (move_is_ep(move) ? PawnValueEndgame : Value(0));
+                         + (move_is_ep(move) ? PawnValueEndgame : VALUE_ZERO);
 
           if (futilityValue < alpha)
           {
@@ -1546,7 +1550,7 @@ namespace {
         return value_mated_in(ply);
 
     // Update transposition table
-    Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
+    Depth d = (depth == DEPTH_ZERO ? DEPTH_ZERO : DEPTH_ZERO - ONE_PLY);
     ValueType vt = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT);
     TT.store(pos.get_key(), value_to_tt(bestValue, ply), vt, d, ss->bestMove, ss->eval, ei.kingDanger[pos.side_to_move()]);
 
@@ -1660,7 +1664,7 @@ namespace {
           {
               Value localAlpha = sp->alpha;
               Depth d = newDepth - ss->reduction;
-              value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(localAlpha+1), -localAlpha, Depth(0), sp->ply+1)
+              value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(localAlpha+1), -localAlpha, DEPTH_ZERO, sp->ply+1)
                                   : - search<NonPV>(pos, ss+1, -(localAlpha+1), -localAlpha, d, sp->ply+1);
 
               doFullDepthSearch = (value > localAlpha);
@@ -1678,21 +1682,21 @@ namespace {
               value = -search<NonPV>(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth-ss->reduction, sp->ply+1);
               doFullDepthSearch = (value > localAlpha);
           }
-          ss->reduction = Depth(0); // Restore original reduction
+          ss->reduction = DEPTH_ZERO; // Restore original reduction
       }
 
       // Step 15. Full depth search
       if (doFullDepthSearch)
       {
           Value localAlpha = sp->alpha;
-          value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(localAlpha+1), -localAlpha, Depth(0), sp->ply+1)
+          value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(localAlpha+1), -localAlpha, DEPTH_ZERO, sp->ply+1)
                                      : - search<NonPV>(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth, sp->ply+1);
 
           // Step extra. pv search (only in PV nodes)
           // Search only for possible new PV nodes, if instead value >= beta then
           // parent node fails low with value <= alpha and tries another move.
           if (PvNode && value > localAlpha && value < sp->beta)
-              value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -sp->beta, -sp->alpha, Depth(0), sp->ply+1)
+              value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -sp->beta, -sp->alpha, DEPTH_ZERO, sp->ply+1)
                                          : - search<PV>(pos, ss+1, -sp->beta, -sp->alpha, newDepth, sp->ply+1);
       }
 
@@ -1851,7 +1855,7 @@ namespace {
 
     assert(m != MOVE_NONE);
 
-    Depth result = Depth(0);
+    Depth result = DEPTH_ZERO;
     *dangerous = moveIsCheck | singleEvasion | mateThreat;
 
     if (*dangerous)
@@ -1884,7 +1888,7 @@ namespace {
     if (   captureOrPromotion
         && pos.type_of_piece_on(move_to(m)) != PAWN
         && (  pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK)
-            - pos.midgame_value_of_piece_on(move_to(m)) == Value(0))
+            - pos.midgame_value_of_piece_on(move_to(m)) == VALUE_ZERO)
         && !move_is_promotion(m)
         && !move_is_ep(m))
     {
@@ -1957,8 +1961,8 @@ namespace {
               || v >= Max(value_mate_in(PLY_MAX), beta)
               || v < Min(value_mated_in(PLY_MAX), beta))
 
-          && (   (is_lower_bound(tte->type()) && v >= beta)
-              || (is_upper_bound(tte->type()) && v < beta));
+          && (   ((tte->type() & VALUE_TYPE_LOWER) && v >= beta)
+              || ((tte->type() & VALUE_TYPE_UPPER) && v < beta));
   }
 
 
@@ -1971,8 +1975,8 @@ namespace {
 
       Value v = value_from_tt(tte->value(), ply);
 
-      if (   (is_lower_bound(tte->type()) && v >= defaultEval)
-          || (is_upper_bound(tte->type()) && v < defaultEval))
+      if (   ((tte->type() & VALUE_TYPE_LOWER) && v >= defaultEval)
+          || ((tte->type() & VALUE_TYPE_UPPER) && v < defaultEval))
           return v;
 
       return defaultEval;
@@ -2165,7 +2169,7 @@ namespace {
     {
         ss->excludedMove = MOVE_NONE;
         ss->skipNullMove = false;
-        ss->reduction = Depth(0);
+        ss->reduction = DEPTH_ZERO;
 
         if (i < 3)
             ss->killers[0] = ss->killers[1] = ss->mateKiller = MOVE_NONE;
@@ -2603,7 +2607,7 @@ namespace {
     assert(*bestValue <= *alpha);
     assert(*alpha < beta);
     assert(beta <= VALUE_INFINITE);
-    assert(depth > Depth(0));
+    assert(depth > DEPTH_ZERO);
     assert(p.thread() >= 0 && p.thread() < ActiveThreads);
     assert(ActiveThreads > 1);
 
@@ -2767,7 +2771,7 @@ namespace {
         pos.do_move(cur->move, st);
         ss[0].currentMove = cur->move;
         moves[count].move = cur->move;
-        moves[count].score = -qsearch<PV>(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, Depth(0), 1);
+        moves[count].score = -qsearch<PV>(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, DEPTH_ZERO, 1);
         moves[count].pv[0] = cur->move;
         moves[count].pv[1] = MOVE_NONE;
         pos.undo_move(cur->move);
@@ -2777,6 +2781,26 @@ namespace {
   }
 
 
+  void RootMoveList::set_mp_scores(const Position &pos)
+  {
+      MovePicker mp = MovePicker(pos, MOVE_NONE, ONE_PLY, H);
+      Move move;
+
+      int moveCount = 0;
+      while ((move = mp.get_next_move()) != MOVE_NONE)
+      {
+          moveCount++;
+          for (int i = 0; i < count; i++)
+          {
+              if (moves[i].move == move)
+              {
+                  moves[i].mp_score = 512 - moveCount;
+                  break;
+              }
+          }
+      }
+  }
+
   // RootMoveList simple methods definitions
 
   void RootMoveList::set_move_nodes(int moveNum, int64_t nodes) {