Skip to content

Commit 88f17a8

Browse files
BM123499vondele
authored andcommitted
Update Elo estimates for terms in search
This updates estimates from 2yr ago #2401, and adds missing terms. All tests run at 10+0.1 (STC), 20000 games, error bars +- 1.8 Elo, book 8moves_v3.png. A table of Elo values with the links to the corresponding tests can be found at the PR closes #3868 Non-functional Change
1 parent 22e92d2 commit 88f17a8

File tree

2 files changed

+29
-29
lines changed

2 files changed

+29
-29
lines changed

src/evaluate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ Value Eval::evaluate(const Position& pos) {
10831083

10841084
Value v;
10851085

1086-
// Deciding between classical and NNUE eval: for high PSQ imbalance we use classical,
1086+
// Deciding between classical and NNUE eval (~10 Elo): for high PSQ imbalance we use classical,
10871087
// but we switch to NNUE during long shuffling or with high material on the board.
10881088

10891089
if ( !useNNUE

src/search.cpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -671,20 +671,20 @@ namespace {
671671
&& (ttValue >= beta ? (tte->bound() & BOUND_LOWER)
672672
: (tte->bound() & BOUND_UPPER)))
673673
{
674-
// If ttMove is quiet, update move sorting heuristics on TT hit
674+
// If ttMove is quiet, update move sorting heuristics on TT hit (~1 Elo)
675675
if (ttMove)
676676
{
677677
if (ttValue >= beta)
678678
{
679-
// Bonus for a quiet ttMove that fails high
679+
// Bonus for a quiet ttMove that fails high (~3 Elo)
680680
if (!ttCapture)
681681
update_quiet_stats(pos, ss, ttMove, stat_bonus(depth));
682682

683-
// Extra penalty for early quiet moves of the previous ply
683+
// Extra penalty for early quiet moves of the previous ply (~0 Elo)
684684
if ((ss-1)->moveCount <= 2 && !priorCapture)
685685
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + 1));
686686
}
687-
// Penalty for a quiet ttMove that fails low
687+
// Penalty for a quiet ttMove that fails low (~1 Elo)
688688
else if (!ttCapture)
689689
{
690690
int penalty = -stat_bonus(depth);
@@ -773,7 +773,7 @@ namespace {
773773
if (eval == VALUE_DRAW)
774774
eval = value_draw(thisThread);
775775

776-
// Can ttValue be used as a better position evaluation?
776+
// ttValue can be used as a better position evaluation (~4 Elo)
777777
if ( ttValue != VALUE_NONE
778778
&& (tte->bound() & (ttValue > eval ? BOUND_LOWER : BOUND_UPPER)))
779779
eval = ttValue;
@@ -787,7 +787,7 @@ namespace {
787787
tte->save(posKey, VALUE_NONE, ss->ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, eval);
788788
}
789789

790-
// Use static evaluation difference to improve quiet move ordering
790+
// Use static evaluation difference to improve quiet move ordering (~3 Elo)
791791
if (is_ok((ss-1)->currentMove) && !(ss-1)->inCheck && !priorCapture)
792792
{
793793
int bonus = std::clamp(-16 * int((ss-1)->staticEval + ss->staticEval), -2000, 2000);
@@ -804,15 +804,15 @@ namespace {
804804

805805
improving = improvement > 0;
806806

807-
// Step 7. Futility pruning: child node (~50 Elo).
807+
// Step 7. Futility pruning: child node (~25 Elo).
808808
// The depth condition is important for mate finding.
809809
if ( !ss->ttPv
810810
&& depth < 9
811811
&& eval - futility_margin(depth, improving) >= beta
812812
&& eval < 15000) // 50% larger than VALUE_KNOWN_WIN, but smaller than TB wins.
813813
return eval;
814814

815-
// Step 8. Null move search with verification search (~40 Elo)
815+
// Step 8. Null move search with verification search (~22 Elo)
816816
if ( !PvNode
817817
&& (ss-1)->currentMove != MOVE_NULL
818818
&& (ss-1)->statScore < 23767
@@ -925,7 +925,7 @@ namespace {
925925
ss->ttPv = ttPv;
926926
}
927927

928-
// Step 10. If the position is not in TT, decrease depth by 2 or 1 depending on node type
928+
// Step 10. If the position is not in TT, decrease depth by 2 or 1 depending on node type (~3 Elo)
929929
if ( PvNode
930930
&& depth >= 6
931931
&& !ttMove)
@@ -940,7 +940,7 @@ namespace {
940940

941941
int rangeReduction = 0;
942942

943-
// Step 11. A small Probcut idea, when we are in check
943+
// Step 11. A small Probcut idea, when we are in check (~0 Elo)
944944
probCutBeta = beta + 409;
945945
if ( ss->inCheck
946946
&& !PvNode
@@ -1017,12 +1017,12 @@ namespace {
10171017

10181018
Value delta = beta - alpha;
10191019

1020-
// Step 13. Pruning at shallow depth (~200 Elo). Depth conditions are important for mate finding.
1020+
// Step 13. Pruning at shallow depth (~98 Elo). Depth conditions are important for mate finding.
10211021
if ( !rootNode
10221022
&& pos.non_pawn_material(us)
10231023
&& bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
10241024
{
1025-
// Skip quiet moves if movecount exceeds our FutilityMoveCount threshold
1025+
// Skip quiet moves if movecount exceeds our FutilityMoveCount threshold (~7 Elo)
10261026
moveCountPruning = moveCount >= futility_move_count(improving, depth);
10271027

10281028
// Reduced depth of the next LMR search
@@ -1031,18 +1031,18 @@ namespace {
10311031
if ( captureOrPromotion
10321032
|| givesCheck)
10331033
{
1034-
// Futility pruning for captures
1034+
// Futility pruning for captures (~0 Elo)
10351035
if ( !pos.empty(to_sq(move))
10361036
&& !givesCheck
10371037
&& !PvNode
10381038
&& lmrDepth < 6
10391039
&& !ss->inCheck
1040-
&& ss->staticEval + 342 + 238 * lmrDepth + PieceValue[EG][pos.piece_on(to_sq(move))]
1040+
&& ss->staticEval + 342 + 238 * lmrDepth + PieceValue[EG][pos.piece_on(to_sq(move))]
10411041
+ captureHistory[movedPiece][to_sq(move)][type_of(pos.piece_on(to_sq(move)))] / 8 < alpha)
10421042
continue;
10431043

1044-
// SEE based pruning
1045-
if (!pos.see_ge(move, Value(-218) * depth)) // (~25 Elo)
1044+
// SEE based pruning (~9 Elo)
1045+
if (!pos.see_ge(move, Value(-218) * depth))
10461046
continue;
10471047
}
10481048
else
@@ -1051,28 +1051,28 @@ namespace {
10511051
+ (*contHist[1])[movedPiece][to_sq(move)]
10521052
+ (*contHist[3])[movedPiece][to_sq(move)];
10531053

1054-
// Continuation history based pruning (~20 Elo)
1054+
// Continuation history based pruning (~2 Elo)
10551055
if ( lmrDepth < 5
10561056
&& history < -3000 * depth + 3000)
10571057
continue;
10581058

10591059
history += thisThread->mainHistory[us][from_to(move)];
10601060

1061-
// Futility pruning: parent node (~5 Elo)
1061+
// Futility pruning: parent node (~9 Elo)
10621062
if ( !ss->inCheck
10631063
&& lmrDepth < 8
10641064
&& ss->staticEval + 142 + 139 * lmrDepth + history / 64 <= alpha)
10651065
continue;
10661066

1067-
// Prune moves with negative SEE (~20 Elo)
1067+
// Prune moves with negative SEE (~3 Elo)
10681068
if (!pos.see_ge(move, Value(-21 * lmrDepth * lmrDepth - 21 * lmrDepth)))
10691069
continue;
10701070
}
10711071
}
10721072

1073-
// Step 14. Extensions (~75 Elo)
1073+
// Step 14. Extensions (~66 Elo)
10741074

1075-
// Singular extension search (~70 Elo). If all moves but one fail low on a
1075+
// Singular extension search (~58 Elo). If all moves but one fail low on a
10761076
// search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
10771077
// then that move is singular and should be extended. To verify this we do
10781078
// a reduced search on all the other moves but the ttMove and if the
@@ -1117,13 +1117,13 @@ namespace {
11171117
extension = -2;
11181118
}
11191119

1120-
// Check extensions
1120+
// Check extensions (~1 Elo)
11211121
else if ( givesCheck
11221122
&& depth > 6
11231123
&& abs(ss->staticEval) > 100)
11241124
extension = 1;
11251125

1126-
// Quiet ttMove extensions
1126+
// Quiet ttMove extensions (~0 Elo)
11271127
else if ( PvNode
11281128
&& move == ttMove
11291129
&& move == ss->killers[0]
@@ -1149,7 +1149,7 @@ namespace {
11491149

11501150
bool doDeeperSearch = false;
11511151

1152-
// Step 16. Late moves reduction / extension (LMR, ~200 Elo)
1152+
// Step 16. Late moves reduction / extension (LMR, ~98 Elo)
11531153
// We use various heuristics for the sons of a node after the first son has
11541154
// been searched. In general we would like to reduce them, but there are many
11551155
// cases where we extend a son if it has good chances to be "interesting".
@@ -1467,7 +1467,7 @@ namespace {
14671467
if ((ss->staticEval = bestValue = tte->eval()) == VALUE_NONE)
14681468
ss->staticEval = bestValue = evaluate(pos);
14691469

1470-
// Can ttValue be used as a better position evaluation?
1470+
// ttValue can be used as a better position evaluation (~7 Elo)
14711471
if ( ttValue != VALUE_NONE
14721472
&& (tte->bound() & (ttValue > bestValue ? BOUND_LOWER : BOUND_UPPER)))
14731473
bestValue = ttValue;
@@ -1522,7 +1522,7 @@ namespace {
15221522

15231523
moveCount++;
15241524

1525-
// Futility pruning and moveCount pruning
1525+
// Futility pruning and moveCount pruning (~5 Elo)
15261526
if ( bestValue > VALUE_TB_LOSS_IN_MAX_PLY
15271527
&& !givesCheck
15281528
&& futilityBase > -VALUE_KNOWN_WIN
@@ -1547,7 +1547,7 @@ namespace {
15471547
}
15481548
}
15491549

1550-
// Do not search moves with negative SEE values
1550+
// Do not search moves with negative SEE values (~5 Elo)
15511551
if ( bestValue > VALUE_TB_LOSS_IN_MAX_PLY
15521552
&& !pos.see_ge(move))
15531553
continue;
@@ -1561,7 +1561,7 @@ namespace {
15611561
[pos.moved_piece(move)]
15621562
[to_sq(move)];
15631563

1564-
// Continuation history based pruning
1564+
// Continuation history based pruning (~2 Elo)
15651565
if ( !captureOrPromotion
15661566
&& bestValue > VALUE_TB_LOSS_IN_MAX_PLY
15671567
&& (*contHist[0])[pos.moved_piece(move)][to_sq(move)] < CounterMovePruneThreshold

0 commit comments

Comments
 (0)