int FutilityMoveCounts[2][16]; // [improving][depth]
int Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber]
int FutilityMoveCounts[2][16]; // [improving][depth]
int Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber]
template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
}
template <bool PvNode> Depth reduction(bool i, Depth d, int mn) {
return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY;
}
// When we reach the maximum depth, we can arrive here without a raise of
// Threads.stop. However, if we are pondering or in an infinite search,
// the UCI protocol states that we shouldn't print the best move before the
// When we reach the maximum depth, we can arrive here without a raise of
// Threads.stop. However, if we are pondering or in an infinite search,
// the UCI protocol states that we shouldn't print the best move before the
// Check if there are threads with a better score than main thread
Thread* bestThread = this;
if ( !this->easyMovePlayed
// Check if there are threads with a better score than main thread
Thread* bestThread = this;
if ( !this->easyMovePlayed
Depth depthDiff = th->completedDepth - bestThread->completedDepth;
Value scoreDiff = th->rootMoves[0].score - bestThread->rootMoves[0].score;
Depth depthDiff = th->completedDepth - bestThread->completedDepth;
Value scoreDiff = th->rootMoves[0].score - bestThread->rootMoves[0].score;
Value bestValue, alpha, beta, delta;
Move easyMove = MOVE_NONE;
MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
Value bestValue, alpha, beta, delta;
Move easyMove = MOVE_NONE;
MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
// Sort the PV lines searched so far and update the GUI
std::stable_sort(rootMoves.begin(), rootMoves.begin() + PVIdx + 1);
// Sort the PV lines searched so far and update the GUI
std::stable_sort(rootMoves.begin(), rootMoves.begin() + PVIdx + 1);
sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
}
if (!Threads.stop)
completedDepth = rootDepth;
sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
}
if (!Threads.stop)
completedDepth = rootDepth;
// Do we have time for the next iteration? Can we stop searching now?
if (Limits.use_time_management())
{
// Do we have time for the next iteration? Can we stop searching now?
if (Limits.use_time_management())
{
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode, bool skipEarlyPruning) {
const bool PvNode = NT == PV;
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode, bool skipEarlyPruning) {
const bool PvNode = NT == PV;
assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
assert(PvNode || (alpha == beta - 1));
assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
assert(PvNode || (alpha == beta - 1));
Depth extension, newDepth;
Value bestValue, value, ttValue, eval;
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
Depth extension, newDepth;
Value bestValue, value, ttValue, eval;
bool ttHit, inCheck, givesCheck, singularExtensionNode, improving;
- bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture;
+ bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture, pvExact;
// Check for the available remaining time
if (thisThread == Threads.main())
static_cast<MainThread*>(thisThread)->check_time();
// Check for the available remaining time
if (thisThread == Threads.main())
static_cast<MainThread*>(thisThread)->check_time();
- // Used to send selDepth info to GUI
- if (PvNode && thisThread->selDepth < ss->ply)
- thisThread->selDepth = ss->ply;
+ // Used to send selDepth info to GUI (selDepth counts from 1, ply from 0)
+ if (PvNode && thisThread->selDepth < ss->ply + 1)
+ thisThread->selDepth = ss->ply + 1;
ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
ss->contHistory = &thisThread->contHistory[NO_PIECE][0];
(ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
ss->contHistory = &thisThread->contHistory[NO_PIECE][0];
(ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE;
- value = v < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply
- : v > drawScore ? VALUE_MATE - MAX_PLY - ss->ply
+ value = v < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply + 1
+ : v > drawScore ? VALUE_MATE - MAX_PLY - ss->ply - 1
: VALUE_DRAW + 2 * v * drawScore;
tte->save(posKey, value_to_tt(value, ss->ply), BOUND_EXACT,
: VALUE_DRAW + 2 * v * drawScore;
tte->save(posKey, value_to_tt(value, ss->ply), BOUND_EXACT,
// Step 11. Loop through moves
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
// Step 11. Loop through moves
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
// only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
ttDepth = InCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS
: DEPTH_QS_NO_CHECKS;
// only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
ttDepth = InCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS
: DEPTH_QS_NO_CHECKS;
// Transposition table lookup
posKey = pos.key();
tte = TT.probe(posKey, ttHit);
// Transposition table lookup
posKey = pos.key();
tte = TT.probe(posKey, ttHit);
// to search the moves. Because the depth is <= 0 here, only captures,
// queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
// be generated.
// to search the moves. Because the depth is <= 0 here, only captures,
// queen promotions and checks (only if depth >= DEPTH_QS_CHECKS) will
// be generated.
- const PieceToHistory* contHist[4] = {};
- MovePicker mp(pos, ttMove, depth, &pos.this_thread()->mainHistory, contHist, to_sq((ss-1)->currentMove));
+ MovePicker mp(pos, ttMove, depth, &pos.this_thread()->mainHistory, to_sq((ss-1)->currentMove));
// Loop through the moves until no moves remain or a beta cutoff occurs
while ((move = mp.next_move()) != MOVE_NONE)
// Loop through the moves until no moves remain or a beta cutoff occurs
while ((move = mp.next_move()) != MOVE_NONE)