Smooth improving
authorStefano Cardanobile <stefano.cardanobile@gmail.com>
Thu, 14 Oct 2021 20:26:42 +0000 (22:26 +0200)
committerStéphane Nicolet <cassio@free.fr>
Fri, 15 Oct 2021 12:57:01 +0000 (14:57 +0200)
Smooth dependency on improvement margin in null move search.

STC
LLR: 2.93 (-2.94,2.94) <-0.50,2.50>
Total: 17384 W: 4468 L: 4272 D: 8644
Ptnml(0-2): 42, 1919, 4592, 2079, 60
https://tests.stockfishchess.org/tests/view/61689b8a1e5f6627cc1c0fdc

LTC
LLR: 2.94 (-2.94,2.94) <0.50,3.50>
Total: 45648 W: 11525 L: 11243 D: 22880
Ptnml(0-2): 26, 4731, 13036, 4997, 34
https://tests.stockfishchess.org/tests/view/6168a12c1e5f6627cc1c0fe3

It would be interesting to test if the other pruning/reduction heuristics
in master which are using the improving variable (ie the sign of improvement)
could benefit from a smooth function of the improvement value (or maybe a
Relu of the improvement value).

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

Bench: 4916775

src/search.cpp

index 1aaf53d84d1b018374a7bc612d57e34e968c5d35..9f005587aa4c5845a0a1fcf0b9031be23f59bbc2 100644 (file)
@@ -590,7 +590,7 @@ namespace {
     bool captureOrPromotion, doFullDepthSearch, moveCountPruning,
          ttCapture, singularQuietLMR, noLMRExtension;
     Piece movedPiece;
     bool captureOrPromotion, doFullDepthSearch, moveCountPruning,
          ttCapture, singularQuietLMR, noLMRExtension;
     Piece movedPiece;
-    int moveCount, captureCount, quietCount, bestMoveCount;
+    int moveCount, captureCount, quietCount, bestMoveCount, improvement;
 
     // Step 1. Initialize node
     ss->inCheck        = pos.checkers();
 
     // Step 1. Initialize node
     ss->inCheck        = pos.checkers();
@@ -766,6 +766,7 @@ namespace {
         // Skip early pruning when in check
         ss->staticEval = eval = VALUE_NONE;
         improving = false;
         // Skip early pruning when in check
         ss->staticEval = eval = VALUE_NONE;
         improving = false;
+        improvement = 0;
         goto moves_loop;
     }
     else if (ss->ttHit)
         goto moves_loop;
     }
     else if (ss->ttHit)
@@ -804,13 +805,15 @@ namespace {
         thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << bonus;
     }
 
         thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << bonus;
     }
 
-    // Set up improving flag that is used in various pruning heuristics
-    // We define position as improving if static evaluation of position is better
-    // Than the previous static evaluation at our turn
-    // In case of us being in check at our previous move we look at move prior to it
-    improving =  (ss-2)->staticEval == VALUE_NONE
-               ? ss->staticEval > (ss-4)->staticEval || (ss-4)->staticEval == VALUE_NONE
-               : ss->staticEval > (ss-2)->staticEval;
+    // Set up the improvement variable, which is the difference between the current
+    // static evaluation and the previous static evaluation at our turn (if we were
+    // in check at our previous move we look at the move prior to it). The improvement
+    // margin and the improving flag are used in various pruning heuristics.
+    improvement =   (ss-2)->staticEval != VALUE_NONE ? ss->staticEval - (ss-2)->staticEval
+                  : (ss-4)->staticEval != VALUE_NONE ? ss->staticEval - (ss-4)->staticEval
+                  :                                    200;
+
+    improving = improvement > 0;
 
     // Step 7. Futility pruning: child node (~50 Elo).
     // The depth condition is important for mate finding.
 
     // Step 7. Futility pruning: child node (~50 Elo).
     // The depth condition is important for mate finding.
@@ -826,7 +829,7 @@ namespace {
         && (ss-1)->statScore < 23767
         &&  eval >= beta
         &&  eval >= ss->staticEval
         && (ss-1)->statScore < 23767
         &&  eval >= beta
         &&  eval >= ss->staticEval
-        &&  ss->staticEval >= beta - 20 * depth - 22 * improving + 168 * ss->ttPv + 177
+        &&  ss->staticEval >= beta - 20 * depth - improvement / 15 + 168 * ss->ttPv + 177
         && !excludedMove
         &&  pos.non_pawn_material(us)
         && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
         && !excludedMove
         &&  pos.non_pawn_material(us)
         && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))