Skip to content

Commit

Permalink
Introduce ProbCut for check evasions
Browse files Browse the repository at this point in the history
The idea of this patch can be described as follows: if we are in check
and the transposition table move is a capture that returns a value
far above beta, we can assume that the opponent just blundered a piece
by giving check, and we return the transposition table value. This is
similar to the usual probCut logic for quiet moves, but with a different
threshold.

Passed STC
LLR: 2.94 (-2.94,2.94) {-0.25,1.25}
Total: 33440 W: 3056 L: 2891 D: 27493
Ptnml(0-2): 110, 2338, 11672, 2477, 123
https://tests.stockfishchess.org/tests/view/602cd1087f517a561bc49bda

Passed LTC
LLR: 2.98 (-2.94,2.94) {0.25,1.25}
Total: 10072 W: 401 L: 309 D: 9362
Ptnml(0-2): 2, 288, 4365, 378, 3
https://tests.stockfishchess.org/tests/view/602ceea57f517a561bc49bf0

The committed version has an additional fix to never return unproven wins
in the tablebase range or the mate range. This fix passed tests for non-
regression at STC and LTC:

STC:
LLR: 2.93 (-2.94,2.94) {-1.25,0.25}
Total: 26240 W: 2354 L: 2280 D: 21606
Ptnml(0-2): 85, 1763, 9372, 1793, 107
https://tests.stockfishchess.org/tests/view/602d86a87f517a561bc49c7a

LTC:
LLR: 2.95 (-2.94,2.94) {-0.75,0.25}
Total: 35304 W: 1299 L: 1256 D: 32749
Ptnml(0-2): 14, 1095, 15395, 1130, 18
https://tests.stockfishchess.org/tests/view/602d98d17f517a561bc49c83

Closes #3362

Bench: 3830215
  • Loading branch information
Vizvezdenec authored and snicolet committed Feb 20, 2021
1 parent 6294db7 commit 7c30091
Showing 1 changed file with 26 additions and 10 deletions.
36 changes: 26 additions & 10 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,23 @@ namespace {

moves_loop: // When in check, search starts from here

ttCapture = ttMove && pos.capture_or_promotion(ttMove);

// Step 11. A small Probcut idea, when we are in check
probCutBeta = beta + 400;
if ( ss->inCheck
&& !PvNode
&& depth >= 4
&& ttCapture
&& (tte->bound() & BOUND_LOWER)
&& tte->depth() >= depth - 3
&& ttValue >= probCutBeta
&& abs(ttValue) <= VALUE_KNOWN_WIN
&& abs(beta) <= VALUE_KNOWN_WIN
)
return probCutBeta;


const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory,
nullptr , (ss-4)->continuationHistory,
nullptr , (ss-6)->continuationHistory };
Expand All @@ -985,12 +1002,11 @@ namespace {

value = bestValue;
singularQuietLMR = moveCountPruning = false;
ttCapture = ttMove && pos.capture_or_promotion(ttMove);

// Mark this node as being searched
ThreadHolding th(thisThread, posKey, ss->ply);

// Step 11. Loop through all pseudo-legal moves until no moves remain
// Step 12. Loop through all pseudo-legal moves until no moves remain
// or a beta cutoff occurs.
while ((move = mp.next_move(moveCountPruning)) != MOVE_NONE)
{
Expand Down Expand Up @@ -1036,7 +1052,7 @@ namespace {
// Calculate new depth for this move
newDepth = depth - 1;

// Step 12. Pruning at shallow depth (~200 Elo)
// Step 13. Pruning at shallow depth (~200 Elo)
if ( !rootNode
&& pos.non_pawn_material(us)
&& bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
Expand Down Expand Up @@ -1084,7 +1100,7 @@ namespace {
}
}

// Step 13. Extensions (~75 Elo)
// Step 14. Extensions (~75 Elo)

// Singular extension search (~70 Elo). If all moves but one fail low on a
// search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
Expand Down Expand Up @@ -1156,10 +1172,10 @@ namespace {
[movedPiece]
[to_sq(move)];

// Step 14. Make the move
// Step 15. Make the move
pos.do_move(move, st, givesCheck);

// Step 15. Reduced depth search (LMR, ~200 Elo). If the move fails high it will be
// Step 16. Reduced depth search (LMR, ~200 Elo). If the move fails high it will be
// re-searched at full depth.
if ( depth >= 3
&& moveCount > 1 + 2 * rootNode
Expand Down Expand Up @@ -1266,7 +1282,7 @@ namespace {
didLMR = false;
}

// Step 16. Full depth search when LMR is skipped or fails high
// Step 17. Full depth search when LMR is skipped or fails high
if (doFullDepthSearch)
{
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode);
Expand All @@ -1293,12 +1309,12 @@ namespace {
std::min(maxNextDepth, newDepth), false);
}

// Step 17. Undo move
// Step 18. Undo move
pos.undo_move(move);

assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);

// Step 18. Check for a new best move
// Step 19. Check for a new best move
// Finished searching the move. If a stop occurred, the return value of
// the search cannot be trusted, and we return immediately without
// updating best move, PV and TT.
Expand Down Expand Up @@ -1375,7 +1391,7 @@ namespace {
return VALUE_DRAW;
*/

// Step 19. Check for mate and stalemate
// Step 20. Check for mate and stalemate
// 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
// return a fail low score.
Expand Down

0 comments on commit 7c30091

Please sign in to comment.