@@ -65,18 +65,19 @@ namespace {
6565
6666 // Futility margin
6767 Value futility_margin (Depth d, bool improving) {
68- return Value (214 * (d - improving));
68+ return Value (171 * (d - improving));
6969 }
7070
7171 // Reductions lookup table, initialized at startup
7272 int Reductions[MAX_MOVES]; // [depth or moveNumber]
7373
7474 Depth reduction (bool i, Depth d, int mn, Value delta, Value rootDelta) {
7575 int r = Reductions[d] * Reductions[mn];
76+
7677 if (rootDelta != 0 )
77- return (r + 1358 - int (delta) * 1024 / int (rootDelta)) / 1024 + (!i && r > 904 );
78- else // avoid divide by zero error
79- return (r + 1358 - int (delta) * 1024 ) / 1024 + (!i && r > 904 );
78+ return (r + 1575 - int (delta) * 1024 / int (rootDelta)) / 1024 + (!i && r > 1011 );
79+ else // SFplus: avoid divide by zero error
80+ return (r + 1575 - int (delta) * 1024 ) / 1024 + (!i && r > 1011 );
8081 }
8182
8283 constexpr int futility_move_count (bool improving, Depth depth) {
@@ -85,7 +86,7 @@ namespace {
8586
8687 // History and stats update bonus, based on depth
8788 int stat_bonus (Depth d) {
88- return std::min ((6 * d + 229 ) * d - 215 , 2000 );
89+ return std::min ((7 * d + 254 ) * d - 206 , 1990 );
8990 }
9091
9192 // Add a small random component to draw evaluations to avoid 3-fold blindness
@@ -162,7 +163,7 @@ namespace {
162163void Search::init () {
163164
164165 for (int i = 1 ; i < MAX_MOVES; ++i)
165- Reductions[i] = int ((21.9 + std::log (Threads.size ()) / 2 ) * std::log (i));
166+ Reductions[i] = int ((21.5 + std::log (Threads.size ()) / 2 ) * std::log (i));
166167}
167168
168169
@@ -345,10 +346,10 @@ void Thread::search() {
345346
346347 multiPV = std::min (multiPV, rootMoves.size ());
347348
348- complexityAverage.set (232 , 1 );
349+ complexityAverage.set (190 , 1 );
349350
350351 trend = SCORE_ZERO;
351- optimism[ us] = Value (25 );
352+ optimism[ us] = Value (34 );
352353 optimism[~us] = -optimism[us];
353354
354355 int searchAgainCounter = 0 ;
@@ -418,16 +419,16 @@ void Thread::search() {
418419 if (rootDepth >= 4 )
419420 {
420421 Value prev = rootMoves[pvIdx].averageScore ;
421- delta = Value (17 ) + int (prev) * prev / 16384 ;
422+ delta = Value (16 ) + int (prev) * prev / 16384 ;
422423 alpha = std::max (prev - delta,-VALUE_INFINITE);
423424 beta = std::min (prev + delta, VALUE_INFINITE);
424425
425426 // Adjust trend and optimism based on root move's previousScore
426- int tr = sigmoid (prev, 0 , 0 , 147 , 113 , 1 );
427+ int tr = sigmoid (prev, 6 , 13 , 96 , 110 , 1 );
427428 trend = (us == WHITE ? make_score (tr, tr / 2 )
428429 : -make_score (tr, tr / 2 ));
429430
430- int opt = sigmoid (prev, 0 , 25 , 147 , 14464 , 256 );
431+ int opt = sigmoid (prev, 7 , 21 , 94 , 14786 , 221 );
431432 optimism[ us] = Value (opt);
432433 optimism[~us] = -optimism[us];
433434 }
@@ -482,7 +483,7 @@ void Thread::search() {
482483 else
483484 break ;
484485
485- delta += delta / 4 + 5 ;
486+ delta += delta / 4 + 3 ;
486487
487488 assert (alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE);
488489 }
@@ -528,17 +529,17 @@ void Thread::search() {
528529 && !Threads.stop
529530 && !mainThread->stopOnPonderhit )
530531 {
531- double fallingEval = (142 + 12 * (mainThread->bestPreviousAverageScore - bestValue)
532- + 6 * (mainThread->iterValue [iterIdx] - bestValue)) / 825.0 ;
532+ double fallingEval = (87 + 12 * (mainThread->bestPreviousAverageScore - bestValue)
533+ + 6 * (mainThread->iterValue [iterIdx] - bestValue)) / 777.20 ;
533534 fallingEval = std::clamp (fallingEval, 0.5 , 1.5 );
534535
535536 // If the bestMove is stable over several iterations, reduce time accordingly
536- timeReduction = lastBestMoveDepth + 9 < completedDepth ? 1.92 : 0.95 ;
537- double reduction = (1.47 + mainThread->previousTimeReduction ) / (2.32 * timeReduction);
537+ timeReduction = lastBestMoveDepth + 8 < completedDepth ? 1.70 : 0.91 ;
538+ double reduction = (1.59 + mainThread->previousTimeReduction ) / (2.33 * timeReduction);
538539 double bestMoveInstability = 1.073 + std::max (1.0 , 2.25 - 9.9 / rootDepth)
539540 * totBestMoveChanges / Threads.size ();
540541 int complexity = mainThread->complexityAverage .value ();
541- double complexPosition = std::clamp (1.0 + (complexity - 232 ) / 1750.0 , 0.5 , 1.5 );
542+ double complexPosition = std::clamp (1.0 + (complexity - 312 ) / 1750.0 , 0.5 , 1.5 );
542543
543544 double totalTime = Time.optimum () * fallingEval * reduction * bestMoveInstability * complexPosition;
544545
@@ -559,7 +560,7 @@ void Thread::search() {
559560 }
560561 else if ( Threads.increaseDepth
561562 && !mainThread->ponder
562- && Time.elapsed () > totalTime * 0.58 )
563+ && Time.elapsed () > totalTime * 0.55 )
563564 Threads.increaseDepth = false ;
564565 else
565566 Threads.increaseDepth = true ;
@@ -857,19 +858,19 @@ namespace {
857858 // Step 8. Futility pruning: child node (~25 Elo).
858859 // The depth condition is important for mate finding.
859860 if ( !ss->ttPv
860- && depth < 9
861+ && depth < 8
861862 && eval - futility_margin (depth, improving) - (ss-1 )->statScore / 256 >= beta
862863 && eval >= beta
863- && eval < 15000 ) // 50% larger than VALUE_KNOWN_WIN, but smaller than TB wins.
864+ && eval < 17548 ) // 50% larger than VALUE_KNOWN_WIN, but smaller than TB wins.
864865 return eval;
865866
866867 // Step 9. Null move search with verification search (~22 Elo)
867868 if ( !PvNode
868869 && (ss-1 )->currentMove != MOVE_NULL
869- && (ss-1 )->statScore < 23767
870+ && (ss-1 )->statScore < 13706
870871 && eval >= beta
871872 && eval >= ss->staticEval
872- && ss->staticEval >= beta - 20 * depth - improvement / 15 + 204 + complexity / 25
873+ && ss->staticEval >= beta - 19 * depth - improvement / 15 + 200 + complexity / 25
873874 && !excludedMove
874875 && pos.non_pawn_material (us)
875876 && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor ))
@@ -913,13 +914,13 @@ namespace {
913914 }
914915 }
915916
916- probCutBeta = beta + 209 - 44 * improving;
917+ probCutBeta = beta + 229 - 47 * improving;
917918
918919 // Step 10. ProbCut (~4 Elo)
919920 // If we have a good enough capture and a reduced search returns a value
920921 // much above beta, we can (almost) safely prune the previous move.
921922 if ( !PvNode
922- && depth > 4
923+ && depth > 3
923924 && abs (beta) < VALUE_TB_WIN_IN_MAX_PLY
924925 // if value from transposition table is lower than probCutBeta, don't attempt probCut
925926 // there and in further interactions with transposition table cutoff depth is set to depth - 3
@@ -940,7 +941,6 @@ namespace {
940941 if (move != excludedMove && pos.legal (move))
941942 {
942943 assert (pos.capture_or_promotion (move));
943- assert (depth >= 5 );
944944
945945 captureOrPromotion = true ;
946946
@@ -978,19 +978,19 @@ namespace {
978978
979979 // Step 11. If the position is not in TT, decrease depth by 2 or 1 depending on node type (~3 Elo)
980980 if ( PvNode
981- && depth >= 6
981+ && depth >= 4
982982 && !ttMove)
983983 depth -= 2 ;
984984
985985 if ( cutNode
986- && depth >= 9
986+ && depth >= 7
987987 && !ttMove)
988988 depth--;
989989
990990moves_loop: // When in check, search starts here
991991
992992 // Step 12. A small Probcut idea, when we are in check (~0 Elo)
993- probCutBeta = beta + 409 ;
993+ probCutBeta = beta + 401 ;
994994 if ( ss->inCheck
995995 && !PvNode
996996 && depth >= 4
@@ -1086,12 +1086,12 @@ namespace {
10861086 && !PvNode
10871087 && lmrDepth < 6
10881088 && !ss->inCheck
1089- && ss->staticEval + 342 + 238 * lmrDepth + PieceValue[EG][pos.piece_on (to_sq (move))]
1089+ && ss->staticEval + 392 + 207 * lmrDepth + PieceValue[EG][pos.piece_on (to_sq (move))]
10901090 + captureHistory[movedPiece][to_sq (move)][type_of (pos.piece_on (to_sq (move)))] / 8 < alpha)
10911091 continue ;
10921092
10931093 // SEE based pruning (~9 Elo)
1094- if (!pos.see_ge (move, Value (-217 ) * depth))
1094+ if (!pos.see_ge (move, Value (-200 ) * depth))
10951095 continue ;
10961096 }
10971097 else
@@ -1109,12 +1109,12 @@ namespace {
11091109
11101110 // Futility pruning: parent node (~9 Elo)
11111111 if ( !ss->inCheck
1112- && lmrDepth < 8
1113- && ss->staticEval + 138 + 137 * lmrDepth + history / 64 <= alpha)
1112+ && lmrDepth < 11
1113+ && ss->staticEval + 131 + 137 * lmrDepth + history / 64 <= alpha)
11141114 continue ;
11151115
11161116 // Prune moves with negative SEE (~3 Elo)
1117- if (!pos.see_ge (move, Value (-21 * lmrDepth * lmrDepth - 21 * lmrDepth)))
1117+ if (!pos.see_ge (move, Value (-25 * lmrDepth * lmrDepth - 29 * lmrDepth)))
11181118 continue ;
11191119 }
11201120 }
@@ -1150,7 +1150,7 @@ namespace {
11501150
11511151 // Avoid search explosion by limiting the number of double extensions
11521152 if ( !PvNode
1153- && value < singularBeta - 75
1153+ && value < singularBeta - 71
11541154 && ss->doubleExtensions <= 6 )
11551155 extension = 2 ;
11561156 }
@@ -1170,15 +1170,15 @@ namespace {
11701170
11711171 // Check extensions (~1 Elo)
11721172 else if ( givesCheck
1173- && depth > 6
1174- && abs (ss->staticEval ) > 100 )
1173+ && depth > 7
1174+ && abs (ss->staticEval ) > 128 )
11751175 extension = 1 ;
11761176
11771177 // Quiet ttMove extensions (~0 Elo)
11781178 else if ( PvNode
11791179 && move == ttMove
11801180 && move == ss->killers [0 ]
1181- && (*contHist[0 ])[movedPiece][to_sq (move)] >= 10000 )
1181+ && (*contHist[0 ])[movedPiece][to_sq (move)] >= 8932 )
11821182 extension = 1 ;
11831183 }
11841184
@@ -1205,8 +1205,8 @@ namespace {
12051205 // We use various heuristics for the sons of a node after the first son has
12061206 // been searched. In general we would like to reduce them, but there are many
12071207 // cases where we extend a son if it has good chances to be "interesting".
1208- if ( depth >= 3
1209- && moveCount > 1 + 2 * rootNode
1208+ if ( depth >= 2
1209+ && moveCount > 1 + rootNode
12101210 && ( !ss->ttPv
12111211 || !captureOrPromotion
12121212 || (cutNode && (ss-1 )->moveCount > 1 )))
@@ -1215,7 +1215,7 @@ namespace {
12151215
12161216 // Decrease reduction at some PvNodes (~2 Elo)
12171217 if ( PvNode
1218- && bestMoveCount <= 3 )
1218+ && bestMoveCount <= 4 )
12191219 r--;
12201220
12211221 // Decrease reduction if position is or has been on the PV
@@ -1225,7 +1225,7 @@ namespace {
12251225 r -= 2 ;
12261226
12271227 // Decrease reduction if opponent's move count is high (~1 Elo)
1228- if ((ss-1 )->moveCount > 13 )
1228+ if ((ss-1 )->moveCount > 7 )
12291229 r--;
12301230
12311231 // Increase reduction for cut nodes (~3 Elo)
@@ -1240,18 +1240,18 @@ namespace {
12401240 + (*contHist[0 ])[movedPiece][to_sq (move)]
12411241 + (*contHist[1 ])[movedPiece][to_sq (move)]
12421242 + (*contHist[3 ])[movedPiece][to_sq (move)]
1243- - 4923 ;
1243+ - 4142 ;
12441244
12451245 // Decrease/increase reduction for moves with a good/bad history (~30 Elo)
1246- r -= ss->statScore / 14721 ;
1246+ r -= ss->statScore / 15328 ;
12471247
12481248 // In general we want to cap the LMR depth search at newDepth. But if reductions
12491249 // are really negative and movecount is low, we allow this move to be searched
12501250 // deeper than the first move (this may lead to hidden double extensions).
12511251 int deeper = r >= -1 ? 0
12521252 : moveCount <= 5 ? 2
1253- : PvNode && depth > 6 ? 1
1254- : cutNode && moveCount <= 7 ? 1
1253+ : PvNode && depth > 4 ? 1
1254+ : cutNode && moveCount <= 5 ? 1
12551255 : 0 ;
12561256
12571257 Depth d = std::clamp (newDepth - r, 1 , newDepth + deeper);
@@ -1260,7 +1260,7 @@ namespace {
12601260
12611261 // If the son is reduced and fails high it will be re-searched at full depth
12621262 doFullDepthSearch = value > alpha && d < newDepth;
1263- doDeeperSearch = value > (alpha + 62 + 20 * (newDepth - d));
1263+ doDeeperSearch = value > (alpha + 80 + 20 * (newDepth - d));
12641264 didLMR = true ;
12651265 }
12661266 else
@@ -1281,7 +1281,7 @@ namespace {
12811281 : -stat_bonus (newDepth);
12821282
12831283 if (captureOrPromotion)
1284- bonus /= 4 ;
1284+ bonus /= 5 ;
12851285
12861286 update_continuation_histories (ss, movedPiece, to_sq (move), bonus);
12871287 }
@@ -1412,7 +1412,7 @@ namespace {
14121412 // or fail low was really bad
14131413 bool extraBonus = PvNode
14141414 || cutNode
1415- || bestValue < alpha - 94 * depth;
1415+ || bestValue < alpha - 99 * depth;
14161416
14171417 update_continuation_histories (ss-1 , pos.piece_on (prevSq), prevSq, stat_bonus (depth) * (1 + extraBonus));
14181418 }
@@ -1543,7 +1543,7 @@ namespace {
15431543 if (PvNode && bestValue > alpha)
15441544 alpha = bestValue;
15451545
1546- futilityBase = bestValue + 155 ;
1546+ futilityBase = bestValue + 127 ;
15471547 }
15481548
15491549 const PieceToHistory* contHist[] = { (ss-1 )->continuationHistory , (ss-2 )->continuationHistory ,
0 commit comments