return (Depth) Reductions[PvNode][i][std::min(int(d) / ONE_PLY, 63)][std::min(mn, 63)];
}
- size_t PVSize, PVIdx;
+ size_t MultiPV, PVIdx;
TimeManager TimeMgr;
double BestMoveChanges;
Value DrawValue[COLOR_NB];
// Init reductions array
for (hd = 1; hd < 64; ++hd) for (mc = 1; mc < 64; ++mc)
{
- double pvRed = log(double(hd)) * log(double(mc)) / 3.0;
+ double pvRed = 0.00 + log(double(hd)) * log(double(mc)) / 3.00;
double nonPVRed = 0.33 + log(double(hd)) * log(double(mc)) / 2.25;
Reductions[1][1][hd][mc] = (int8_t) ( pvRed >= 1.0 ? floor( pvRed * int(ONE_PLY)) : 0);
Reductions[0][1][hd][mc] = (int8_t) (nonPVRed >= 1.0 ? floor(nonPVRed * int(ONE_PLY)) : 0);
// Init futility move count array
for (d = 0; d < 32; ++d)
{
- FutilityMoveCounts[0][d] = int(2.4 + 0.222 * pow(d + 0.0, 1.8));
- FutilityMoveCounts[1][d] = int(3.0 + 0.3 * pow(d + 0.98, 1.8));
+ FutilityMoveCounts[0][d] = int(2.4 + 0.222 * pow(d + 0.00, 1.8));
+ FutilityMoveCounts[1][d] = int(3.0 + 0.300 * pow(d + 0.98, 1.8));
}
}
Countermoves.clear();
Followupmoves.clear();
- PVSize = Options["MultiPV"];
+ MultiPV = Options["MultiPV"];
Skill skill(Options["Skill Level"]);
// Do we have to play with skill handicap? In this case enable MultiPV search
// that we will use behind the scenes to retrieve a set of possible moves.
- if (skill.enabled() && PVSize < 4)
- PVSize = 4;
+ if (skill.enabled() && MultiPV < 4)
+ MultiPV = 4;
- PVSize = std::min(PVSize, RootMoves.size());
+ MultiPV = std::min(MultiPV, RootMoves.size());
// Iterative deepening loop until requested to stop or target depth reached
while (++depth <= MAX_PLY && !Signals.stop && (!Limits.depth || depth <= Limits.depth))
RootMoves[i].prevScore = RootMoves[i].score;
// MultiPV loop. We perform a full root search for each PV line
- for (PVIdx = 0; PVIdx < PVSize && !Signals.stop; ++PVIdx)
+ for (PVIdx = 0; PVIdx < MultiPV && !Signals.stop; ++PVIdx)
{
// Reset aspiration window starting size
if (depth >= 5)
// Sort the PV lines searched so far and update the GUI
std::stable_sort(RootMoves.begin(), RootMoves.begin() + PVIdx + 1);
- if (PVIdx + 1 == PVSize || Time::now() - SearchTime > 3000)
+ if (PVIdx + 1 == MultiPV || Time::now() - SearchTime > 3000)
sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl;
}
bool stop = false; // Local variable, not the volatile Signals.stop
// Take some extra time if the best move has changed
- if (depth > 4 && depth < 50 && PVSize == 1)
+ if (depth > 4 && depth < 50 && MultiPV == 1)
TimeMgr.pv_instability(BestMoveChanges);
// Stop the search if only one legal move is available or all
const bool SpNode = (NT == SplitPointPV || NT == SplitPointNonPV || NT == SplitPointRoot);
const bool RootNode = (NT == Root || NT == SplitPointRoot);
- assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE);
+ assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
assert(PvNode || (alpha == beta - 1));
assert(depth > DEPTH_ZERO);
{
// Step 2. Check for aborted search and immediate draw
if (Signals.stop || pos.is_draw() || ss->ply > MAX_PLY)
- return DrawValue[pos.side_to_move()];
+ return ss->ply > MAX_PLY && !inCheck ? evaluate(pos) : DrawValue[pos.side_to_move()];
// Step 3. Mate distance pruning. Even if we mate at the next move our score
// would be at best mate_in(ss->ply+1), but if alpha is already bigger because
}
// Step 10. Internal iterative deepening (skipped when in check)
- if ( depth >= (PvNode ? 5 * ONE_PLY : 8 * ONE_PLY)
- && ttMove == MOVE_NONE
+ if ( depth >= (PvNode ? 5 * ONE_PLY : 8 * ONE_PLY)
+ && !ttMove
&& (PvNode || ss->staticEval + Value(256) >= beta))
{
Depth d = depth - 2 * ONE_PLY - (PvNode ? DEPTH_ZERO : depth / 4);
|| pos.advanced_pawn_push(move);
// Step 12. Extend checks
- if (givesCheck && pos.see_sign(move) >= 0)
+ if (givesCheck && pos.see_sign(move) >= VALUE_ZERO)
ext = ONE_PLY;
// Singular extension search. If all moves but one fail low on a search of
}
// Prune moves with negative SEE at low depths
- if (predictedDepth < 4 * ONE_PLY && pos.see_sign(move) < 0)
+ if (predictedDepth < 4 * ONE_PLY && pos.see_sign(move) < VALUE_ZERO)
{
if (SpNode)
splitPoint->mutex.lock();
// Check for an instant draw or if the maximum ply has been reached
if (pos.is_draw() || ss->ply > MAX_PLY)
- return DrawValue[pos.side_to_move()];
+ return ss->ply > MAX_PLY && !InCheck ? evaluate(pos) : DrawValue[pos.side_to_move()];
// Decide whether or not to include checks: this fixes also the type of
// TT entry depth that we are going to use. Note that in qsearch we use
continue;
}
- if (futilityBase < beta && pos.see(move) <= 0)
+ if (futilityBase < beta && pos.see(move) <= VALUE_ZERO)
{
bestValue = std::max(bestValue, futilityBase);
continue;
&& (!InCheck || evasionPrunable)
&& move != ttMove
&& type_of(move) != PROMOTION
- && pos.see_sign(move) < 0)
+ && pos.see_sign(move) < VALUE_ZERO)
continue;
// Check for legality just before making the move
rk.rand<unsigned>();
// RootMoves are already sorted by score in descending order
- int variance = std::min(RootMoves[0].score - RootMoves[PVSize - 1].score, PawnValueMg);
+ int variance = std::min(RootMoves[0].score - RootMoves[MultiPV - 1].score, PawnValueMg);
int weakness = 120 - 2 * level;
int max_s = -VALUE_INFINITE;
best = MOVE_NONE;
// Choose best move. For each move score we add two terms both dependent on
// weakness. One deterministic and bigger for weaker moves, and one random,
// then we choose the move with the resulting highest score.
- for (size_t i = 0; i < PVSize; ++i)
+ for (size_t i = 0; i < MultiPV; ++i)
{
int s = RootMoves[i].score;