return d > 17 ? 0 : 29 * d * d + 138 * d - 134;
}
- // Add a small random component to draw evaluations to keep search dynamic
+ // Add a small random component to draw evaluations to keep search dynamic
// and to avoid 3fold-blindness.
Value value_draw(Depth depth, Thread* thisThread) {
- return depth < 4 ? VALUE_DRAW
+ return depth < 4 ? VALUE_DRAW
: VALUE_DRAW + Value(2 * (thisThread->nodes.load(std::memory_order_relaxed) % 2) - 1);
}
&& !Threads.stop
&& !Threads.stopOnPonderhit)
{
- const int F[] = { failedLow,
- bestValue - mainThread->previousScore };
-
- int improvingFactor = std::max(246, std::min(832, 306 + 119 * F[0] - 6 * F[1]));
+ double fallingEval = (306 + 119 * failedLow + 6 * (mainThread->previousScore - bestValue)) / 581.0;
+ fallingEval = std::max(0.5, std::min(1.5, fallingEval));
// If the bestMove is stable over several iterations, reduce time accordingly
timeReduction = 1.0;
// Stop the search if we have only one legal move, or if available time elapsed
if ( rootMoves.size() == 1
- || Time.elapsed() > Time.optimum() * bestMoveInstability * improvingFactor / 581)
+ || Time.elapsed() > Time.optimum() * bestMoveInstability * fallingEval)
{
// If we are allowed to ponder do not stop the search now but
// keep pondering until the GUI sends "ponderhit" or "stop".
if ( Threads.stop.load(std::memory_order_relaxed)
|| pos.is_draw(ss->ply)
|| ss->ply >= MAX_PLY)
- return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos)
+ return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos)
: value_draw(depth, pos.this_thread());
// Step 3. Mate distance pruning. Even if we mate at the next move our score
TB::ProbeState err;
TB::WDLScore wdl = Tablebases::probe_wdl(pos, &err);
+ // Force check of time on the next occasion
+ if (thisThread == Threads.main())
+ static_cast<MainThread*>(thisThread)->callsCnt = 0;
+
if (err != TB::ProbeState::FAIL)
{
thisThread->tbHits.fetch_add(1, std::memory_order_relaxed);
&& pos.see_ge(move))
extension = ONE_PLY;
- else if ( pos.can_castle(us) // Extension for king moves that change castling rights
- && type_of(movedPiece) == KING)
+ // Extension if castling
+ else if (type_of(move) == CASTLING)
extension = ONE_PLY;
// Calculate new depth for this move
update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth + ONE_PLY));
- // Extra penalty for a quiet TT move in previous ply when it gets refuted
- if ((ss-1)->moveCount == 1 && !pos.captured_piece())
- update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
+ // Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted
+ if ( (ss-1)->moveCount == 1
+ || ((ss-1)->currentMove == (ss-1)->killers[0] && (ss-1)->killers[0]))
+ if (!pos.captured_piece())
+ update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY));
+
}
// Bonus for prior countermove that caused the fail low
else if ( (depth >= 3 * ONE_PLY || PvNode)
if (value > alpha)
{
+ bestMove = move;
+
if (PvNode) // Update pv even in fail-high case
update_pv(ss->pv, move, (ss+1)->pv);
if (PvNode && value < beta) // Update alpha here!
- {
alpha = value;
- bestMove = move;
- }
- else // Fail high
- {
- tte->save(posKey, value_to_tt(value, ss->ply), BOUND_LOWER,
- ttDepth, move, ss->staticEval);
-
- return value;
- }
+ else
+ break; // Fail high
}
}
}
return mated_in(ss->ply); // Plies to mate from the root
tte->save(posKey, value_to_tt(bestValue, ss->ply),
- PvNode && bestValue > oldAlpha ? BOUND_EXACT : BOUND_UPPER,
+ bestValue >= beta ? BOUND_LOWER :
+ PvNode && bestValue > oldAlpha ? BOUND_EXACT : BOUND_UPPER,
ttDepth, bestMove, ss->staticEval);
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);