summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
b2961ad)
Adjust ProbCut rBeta by whether the score is improving, and also
set improving to false when in check. More precisely, this patch
has two parts:
1) the increased beta threshold for ProbCut is now adjusted based
on whether the score is improving
2) when in check, improving is always set to false.
Co-authored by Joost VandeVondele (@vondele) and Bill Henry (@VoyagerOne).
STC:
LLR: 2.96 (-2.94,2.94) [0.00,5.00]
Total: 13480 W: 2840 L: 2648 D: 7992
http://tests.stockfishchess.org/tests/view/
5aa693fe0ebc59029781004c
LTC:
LLR: 2.97 (-2.94,2.94) [0.00,5.00]
Total: 25895 W: 4099 L: 3880 D: 17916
http://tests.stockfishchess.org/tests/view/
5aa6ac940ebc59029781006e
In terms of opportunities for future work opened up by this patch,
the ProbCut rBeta formula could probably be tuned to gain more Elo.
Closes https://github.com/official-stockfish/Stockfish/pull/1485
Bench:
5328254
if (inCheck)
{
ss->staticEval = eval = VALUE_NONE;
if (inCheck)
{
ss->staticEval = eval = VALUE_NONE;
goto moves_loop;
}
else if (ttHit)
goto moves_loop;
}
else if (ttHit)
{
assert(is_ok((ss-1)->currentMove));
{
assert(is_ok((ss-1)->currentMove));
- Value rbeta = std::min(beta + 200, VALUE_INFINITE);
+ Value rbeta = std::min(beta + 216 - 48 * improving, VALUE_INFINITE);
MovePicker mp(pos, ttMove, rbeta - ss->staticEval, &thisThread->captureHistory);
int probCutCount = 0;
MovePicker mp(pos, ttMove, rbeta - ss->staticEval, &thisThread->captureHistory);
int probCutCount = 0;
// Step 17. Full depth search when LMR is skipped or fails high
if (doFullDepthSearch)
// Step 17. Full depth search when LMR is skipped or fails high
if (doFullDepthSearch)
- value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha)
- : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode, false);
+ value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha)
+ : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode, false);
// For PV nodes only, do a full PV search on the first move or after a fail
// high (in the latter case search only if value < beta), otherwise let the
// For PV nodes only, do a full PV search on the first move or after a fail
// high (in the latter case search only if value < beta), otherwise let the
(ss+1)->pv = pv;
(ss+1)->pv[0] = MOVE_NONE;
(ss+1)->pv = pv;
(ss+1)->pv[0] = MOVE_NONE;
- value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha)
- : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, false, false);
+ value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha)
+ : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, false, false);
Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
const bool PvNode = NT == PV;
Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {
const bool PvNode = NT == PV;
- const bool InCheck = bool(pos.checkers());
+ const bool inCheck = bool(pos.checkers());
assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
assert(PvNode || (alpha == beta - 1));
assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
assert(PvNode || (alpha == beta - 1));
// Check for an immediate draw or maximum ply reached
if ( pos.is_draw(ss->ply)
|| ss->ply >= MAX_PLY)
// Check for an immediate draw or maximum ply reached
if ( pos.is_draw(ss->ply)
|| ss->ply >= MAX_PLY)
- return (ss->ply >= MAX_PLY && !InCheck) ? evaluate(pos) : VALUE_DRAW;
+ return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos) : VALUE_DRAW;
assert(0 <= ss->ply && ss->ply < MAX_PLY);
// Decide whether or not to include checks: this fixes also the type of
// TT entry depth that we are going to use. Note that in qsearch we use
// only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
assert(0 <= ss->ply && ss->ply < MAX_PLY);
// Decide whether or not to include checks: this fixes also the type of
// TT entry depth that we are going to use. Note that in qsearch we use
// only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
- ttDepth = InCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS
+ ttDepth = inCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS
: DEPTH_QS_NO_CHECKS;
// Transposition table lookup
posKey = pos.key();
: DEPTH_QS_NO_CHECKS;
// Transposition table lookup
posKey = pos.key();
return ttValue;
// Evaluate the position statically
return ttValue;
// Evaluate the position statically
{
ss->staticEval = VALUE_NONE;
bestValue = futilityBase = -VALUE_INFINITE;
{
ss->staticEval = VALUE_NONE;
bestValue = futilityBase = -VALUE_INFINITE;
moveCount++;
// Futility pruning
moveCount++;
// Futility pruning
&& !givesCheck
&& futilityBase > -VALUE_KNOWN_WIN
&& !pos.advanced_pawn_push(move))
&& !givesCheck
&& futilityBase > -VALUE_KNOWN_WIN
&& !pos.advanced_pawn_push(move))
}
// Detect non-capture evasions that are candidates to be pruned
}
// Detect non-capture evasions that are candidates to be pruned
- evasionPrunable = InCheck
+ evasionPrunable = inCheck
&& (depth != DEPTH_ZERO || moveCount > 2)
&& bestValue > VALUE_MATED_IN_MAX_PLY
&& !pos.capture(move);
// Don't search moves with negative SEE values
&& (depth != DEPTH_ZERO || moveCount > 2)
&& bestValue > VALUE_MATED_IN_MAX_PLY
&& !pos.capture(move);
// Don't search moves with negative SEE values
- if ( (!InCheck || evasionPrunable)
+ if ( (!inCheck || evasionPrunable)
&& !pos.see_ge(move))
continue;
&& !pos.see_ge(move))
continue;
// All legal moves have been searched. A special case: If we're in check
// and no legal moves were found, it is checkmate.
// All legal moves have been searched. A special case: If we're in check
// and no legal moves were found, it is checkmate.
- if (InCheck && bestValue == -VALUE_INFINITE)
+ if (inCheck && bestValue == -VALUE_INFINITE)
return mated_in(ss->ply); // Plies to mate from the root
tte->save(posKey, value_to_tt(bestValue, ss->ply),
return mated_in(ss->ply); // Plies to mate from the root
tte->save(posKey, value_to_tt(bestValue, ss->ply),