There are two concepts with this patch:
Limit check extensions by using move count.
The idea is to limit search explosion.
Always extend check if the first move gives check.
The idea is to save expensive SEE calls, since the vast
majority of first move will have SEE value >= 0, also
first move may still be strong even if the SEE is negative.
STC:
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 16503 W: 3068 L: 2873 D: 10562
LTC:
LLR: 2.97 (-2.94,2.94) [0.00,5.00]
Total: 37202 W: 5261 L: 5014 D: 26927
bench:
8543366
Depth extension, newDepth, predictedDepth;
Value bestValue, value, ttValue, eval, nullValue;
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
Depth extension, newDepth, predictedDepth;
Value bestValue, value, ttValue, eval, nullValue;
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
- bool captureOrPromotion, doFullDepthSearch;
+ bool captureOrPromotion, doFullDepthSearch, moveCountPruning;
Piece moved_piece;
int moveCount, quietCount;
Piece moved_piece;
int moveCount, quietCount;
? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
: pos.gives_check(move, ci);
? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
: pos.gives_check(move, ci);
+ moveCountPruning = depth < 16 * ONE_PLY
+ && moveCount >= FutilityMoveCounts[improving][depth];
+
// Step 12. Extend checks
// Step 12. Extend checks
- if (givesCheck && pos.see_sign(move) >= VALUE_ZERO)
+ if ( givesCheck
+ && ( moveCount == 1
+ || (!moveCountPruning && pos.see_sign(move) >= VALUE_ZERO)))
extension = ONE_PLY;
// Singular extension search. If all moves but one fail low on a search of
extension = ONE_PLY;
// Singular extension search. If all moves but one fail low on a search of
&& bestValue > VALUE_MATED_IN_MAX_PLY)
{
// Move count based pruning
&& bestValue > VALUE_MATED_IN_MAX_PLY)
{
// Move count based pruning
- if ( depth < 16 * ONE_PLY
- && moveCount >= FutilityMoveCounts[improving][depth])
continue;
// Countermoves based pruning
continue;
// Countermoves based pruning