// but if we are pondering or in infinite search, we shouldn't print the best
// move before we are told to do so.
if (!Signals.stop && (Limits.ponder || Limits.infinite))
- RootPos.this_thread()->wait_for_stop_or_ponderhit();
+ {
+ Signals.stopOnPonderhit = true;
+ RootPos.this_thread()->wait_for_stop();
+ }
// Best move could be MOVE_NONE when searching on a stalemate position
sync_cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], RootPos.is_chess960())
else if (tte)
{
- // Following asserts are valid only in single thread condition because
- // TT access is always racy and its contents cannot be trusted.
- assert(tte->static_value() != VALUE_NONE || Threads.size() > 1);
- assert(ttValue != VALUE_NONE || tte->type() == BOUND_NONE || Threads.size() > 1);
-
- ss->staticEval = eval = tte->static_value();
- ss->evalMargin = tte->static_value_margin();
-
- if (eval == VALUE_NONE || ss->evalMargin == VALUE_NONE) // Due to a race
+ // Never assume anything on values stored in TT
+ if ( (ss->staticEval = eval = tte->static_value()) == VALUE_NONE
+ ||(ss->evalMargin = tte->static_value_margin()) == VALUE_NONE)
eval = ss->staticEval = evaluate(pos, ss->evalMargin);
// Can ttValue be used as a better position evaluation?
ss->staticEval, ss->evalMargin);
}
- // Handling of UCI command 'mate in x moves'. We simply return if after
- // 'x' moves we still have not checkmated the opponent.
- if (PvNode && !RootNode && !inCheck && Limits.mate && ss->ply > 2 * Limits.mate)
- return eval;
-
// Update gain for the parent non-capture move given the static position
// evaluation before and after the move.
if ( (move = (ss-1)->currentMove) != MOVE_NULL
continue;
}
- pvMove = PvNode ? moveCount == 1 : false;
+ pvMove = PvNode && moveCount == 1;
ss->currentMove = move;
if (!SpNode && !captureOrPromotion && playedMoveCount < 64)
movesSearched[playedMoveCount++] = move;
if (value > bestValue)
{
- bestValue = value;
- if (SpNode) sp->bestValue = value;
+ bestValue = SpNode ? sp->bestValue = value : value;
if (value > alpha)
{
- bestMove = move;
- if (SpNode) sp->bestMove = move;
+ bestMove = SpNode ? sp->bestMove = move : move;
- if (PvNode && value < beta)
- {
- alpha = value; // Update alpha here! Always alpha < beta
- if (SpNode) sp->alpha = value;
- }
+ if (PvNode && value < beta) // Update alpha! Always alpha < beta
+ alpha = SpNode ? sp->alpha = value : value;
else
{
assert(value >= beta); // Fail high
- if (SpNode) sp->cutoff = true;
+ if (SpNode)
+ sp->cutoff = true;
+
break;
}
}
Key posKey;
Move ttMove, move, bestMove;
Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
- bool givesCheck, enoughMaterial, evasionPrunable, fromNull;
+ bool givesCheck, enoughMaterial, evasionPrunable;
Depth ttDepth;
// To flag BOUND_EXACT a node with eval above alpha and no available moves
ss->currentMove = bestMove = MOVE_NONE;
ss->ply = (ss-1)->ply + 1;
- fromNull = (ss-1)->currentMove == MOVE_NULL;
// Check for an instant draw or maximum ply reached
if (pos.is_draw<false, false>() || ss->ply > MAX_PLY)
}
else
{
- if (fromNull)
- {
- // Approximated score. Real one is slightly higher due to tempo
- ss->staticEval = bestValue = -(ss-1)->staticEval;
- ss->evalMargin = VALUE_ZERO;
- }
- else if (tte)
+ if (tte)
{
- assert(tte->static_value() != VALUE_NONE || Threads.size() > 1);
-
- ss->staticEval = bestValue = tte->static_value();
- ss->evalMargin = tte->static_value_margin();
-
- if (ss->staticEval == VALUE_NONE || ss->evalMargin == VALUE_NONE) // Due to a race
+ // Never assume anything on values stored in TT
+ if ( (ss->staticEval = bestValue = tte->static_value()) == VALUE_NONE
+ ||(ss->evalMargin = tte->static_value_margin()) == VALUE_NONE)
ss->staticEval = bestValue = evaluate(pos, ss->evalMargin);
}
else
// Futility pruning
if ( !PvNode
&& !InCheck
- && !fromNull
&& !givesCheck
&& move != ttMove
&& enoughMaterial
&& !sp->slavesMask)
{
assert(!sp->master->is_searching);
- sp->master->wake_up();
+ sp->master->notify_one();
}
// After releasing the lock we cannot access anymore any SplitPoint