@@ -77,27 +77,27 @@ enum NodeType {
7777
7878// Futility margin
7979Value futility_margin (Depth d, bool noTtCutNode, bool improving) {
80- return Value ((125 - 43 * noTtCutNode) * (d - improving));
80+ return Value ((116 - 44 * noTtCutNode) * (d - improving));
8181}
8282
8383// Reductions lookup table initialized at startup
8484int Reductions[MAX_MOVES]; // [depth or moveNumber]
8585
8686Depth reduction (bool i, Depth d, int mn, Value delta, Value rootDelta) {
8787 int reductionScale = Reductions[d] * Reductions[mn];
88- return (reductionScale + 1487 - int (delta) * 976 / int (rootDelta)) / 1024
89- + (!i && reductionScale > 808 );
88+ return (reductionScale + 1346 - int (delta) * 896 / int (rootDelta)) / 1024
89+ + (!i && reductionScale > 880 );
9090}
9191
9292constexpr int futility_move_count (bool improving, Depth depth) {
9393 return improving ? (3 + depth * depth) : (3 + depth * depth) / 2 ;
9494}
9595
9696// History and stats update bonus, based on depth
97- int stat_bonus (Depth d) { return std::min (291 * d - 350 , 1200 ); }
97+ int stat_bonus (Depth d) { return std::min (268 * d - 352 , 1153 ); }
9898
9999// History and stats update malus, based on depth
100- int stat_malus (Depth d) { return std::min (361 * d - 361 , 1182 ); }
100+ int stat_malus (Depth d) { return std::min (400 * d - 354 , 1201 ); }
101101
102102// Add a small random component to draw evaluations to avoid 3-fold blindness
103103Value value_draw (const Thread* thisThread) {
@@ -367,12 +367,12 @@ void Thread::search() {
367367
368368 // Reset aspiration window starting size
369369 Value avg = rootMoves[pvIdx].averageScore ;
370- delta = Value (10 ) + int (avg) * avg / 15335 ;
370+ delta = Value (9 ) + int (avg) * avg / 14847 ;
371371 alpha = std::max (avg - delta, -VALUE_INFINITE);
372372 beta = std::min (avg + delta, VALUE_INFINITE);
373373
374374 // Adjust optimism based on root move's averageScore (~4 Elo)
375- optimism[us] = 110 * avg / (std::abs (avg) + 121 );
375+ optimism[us] = 121 * avg / (std::abs (avg) + 109 );
376376 optimism[~us] = -optimism[us];
377377
378378 // Start with a small aspiration window and, in the case of a fail
@@ -746,7 +746,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
746746 // Use static evaluation difference to improve quiet move ordering (~4 Elo)
747747 if (is_ok ((ss - 1 )->currentMove ) && !(ss - 1 )->inCheck && !priorCapture)
748748 {
749- int bonus = std::clamp (-14 * int ((ss - 1 )->staticEval + ss->staticEval ), -1449 , 1449 );
749+ int bonus = std::clamp (-13 * int ((ss - 1 )->staticEval + ss->staticEval ), -1555 , 1452 );
750750 thisThread->mainHistory [~us][from_to ((ss - 1 )->currentMove )] << bonus;
751751 if (type_of (pos.piece_on (prevSq)) != PAWN && type_of ((ss - 1 )->currentMove ) != PROMOTION)
752752 thisThread->pawnHistory [pawn_structure (pos)][pos.piece_on (prevSq)][prevSq] << bonus / 4 ;
@@ -765,7 +765,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
765765 // If eval is really low check with qsearch if it can exceed alpha, if it can't,
766766 // return a fail low.
767767 // Adjust razor margin according to cutoffCnt. (~1 Elo)
768- if (eval < alpha - 474 - (270 - 174 * ((ss + 1 )->cutoffCnt > 3 )) * depth * depth)
768+ if (eval < alpha - 472 - (284 - 165 * ((ss + 1 )->cutoffCnt > 3 )) * depth * depth)
769769 {
770770 value = qsearch<NonPV>(pos, ss, alpha - 1 , alpha);
771771 if (value < alpha)
@@ -776,22 +776,22 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
776776 // The depth condition is important for mate finding.
777777 if (!ss->ttPv && depth < 9
778778 && eval - futility_margin (depth, cutNode && !ss->ttHit , improving)
779- - (ss - 1 )->statScore / 321
779+ - (ss - 1 )->statScore / 337
780780 >= beta
781- && eval >= beta && eval < 29462 // smaller than TB wins
781+ && eval >= beta && eval < 29008 // smaller than TB wins
782782 && (!ttMove || ttCapture))
783783 return (eval + beta) / 2 ;
784784
785785 // Step 9. Null move search with verification search (~35 Elo)
786- if (!PvNode && (ss - 1 )->currentMove != MOVE_NULL && (ss - 1 )->statScore < 17257 && eval >= beta
787- && eval >= ss->staticEval && ss->staticEval >= beta - 24 * depth + 281 && !excludedMove
786+ if (!PvNode && (ss - 1 )->currentMove != MOVE_NULL && (ss - 1 )->statScore < 17496 && eval >= beta
787+ && eval >= ss->staticEval && ss->staticEval >= beta - 23 * depth + 304 && !excludedMove
788788 && pos.non_pawn_material (us) && ss->ply >= thisThread->nmpMinPly
789789 && beta > VALUE_TB_LOSS_IN_MAX_PLY)
790790 {
791791 assert (eval - beta >= 0 );
792792
793793 // Null move dynamic reduction based on depth and eval
794- Depth R = std::min (int (eval - beta) / 152 , 6 ) + depth / 3 + 4 ;
794+ Depth R = std::min (int (eval - beta) / 144 , 6 ) + depth / 3 + 4 ;
795795
796796 ss->currentMove = MOVE_NULL;
797797 ss->continuationHistory = &thisThread->continuationHistory [0 ][0 ][NO_PIECE][0 ];
@@ -805,7 +805,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
805805 // Do not return unproven mate or TB scores
806806 if (nullValue >= beta && nullValue < VALUE_TB_WIN_IN_MAX_PLY)
807807 {
808- if (thisThread->nmpMinPly || depth < 14 )
808+ if (thisThread->nmpMinPly || depth < 15 )
809809 return nullValue;
810810
811811 assert (!thisThread->nmpMinPly ); // Recursive verification is not allowed
@@ -838,7 +838,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
838838 if (cutNode && depth >= 8 && !ttMove)
839839 depth -= 2 ;
840840
841- probCutBeta = beta + 168 - 70 * improving;
841+ probCutBeta = beta + 163 - 67 * improving;
842842
843843 // Step 11. ProbCut (~10 Elo)
844844 // If we have a good enough capture (or queen promotion) and a reduced search returns a value
@@ -896,7 +896,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
896896moves_loop: // When in check, search starts here
897897
898898 // Step 12. A small Probcut idea, when we are in check (~4 Elo)
899- probCutBeta = beta + 416 ;
899+ probCutBeta = beta + 425 ;
900900 if (ss->inCheck && !PvNode && ttCapture && (tte->bound () & BOUND_LOWER)
901901 && tte->depth () >= depth - 4 && ttValue >= probCutBeta
902902 && abs (ttValue) < VALUE_TB_WIN_IN_MAX_PLY && abs (beta) < VALUE_TB_WIN_IN_MAX_PLY)
@@ -983,14 +983,14 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
983983 {
984984 Piece capturedPiece = pos.piece_on (to_sq (move));
985985 int futilityEval =
986- ss->staticEval + 239 + 291 * lmrDepth + PieceValue[capturedPiece]
986+ ss->staticEval + 238 + 305 * lmrDepth + PieceValue[capturedPiece]
987987 + captureHistory[movedPiece][to_sq (move)][type_of (capturedPiece)] / 7 ;
988988 if (futilityEval < alpha)
989989 continue ;
990990 }
991991
992992 // SEE based pruning for captures and checks (~11 Elo)
993- if (!pos.see_ge (move, Value (-185 ) * depth))
993+ if (!pos.see_ge (move, Value (-187 ) * depth))
994994 continue ;
995995 }
996996 else
@@ -1001,18 +1001,18 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
10011001 + thisThread->pawnHistory [pawn_structure (pos)][movedPiece][to_sq (move)];
10021002
10031003 // Continuation history based pruning (~2 Elo)
1004- if (lmrDepth < 6 && history < -3645 * depth)
1004+ if (lmrDepth < 6 && history < -3752 * depth)
10051005 continue ;
10061006
10071007 history += 2 * thisThread->mainHistory [us][from_to (move)];
10081008
1009- lmrDepth += history / 7836 ;
1009+ lmrDepth += history / 7838 ;
10101010 lmrDepth = std::max (lmrDepth, -1 );
10111011
10121012 // Futility pruning: parent node (~13 Elo)
1013- if (!ss->inCheck && lmrDepth < 13
1014- && ss->staticEval + (bestValue < ss->staticEval - 62 ? 123 : 77 )
1015- + 127 * lmrDepth
1013+ if (!ss->inCheck && lmrDepth < 14
1014+ && ss->staticEval + (bestValue < ss->staticEval - 57 ? 124 : 71 )
1015+ + 118 * lmrDepth
10161016 <= alpha)
10171017 continue ;
10181018
@@ -1039,11 +1039,11 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
10391039 // so changing them requires tests at these types of time controls.
10401040 // Recursive singular search is avoided.
10411041 if (!rootNode && move == ttMove && !excludedMove
1042- && depth >= 4 - (thisThread->completedDepth > 24 ) + 2 * (PvNode && tte->is_pv ())
1042+ && depth >= 4 - (thisThread->completedDepth > 27 ) + 2 * (PvNode && tte->is_pv ())
10431043 && abs (ttValue) < VALUE_TB_WIN_IN_MAX_PLY && (tte->bound () & BOUND_LOWER)
10441044 && tte->depth () >= depth - 3 )
10451045 {
1046- Value singularBeta = ttValue - (64 + 57 * (ss->ttPv && !PvNode)) * depth / 64 ;
1046+ Value singularBeta = ttValue - (66 + 58 * (ss->ttPv && !PvNode)) * depth / 64 ;
10471047 Depth singularDepth = newDepth / 2 ;
10481048
10491049 ss->excludedMove = move;
@@ -1057,7 +1057,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
10571057 singularQuietLMR = !ttCapture;
10581058
10591059 // Avoid search explosion by limiting the number of double extensions
1060- if (!PvNode && value < singularBeta - 18 && ss->doubleExtensions <= 11 )
1060+ if (!PvNode && value < singularBeta - 17 && ss->doubleExtensions <= 11 )
10611061 {
10621062 extension = 2 ;
10631063 depth += depth < 15 ;
@@ -1092,18 +1092,18 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
10921092 }
10931093
10941094 // Check extensions (~1 Elo)
1095- else if (givesCheck && depth > 9 )
1095+ else if (givesCheck && depth > 10 )
10961096 extension = 1 ;
10971097
10981098 // Quiet ttMove extensions (~1 Elo)
10991099 else if (PvNode && move == ttMove && move == ss->killers [0 ]
1100- && (*contHist[0 ])[movedPiece][to_sq (move)] >= 4194 )
1100+ && (*contHist[0 ])[movedPiece][to_sq (move)] >= 4325 )
11011101 extension = 1 ;
11021102
11031103 // Recapture extensions (~1 Elo)
11041104 else if (PvNode && move == ttMove && to_sq (move) == prevSq
11051105 && captureHistory[movedPiece][to_sq (move)][type_of (pos.piece_on (to_sq (move)))]
1106- > 4000 )
1106+ > 4146 )
11071107 extension = 1 ;
11081108 }
11091109
@@ -1162,10 +1162,10 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
11621162 ss->statScore = 2 * thisThread->mainHistory [us][from_to (move)]
11631163 + (*contHist[0 ])[movedPiece][to_sq (move)]
11641164 + (*contHist[1 ])[movedPiece][to_sq (move)]
1165- + (*contHist[3 ])[movedPiece][to_sq (move)] - 3848 ;
1165+ + (*contHist[3 ])[movedPiece][to_sq (move)] - 3817 ;
11661166
11671167 // Decrease/increase reduction for moves with a good/bad history (~25 Elo)
1168- r -= ss->statScore / 14200 ;
1168+ r -= ss->statScore / 14767 ;
11691169
11701170 // Step 17. Late moves reduction / extension (LMR, ~117 Elo)
11711171 // We use various heuristics for the sons of a node after the first son has
@@ -1188,7 +1188,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
11881188 {
11891189 // Adjust full-depth search based on LMR results - if the result
11901190 // was good enough search deeper, if it was bad enough search shallower.
1191- const bool doDeeperSearch = value > (bestValue + 50 + 2 * newDepth); // (~1 Elo)
1191+ const bool doDeeperSearch = value > (bestValue + 53 + 2 * newDepth); // (~1 Elo)
11921192 const bool doShallowerSearch = value < bestValue + newDepth; // (~2 Elo)
11931193
11941194 newDepth += doDeeperSearch - doShallowerSearch;
@@ -1303,7 +1303,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
13031303 else
13041304 {
13051305 // Reduce other moves if we have found at least one score improvement (~2 Elo)
1306- if (depth > 2 && depth < 12 && beta < 13828 && value > -11369 )
1306+ if (depth > 2 && depth < 12 && beta < 13782 && value > -11541 )
13071307 depth -= 2 ;
13081308
13091309 assert (depth > 0 );
@@ -1342,7 +1342,7 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo
13421342 // Bonus for prior countermove that caused the fail low
13431343 else if (!priorCapture && prevSq != SQ_NONE)
13441344 {
1345- int bonus = (depth > 6 ) + (PvNode || cutNode) + (bestValue < alpha - 657 )
1345+ int bonus = (depth > 6 ) + (PvNode || cutNode) + (bestValue < alpha - 656 )
13461346 + ((ss - 1 )->moveCount > 10 );
13471347 update_continuation_histories (ss - 1 , pos.piece_on (prevSq), prevSq,
13481348 stat_bonus (depth) * bonus);
@@ -1475,7 +1475,7 @@ Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
14751475 if (bestValue > alpha)
14761476 alpha = bestValue;
14771477
1478- futilityBase = ss->staticEval + 200 ;
1478+ futilityBase = ss->staticEval + 182 ;
14791479 }
14801480
14811481 const PieceToHistory* contHist[] = {(ss - 1 )->continuationHistory ,
@@ -1555,7 +1555,7 @@ Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
15551555 continue ;
15561556
15571557 // Do not search moves with bad enough SEE values (~5 Elo)
1558- if (!pos.see_ge (move, Value (-90 )))
1558+ if (!pos.see_ge (move, Value (-77 )))
15591559 continue ;
15601560 }
15611561
@@ -1691,7 +1691,7 @@ void update_all_stats(const Position& pos,
16911691
16921692 if (!pos.capture_stage (bestMove))
16931693 {
1694- int bestMoveBonus = bestValue > beta + 168 ? quietMoveBonus // larger bonus
1694+ int bestMoveBonus = bestValue > beta + 173 ? quietMoveBonus // larger bonus
16951695 : stat_bonus (depth); // smaller bonus
16961696
16971697 // Increase stats for the best move in case it was a quiet move
0 commit comments