@@ -75,6 +75,12 @@ namespace {
7575 return Reductions[PvNode][i][std::min (d / ONE_PLY, 63 )][std::min (mn, 63 )] * ONE_PLY;
7676 }
7777
78+ // History and stats update bonus, based on depth
79+ Value stat_bonus (Depth depth) {
80+ int d = depth / ONE_PLY ;
81+ return Value (d * d + 2 * d - 2 );
82+ }
83+
7884 // Skill structure is used to implement strength limit
7985 struct Skill {
8086 Skill (int l) : level(l) {}
@@ -155,9 +161,6 @@ namespace {
155161
156162 const size_t HalfDensitySize = std::extent<decltype (HalfDensity)>::value;
157163
158- Value bonus (Depth depth) { int d = depth / ONE_PLY ; return Value (d * d + 2 * d - 2 ); }
159- Value penalty (Depth depth) { int d = depth / ONE_PLY ; return -Value (d * d + 4 * d + 1 ); }
160-
161164 EasyMoveManager EasyMove;
162165 Value DrawValue[COLOR_NB];
163166
@@ -642,14 +645,24 @@ namespace {
642645 : (tte->bound () & BOUND_UPPER)))
643646 {
644647 // If ttMove is quiet, update move sorting heuristics on TT hit
645- if (ttValue >= beta && ttMove)
648+ if (ttMove)
646649 {
647- if (!pos.capture_or_promotion (ttMove))
648- update_stats (pos, ss, ttMove, nullptr , 0 , bonus (depth));
650+ if (ttValue >= beta)
651+ {
652+ if (!pos.capture_or_promotion (ttMove))
653+ update_stats (pos, ss, ttMove, nullptr , 0 , stat_bonus (depth));
649654
650- // Extra penalty for a quiet TT move in previous ply when it gets refuted
651- if ((ss-1 )->moveCount == 1 && !pos.captured_piece ())
652- update_cm_stats (ss-1 , pos.piece_on (prevSq), prevSq, penalty (depth));
655+ // Extra penalty for a quiet TT move in previous ply when it gets refuted
656+ if ((ss-1 )->moveCount == 1 && !pos.captured_piece ())
657+ update_cm_stats (ss-1 , pos.piece_on (prevSq), prevSq, -stat_bonus (depth + ONE_PLY));
658+ }
659+ // Penalty for a quiet ttMove that fails low
660+ else if (ttValue < alpha && !pos.capture_or_promotion (ttMove))
661+ {
662+ Value penalty = -stat_bonus (depth + ONE_PLY);
663+ thisThread->history .update (pos.side_to_move (), ttMove, penalty);
664+ update_cm_stats (ss, pos.moved_piece (ttMove), to_sq (ttMove), penalty);
665+ }
653666 }
654667 return ttValue;
655668 }
@@ -988,7 +1001,7 @@ namespace {
9881001 + (fmh ? (*fmh )[moved_piece][to_sq (move)] : VALUE_ZERO)
9891002 + (fmh2 ? (*fmh2)[moved_piece][to_sq (move)] : VALUE_ZERO)
9901003 + thisThread->history .get (~pos.side_to_move (), move)
991- - 8000 ; // Correction factor
1004+ - 4000 ; // Correction factor
9921005
9931006 // Decrease/increase reduction by comparing opponent's stat score
9941007 if (ss->history > VALUE_ZERO && (ss-1 )->history < VALUE_ZERO)
@@ -1120,17 +1133,17 @@ namespace {
11201133
11211134 // Quiet best move: update move sorting heuristics
11221135 if (!pos.capture_or_promotion (bestMove))
1123- update_stats (pos, ss, bestMove, quietsSearched, quietCount, bonus (depth));
1136+ update_stats (pos, ss, bestMove, quietsSearched, quietCount, stat_bonus (depth));
11241137
11251138 // Extra penalty for a quiet TT move in previous ply when it gets refuted
11261139 if ((ss-1 )->moveCount == 1 && !pos.captured_piece ())
1127- update_cm_stats (ss-1 , pos.piece_on (prevSq), prevSq, penalty (depth));
1140+ update_cm_stats (ss-1 , pos.piece_on (prevSq), prevSq, - stat_bonus (depth + ONE_PLY ));
11281141 }
11291142 // Bonus for prior countermove that caused the fail low
11301143 else if ( depth >= 3 * ONE_PLY
11311144 && !pos.captured_piece ()
11321145 && is_ok ((ss-1 )->currentMove ))
1133- update_cm_stats (ss-1 , pos.piece_on (prevSq), prevSq, bonus (depth));
1146+ update_cm_stats (ss-1 , pos.piece_on (prevSq), prevSq, stat_bonus (depth));
11341147
11351148 tte->save (posKey, value_to_tt (bestValue, ss->ply ),
11361149 bestValue >= beta ? BOUND_LOWER :
0 commit comments