namespace {
/// Types
-
+ enum NodeType { NonPV, PV};
// ThreadsManager class is used to handle all the threads related stuff in search,
// init, starting, parking and, the most important, launching a slave thread at a
Value id_loop(const Position& pos, Move searchMoves[]);
Value root_search(Position& pos, SearchStack ss[], RootMoveList& rml, Value* alphaPtr, Value* betaPtr);
- template <bool PvNode>
+ template <NodeType PvNode>
Value search(Position& pos, SearchStack ss[], Value alpha, Value beta, Depth depth, int ply, bool allowNullmove, int threadID, Move excludedMove = MOVE_NONE);
Value qsearch(Position& pos, SearchStack ss[], Value alpha, Value beta, Depth depth, int ply, int threadID);
alpha = -VALUE_INFINITE;
// Full depth PV search, done on first move or after a fail high
- value = -search<true>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
+ value = -search<PV>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
}
else
{
if (ss[0].reduction)
{
// Reduced depth non-pv search using alpha as upperbound
- value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth-ss[0].reduction, 1, true, 0);
+ value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth-ss[0].reduction, 1, true, 0);
doFullDepthSearch = (value > alpha);
}
}
{
// Full depth non-pv search using alpha as upperbound
ss[0].reduction = Depth(0);
- value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth, 1, true, 0);
+ value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth, 1, true, 0);
// If we are above alpha then research at same depth but as PV
// to get a correct score or eventually a fail high above beta.
if (value > alpha)
- value = -search<true>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
+ value = -search<PV>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
}
}
// search_pv() is the main search function for PV nodes.
- template <bool PvNode>
+ template <NodeType PvNode>
Value search(Position& pos, SearchStack ss[], Value alpha, Value beta,
Depth depth, int ply, bool allowNullmove, int threadID, Move excludedMove) {
-
assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE);
assert(beta > alpha && beta <= VALUE_INFINITE);
assert(ply >= 0 && ply < PLY_MAX);
pos.do_null_move(st);
- nullValue = -search<false>(pos, ss, -beta, -alpha, depth-R*OnePly, ply+1, false, threadID);
+ nullValue = -search<NonPV>(pos, ss, -beta, -alpha, depth-R*OnePly, ply+1, false, threadID);
pos.undo_null_move();
return nullValue;
// Do zugzwang verification search
- Value v = search<false>(pos, ss, alpha, beta, depth-5*OnePly, ply, false, threadID);
+ Value v = search<NonPV>(pos, ss, alpha, beta, depth-5*OnePly, ply, false, threadID);
if (v >= beta)
return nullValue;
} else {
&& depth >= IIDDepthAtPVNodes
&& ttMove == MOVE_NONE)
{
- search<true>(pos, ss, alpha, beta, depth-2*OnePly, ply, false, threadID);
+ search<PV>(pos, ss, alpha, beta, depth-2*OnePly, ply, false, threadID);
ttMove = ss[ply].pv[ply];
tte = TT.retrieve(posKey);
}
&& !isCheck
&& ss[ply].eval >= beta - IIDMargin)
{
- search<false>(pos, ss, alpha, beta, depth/2, ply, false, threadID);
+ search<NonPV>(pos, ss, alpha, beta, depth/2, ply, false, threadID);
ttMove = ss[ply].pv[ply];
tte = TT.retrieve(posKey);
}
if (abs(ttValue) < VALUE_KNOWN_WIN)
{
- Value excValue = search<false>(pos, ss, ttValue - SingularExtensionMargin - 1, ttValue - SingularExtensionMargin, depth / 2, ply, false, threadID, move);
+ Value excValue = search<NonPV>(pos, ss, ttValue - SingularExtensionMargin - 1, ttValue - SingularExtensionMargin, depth / 2, ply, false, threadID, move);
if (excValue < ttValue - SingularExtensionMargin)
ext = OnePly;
// Step extra. pv search (only in PV nodes)
// The first move in list is the expected PV
if (PvNode && moveCount == 1)
- value = -search<true>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
+ value = -search<PV>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
else
{
// Step 14. Reduced search
ss[ply].reduction = (PvNode ? pv_reduction(depth, moveCount) : nonpv_reduction(depth, moveCount));
if (ss[ply].reduction)
{
- value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID);
+ value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID);
doFullDepthSearch = (value > alpha);
}
}
if (doFullDepthSearch)
{
ss[ply].reduction = Depth(0);
- value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth, ply+1, true, threadID);
+ value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth, ply+1, true, threadID);
// Step extra. pv search (only in PV nodes)
if (PvNode && value > alpha && value < beta)
- value = -search<true>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
+ value = -search<PV>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
}
}
ss[sp->ply].reduction = nonpv_reduction(sp->depth, moveCount);
if (ss[sp->ply].reduction)
{
- value = -search<false>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
+ value = -search<NonPV>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
doFullDepthSearch = (value >= sp->beta && !TM.thread_should_stop(threadID));
}
}
if (doFullDepthSearch)
{
ss[sp->ply].reduction = Depth(0);
- value = -search<false>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth, sp->ply+1, true, threadID);
+ value = -search<NonPV>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth, sp->ply+1, true, threadID);
}
// Step 16. Undo move
if (ss[sp->ply].reduction)
{
Value localAlpha = sp->alpha;
- value = -search<false>(pos, ss, -(localAlpha+1), -localAlpha, newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
+ value = -search<NonPV>(pos, ss, -(localAlpha+1), -localAlpha, newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
doFullDepthSearch = (value > localAlpha && !TM.thread_should_stop(threadID));
}
}
{
Value localAlpha = sp->alpha;
ss[sp->ply].reduction = Depth(0);
- value = -search<false>(pos, ss, -(localAlpha+1), -localAlpha, newDepth, sp->ply+1, true, threadID);
+ value = -search<NonPV>(pos, ss, -(localAlpha+1), -localAlpha, newDepth, sp->ply+1, true, threadID);
if (value > localAlpha && value < sp->beta && !TM.thread_should_stop(threadID))
{
// to be higher or equal then beta, if so, avoid to start a PV search.
localAlpha = sp->alpha;
if (localAlpha < sp->beta)
- value = -search<true>(pos, ss, -sp->beta, -localAlpha, newDepth, sp->ply+1, false, threadID);
+ value = -search<PV>(pos, ss, -sp->beta, -localAlpha, newDepth, sp->ply+1, false, threadID);
}
}