}
-/// Search::clear() resets search state to zero, to obtain reproducible results
+/// Search::clear() resets search state to its initial value, to obtain reproducible results
void Search::clear() {
th->history.clear();
th->counterMoveHistory.clear();
th->resetCalls = true;
+
CounterMoveStats& cm = th->counterMoveHistory[NO_PIECE][0];
- int* t = &cm[NO_PIECE][0];
- std::fill(t, t + sizeof(cm), CounterMovePruneThreshold - 1);
+ auto* t = &cm[NO_PIECE][0];
+ std::fill(t, t + sizeof(cm)/sizeof(*t), CounterMovePruneThreshold - 1);
}
Threads.main()->previousScore = VALUE_INFINITE;
Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
bool ttHit, givesCheck, evasionPrunable;
Depth ttDepth;
+ int moveCount;
if (PvNode)
{
ss->currentMove = bestMove = MOVE_NONE;
ss->ply = (ss-1)->ply + 1;
+ moveCount = 0;
// Check for an instant draw or if the maximum ply has been reached
if (pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
? pos.check_squares(type_of(pos.piece_on(from_sq(move)))) & to_sq(move)
: pos.gives_check(move);
+ moveCount++;
+
// Futility pruning
if ( !InCheck
&& !givesCheck
// Detect non-capture evasions that are candidates to be pruned
evasionPrunable = InCheck
- && depth != DEPTH_ZERO
+ && (depth != DEPTH_ZERO || moveCount > 2)
&& bestValue > VALUE_MATED_IN_MAX_PLY
&& !pos.capture(move);
// Check for legality just before making the move
if (!pos.legal(move))
+ {
+ moveCount--;
continue;
+ }
ss->currentMove = move;