]> git.sesse.net Git - stockfish/commitdiff
Rewarding Quiet Moves that Enable Razoring
authorFauziAkram <fauzi.dabat@hotmail.com>
Fri, 27 Oct 2023 10:28:55 +0000 (13:28 +0300)
committerDisservin <disservin.social@gmail.com>
Fri, 27 Oct 2023 15:32:19 +0000 (17:32 +0200)
The main idea of the patch comes from @peregrineshahin :
https://tests.stockfishchess.org/tests/view/65205363ac57711436728781

Another small idea (tuning) comes from @Vizvezdenec
https://tests.stockfishchess.org/tests/view/652e071ade6d262d08d318f4 And a long
phases of tuning and tests was done by me in order to make the patch be able to
pass both tests.

The idea, as mentioned by Peregrine is that in our standard code, if no best
move found after searching all moves, we give a bonus to the previous move that
caused the fail high. So in razoring we assume no bestmove will be found so we
might as well do the same.

Passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 82336 W: 20997 L: 20610 D: 40729
Ptnml(0-2): 288, 9710, 20753, 10161, 256
https://tests.stockfishchess.org/tests/view/6538fafbcc309ae83955d8f0

Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 46584 W: 11753 L: 11411 D: 23420
Ptnml(0-2): 21, 5133, 12642, 5475, 21
https://tests.stockfishchess.org/tests/view/653a3f2ccc309ae83955f223

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

Bench: 1258079

Co-Authored-By: Shahin M. Shahin <41402573+peregrineshahin@users.noreply.github.com>
src/evaluate.cpp
src/search.cpp

index c405cfb55388601ac1bf130fbdab8b69e0f79d30..9c39d4c07fbb407ed7934dc14ab118994615c557 100644 (file)
@@ -144,8 +144,8 @@ void NNUE::verify() {
 }
 
 
-// Returns a static, purely materialistic evaluation of the position
-// from the point of view of the given color. It can be divided by PawnValue to get
+// Returns a static, purely materialistic evaluation of the position from
+// the point of view of the given color. It can be divided by PawnValue to get
 // an approximation of the material advantage on the board in terms of pawns.
 Value Eval::simple_eval(const Position& pos, Color c) {
     return PawnValue * (pos.count<PAWN>(c) - pos.count<PAWN>(~c))
index 0ffca247853faa03b1272d884b3560dc25edfc86..65b27d16d4f4f68c02350f8f8d65a9bdfc54abfb 100644 (file)
@@ -77,7 +77,7 @@ enum NodeType {
 
 // Futility margin
 Value futility_margin(Depth d, bool noTtCutNode, bool improving) {
-    return Value((126 - 42 * noTtCutNode) * (d - improving));
+    return Value((125 - 43 * noTtCutNode) * (d - improving));
 }
 
 // Reductions lookup table initialized at startup
@@ -85,8 +85,8 @@ int Reductions[MAX_MOVES];  // [depth or moveNumber]
 
 Depth reduction(bool i, Depth d, int mn, Value delta, Value rootDelta) {
     int reductionScale = Reductions[d] * Reductions[mn];
-    return (reductionScale + 1560 - int(delta) * 945 / int(rootDelta)) / 1024
-         + (!i && reductionScale > 791);
+    return (reductionScale + 1487 - int(delta) * 976 / int(rootDelta)) / 1024
+         + (!i && reductionScale > 808);
 }
 
 constexpr int futility_move_count(bool improving, Depth depth) {
@@ -94,7 +94,7 @@ constexpr int futility_move_count(bool improving, Depth depth) {
 }
 
 // History and stats update bonus, based on depth
-int stat_bonus(Depth d) { return std::min(334 * d - 531, 1538); }
+int stat_bonus(Depth d) { return std::min(357 * d - 483, 1511); }
 
 // Add a small random component to draw evaluations to avoid 3-fold blindness
 Value value_draw(const Thread* thisThread) {
@@ -761,11 +761,19 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
     // If eval is really low check with qsearch if it can exceed alpha, if it can't,
     // return a fail low.
     // Adjust razor margin according to cutoffCnt. (~1 Elo)
-    if (eval < alpha - 492 - (257 - 200 * ((ss + 1)->cutoffCnt > 3)) * depth * depth)
+    if (eval < alpha - 474 - (270 - 174 * ((ss + 1)->cutoffCnt > 3)) * depth * depth)
     {
         value = qsearch<NonPV>(pos, ss, alpha - 1, alpha);
         if (value < alpha)
+        {
+            if (!priorCapture && prevSq != SQ_NONE)
+            {
+                int bonus = (depth > 6) + (PvNode || cutNode) + (value < alpha - 658) + ((ss-1)->moveCount > 11);
+                update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus);
+                thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << stat_bonus(depth) * bonus * 57 / 100;
+            }
             return value;
+        }
     }
 
     // Step 8. Futility pruning: child node (~40 Elo)
@@ -993,22 +1001,22 @@ moves_loop:  // When in check, search starts here
                             + thisThread->pawnHistory[pawn_structure(pos)][movedPiece][to_sq(move)];
 
                 // Continuation history based pruning (~2 Elo)
-                if (lmrDepth < 6 && history < -3498 * depth)
+                if (lmrDepth < 6 && history < -3645 * depth)
                     continue;
 
                 history += 2 * thisThread->mainHistory[us][from_to(move)];
 
-                lmrDepth += history / 7815;
-                lmrDepth = std::max(lmrDepth, -2);
+                lmrDepth += history / 7836;
+                lmrDepth = std::max(lmrDepth, -1);
 
                 // Futility pruning: parent node (~13 Elo)
-                if (!ss->inCheck && lmrDepth < 13 && ss->staticEval + 80 + 122 * lmrDepth <= alpha)
+                if (!ss->inCheck && lmrDepth < 13 && ss->staticEval + 77 + 124 * lmrDepth <= alpha)
                     continue;
 
                 lmrDepth = std::max(lmrDepth, 0);
 
                 // Prune moves with negative SEE (~4 Elo)
-                if (!pos.see_ge(move, Value(-27 * lmrDepth * lmrDepth)))
+                if (!pos.see_ge(move, Value(-26 * lmrDepth * lmrDepth)))
                     continue;
             }
         }
@@ -1318,12 +1326,12 @@ moves_loop:  // When in check, search starts here
     // Bonus for prior countermove that caused the fail low
     else if (!priorCapture && prevSq != SQ_NONE)
     {
-        int bonus = (depth > 6) + (PvNode || cutNode) + (bestValue < alpha - 653)
-                  + ((ss - 1)->moveCount > 11);
+        int bonus = (depth > 6) + (PvNode || cutNode) + (bestValue < alpha - 657)
+                  + ((ss - 1)->moveCount > 10);
         update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq,
                                       stat_bonus(depth) * bonus);
         thisThread->mainHistory[~us][from_to((ss - 1)->currentMove)]
-          << stat_bonus(depth) * bonus / 2;
+          << stat_bonus(depth) * bonus * 61 / 100;
     }
 
     if (PvNode)