const int skipPhase[] = { 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7 };
// Razoring and futility margin based on depth
- const int razor_margin[4] = { 483, 570, 603, 554 };
+ // razor_margin[0] is unused as long as depth >= ONE_PLY in search
+ const int razor_margin[] = { 0, 570, 603, 554 };
Value futility_margin(Depth d) { return Value(150 * d / ONE_PLY); }
// Futility and reductions lookup tables, initialized at startup
int FutilityMoveCounts[2][16]; // [improving][depth]
int Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber]
- // Threshold used for countermoves based pruning.
+ // Threshold used for countermoves based pruning
const int CounterMovePruneThreshold = 0;
template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
th->counterMoves.clear();
th->history.clear();
th->counterMoveHistory.clear();
- th->counterMoveHistory[NO_PIECE][0].fill(CounterMovePruneThreshold-1);
th->resetCalls = true;
+ CounterMoveStats& cm = th->counterMoveHistory[NO_PIECE][0];
+ int* t = &cm[NO_PIECE][0];
+ std::fill(t, t + sizeof(cm), CounterMovePruneThreshold - 1);
}
Threads.main()->previousScore = VALUE_INFINITE;
if (thisThread->resetCalls.load(std::memory_order_relaxed))
{
thisThread->resetCalls = false;
+
// At low node count increase the checking rate to about 0.1% of nodes
// otherwise use a default value.
- thisThread->callsCnt = Limits.nodes ? std::min((int64_t)4096, Limits.nodes / 1024)
+ thisThread->callsCnt = Limits.nodes ? std::min(4096, int(Limits.nodes / 1024))
: 4096;
}
// (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
// is singular and should be extended. To verify this we do a reduced search
// on all the other moves but the ttMove and if the result is lower than
- // ttValue minus a margin then we extend the ttMove.
+ // ttValue minus a margin then we will extend the ttMove.
if ( singularExtensionNode
&& move == ttMove
&& pos.legal(move))
if (value < rBeta)
extension = ONE_PLY;
}
- else if ( givesCheck
+ else if ( givesCheck
&& !moveCountPruning
&& pos.see_ge(move, VALUE_ZERO))
extension = ONE_PLY;
{
if ( !captureOrPromotion
&& !givesCheck
- && (!pos.advanced_pawn_push(move) || pos.non_pawn_material() >= 5000))
+ && (!pos.advanced_pawn_push(move) || pos.non_pawn_material() >= Value(5000)))
{
// Move count based pruning
- if (moveCountPruning) {
+ if (moveCountPruning)
+ {
skipQuiets = true;
continue;
}
&& is_ok((ss-1)->currentMove))
update_cm_stats(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth));
- if(!excludedMove)
+ if (!excludedMove)
tte->save(posKey, value_to_tt(bestValue, ss->ply),
- bestValue >= beta ? BOUND_LOWER :
- PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
- depth, bestMove, ss->staticEval, TT.generation());
+ bestValue >= beta ? BOUND_LOWER :
+ PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
+ depth, bestMove, ss->staticEval, TT.generation());
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
// Detect non-capture evasions that are candidates to be pruned
evasionPrunable = InCheck
+ && depth != DEPTH_ZERO
&& bestValue > VALUE_MATED_IN_MAX_PLY
&& !pos.capture(move);
for (size_t i = 0; i < multiPV; ++i)
{
- bool updated = (i <= PVIdx);
+ bool updated = (i <= PVIdx && rootMoves[i].score != -VALUE_INFINITE);
if (depth == ONE_PLY && !updated)
continue;