mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 09:13:08 +00:00
Reintroduce razoring
Razoring was simplified away some years ago, this patch reintroduces it in a slightly different form. Now for low depths if eval is far below alpha we check if qsearch can push it above alpha - and if it can't we return a fail low. passed STC https://tests.stockfishchess.org/tests/view/61fbf968d508ec6a1c9f3274 LLR: 2.94 (-2.94,2.94) <0.00,2.50> Total: 226120 W: 61106 L: 60472 D: 104542 Ptnml(0-2): 1118, 25592, 59080, 26078, 1192 passed LTC https://tests.stockfishchess.org/tests/view/61fcc569d508ec6a1c9f5617 LLR: 2.94 (-2.94,2.94) <0.50,3.00> Total: 113128 W: 30851 L: 30397 D: 51880 Ptnml(0-2): 114, 11483, 32926, 11917, 124 closes https://github.com/official-stockfish/Stockfish/pull/3921 bench 4684080
This commit is contained in:
parent
95d7369e54
commit
4d3950c6eb
1 changed files with 24 additions and 14 deletions
|
@ -773,7 +773,17 @@ namespace {
|
||||||
|
|
||||||
thisThread->complexityAverage.update(complexity);
|
thisThread->complexityAverage.update(complexity);
|
||||||
|
|
||||||
// Step 7. Futility pruning: child node (~25 Elo).
|
// Step 7. Razoring.
|
||||||
|
// If eval is really low check with qsearch if it can exceed alpha, if it can't,
|
||||||
|
// return a fail low.
|
||||||
|
if (!PvNode && depth <= 6 && eval < alpha - 400 - 300 * depth * depth)
|
||||||
|
{
|
||||||
|
value = qsearch<NonPV>(pos, ss, alpha - 1, alpha);
|
||||||
|
if (value < alpha)
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8. Futility pruning: child node (~25 Elo).
|
||||||
// The depth condition is important for mate finding.
|
// The depth condition is important for mate finding.
|
||||||
if ( !ss->ttPv
|
if ( !ss->ttPv
|
||||||
&& depth < 9
|
&& depth < 9
|
||||||
|
@ -782,7 +792,7 @@ namespace {
|
||||||
&& eval < 15000) // 50% larger than VALUE_KNOWN_WIN, but smaller than TB wins.
|
&& eval < 15000) // 50% larger than VALUE_KNOWN_WIN, but smaller than TB wins.
|
||||||
return eval;
|
return eval;
|
||||||
|
|
||||||
// Step 8. Null move search with verification search (~22 Elo)
|
// Step 9. Null move search with verification search (~22 Elo)
|
||||||
if ( !PvNode
|
if ( !PvNode
|
||||||
&& (ss-1)->currentMove != MOVE_NULL
|
&& (ss-1)->currentMove != MOVE_NULL
|
||||||
&& (ss-1)->statScore < 23767
|
&& (ss-1)->statScore < 23767
|
||||||
|
@ -834,7 +844,7 @@ namespace {
|
||||||
|
|
||||||
probCutBeta = beta + 209 - 44 * improving;
|
probCutBeta = beta + 209 - 44 * improving;
|
||||||
|
|
||||||
// Step 9. ProbCut (~4 Elo)
|
// Step 10. ProbCut (~4 Elo)
|
||||||
// If we have a good enough capture and a reduced search returns a value
|
// If we have a good enough capture and a reduced search returns a value
|
||||||
// much above beta, we can (almost) safely prune the previous move.
|
// much above beta, we can (almost) safely prune the previous move.
|
||||||
if ( !PvNode
|
if ( !PvNode
|
||||||
|
@ -895,7 +905,7 @@ namespace {
|
||||||
ss->ttPv = ttPv;
|
ss->ttPv = ttPv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10. If the position is not in TT, decrease depth by 2 or 1 depending on node type (~3 Elo)
|
// Step 11. If the position is not in TT, decrease depth by 2 or 1 depending on node type (~3 Elo)
|
||||||
if ( PvNode
|
if ( PvNode
|
||||||
&& depth >= 6
|
&& depth >= 6
|
||||||
&& !ttMove)
|
&& !ttMove)
|
||||||
|
@ -908,7 +918,7 @@ namespace {
|
||||||
|
|
||||||
moves_loop: // When in check, search starts here
|
moves_loop: // When in check, search starts here
|
||||||
|
|
||||||
// Step 11. A small Probcut idea, when we are in check (~0 Elo)
|
// Step 12. A small Probcut idea, when we are in check (~0 Elo)
|
||||||
probCutBeta = beta + 409;
|
probCutBeta = beta + 409;
|
||||||
if ( ss->inCheck
|
if ( ss->inCheck
|
||||||
&& !PvNode
|
&& !PvNode
|
||||||
|
@ -945,7 +955,7 @@ moves_loop: // When in check, search starts here
|
||||||
&& (tte->bound() & BOUND_UPPER)
|
&& (tte->bound() & BOUND_UPPER)
|
||||||
&& tte->depth() >= depth;
|
&& tte->depth() >= depth;
|
||||||
|
|
||||||
// Step 12. Loop through all pseudo-legal moves until no moves remain
|
// Step 13. Loop through all pseudo-legal moves until no moves remain
|
||||||
// or a beta cutoff occurs.
|
// or a beta cutoff occurs.
|
||||||
while ((move = mp.next_move(moveCountPruning)) != MOVE_NONE)
|
while ((move = mp.next_move(moveCountPruning)) != MOVE_NONE)
|
||||||
{
|
{
|
||||||
|
@ -985,7 +995,7 @@ moves_loop: // When in check, search starts here
|
||||||
|
|
||||||
Value delta = beta - alpha;
|
Value delta = beta - alpha;
|
||||||
|
|
||||||
// Step 13. Pruning at shallow depth (~98 Elo). Depth conditions are important for mate finding.
|
// Step 14. Pruning at shallow depth (~98 Elo). Depth conditions are important for mate finding.
|
||||||
if ( !rootNode
|
if ( !rootNode
|
||||||
&& pos.non_pawn_material(us)
|
&& pos.non_pawn_material(us)
|
||||||
&& bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
|
&& bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
|
||||||
|
@ -1038,7 +1048,7 @@ moves_loop: // When in check, search starts here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 14. Extensions (~66 Elo)
|
// Step 15. Extensions (~66 Elo)
|
||||||
// We take care to not overdo to avoid search getting stuck.
|
// We take care to not overdo to avoid search getting stuck.
|
||||||
if (ss->ply < thisThread->rootDepth * 2)
|
if (ss->ply < thisThread->rootDepth * 2)
|
||||||
{
|
{
|
||||||
|
@ -1115,12 +1125,12 @@ moves_loop: // When in check, search starts here
|
||||||
[movedPiece]
|
[movedPiece]
|
||||||
[to_sq(move)];
|
[to_sq(move)];
|
||||||
|
|
||||||
// Step 15. Make the move
|
// Step 16. Make the move
|
||||||
pos.do_move(move, st, givesCheck);
|
pos.do_move(move, st, givesCheck);
|
||||||
|
|
||||||
bool doDeeperSearch = false;
|
bool doDeeperSearch = false;
|
||||||
|
|
||||||
// Step 16. Late moves reduction / extension (LMR, ~98 Elo)
|
// Step 17. Late moves reduction / extension (LMR, ~98 Elo)
|
||||||
// We use various heuristics for the sons of a node after the first son has
|
// We use various heuristics for the sons of a node after the first son has
|
||||||
// been searched. In general we would like to reduce them, but there are many
|
// been searched. In general we would like to reduce them, but there are many
|
||||||
// cases where we extend a son if it has good chances to be "interesting".
|
// cases where we extend a son if it has good chances to be "interesting".
|
||||||
|
@ -1188,7 +1198,7 @@ moves_loop: // When in check, search starts here
|
||||||
didLMR = false;
|
didLMR = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 17. Full depth search when LMR is skipped or fails high
|
// Step 18. Full depth search when LMR is skipped or fails high
|
||||||
if (doFullDepthSearch)
|
if (doFullDepthSearch)
|
||||||
{
|
{
|
||||||
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth + doDeeperSearch, !cutNode);
|
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth + doDeeperSearch, !cutNode);
|
||||||
|
@ -1218,12 +1228,12 @@ moves_loop: // When in check, search starts here
|
||||||
std::min(maxNextDepth, newDepth), false);
|
std::min(maxNextDepth, newDepth), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 18. Undo move
|
// Step 19. Undo move
|
||||||
pos.undo_move(move);
|
pos.undo_move(move);
|
||||||
|
|
||||||
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
|
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
|
||||||
|
|
||||||
// Step 19. Check for a new best move
|
// Step 20. Check for a new best move
|
||||||
// Finished searching the move. If a stop occurred, the return value of
|
// Finished searching the move. If a stop occurred, the return value of
|
||||||
// the search cannot be trusted, and we return immediately without
|
// the search cannot be trusted, and we return immediately without
|
||||||
// updating best move, PV and TT.
|
// updating best move, PV and TT.
|
||||||
|
@ -1306,7 +1316,7 @@ moves_loop: // When in check, search starts here
|
||||||
return VALUE_DRAW;
|
return VALUE_DRAW;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Step 20. Check for mate and stalemate
|
// Step 21. Check for mate and stalemate
|
||||||
// All legal moves have been searched and if there are no legal moves, it
|
// All legal moves have been searched and if there are no legal moves, it
|
||||||
// must be a mate or a stalemate. If we are in a singular extension search then
|
// must be a mate or a stalemate. If we are in a singular extension search then
|
||||||
// return a fail low score.
|
// return a fail low score.
|
||||||
|
|
Loading…
Add table
Reference in a new issue