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;
}
bool enabled() const { return level < 20; }
bool time_to_pick(Depth depth) const { return depth / ONE_PLY == 1 + level; }
bool enabled() const { return level < 20; }
bool time_to_pick(Depth depth) const { return depth / ONE_PLY == 1 + level; }
// 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
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);
- std::swap(rootMoves[0], *std::find(rootMoves.begin(),
- rootMoves.end(), skill.best_move(multiPV)));
+ std::swap(rootMoves[0], *std::find(rootMoves.begin(), rootMoves.end(),
+ skill.best ? skill.best : skill.pick_best(multiPV)));
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
- int mch = std::max(1, moveCount - (ss-1)->moveCount / 16);
- Depth r = reduction<PvNode>(improving, depth, mch);
+ Depth r = reduction<PvNode>(improving, depth, moveCount);
// 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);
int push = ( weakness * int(topScore - rootMoves[i].score)
+ delta * (rng.rand<unsigned>() % weakness)) / 128;
int push = ( weakness * int(topScore - rootMoves[i].score)
+ delta * (rng.rand<unsigned>() % weakness)) / 128;