// History and stats update bonus, based on depth
int stat_bonus(Depth depth) {
// History and stats update bonus, based on depth
int stat_bonus(Depth depth) {
- CounterMoveStats& cm = th->counterMoveHistory[NO_PIECE][0];
- int* t = &cm[NO_PIECE][0];
- std::fill(t, t + sizeof(cm), CounterMovePruneThreshold - 1);
+ th->counterMoves.fill(MOVE_NONE);
+ th->history.fill(0);
+
+ for (auto& to : th->counterMoveHistory)
+ for (auto& h : to)
+ h.fill(0);
+
+ th->counterMoveHistory[NO_PIECE][0].fill(CounterMovePruneThreshold - 1);
Color us = rootPos.side_to_move();
Time.init(Limits, us, rootPos.game_ply());
Color us = rootPos.side_to_move();
Time.init(Limits, us, rootPos.game_ply());
int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
DrawValue[ us] = VALUE_DRAW - Value(contempt);
int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
DrawValue[ us] = VALUE_DRAW - Value(contempt);
MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
std::memset(ss-4, 0, 7 * sizeof(Stack));
MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr);
std::memset(ss-4, 0, 7 * sizeof(Stack));
- for(int i = 4; i > 0; i--)
- (ss-i)->counterMoves = &this->counterMoveHistory[NO_PIECE][0]; // Use as sentinel
+ for (int i = 4; i > 0; i--)
+ (ss-i)->history = &this->counterMoveHistory[NO_PIECE][0]; // Use as sentinel
multiPV = std::min(multiPV, rootMoves.size());
// Iterative deepening loop until requested to stop or the target depth is reached
multiPV = std::min(multiPV, rootMoves.size());
// Iterative deepening loop until requested to stop or the target depth is reached
{
bestValue = ::search<PV>(rootPos, ss, alpha, beta, rootDepth, false, false);
{
bestValue = ::search<PV>(rootPos, ss, alpha, beta, rootDepth, false, false);
// Bring the best move to the front. It is critical that sorting
// is done with a stable algorithm because all the values but the
// first and eventually the new best one are set to -VALUE_INFINITE
// Bring the best move to the front. It is critical that sorting
// is done with a stable algorithm because all the values but the
// first and eventually the new best one are set to -VALUE_INFINITE
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;
+ bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture;
Thread* thisThread = pos.this_thread();
inCheck = pos.checkers();
moveCount = quietCount = ss->moveCount = 0;
Thread* thisThread = pos.this_thread();
inCheck = pos.checkers();
moveCount = quietCount = ss->moveCount = 0;
// At low node count increase the checking rate to about 0.1% of nodes
// otherwise use a default value.
thisThread->callsCnt = Limits.nodes ? std::min(4096, int(Limits.nodes / 1024))
// At low node count increase the checking rate to about 0.1% of nodes
// otherwise use a default value.
thisThread->callsCnt = Limits.nodes ? std::min(4096, int(Limits.nodes / 1024))
assert(0 <= ss->ply && ss->ply < MAX_PLY);
ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
assert(0 <= ss->ply && ss->ply < MAX_PLY);
ss->currentMove = (ss+1)->excludedMove = bestMove = MOVE_NONE;
Depth R = ((823 + 67 * depth / ONE_PLY) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY;
ss->currentMove = MOVE_NULL;
Depth R = ((823 + 67 * depth / ONE_PLY) / 256 + std::min((eval - beta) / PawnValueMg, 3)) * ONE_PLY;
ss->currentMove = MOVE_NULL;
pos.do_null_move(st);
Value nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -beta+1)
pos.do_null_move(st);
Value nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -beta+1)
&& abs(beta) < VALUE_MATE_IN_MAX_PLY)
{
Value rbeta = std::min(beta + 200, VALUE_INFINITE);
&& abs(beta) < VALUE_MATE_IN_MAX_PLY)
{
Value rbeta = std::min(beta + 200, VALUE_INFINITE);
assert(is_ok((ss-1)->currentMove));
MovePicker mp(pos, ttMove, rbeta - ss->staticEval);
assert(is_ok((ss-1)->currentMove));
MovePicker mp(pos, ttMove, rbeta - ss->staticEval);
- value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth, !cutNode, false);
+ value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, depth - 4 * ONE_PLY, !cutNode, false);
- const CounterMoveStats& cmh = *(ss-1)->counterMoves;
- const CounterMoveStats& fmh = *(ss-2)->counterMoves;
- const CounterMoveStats& fm2 = *(ss-4)->counterMoves;
+ const PieceToHistory& cmh = *(ss-1)->history;
+ const PieceToHistory& fmh = *(ss-2)->history;
+ const PieceToHistory& fm2 = *(ss-4)->history;
MovePicker mp(pos, ttMove, depth, ss);
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
MovePicker mp(pos, ttMove, depth, ss);
value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc
// 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
// Step 14. Make the move
pos.do_move(move, st, givesCheck);
// Step 14. Make the move
pos.do_move(move, st, givesCheck);
- ss->history = cmh[moved_piece][to_sq(move)]
- + fmh[moved_piece][to_sq(move)]
- + fm2[moved_piece][to_sq(move)]
- + thisThread->history.get(~pos.side_to_move(), move)
- - 4000; // Correction factor
+ ss->statScore = cmh[moved_piece][to_sq(move)]
+ + fmh[moved_piece][to_sq(move)]
+ + fm2[moved_piece][to_sq(move)]
+ + thisThread->history[~pos.side_to_move()][from_to(move)]
+ - 4000; // Correction factor
Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
bool ttHit, givesCheck, evasionPrunable;
Depth ttDepth;
Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
bool ttHit, givesCheck, evasionPrunable;
Depth ttDepth;
// Check for an instant draw or if the maximum ply has been reached
if (pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)
// Check for an instant draw or if the maximum ply has been reached
if (pos.is_draw(ss->ply) || ss->ply >= MAX_PLY)