enum NodeType { NonPV, PV, Root };
// Futility margin
- Value futility_margin(Depth d, bool improving) {
- return Value(140 * (d - improving));
+ Value futility_margin(Depth d, bool noTtCutNode, bool improving) {
+ return Value((140 - 40 * noTtCutNode) * (d - improving));
}
// Reductions lookup table initialized at startup
bool givesCheck, improving, priorCapture, singularQuietLMR;
bool capture, moveCountPruning, ttCapture;
Piece movedPiece;
- int moveCount, captureCount, quietCount, improvement;
+ int moveCount, captureCount, quietCount;
// Step 1. Initialize node
Thread* thisThread = pos.this_thread();
// Skip early pruning when in check
ss->staticEval = eval = VALUE_NONE;
improving = false;
- improvement = 0;
goto moves_loop;
}
else if (excludedMove)
thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << bonus;
}
- // Set up the improvement variable, which is the difference between the current
- // static evaluation and the previous static evaluation at our turn (if we were
- // in check at our previous move we look at the move prior to it). The improvement
- // margin and the improving flag are used in various pruning heuristics.
- improvement = (ss-2)->staticEval != VALUE_NONE ? ss->staticEval - (ss-2)->staticEval
- : (ss-4)->staticEval != VALUE_NONE ? ss->staticEval - (ss-4)->staticEval
- : 173;
- improving = improvement > 0;
+ // Set up the improving flag, which is true if current static evaluation is
+ // bigger than the previous static evaluation at our turn (if we were in
+ // check at our previous move we look at static evaluaion at move prior to it
+ // and if we were in check at move prior to it flag is set to true) and is
+ // false otherwise. The improving flag is used in various pruning heuristics.
+ improving = (ss-2)->staticEval != VALUE_NONE ? ss->staticEval > (ss-2)->staticEval
+ : (ss-4)->staticEval != VALUE_NONE ? ss->staticEval > (ss-4)->staticEval
+ : true;
// Step 7. Razoring (~1 Elo).
// If eval is really low check with qsearch if it can exceed alpha, if it can't,
// The depth condition is important for mate finding.
if ( !ss->ttPv
&& depth < 9
- && eval - futility_margin(depth, improving) - (ss-1)->statScore / 306 >= beta
+ && eval - futility_margin(depth, cutNode && !ss->ttHit, improving) - (ss-1)->statScore / 306 >= beta
&& eval >= beta
&& eval < 24923) // larger than VALUE_KNOWN_WIN, but smaller than TB wins
return eval;
// Decrease reduction for PvNodes based on depth (~2 Elo)
if (PvNode)
- r -= 1 + 12 / (3 + depth);
+ r -= 1 + (depth < 6);
// Decrease reduction if ttMove has been singularly extended (~1 Elo)
if (singularQuietLMR)
Piece moved_piece = pos.moved_piece(bestMove);
PieceType captured;
- int bonus1 = stat_bonus(depth + 1);
+ int quietMoveBonus = stat_bonus(depth + 1);
if (!pos.capture_stage(bestMove))
{
- int bonus2 = bestValue > beta + 145 ? bonus1 // larger bonus
- : stat_bonus(depth); // smaller bonus
+ int bestMoveBonus = bestValue > beta + 145 ? quietMoveBonus // larger bonus
+ : stat_bonus(depth); // smaller bonus
// Increase stats for the best move in case it was a quiet move
- update_quiet_stats(pos, ss, bestMove, bonus2);
+ update_quiet_stats(pos, ss, bestMove, bestMoveBonus);
// Decrease stats for all non-best quiet moves
for (int i = 0; i < quietCount; ++i)
{
- thisThread->mainHistory[us][from_to(quietsSearched[i])] << -bonus2;
- update_continuation_histories(ss, pos.moved_piece(quietsSearched[i]), to_sq(quietsSearched[i]), -bonus2);
+ thisThread->mainHistory[us][from_to(quietsSearched[i])] << -bestMoveBonus;
+ update_continuation_histories(ss, pos.moved_piece(quietsSearched[i]), to_sq(quietsSearched[i]), -bestMoveBonus);
}
}
else
{
// Increase stats for the best move in case it was a capture move
captured = type_of(pos.piece_on(to_sq(bestMove)));
- captureHistory[moved_piece][to_sq(bestMove)][captured] << bonus1;
+ captureHistory[moved_piece][to_sq(bestMove)][captured] << quietMoveBonus;
}
// Extra penalty for a quiet early move that was not a TT move or
if ( prevSq != SQ_NONE
&& ((ss-1)->moveCount == 1 + (ss-1)->ttHit || ((ss-1)->currentMove == (ss-1)->killers[0]))
&& !pos.captured_piece())
- update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -bonus1);
+ update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -quietMoveBonus);
// Decrease stats for all non-best capture moves
for (int i = 0; i < captureCount; ++i)
{
moved_piece = pos.moved_piece(capturesSearched[i]);
captured = type_of(pos.piece_on(to_sq(capturesSearched[i])));
- captureHistory[moved_piece][to_sq(capturesSearched[i])][captured] << -bonus1;
+ captureHistory[moved_piece][to_sq(capturesSearched[i])][captured] << -quietMoveBonus;
}
}