]> git.sesse.net Git - stockfish/commitdiff
Reintroduce razoring
authorMichael Chaly <Vizvezdenec@gmail.com>
Sat, 5 Feb 2022 01:03:02 +0000 (04:03 +0300)
committerJoost VandeVondele <Joost.VandeVondele@gmail.com>
Sat, 5 Feb 2022 06:40:21 +0000 (07:40 +0100)
Razoring was simplified away some years ago, this patch reintroduces it in a slightly different form.
Now for low depths if eval is far below alpha we check if qsearch can push it above alpha - and if it can't we return a fail low.

passed STC
https://tests.stockfishchess.org/tests/view/61fbf968d508ec6a1c9f3274
LLR: 2.94 (-2.94,2.94) <0.00,2.50>
Total: 226120 W: 61106 L: 60472 D: 104542
Ptnml(0-2): 1118, 25592, 59080, 26078, 1192

passed LTC
https://tests.stockfishchess.org/tests/view/61fcc569d508ec6a1c9f5617
LLR: 2.94 (-2.94,2.94) <0.50,3.00>
Total: 113128 W: 30851 L: 30397 D: 51880
Ptnml(0-2): 114, 11483, 32926, 11917, 124

closes https://github.com/official-stockfish/Stockfish/pull/3921

bench 4684080

src/search.cpp

index c0f77f8afbcd2a35581a13a9d3daa5db17e57179..6ca3b56ec924c5d825a5032bce201c0fd8bb0a66 100644 (file)
@@ -773,7 +773,17 @@ namespace {
 
     thisThread->complexityAverage.update(complexity);
 
-    // Step 7. Futility pruning: child node (~25 Elo).
+    // Step 7. Razoring.
+    // If eval is really low check with qsearch if it can exceed alpha, if it can't,
+    // return a fail low.
+    if (!PvNode && depth <= 6 && eval < alpha - 400 - 300 * depth * depth)
+    {
+        value = qsearch<NonPV>(pos, ss, alpha - 1, alpha);
+        if (value < alpha)
+            return value;
+    }
+
+    // Step 8. Futility pruning: child node (~25 Elo).
     // The depth condition is important for mate finding.
     if (   !ss->ttPv
         &&  depth < 9
@@ -782,7 +792,7 @@ namespace {
         &&  eval < 15000) // 50% larger than VALUE_KNOWN_WIN, but smaller than TB wins.
         return eval;
 
-    // Step 8. Null move search with verification search (~22 Elo)
+    // Step 9. Null move search with verification search (~22 Elo)
     if (   !PvNode
         && (ss-1)->currentMove != MOVE_NULL
         && (ss-1)->statScore < 23767
@@ -834,7 +844,7 @@ namespace {
 
     probCutBeta = beta + 209 - 44 * improving;
 
-    // Step 9. ProbCut (~4 Elo)
+    // Step 10. ProbCut (~4 Elo)
     // If we have a good enough capture and a reduced search returns a value
     // much above beta, we can (almost) safely prune the previous move.
     if (   !PvNode
@@ -895,7 +905,7 @@ namespace {
          ss->ttPv = ttPv;
     }
 
-    // Step 10. If the position is not in TT, decrease depth by 2 or 1 depending on node type (~3 Elo)
+    // Step 11. If the position is not in TT, decrease depth by 2 or 1 depending on node type (~3 Elo)
     if (   PvNode
         && depth >= 6
         && !ttMove)
@@ -908,7 +918,7 @@ namespace {
 
 moves_loop: // When in check, search starts here
 
-    // Step 11. A small Probcut idea, when we are in check (~0 Elo)
+    // Step 12. A small Probcut idea, when we are in check (~0 Elo)
     probCutBeta = beta + 409;
     if (   ss->inCheck
         && !PvNode
@@ -945,7 +955,7 @@ moves_loop: // When in check, search starts here
                          && (tte->bound() & BOUND_UPPER)
                          && tte->depth() >= depth;
 
-    // Step 12. Loop through all pseudo-legal moves until no moves remain
+    // Step 13. Loop through all pseudo-legal moves until no moves remain
     // or a beta cutoff occurs.
     while ((move = mp.next_move(moveCountPruning)) != MOVE_NONE)
     {
@@ -985,7 +995,7 @@ moves_loop: // When in check, search starts here
 
       Value delta = beta - alpha;
 
-      // Step 13. Pruning at shallow depth (~98 Elo). Depth conditions are important for mate finding.
+      // Step 14. Pruning at shallow depth (~98 Elo). Depth conditions are important for mate finding.
       if (  !rootNode
           && pos.non_pawn_material(us)
           && bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
@@ -1038,7 +1048,7 @@ moves_loop: // When in check, search starts here
           }
       }
 
-      // Step 14. Extensions (~66 Elo)
+      // Step 15. Extensions (~66 Elo)
       // We take care to not overdo to avoid search getting stuck.
       if (ss->ply < thisThread->rootDepth * 2)
       {
@@ -1115,12 +1125,12 @@ moves_loop: // When in check, search starts here
                                                                 [movedPiece]
                                                                 [to_sq(move)];
 
-      // Step 15. Make the move
+      // Step 16. Make the move
       pos.do_move(move, st, givesCheck);
 
       bool doDeeperSearch = false;
 
-      // Step 16. Late moves reduction / extension (LMR, ~98 Elo)
+      // Step 17. Late moves reduction / extension (LMR, ~98 Elo)
       // We use various heuristics for the sons of a node after the first son has
       // been searched. In general we would like to reduce them, but there are many
       // cases where we extend a son if it has good chances to be "interesting".
@@ -1188,7 +1198,7 @@ moves_loop: // When in check, search starts here
           didLMR = false;
       }
 
-      // Step 17. Full depth search when LMR is skipped or fails high
+      // Step 18. Full depth search when LMR is skipped or fails high
       if (doFullDepthSearch)
       {
           value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth + doDeeperSearch, !cutNode);
@@ -1218,12 +1228,12 @@ moves_loop: // When in check, search starts here
                               std::min(maxNextDepth, newDepth), false);
       }
 
-      // Step 18. Undo move
+      // Step 19. Undo move
       pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
 
-      // Step 19. Check for a new best move
+      // Step 20. Check for a new best move
       // Finished searching the move. If a stop occurred, the return value of
       // the search cannot be trusted, and we return immediately without
       // updating best move, PV and TT.
@@ -1306,7 +1316,7 @@ moves_loop: // When in check, search starts here
         return VALUE_DRAW;
     */
 
-    // Step 20. Check for mate and stalemate
+    // Step 21. Check for mate and stalemate
     // All legal moves have been searched and if there are no legal moves, it
     // must be a mate or a stalemate. If we are in a singular extension search then
     // return a fail low score.