@@ -63,15 +63,15 @@ namespace {
6363
6464 // Futility margin
6565 Value futility_margin (Depth d, bool improving) {
66- return Value (171 * (d - improving));
66+ return Value (147 * (d - improving));
6767 }
6868
6969 // Reductions lookup table, initialized at startup
7070 int Reductions[MAX_MOVES]; // [depth or moveNumber]
7171
7272 Depth reduction (bool i, Depth d, int mn, Value delta, Value rootDelta) {
7373 int r = Reductions[d] * Reductions[mn];
74- return (r + 1575 - int (delta) * 1024 / int (rootDelta)) / 1024 + (!i && r > 1011 );
74+ return (r + 1627 - int (delta) * 1024 / int (rootDelta)) / 1024 + (!i && r > 992 );
7575 }
7676
7777 constexpr int futility_move_count (bool improving, Depth depth) {
@@ -80,7 +80,7 @@ namespace {
8080
8181 // History and stats update bonus, based on depth
8282 int stat_bonus (Depth d) {
83- return std::min ((7 * d + 254 ) * d - 206 , 1990 );
83+ return std::min ((8 * d + 281 ) * d - 241 , 1949 );
8484 }
8585
8686 // Add a small random component to draw evaluations to avoid 3-fold blindness
@@ -157,7 +157,7 @@ namespace {
157157void Search::init () {
158158
159159 for (int i = 1 ; i < MAX_MOVES; ++i)
160- Reductions[i] = int ((21.5 + std::log (Threads.size ()) / 2 ) * std::log (i));
160+ Reductions[i] = int ((21.14 + std::log (Threads.size ()) / 2 ) * std::log (i));
161161}
162162
163163
@@ -303,10 +303,10 @@ void Thread::search() {
303303
304304 multiPV = std::min (multiPV, rootMoves.size ());
305305
306- complexityAverage.set (190 , 1 );
306+ complexityAverage.set (211 , 1 );
307307
308308 trend = SCORE_ZERO;
309- optimism[ us] = Value (34 );
309+ optimism[ us] = Value (33 );
310310 optimism[~us] = -optimism[us];
311311
312312 int searchAgainCounter = 0 ;
@@ -349,16 +349,16 @@ void Thread::search() {
349349 if (rootDepth >= 4 )
350350 {
351351 Value prev = rootMoves[pvIdx].averageScore ;
352- delta = Value (16 ) + int (prev) * prev / 16384 ;
352+ delta = Value (19 ) + int (prev) * prev / 18321 ;
353353 alpha = std::max (prev - delta,-VALUE_INFINITE);
354354 beta = std::min (prev + delta, VALUE_INFINITE);
355355
356356 // Adjust trend and optimism based on root move's previousScore
357- int tr = sigmoid (prev, 6 , 13 , 96 , 110 , 1 );
357+ int tr = sigmoid (prev, 4 , 11 , 92 , 119 , 1 );
358358 trend = (us == WHITE ? make_score (tr, tr / 2 )
359359 : -make_score (tr, tr / 2 ));
360360
361- int opt = sigmoid (prev, 7 , 21 , 94 , 14786 , 221 );
361+ int opt = sigmoid (prev, 9 , 18 , 115 , 12250 , 187 );
362362 optimism[ us] = Value (opt);
363363 optimism[~us] = -optimism[us];
364364 }
@@ -413,7 +413,7 @@ void Thread::search() {
413413 else
414414 break ;
415415
416- delta += delta / 4 + 3 ;
416+ delta += delta / 4 + 2 ;
417417
418418 assert (alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE);
419419 }
@@ -459,17 +459,17 @@ void Thread::search() {
459459 && !Threads.stop
460460 && !mainThread->stopOnPonderhit )
461461 {
462- double fallingEval = (87 + 12 * (mainThread->bestPreviousAverageScore - bestValue)
463- + 6 * (mainThread->iterValue [iterIdx] - bestValue)) / 777.20 ;
462+ double fallingEval = (66 + 12 * (mainThread->bestPreviousAverageScore - bestValue)
463+ + 6 * (mainThread->iterValue [iterIdx] - bestValue)) / 809.70 ;
464464 fallingEval = std::clamp (fallingEval, 0.5 , 1.5 );
465465
466466 // If the bestMove is stable over several iterations, reduce time accordingly
467- timeReduction = lastBestMoveDepth + 8 < completedDepth ? 1.70 : 0.91 ;
468- double reduction = (1.59 + mainThread->previousTimeReduction ) / (2.33 * timeReduction);
467+ timeReduction = lastBestMoveDepth + 8 < completedDepth ? 1.73 : 0.94 ;
468+ double reduction = (1.66 + mainThread->previousTimeReduction ) / (2.35 * timeReduction);
469469 double bestMoveInstability = 1.073 + std::max (1.0 , 2.25 - 9.9 / rootDepth)
470470 * totBestMoveChanges / Threads.size ();
471471 int complexity = mainThread->complexityAverage .value ();
472- double complexPosition = std::clamp (1.0 + (complexity - 312 ) / 1750 .0 , 0.5 , 1.5 );
472+ double complexPosition = std::clamp (1.0 + (complexity - 293 ) / 1525 .0 , 0.5 , 1.5 );
473473
474474 double totalTime = Time.optimum () * fallingEval * reduction * bestMoveInstability * complexPosition;
475475
@@ -490,7 +490,7 @@ void Thread::search() {
490490 }
491491 else if ( Threads.increaseDepth
492492 && !mainThread->ponder
493- && Time.elapsed () > totalTime * 0.55 )
493+ && Time.elapsed () > totalTime * 0.49 )
494494 Threads.increaseDepth = false ;
495495 else
496496 Threads.increaseDepth = true ;
@@ -766,7 +766,7 @@ namespace {
766766 // margin and the improving flag are used in various pruning heuristics.
767767 improvement = (ss-2 )->staticEval != VALUE_NONE ? ss->staticEval - (ss-2 )->staticEval
768768 : (ss-4 )->staticEval != VALUE_NONE ? ss->staticEval - (ss-4 )->staticEval
769- : 200 ;
769+ : 184 ;
770770
771771 improving = improvement > 0 ;
772772 complexity = abs (ss->staticEval - (us == WHITE ? eg_value (pos.psq_score ()) : -eg_value (pos.psq_score ())));
@@ -778,7 +778,7 @@ namespace {
778778 // return a fail low.
779779 if ( !PvNode
780780 && depth <= 6
781- && eval < alpha - 400 - 300 * depth * depth)
781+ && eval < alpha - 486 - 314 * depth * depth)
782782 {
783783 value = qsearch<NonPV>(pos, ss, alpha - 1 , alpha);
784784 if (value < alpha)
@@ -791,24 +791,24 @@ namespace {
791791 && depth < 8
792792 && eval - futility_margin (depth, improving) - (ss-1 )->statScore / 256 >= beta
793793 && eval >= beta
794- && eval < 17548 ) // 50% larger than VALUE_KNOWN_WIN, but smaller than TB wins.
794+ && eval < 22266 ) // larger than VALUE_KNOWN_WIN, but smaller than TB wins.
795795 return eval;
796796
797797 // Step 9. Null move search with verification search (~22 Elo)
798798 if ( !PvNode
799799 && (ss-1 )->currentMove != MOVE_NULL
800- && (ss-1 )->statScore < 13706
800+ && (ss-1 )->statScore < 15075
801801 && eval >= beta
802802 && eval >= ss->staticEval
803- && ss->staticEval >= beta - 19 * depth - improvement / 15 + 200 + complexity / 25
803+ && ss->staticEval >= beta - 18 * depth - improvement / 19 + 215 + complexity / 30
804804 && !excludedMove
805805 && pos.non_pawn_material (us)
806806 && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor ))
807807 {
808808 assert (eval - beta >= 0 );
809809
810810 // Null move dynamic reduction based on depth, eval and complexity of position
811- Depth R = std::min (int (eval - beta) / 205 , 3 ) + depth / 3 + 4 - (complexity > 500 );
811+ Depth R = std::min (int (eval - beta) / 184 , 4 ) + depth / 3 + 4 - (complexity > 799 );
812812
813813 ss->currentMove = MOVE_NULL;
814814 ss->continuationHistory = &thisThread->continuationHistory [0 ][0 ][NO_PIECE][0 ];
@@ -844,13 +844,13 @@ namespace {
844844 }
845845 }
846846
847- probCutBeta = beta + 229 - 47 * improving;
847+ probCutBeta = beta + 204 - 52 * improving;
848848
849849 // Step 10. ProbCut (~4 Elo)
850850 // If we have a good enough capture and a reduced search returns a value
851851 // much above beta, we can (almost) safely prune the previous move.
852852 if ( !PvNode
853- && depth > 3
853+ && depth > 4
854854 && abs (beta) < VALUE_TB_WIN_IN_MAX_PLY
855855 // if value from transposition table is lower than probCutBeta, don't attempt probCut
856856 // there and in further interactions with transposition table cutoff depth is set to depth - 3
@@ -908,12 +908,12 @@ namespace {
908908
909909 // Step 11. If the position is not in TT, decrease depth by 2 or 1 depending on node type (~3 Elo)
910910 if ( PvNode
911- && depth >= 4
911+ && depth >= 3
912912 && !ttMove)
913913 depth -= 2 ;
914914
915915 if ( cutNode
916- && depth >= 7
916+ && depth >= 8
917917 && !ttMove)
918918 depth--;
919919
@@ -923,7 +923,7 @@ namespace {
923923 probCutBeta = beta + 401 ;
924924 if ( ss->inCheck
925925 && !PvNode
926- && depth >= 4
926+ && depth >= 2
927927 && ttCapture
928928 && (tte->bound () & BOUND_LOWER)
929929 && tte->depth () >= depth - 3
@@ -1014,14 +1014,14 @@ namespace {
10141014 if ( !pos.empty (to_sq (move))
10151015 && !givesCheck
10161016 && !PvNode
1017- && lmrDepth < 6
1017+ && lmrDepth < 7
10181018 && !ss->inCheck
1019- && ss->staticEval + 392 + 207 * lmrDepth + PieceValue[EG][pos.piece_on (to_sq (move))]
1020- + captureHistory[movedPiece][to_sq (move)][type_of (pos.piece_on (to_sq (move)))] / 8 < alpha)
1019+ && ss->staticEval + 424 + 138 * lmrDepth + PieceValue[EG][pos.piece_on (to_sq (move))]
1020+ + captureHistory[movedPiece][to_sq (move)][type_of (pos.piece_on (to_sq (move)))] / 7 < alpha)
10211021 continue ;
10221022
10231023 // SEE based pruning (~9 Elo)
1024- if (!pos.see_ge (move, Value (-200 ) * depth))
1024+ if (!pos.see_ge (move, Value (-214 ) * depth))
10251025 continue ;
10261026 }
10271027 else
@@ -1040,11 +1040,11 @@ namespace {
10401040 // Futility pruning: parent node (~9 Elo)
10411041 if ( !ss->inCheck
10421042 && lmrDepth < 11
1043- && ss->staticEval + 131 + 137 * lmrDepth + history / 64 <= alpha)
1043+ && ss->staticEval + 147 + 125 * lmrDepth + history / 64 <= alpha)
10441044 continue ;
10451045
10461046 // Prune moves with negative SEE (~3 Elo)
1047- if (!pos.see_ge (move, Value (-25 * lmrDepth * lmrDepth - 29 * lmrDepth)))
1047+ if (!pos.see_ge (move, Value (-23 * lmrDepth * lmrDepth - 31 * lmrDepth)))
10481048 continue ;
10491049 }
10501050 }
@@ -1067,7 +1067,7 @@ namespace {
10671067 && (tte->bound () & BOUND_LOWER)
10681068 && tte->depth () >= depth - 3 )
10691069 {
1070- Value singularBeta = ttValue - 3 * depth;
1070+ Value singularBeta = ttValue - 4 * depth;
10711071 Depth singularDepth = (depth - 1 ) / 2 ;
10721072
10731073 ss->excludedMove = move;
@@ -1080,8 +1080,8 @@ namespace {
10801080
10811081 // Avoid search explosion by limiting the number of double extensions
10821082 if ( !PvNode
1083- && value < singularBeta - 71
1084- && ss->doubleExtensions <= 6 )
1083+ && value < singularBeta - 52
1084+ && ss->doubleExtensions <= 8 )
10851085 extension = 2 ;
10861086 }
10871087
@@ -1100,15 +1100,15 @@ namespace {
11001100
11011101 // Check extensions (~1 Elo)
11021102 else if ( givesCheck
1103- && depth > 7
1104- && abs (ss->staticEval ) > 128 )
1103+ && depth > 8
1104+ && abs (ss->staticEval ) > 81 )
11051105 extension = 1 ;
11061106
11071107 // Quiet ttMove extensions (~0 Elo)
11081108 else if ( PvNode
11091109 && move == ttMove
11101110 && move == ss->killers [0 ]
1111- && (*contHist[0 ])[movedPiece][to_sq (move)] >= 8932 )
1111+ && (*contHist[0 ])[movedPiece][to_sq (move)] >= 7546 )
11121112 extension = 1 ;
11131113 }
11141114
@@ -1145,7 +1145,7 @@ namespace {
11451145
11461146 // Decrease reduction at some PvNodes (~2 Elo)
11471147 if ( PvNode
1148- && bestMoveCount <= 4 )
1148+ && bestMoveCount <= 3 )
11491149 r--;
11501150
11511151 // Decrease reduction if position is or has been on the PV
@@ -1170,18 +1170,18 @@ namespace {
11701170 + (*contHist[0 ])[movedPiece][to_sq (move)]
11711171 + (*contHist[1 ])[movedPiece][to_sq (move)]
11721172 + (*contHist[3 ])[movedPiece][to_sq (move)]
1173- - 4142 ;
1173+ - 4123 ;
11741174
11751175 // Decrease/increase reduction for moves with a good/bad history (~30 Elo)
1176- r -= ss->statScore / 15328 ;
1176+ r -= ss->statScore / 17417 ;
11771177
11781178 // In general we want to cap the LMR depth search at newDepth. But if reductions
11791179 // are really negative and movecount is low, we allow this move to be searched
11801180 // deeper than the first move (this may lead to hidden double extensions).
11811181 int deeper = r >= -1 ? 0
11821182 : moveCount <= 5 ? 2
1183- : PvNode && depth > 4 ? 1
1184- : cutNode && moveCount <= 5 ? 1
1183+ : PvNode && depth > 3 ? 1
1184+ : cutNode && moveCount <= 7 ? 1
11851185 : 0 ;
11861186
11871187 Depth d = std::clamp (newDepth - r, 1 , newDepth + deeper);
@@ -1190,7 +1190,7 @@ namespace {
11901190
11911191 // If the son is reduced and fails high it will be re-searched at full depth
11921192 doFullDepthSearch = value > alpha && d < newDepth;
1193- doDeeperSearch = value > (alpha + 80 + 20 * (newDepth - d));
1193+ doDeeperSearch = value > (alpha + 76 + 11 * (newDepth - d));
11941194 didLMR = true ;
11951195 }
11961196 else
@@ -1211,7 +1211,7 @@ namespace {
12111211 : -stat_bonus (newDepth);
12121212
12131213 if (captureOrPromotion)
1214- bonus /= 5 ;
1214+ bonus /= 6 ;
12151215
12161216 update_continuation_histories (ss, movedPiece, to_sq (move), bonus);
12171217 }
@@ -1335,14 +1335,14 @@ namespace {
13351335 quietsSearched, quietCount, capturesSearched, captureCount, depth);
13361336
13371337 // Bonus for prior countermove that caused the fail low
1338- else if ( (depth >= 3 || PvNode)
1338+ else if ( (depth >= 4 || PvNode)
13391339 && !priorCapture)
13401340 {
13411341 // Assign extra bonus if current node is PvNode or cutNode
13421342 // or fail low was really bad
13431343 bool extraBonus = PvNode
13441344 || cutNode
1345- || bestValue < alpha - 99 * depth;
1345+ || bestValue < alpha - 71 * depth;
13461346
13471347 update_continuation_histories (ss-1 , pos.piece_on (prevSq), prevSq, stat_bonus (depth) * (1 + extraBonus));
13481348 }
@@ -1473,7 +1473,7 @@ namespace {
14731473 if (PvNode && bestValue > alpha)
14741474 alpha = bestValue;
14751475
1476- futilityBase = bestValue + 127 ;
1476+ futilityBase = bestValue + 139 ;
14771477 }
14781478
14791479 const PieceToHistory* contHist[] = { (ss-1 )->continuationHistory , (ss-2 )->continuationHistory ,
0 commit comments