mirror of
https://github.com/opelly27/Stockfish.git
synced 2026-05-20 02:47:45 +00:00
Adjust LMR with correction history
A positive constant increase in base reduction is applied to counter the decrease in average reduction from this tweak. Passed STC: LLR: 2.98 (-2.94,2.94) <0.00,2.00> Total: 109216 W: 28415 L: 27989 D: 52812 Ptnml(0-2): 310, 12848, 27911, 13184, 355 https://tests.stockfishchess.org/tests/view/6760bb0e86d5ee47d9542f26 Passed LTC: LLR: 2.95 (-2.94,2.94) <0.50,2.50> Total: 66918 W: 17073 L: 16694 D: 33151 Ptnml(0-2): 33, 7175, 18666, 7550, 35 https://tests.stockfishchess.org/tests/view/6761e10f86d5ee47d95431fa closes https://github.com/official-stockfish/Stockfish/pull/5727 Bench: 1294909
This commit is contained in:
+20
-16
@@ -77,9 +77,7 @@ constexpr int futility_move_count(bool improving, Depth depth) {
|
|||||||
return (3 + depth * depth) / (2 - improving);
|
return (3 + depth * depth) / (2 - improving);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add correctionHistory value to raw staticEval and guarantee evaluation
|
int correction_value(const Worker& w, const Position& pos, Stack* ss) {
|
||||||
// does not hit the tablebase range.
|
|
||||||
Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos, Stack* ss) {
|
|
||||||
const Color us = pos.side_to_move();
|
const Color us = pos.side_to_move();
|
||||||
const auto m = (ss - 1)->currentMove;
|
const auto m = (ss - 1)->currentMove;
|
||||||
const auto pcv = w.pawnCorrectionHistory[us][pawn_structure_index<Correction>(pos)];
|
const auto pcv = w.pawnCorrectionHistory[us][pawn_structure_index<Correction>(pos)];
|
||||||
@@ -87,15 +85,17 @@ Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos, St
|
|||||||
const auto micv = w.minorPieceCorrectionHistory[us][minor_piece_index(pos)];
|
const auto micv = w.minorPieceCorrectionHistory[us][minor_piece_index(pos)];
|
||||||
const auto wnpcv = w.nonPawnCorrectionHistory[WHITE][us][non_pawn_index<WHITE>(pos)];
|
const auto wnpcv = w.nonPawnCorrectionHistory[WHITE][us][non_pawn_index<WHITE>(pos)];
|
||||||
const auto bnpcv = w.nonPawnCorrectionHistory[BLACK][us][non_pawn_index<BLACK>(pos)];
|
const auto bnpcv = w.nonPawnCorrectionHistory[BLACK][us][non_pawn_index<BLACK>(pos)];
|
||||||
int cntcv = 1;
|
const auto cntcv =
|
||||||
|
m.is_ok() ? (*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()]
|
||||||
|
: 0;
|
||||||
|
|
||||||
if (m.is_ok())
|
return (6384 * pcv + 3583 * macv + 6492 * micv + 6725 * (wnpcv + bnpcv) + 5880 * cntcv);
|
||||||
cntcv = int((*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()]);
|
}
|
||||||
|
|
||||||
const auto cv =
|
// Add correctionHistory value to raw staticEval and guarantee evaluation
|
||||||
(6384 * pcv + 3583 * macv + 6492 * micv + 6725 * (wnpcv + bnpcv) + cntcv * 5880) / 131072;
|
// does not hit the tablebase range.
|
||||||
v += cv;
|
Value to_corrected_static_eval(Value v, const int cv) {
|
||||||
return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
return std::clamp(v + cv / 131072, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// History and stats update bonus, based on depth
|
// History and stats update bonus, based on depth
|
||||||
@@ -710,6 +710,7 @@ Value Search::Worker::search(
|
|||||||
|
|
||||||
// Step 6. Static evaluation of the position
|
// Step 6. Static evaluation of the position
|
||||||
Value unadjustedStaticEval = VALUE_NONE;
|
Value unadjustedStaticEval = VALUE_NONE;
|
||||||
|
const auto correctionValue = correction_value(*thisThread, pos, ss);
|
||||||
if (ss->inCheck)
|
if (ss->inCheck)
|
||||||
{
|
{
|
||||||
// Skip early pruning when in check
|
// Skip early pruning when in check
|
||||||
@@ -733,8 +734,7 @@ Value Search::Worker::search(
|
|||||||
else if (PvNode)
|
else if (PvNode)
|
||||||
Eval::NNUE::hint_common_parent_position(pos, networks[numaAccessToken], refreshTable);
|
Eval::NNUE::hint_common_parent_position(pos, networks[numaAccessToken], refreshTable);
|
||||||
|
|
||||||
ss->staticEval = eval =
|
ss->staticEval = eval = to_corrected_static_eval(unadjustedStaticEval, correctionValue);
|
||||||
to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss);
|
|
||||||
|
|
||||||
// ttValue can be used as a better position evaluation (~7 Elo)
|
// ttValue can be used as a better position evaluation (~7 Elo)
|
||||||
if (is_valid(ttData.value)
|
if (is_valid(ttData.value)
|
||||||
@@ -744,8 +744,7 @@ Value Search::Worker::search(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
unadjustedStaticEval = evaluate(pos);
|
unadjustedStaticEval = evaluate(pos);
|
||||||
ss->staticEval = eval =
|
ss->staticEval = eval = to_corrected_static_eval(unadjustedStaticEval, correctionValue);
|
||||||
to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss);
|
|
||||||
|
|
||||||
// Static evaluation is saved as it was before adjustment by correction history
|
// Static evaluation is saved as it was before adjustment by correction history
|
||||||
ttWriter.write(posKey, VALUE_NONE, ss->ttPv, BOUND_NONE, DEPTH_UNSEARCHED, Move::none(),
|
ttWriter.write(posKey, VALUE_NONE, ss->ttPv, BOUND_NONE, DEPTH_UNSEARCHED, Move::none(),
|
||||||
@@ -1155,6 +1154,10 @@ moves_loop: // When in check, search starts here
|
|||||||
|
|
||||||
// These reduction adjustments have no proven non-linear scaling
|
// These reduction adjustments have no proven non-linear scaling
|
||||||
|
|
||||||
|
r += 330;
|
||||||
|
|
||||||
|
r -= std::min(std::abs(correctionValue) / 32768, 2048);
|
||||||
|
|
||||||
// Increase reduction for cut nodes (~4 Elo)
|
// Increase reduction for cut nodes (~4 Elo)
|
||||||
if (cutNode)
|
if (cutNode)
|
||||||
r += 2518 - (ttData.depth >= depth && ss->ttPv) * 991;
|
r += 2518 - (ttData.depth >= depth && ss->ttPv) * 991;
|
||||||
@@ -1526,6 +1529,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)
|
|||||||
|
|
||||||
// Step 4. Static evaluation of the position
|
// Step 4. Static evaluation of the position
|
||||||
Value unadjustedStaticEval = VALUE_NONE;
|
Value unadjustedStaticEval = VALUE_NONE;
|
||||||
|
const auto correctionValue = correction_value(*thisThread, pos, ss);
|
||||||
if (ss->inCheck)
|
if (ss->inCheck)
|
||||||
bestValue = futilityBase = -VALUE_INFINITE;
|
bestValue = futilityBase = -VALUE_INFINITE;
|
||||||
else
|
else
|
||||||
@@ -1537,7 +1541,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)
|
|||||||
if (!is_valid(unadjustedStaticEval))
|
if (!is_valid(unadjustedStaticEval))
|
||||||
unadjustedStaticEval = evaluate(pos);
|
unadjustedStaticEval = evaluate(pos);
|
||||||
ss->staticEval = bestValue =
|
ss->staticEval = bestValue =
|
||||||
to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss);
|
to_corrected_static_eval(unadjustedStaticEval, correctionValue);
|
||||||
|
|
||||||
// ttValue can be used as a better position evaluation (~13 Elo)
|
// ttValue can be used as a better position evaluation (~13 Elo)
|
||||||
if (is_valid(ttData.value) && !is_decisive(ttData.value)
|
if (is_valid(ttData.value) && !is_decisive(ttData.value)
|
||||||
@@ -1550,7 +1554,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)
|
|||||||
unadjustedStaticEval =
|
unadjustedStaticEval =
|
||||||
(ss - 1)->currentMove != Move::null() ? evaluate(pos) : -(ss - 1)->staticEval;
|
(ss - 1)->currentMove != Move::null() ? evaluate(pos) : -(ss - 1)->staticEval;
|
||||||
ss->staticEval = bestValue =
|
ss->staticEval = bestValue =
|
||||||
to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss);
|
to_corrected_static_eval(unadjustedStaticEval, correctionValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stand pat. Return immediately if static value is at least beta
|
// Stand pat. Return immediately if static value is at least beta
|
||||||
|
|||||||
Reference in New Issue
Block a user