If the node doesn't go through LMR and r is too big,
reduce search depth by one ply.
STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 664888 W: 176375 L: 175169 D: 313344
Ptnml(0-2): 1965, 73754, 179851, 74858, 2016
https://tests.stockfishchess.org/tests/view/
6399414c93ed41c57ede8fb8
LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 150784 W: 40553 L: 40031 D: 70200
Ptnml(0-2): 76, 14668, 45387, 15180, 81
https://tests.stockfishchess.org/tests/view/
639dee6e11c576d919dc2b38
closes https://github.com/official-stockfish/Stockfish/pull/4290
Bench:
3727508
// Step 16. Make the move
pos.do_move(move, st, givesCheck);
// Step 16. Make the move
pos.do_move(move, st, givesCheck);
- // Step 17. Late moves reduction / extension (LMR, ~98 Elo)
- // 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
- // cases where we extend a son if it has good chances to be "interesting".
- if ( depth >= 2
- && moveCount > 1 + (PvNode && ss->ply <= 1)
- && ( !ss->ttPv
- || !capture
- || (cutNode && (ss-1)->moveCount > 1)))
- {
- Depth r = reduction(improving, depth, moveCount, delta, thisThread->rootDelta);
+ Depth r = reduction(improving, depth, moveCount, delta, thisThread->rootDelta);
- // Decrease reduction if position is or has been on the PV
- // and node is not likely to fail low. (~3 Elo)
- if ( ss->ttPv
- && !likelyFailLow)
- r -= 2;
+ // Decrease reduction if position is or has been on the PV
+ // and node is not likely to fail low. (~3 Elo)
+ if ( ss->ttPv
+ && !likelyFailLow)
+ r -= 2;
- // Decrease reduction if opponent's move count is high (~1 Elo)
- if ((ss-1)->moveCount > 7)
- r--;
+ // Decrease reduction if opponent's move count is high (~1 Elo)
+ if ((ss-1)->moveCount > 7)
+ r--;
- // Increase reduction for cut nodes (~3 Elo)
- if (cutNode)
- r += 2;
+ // Increase reduction for cut nodes (~3 Elo)
+ if (cutNode)
+ r += 2;
- // Increase reduction if ttMove is a capture (~3 Elo)
- if (ttCapture)
- r++;
+ // Increase reduction if ttMove is a capture (~3 Elo)
+ if (ttCapture)
+ r++;
- // Decrease reduction for PvNodes based on depth
- if (PvNode)
- r -= 1 + 11 / (3 + depth);
+ // Decrease reduction for PvNodes based on depth
+ if (PvNode)
+ r -= 1 + 11 / (3 + depth);
- // Decrease reduction if ttMove has been singularly extended (~1 Elo)
- if (singularQuietLMR)
- r--;
+ // Decrease reduction if ttMove has been singularly extended (~1 Elo)
+ if (singularQuietLMR)
+ r--;
- // Decrease reduction if we move a threatened piece (~1 Elo)
- if ( depth > 9
- && (mp.threatenedPieces & from_sq(move)))
- r--;
+ // Decrease reduction if we move a threatened piece (~1 Elo)
+ if ( depth > 9
+ && (mp.threatenedPieces & from_sq(move)))
+ r--;
- // Increase reduction if next ply has a lot of fail high
- if ((ss+1)->cutoffCnt > 3)
- r++;
+ // Increase reduction if next ply has a lot of fail high
+ if ((ss+1)->cutoffCnt > 3)
+ r++;
- ss->statScore = 2 * thisThread->mainHistory[us][from_to(move)]
- + (*contHist[0])[movedPiece][to_sq(move)]
- + (*contHist[1])[movedPiece][to_sq(move)]
- + (*contHist[3])[movedPiece][to_sq(move)]
- - 4433;
+ ss->statScore = 2 * thisThread->mainHistory[us][from_to(move)]
+ + (*contHist[0])[movedPiece][to_sq(move)]
+ + (*contHist[1])[movedPiece][to_sq(move)]
+ + (*contHist[3])[movedPiece][to_sq(move)]
+ - 4433;
- // Decrease/increase reduction for moves with a good/bad history (~30 Elo)
- r -= ss->statScore / (13000 + 4152 * (depth > 7 && depth < 19));
+ // Decrease/increase reduction for moves with a good/bad history (~30 Elo)
+ r -= ss->statScore / (13000 + 4152 * (depth > 7 && depth < 19));
+ // Step 17. Late moves reduction / extension (LMR, ~98 Elo)
+ // 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
+ // cases where we extend a son if it has good chances to be "interesting".
+ if ( depth >= 2
+ && moveCount > 1 + (PvNode && ss->ply <= 1)
+ && ( !ss->ttPv
+ || !capture
+ || (cutNode && (ss-1)->moveCount > 1)))
+ {
// In general we want to cap the LMR depth search at newDepth, but when
// reduction is negative, we allow this move a limited search extension
// beyond the first move depth. This may lead to hidden double extensions.
// In general we want to cap the LMR depth search at newDepth, but when
// reduction is negative, we allow this move a limited search extension
// beyond the first move depth. This may lead to hidden double extensions.
- // Step 18. Full depth search when LMR is skipped
+ // Step 18. Full depth search when LMR is skipped. If expected reduction is high, reduce its depth by 1.
else if (!PvNode || moveCount > 1)
{
else if (!PvNode || moveCount > 1)
{
- value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, !cutNode);
+ value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth - (r > 4), !cutNode);
}
// For PV nodes only, do a full PV search on the first move or after a fail
}
// For PV nodes only, do a full PV search on the first move or after a fail