template <NodeType NT>
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode) {
- // Use quiescence search when needed
- if (depth < ONE_PLY)
- return qsearch<NT>(pos, ss, alpha, beta);
-
constexpr bool PvNode = NT == PV;
const bool rootNode = PvNode && ss->ply == 0;
+ // Check if we have an upcoming move which draws by repetition, or
+ // if the opponent had an alternative move earlier to this position.
+ if ( pos.rule50_count() >= 3
+ && alpha < VALUE_DRAW
+ && !rootNode
+ && pos.has_game_cycle(ss->ply))
+ {
+ alpha = VALUE_DRAW;
+ if (alpha >= beta)
+ return alpha;
+ }
+
+ // Dive into quiescence search when the depth reaches zero
+ if (depth < ONE_PLY)
+ return qsearch<NT>(pos, ss, alpha, beta);
+
assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE);
assert(PvNode || (alpha == beta - 1));
assert(DEPTH_ZERO < depth && depth < DEPTH_MAX);
beta = std::min(mate_in(ss->ply+1), beta);
if (alpha >= beta)
return alpha;
-
- // Check if there exists a move which draws by repetition, or an alternative
- // earlier move to this position.
- if ( pos.rule50_count() >= 3
- && alpha < VALUE_DRAW
- && pos.has_game_cycle(ss->ply))
- {
- alpha = VALUE_DRAW;
- if (alpha >= beta)
- return alpha;
- }
}
assert(0 <= ss->ply && ss->ply < MAX_PLY);
&& ss->staticEval >= beta - 36 * depth / ONE_PLY + 225
&& !excludedMove
&& pos.non_pawn_material(us)
- && (ss->ply > thisThread->nmpMinPly || us != thisThread->nmpColor))
+ && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
{
assert(eval - beta >= 0);
// Do verification search at high depths, with null move pruning disabled
// for us, until ply exceeds nmpMinPly.
- thisThread->nmpMinPly = ss->ply + 3 * (depth-R) / 4 - 1;
+ thisThread->nmpMinPly = ss->ply + 3 * (depth-R) / 4;
thisThread->nmpColor = us;
Value v = search<NonPV>(pos, ss, beta-1, beta, depth-R, false);