@@ -63,15 +63,15 @@ namespace {
6363
6464 // Futility margin
6565 Value futility_margin (Depth d, bool improving) {
66- return Value (147 * (d - improving));
66+ return Value (168 * (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 + 1627 - int (delta) * 1024 / int (rootDelta)) / 1024 + (!i && r > 992 );
74+ return (r + 1463 - int (delta) * 1024 / int (rootDelta)) / 1024 + (!i && r > 1010 );
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 ((8 * d + 281 ) * d - 241 , 1949 );
83+ return std::min ((9 * d + 270 ) * d - 311 , 2145 );
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.14 + std::log (Threads.size ()) / 2 ) * std::log (i));
160+ Reductions[i] = int ((20.81 + 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 (211 , 1 );
306+ complexityAverage.set (202 , 1 );
307307
308308 trend = SCORE_ZERO;
309- optimism[ us] = Value (33 );
309+ optimism[ us] = Value (39 );
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 (19 ) + int (prev) * prev / 18321 ;
352+ delta = Value (16 ) + int (prev) * prev / 19178 ;
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, 4 , 11 , 92 , 119 , 1 );
357+ int tr = sigmoid (prev, 3 , 8 , 90 , 125 , 1 );
358358 trend = (us == WHITE ? make_score (tr, tr / 2 )
359359 : -make_score (tr, tr / 2 ));
360360
361- int opt = sigmoid (prev, 9 , 18 , 115 , 12250 , 187 );
361+ int opt = sigmoid (prev, 8 , 17 , 144 , 13966 , 183 );
362362 optimism[ us] = Value (opt);
363363 optimism[~us] = -optimism[us];
364364 }
@@ -459,17 +459,17 @@ void Thread::search() {
459459 && !Threads.stop
460460 && !mainThread->stopOnPonderhit )
461461 {
462- double fallingEval = (66 + 12 * (mainThread->bestPreviousAverageScore - bestValue)
463- + 6 * (mainThread->iterValue [iterIdx] - bestValue)) / 809.70 ;
462+ double fallingEval = (69 + 12 * (mainThread->bestPreviousAverageScore - bestValue)
463+ + 6 * (mainThread->iterValue [iterIdx] - bestValue)) / 781.4 ;
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.73 : 0.94 ;
468- double reduction = (1.66 + mainThread->previousTimeReduction ) / (2.35 * timeReduction);
467+ timeReduction = lastBestMoveDepth + 10 < completedDepth ? 1.63 : 0.73 ;
468+ double reduction = (1.56 + mainThread->previousTimeReduction ) / (2.20 * 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 - 293 ) / 1525.0 , 0.5 , 1.5 );
472+ double complexPosition = std::clamp (1.0 + (complexity - 326 ) / 1618.1 , 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.49 )
493+ && Time.elapsed () > totalTime * 0.43 )
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- : 184 ;
769+ : 175 ;
770770
771771 improving = improvement > 0 ;
772772 complexity = abs (ss->staticEval - (us == WHITE ? eg_value (pos.psq_score ()) : -eg_value (pos.psq_score ())));
@@ -777,8 +777,8 @@ namespace {
777777 // If eval is really low check with qsearch if it can exceed alpha, if it can't,
778778 // return a fail low.
779779 if ( !PvNode
780- && depth <= 6
781- && eval < alpha - 486 - 314 * depth * depth)
780+ && depth <= 7
781+ && eval < alpha - 348 - 258 * 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 < 22266 ) // larger than VALUE_KNOWN_WIN, but smaller than TB wins.
794+ && eval < 26305 ) // 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 < 15075
800+ && (ss-1 )->statScore < 14695
801801 && eval >= beta
802802 && eval >= ss->staticEval
803- && ss->staticEval >= beta - 18 * depth - improvement / 19 + 215 + complexity / 30
803+ && ss->staticEval >= beta - 15 * depth - improvement / 15 + 198 + complexity / 28
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) / 184 , 4 ) + depth / 3 + 4 - (complexity > 799 );
811+ Depth R = std::min (int (eval - beta) / 147 , 5 ) + depth / 3 + 4 - (complexity > 753 );
812812
813813 ss->currentMove = MOVE_NULL;
814814 ss->continuationHistory = &thisThread->continuationHistory [0 ][0 ][NO_PIECE][0 ];
@@ -844,7 +844,7 @@ namespace {
844844 }
845845 }
846846
847- probCutBeta = beta + 204 - 52 * improving;
847+ probCutBeta = beta + 179 - 46 * improving;
848848
849849 // Step 10. ProbCut (~4 Elo)
850850 // If we have a good enough capture and a reduced search returns a value
@@ -920,7 +920,7 @@ namespace {
920920moves_loop: // When in check, search starts here
921921
922922 // Step 12. A small Probcut idea, when we are in check (~0 Elo)
923- probCutBeta = beta + 401 ;
923+ probCutBeta = beta + 481 ;
924924 if ( ss->inCheck
925925 && !PvNode
926926 && depth >= 2
@@ -1014,14 +1014,14 @@ namespace {
10141014 if ( !pos.empty (to_sq (move))
10151015 && !givesCheck
10161016 && !PvNode
1017- && lmrDepth < 7
1017+ && lmrDepth < 6
10181018 && !ss->inCheck
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)
1019+ && ss->staticEval + 281 + 179 * lmrDepth + PieceValue[EG][pos.piece_on (to_sq (move))]
1020+ + captureHistory[movedPiece][to_sq (move)][type_of (pos.piece_on (to_sq (move)))] / 6 < alpha)
10211021 continue ;
10221022
10231023 // SEE based pruning (~9 Elo)
1024- if (!pos.see_ge (move, Value (-214 ) * depth))
1024+ if (!pos.see_ge (move, Value (-203 ) * 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 + 147 + 125 * lmrDepth + history / 64 <= alpha)
1043+ && ss->staticEval + 122 + 138 * lmrDepth + history / 60 <= alpha)
10441044 continue ;
10451045
10461046 // Prune moves with negative SEE (~3 Elo)
1047- if (!pos.see_ge (move, Value (-23 * lmrDepth * lmrDepth - 31 * lmrDepth)))
1047+ if (!pos.see_ge (move, Value (-25 * lmrDepth * lmrDepth - 20 * lmrDepth)))
10481048 continue ;
10491049 }
10501050 }
@@ -1059,15 +1059,15 @@ namespace {
10591059 // a reduced search on all the other moves but the ttMove and if the
10601060 // result is lower than ttValue minus a margin, then we will extend the ttMove.
10611061 if ( !rootNode
1062- && depth >= 6 + 2 * (PvNode && tte->is_pv ())
1062+ && depth >= 4 + 2 * (PvNode && tte->is_pv ())
10631063 && move == ttMove
10641064 && !excludedMove // Avoid recursive singular search
10651065 /* && ttValue != VALUE_NONE Already implicit in the next condition */
10661066 && abs (ttValue) < VALUE_KNOWN_WIN
10671067 && (tte->bound () & BOUND_LOWER)
10681068 && tte->depth () >= depth - 3 )
10691069 {
1070- Value singularBeta = ttValue - 4 * depth;
1070+ Value singularBeta = ttValue - 3 * depth;
10711071 Depth singularDepth = (depth - 1 ) / 2 ;
10721072
10731073 ss->excludedMove = move;
@@ -1080,7 +1080,7 @@ namespace {
10801080
10811081 // Avoid search explosion by limiting the number of double extensions
10821082 if ( !PvNode
1083- && value < singularBeta - 52
1083+ && value < singularBeta - 26
10841084 && ss->doubleExtensions <= 8 )
10851085 extension = 2 ;
10861086 }
@@ -1100,15 +1100,15 @@ namespace {
11001100
11011101 // Check extensions (~1 Elo)
11021102 else if ( givesCheck
1103- && depth > 8
1104- && abs (ss->staticEval ) > 81 )
1103+ && depth > 9
1104+ && abs (ss->staticEval ) > 71 )
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)] >= 7546 )
1111+ && (*contHist[0 ])[movedPiece][to_sq (move)] >= 5491 )
11121112 extension = 1 ;
11131113 }
11141114
@@ -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- - 4123 ;
1173+ - 4334 ;
11741174
11751175 // Decrease/increase reduction for moves with a good/bad history (~30 Elo)
1176- r -= ss->statScore / 17417 ;
1176+ r -= ss->statScore / 15914 ;
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
1182- : moveCount <= 5 ? 2
1183- : PvNode && depth > 3 ? 1
1184- : cutNode && moveCount <= 7 ? 1
1182+ : moveCount <= 4 ? 2
1183+ : PvNode && depth > 4 ? 1
1184+ : cutNode && moveCount <= 8 ? 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 + 76 + 11 * (newDepth - d));
1193+ doDeeperSearch = value > (alpha + 78 + 11 * (newDepth - d));
11941194 didLMR = true ;
11951195 }
11961196 else
@@ -1342,7 +1342,7 @@ namespace {
13421342 // or fail low was really bad
13431343 bool extraBonus = PvNode
13441344 || cutNode
1345- || bestValue < alpha - 71 * depth;
1345+ || bestValue < alpha - 70 * 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 + 139 ;
1476+ futilityBase = bestValue + 118 ;
14771477 }
14781478
14791479 const PieceToHistory* contHist[] = { (ss-1 )->continuationHistory , (ss-2 )->continuationHistory ,
0 commit comments