mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
Search parameters tune at 180+1.8
Passed VLTC: https://tests.stockfishchess.org/tests/view/65200c58ac577114367280bc LLR: 2.95 (-2.94,2.94) <0.00,2.00> Total: 146180 W: 37407 L: 36988 D: 71785 Ptnml(0-2): 21, 14474, 43675, 14905, 15 Passed VLTC SMP: https://tests.stockfishchess.org/tests/view/652403da3125598fc7eb4b6d LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 57580 W: 15061 L: 14739 D: 27780 Ptnml(0-2): 2, 5001, 18460, 5327, 0 closes https://github.com/official-stockfish/Stockfish/pull/4826 Bench: 1099336
This commit is contained in:
parent
7a4de96159
commit
002636362e
1 changed files with 39 additions and 39 deletions
|
@ -73,7 +73,7 @@ namespace {
|
|||
|
||||
// Futility margin
|
||||
Value futility_margin(Depth d, bool noTtCutNode, bool improving) {
|
||||
return Value((140 - 40 * noTtCutNode) * (d - improving));
|
||||
return Value((126 - 42 * noTtCutNode) * (d - improving));
|
||||
}
|
||||
|
||||
// Reductions lookup table initialized at startup
|
||||
|
@ -81,8 +81,8 @@ namespace {
|
|||
|
||||
Depth reduction(bool i, Depth d, int mn, Value delta, Value rootDelta) {
|
||||
int reductionScale = Reductions[d] * Reductions[mn];
|
||||
return (reductionScale + 1372 - int(delta) * 1073 / int(rootDelta)) / 1024
|
||||
+ (!i && reductionScale > 936);
|
||||
return (reductionScale + 1560 - int(delta) * 945 / int(rootDelta)) / 1024
|
||||
+ (!i && reductionScale > 791);
|
||||
}
|
||||
|
||||
constexpr int futility_move_count(bool improving, Depth depth) {
|
||||
|
@ -92,7 +92,7 @@ namespace {
|
|||
|
||||
// History and stats update bonus, based on depth
|
||||
int stat_bonus(Depth d) {
|
||||
return std::min(336 * d - 547, 1561);
|
||||
return std::min(334 * d - 531, 1538);
|
||||
}
|
||||
|
||||
// Add a small random component to draw evaluations to avoid 3-fold blindness
|
||||
|
@ -174,7 +174,7 @@ namespace {
|
|||
void Search::init() {
|
||||
|
||||
for (int i = 1; i < MAX_MOVES; ++i)
|
||||
Reductions[i] = int((20.57 + std::log(Threads.size()) / 2) * std::log(i));
|
||||
Reductions[i] = int((20.37 + std::log(Threads.size()) / 2) * std::log(i));
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,12 +359,12 @@ void Thread::search() {
|
|||
|
||||
// Reset aspiration window starting size
|
||||
Value prev = rootMoves[pvIdx].averageScore;
|
||||
delta = Value(10) + int(prev) * prev / 15799;
|
||||
delta = Value(10) + int(prev) * prev / 17470;
|
||||
alpha = std::max(prev - delta,-VALUE_INFINITE);
|
||||
beta = std::min(prev + delta, VALUE_INFINITE);
|
||||
|
||||
// Adjust optimism based on root move's previousScore (~4 Elo)
|
||||
int opt = 109 * prev / (std::abs(prev) + 141);
|
||||
int opt = 113 * prev / (std::abs(prev) + 109);
|
||||
optimism[ us] = Value(opt);
|
||||
optimism[~us] = -optimism[us];
|
||||
|
||||
|
@ -750,7 +750,7 @@ namespace {
|
|||
// Use static evaluation difference to improve quiet move ordering (~4 Elo)
|
||||
if (is_ok((ss-1)->currentMove) && !(ss-1)->inCheck && !priorCapture)
|
||||
{
|
||||
int bonus = std::clamp(-18 * int((ss-1)->staticEval + ss->staticEval), -1817, 1817);
|
||||
int bonus = std::clamp(-18 * int((ss-1)->staticEval + ss->staticEval), -1812, 1812);
|
||||
thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << bonus;
|
||||
}
|
||||
|
||||
|
@ -767,7 +767,7 @@ namespace {
|
|||
// If eval is really low check with qsearch if it can exceed alpha, if it can't,
|
||||
// return a fail low.
|
||||
// Adjust razor margin according to cutoffCnt. (~1 Elo)
|
||||
if (eval < alpha - 456 - (252 - 200 * ((ss+1)->cutoffCnt > 3)) * depth * depth)
|
||||
if (eval < alpha - 492 - (257 - 200 * ((ss+1)->cutoffCnt > 3)) * depth * depth)
|
||||
{
|
||||
value = qsearch<NonPV>(pos, ss, alpha - 1, alpha);
|
||||
if (value < alpha)
|
||||
|
@ -778,9 +778,9 @@ namespace {
|
|||
// The depth condition is important for mate finding.
|
||||
if ( !ss->ttPv
|
||||
&& depth < 9
|
||||
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving) - (ss-1)->statScore / 306 >= beta
|
||||
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving) - (ss-1)->statScore / 321 >= beta
|
||||
&& eval >= beta
|
||||
&& eval < 24923 // smaller than TB wins
|
||||
&& eval < 29462 // smaller than TB wins
|
||||
&& !( !ttCapture
|
||||
&& ttMove
|
||||
&& thisThread->mainHistory[us][from_to(ttMove)] < 989))
|
||||
|
@ -789,10 +789,10 @@ namespace {
|
|||
// Step 9. Null move search with verification search (~35 Elo)
|
||||
if ( !PvNode
|
||||
&& (ss-1)->currentMove != MOVE_NULL
|
||||
&& (ss-1)->statScore < 17329
|
||||
&& (ss-1)->statScore < 17257
|
||||
&& eval >= beta
|
||||
&& eval >= ss->staticEval
|
||||
&& ss->staticEval >= beta - 21 * depth + 258
|
||||
&& ss->staticEval >= beta - 24 * depth + 281
|
||||
&& !excludedMove
|
||||
&& pos.non_pawn_material(us)
|
||||
&& ss->ply >= thisThread->nmpMinPly
|
||||
|
@ -801,7 +801,7 @@ namespace {
|
|||
assert(eval - beta >= 0);
|
||||
|
||||
// Null move dynamic reduction based on depth and eval
|
||||
Depth R = std::min(int(eval - beta) / 173, 6) + depth / 3 + 4;
|
||||
Depth R = std::min(int(eval - beta) / 152, 6) + depth / 3 + 4;
|
||||
|
||||
ss->currentMove = MOVE_NULL;
|
||||
ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0];
|
||||
|
@ -850,7 +850,7 @@ namespace {
|
|||
&& !ttMove)
|
||||
depth -= 2;
|
||||
|
||||
probCutBeta = beta + 168 - 61 * improving;
|
||||
probCutBeta = beta + 168 - 70 * improving;
|
||||
|
||||
// Step 11. ProbCut (~10 Elo)
|
||||
// If we have a good enough capture (or queen promotion) and a reduced search returns a value
|
||||
|
@ -906,7 +906,7 @@ namespace {
|
|||
moves_loop: // When in check, search starts here
|
||||
|
||||
// Step 12. A small Probcut idea, when we are in check (~4 Elo)
|
||||
probCutBeta = beta + 413;
|
||||
probCutBeta = beta + 416;
|
||||
if ( ss->inCheck
|
||||
&& !PvNode
|
||||
&& ttCapture
|
||||
|
@ -1000,12 +1000,12 @@ moves_loop: // When in check, search starts here
|
|||
if ( !givesCheck
|
||||
&& lmrDepth < 7
|
||||
&& !ss->inCheck
|
||||
&& ss->staticEval + 197 + 248 * lmrDepth + PieceValue[pos.piece_on(to_sq(move))]
|
||||
&& ss->staticEval + 188 + 206 * lmrDepth + PieceValue[pos.piece_on(to_sq(move))]
|
||||
+ captureHistory[movedPiece][to_sq(move)][type_of(pos.piece_on(to_sq(move)))] / 7 < alpha)
|
||||
continue;
|
||||
|
||||
// SEE based pruning for captures and checks (~11 Elo)
|
||||
if (!pos.see_ge(move, Value(-205) * depth))
|
||||
if (!pos.see_ge(move, Value(-185) * depth))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -1016,24 +1016,24 @@ moves_loop: // When in check, search starts here
|
|||
|
||||
// Continuation history based pruning (~2 Elo)
|
||||
if ( lmrDepth < 6
|
||||
&& history < -3832 * depth)
|
||||
&& history < -3232 * depth)
|
||||
continue;
|
||||
|
||||
history += 2 * thisThread->mainHistory[us][from_to(move)];
|
||||
|
||||
lmrDepth += history / 7011;
|
||||
lmrDepth += history / 5793;
|
||||
lmrDepth = std::max(lmrDepth, -2);
|
||||
|
||||
// Futility pruning: parent node (~13 Elo)
|
||||
if ( !ss->inCheck
|
||||
&& lmrDepth < 12
|
||||
&& ss->staticEval + 112 + 138 * lmrDepth <= alpha)
|
||||
&& lmrDepth < 13
|
||||
&& ss->staticEval + 115 + 122 * lmrDepth <= alpha)
|
||||
continue;
|
||||
|
||||
lmrDepth = std::max(lmrDepth, 0);
|
||||
|
||||
// Prune moves with negative SEE (~4 Elo)
|
||||
if (!pos.see_ge(move, Value(-31 * lmrDepth * lmrDepth)))
|
||||
if (!pos.see_ge(move, Value(-27 * lmrDepth * lmrDepth)))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1051,7 +1051,7 @@ moves_loop: // When in check, search starts here
|
|||
// scaling. Their values are optimized to time controls of 180+1.8 and longer
|
||||
// so changing them requires tests at this type of time controls.
|
||||
if ( !rootNode
|
||||
&& depth >= 4 - (thisThread->completedDepth > 22) + 2 * (PvNode && tte->is_pv())
|
||||
&& depth >= 4 - (thisThread->completedDepth > 24) + 2 * (PvNode && tte->is_pv())
|
||||
&& move == ttMove
|
||||
&& !excludedMove // Avoid recursive singular search
|
||||
/* && ttValue != VALUE_NONE Already implicit in the next condition */
|
||||
|
@ -1059,7 +1059,7 @@ moves_loop: // When in check, search starts here
|
|||
&& (tte->bound() & BOUND_LOWER)
|
||||
&& tte->depth() >= depth - 3)
|
||||
{
|
||||
Value singularBeta = ttValue - (82 + 65 * (ss->ttPv && !PvNode)) * depth / 64;
|
||||
Value singularBeta = ttValue - (64 + 57 * (ss->ttPv && !PvNode)) * depth / 64;
|
||||
Depth singularDepth = (depth - 1) / 2;
|
||||
|
||||
ss->excludedMove = move;
|
||||
|
@ -1073,11 +1073,11 @@ moves_loop: // When in check, search starts here
|
|||
|
||||
// Avoid search explosion by limiting the number of double extensions
|
||||
if ( !PvNode
|
||||
&& value < singularBeta - 21
|
||||
&& value < singularBeta - 18
|
||||
&& ss->doubleExtensions <= 11)
|
||||
{
|
||||
extension = 2;
|
||||
depth += depth < 13;
|
||||
depth += depth < 15;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1095,7 +1095,7 @@ moves_loop: // When in check, search starts here
|
|||
|
||||
// If we are on a cutNode, reduce it based on depth (negative extension) (~1 Elo)
|
||||
else if (cutNode)
|
||||
extension = depth < 17 ? -3 : -1;
|
||||
extension = depth < 19 ? -2 : -1;
|
||||
|
||||
// If the eval of ttMove is less than value, we reduce it (negative extension) (~1 Elo)
|
||||
else if (ttValue <= value)
|
||||
|
@ -1111,7 +1111,7 @@ moves_loop: // When in check, search starts here
|
|||
else if ( PvNode
|
||||
&& move == ttMove
|
||||
&& move == ss->killers[0]
|
||||
&& (*contHist[0])[movedPiece][to_sq(move)] >= 5168)
|
||||
&& (*contHist[0])[movedPiece][to_sq(move)] >= 4194)
|
||||
extension = 1;
|
||||
}
|
||||
|
||||
|
@ -1139,7 +1139,7 @@ moves_loop: // When in check, search starts here
|
|||
r -= cutNode && tte->depth() >= depth ? 3 : 2;
|
||||
|
||||
// Decrease reduction if opponent's move count is high (~1 Elo)
|
||||
if ((ss-1)->moveCount > 8)
|
||||
if ((ss-1)->moveCount > 7)
|
||||
r--;
|
||||
|
||||
// Increase reduction for cut nodes (~3 Elo)
|
||||
|
@ -1175,10 +1175,10 @@ moves_loop: // When in check, search starts here
|
|||
+ (*contHist[0])[movedPiece][to_sq(move)]
|
||||
+ (*contHist[1])[movedPiece][to_sq(move)]
|
||||
+ (*contHist[3])[movedPiece][to_sq(move)]
|
||||
- 4006;
|
||||
- 3848;
|
||||
|
||||
// Decrease/increase reduction for moves with a good/bad history (~25 Elo)
|
||||
r -= ss->statScore / (11124 + 4740 * (depth > 5 && depth < 22));
|
||||
r -= ss->statScore / (10216 + 3855 * (depth > 5 && depth < 23));
|
||||
|
||||
// Step 17. Late moves reduction / extension (LMR, ~117 Elo)
|
||||
// We use various heuristics for the sons of a node after the first son has
|
||||
|
@ -1202,8 +1202,8 @@ moves_loop: // When in check, search starts here
|
|||
{
|
||||
// Adjust full-depth search based on LMR results - if the result
|
||||
// was good enough search deeper, if it was bad enough search shallower
|
||||
const bool doDeeperSearch = value > (bestValue + 64 + 11 * (newDepth - d));
|
||||
const bool doEvenDeeperSearch = value > alpha + 711 && ss->doubleExtensions <= 6;
|
||||
const bool doDeeperSearch = value > (bestValue + 51 + 10 * (newDepth - d));
|
||||
const bool doEvenDeeperSearch = value > alpha + 700 && ss->doubleExtensions <= 6;
|
||||
const bool doShallowerSearch = value < bestValue + newDepth;
|
||||
|
||||
ss->doubleExtensions = ss->doubleExtensions + doEvenDeeperSearch;
|
||||
|
@ -1321,8 +1321,8 @@ moves_loop: // When in check, search starts here
|
|||
// Reduce other moves if we have found at least one score improvement (~2 Elo)
|
||||
if ( depth > 2
|
||||
&& depth < 12
|
||||
&& beta < 14362
|
||||
&& value > -12393)
|
||||
&& beta < 13828
|
||||
&& value > -11369)
|
||||
depth -= 2;
|
||||
|
||||
assert(depth > 0);
|
||||
|
@ -1371,7 +1371,7 @@ moves_loop: // When in check, search starts here
|
|||
// Bonus for prior countermove that caused the fail low
|
||||
else if (!priorCapture && prevSq != SQ_NONE)
|
||||
{
|
||||
int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 800) + ((ss-1)->moveCount > 12);
|
||||
int bonus = (depth > 6) + (PvNode || cutNode) + (bestValue < alpha - 653) + ((ss-1)->moveCount > 11);
|
||||
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus);
|
||||
thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << stat_bonus(depth) * bonus / 2;
|
||||
}
|
||||
|
@ -1593,7 +1593,7 @@ moves_loop: // When in check, search starts here
|
|||
continue;
|
||||
|
||||
// Do not search moves with bad enough SEE values (~5 Elo)
|
||||
if (!pos.see_ge(move, Value(-95)))
|
||||
if (!pos.see_ge(move, Value(-90)))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1726,7 @@ moves_loop: // When in check, search starts here
|
|||
|
||||
if (!pos.capture_stage(bestMove))
|
||||
{
|
||||
int bestMoveBonus = bestValue > beta + 145 ? quietMoveBonus // larger bonus
|
||||
int bestMoveBonus = bestValue > beta + 168 ? quietMoveBonus // larger bonus
|
||||
: stat_bonus(depth); // smaller bonus
|
||||
|
||||
// Increase stats for the best move in case it was a quiet move
|
||||
|
|
Loading…
Add table
Reference in a new issue