1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 00:33:09 +00:00

Unify search() template parameters

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2011-05-28 12:13:42 +01:00
parent 853e2a9495
commit 013dc43d5d

View file

@ -47,7 +47,7 @@ namespace {
const bool FakeSplit = false;
// Different node types, used as template parameter
enum NodeType { NonPV, PV };
enum NodeType { Root, PV, NonPV, SplitPointPV, SplitPointNonPV };
// RootMove struct is used for moves at the root of the tree. For each root
// move, we store two scores, a node count, and a PV (really a refutation
@ -189,9 +189,9 @@ namespace {
// Reduction lookup tables (initialized at startup) and their access function
int8_t Reductions[2][64][64]; // [pv][depth][moveNumber]
template <NodeType PV> inline Depth reduction(Depth d, int mn) {
template <bool PvNode> inline Depth reduction(Depth d, int mn) {
return (Depth) Reductions[PV][Min(d / ONE_PLY, 63)][Min(mn, 63)];
return (Depth) Reductions[PvNode][Min(d / ONE_PLY, 63)][Min(mn, 63)];
}
// Easy move margin. An easy move candidate must be at least this much
@ -233,20 +233,13 @@ namespace {
Move id_loop(Position& pos, Move searchMoves[], Move* ponderMove);
template <NodeType PvNode, bool SpNode, bool Root>
template <NodeType NT>
Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth);
template <NodeType PvNode>
template <NodeType NT>
Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth);
template <NodeType PvNode>
inline Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth) {
return depth < ONE_PLY ? qsearch<PvNode>(pos, ss, alpha, beta, DEPTH_ZERO)
: search<PvNode, false, false>(pos, ss, alpha, beta, depth);
}
template <NodeType PvNode>
template <bool PvNode>
Depth extension(const Position& pos, Move m, bool captureOrPromotion, bool moveIsCheck, bool* dangerous);
bool check_is_dangerous(Position &pos, Move move, Value futilityBase, Value beta, Value *bValue);
@ -304,8 +297,8 @@ void init_search() {
{
double pvRed = log(double(hd)) * log(double(mc)) / 3.0;
double nonPVRed = 0.33 + log(double(hd)) * log(double(mc)) / 2.25;
Reductions[PV][hd][mc] = (int8_t) ( pvRed >= 1.0 ? floor( pvRed * int(ONE_PLY)) : 0);
Reductions[NonPV][hd][mc] = (int8_t) (nonPVRed >= 1.0 ? floor(nonPVRed * int(ONE_PLY)) : 0);
Reductions[1][hd][mc] = (int8_t) ( pvRed >= 1.0 ? floor( pvRed * int(ONE_PLY)) : 0);
Reductions[0][hd][mc] = (int8_t) (nonPVRed >= 1.0 ? floor(nonPVRed * int(ONE_PLY)) : 0);
}
// Init futility margins array
@ -541,7 +534,7 @@ namespace {
// research with bigger window until not failing high/low anymore.
do {
// Search starting from ss+1 to allow calling update_gains()
value = search<PV, false, true>(pos, ss+1, alpha, beta, depth * ONE_PLY);
value = search<Root>(pos, ss+1, alpha, beta, depth * ONE_PLY);
// Write PV back to transposition table in case the relevant entries
// have been overwritten during the search.
@ -663,9 +656,13 @@ namespace {
// all this work again. We also don't need to store anything to the hash table
// here: This is taken care of after we return from the split point.
template <NodeType PvNode, bool SpNode, bool Root>
template <NodeType NT>
Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth) {
const bool PvNode = (NT == PV || NT == Root || NT == SplitPointPV);
const bool SpNode = (NT == SplitPointPV || NT == SplitPointNonPV);
const bool RootNode = (NT == Root);
assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE);
assert(beta > alpha && beta <= VALUE_INFINITE);
assert(PvNode || alpha == beta - 1);
@ -703,7 +700,7 @@ namespace {
threatMove = sp->threatMove;
goto split_point_start;
}
else if (Root)
else if (RootNode)
bestValue = alpha;
// Step 1. Initialize node and poll. Polling can abort search
@ -721,7 +718,7 @@ namespace {
if (( StopRequest
|| Threads[threadID].cutoff_occurred()
|| pos.is_draw()
|| ss->ply > PLY_MAX) && !Root)
|| ss->ply > PLY_MAX) && !RootNode)
return VALUE_DRAW;
// Step 3. Mate distance pruning
@ -742,7 +739,7 @@ namespace {
// At PV nodes we check for exact scores, while at non-PV nodes we check for
// a fail high/low. Biggest advantage at probing at PV nodes is to have a
// smooth experience in analysis mode.
if ( !Root
if ( !RootNode
&& tte
&& (PvNode ? tte->depth() >= depth && tte->type() == VALUE_TYPE_EXACT
: ok_to_use_TT(tte, depth, beta, ss->ply)))
@ -821,7 +818,8 @@ namespace {
pos.do_null_move(st);
(ss+1)->skipNullMove = true;
nullValue = -search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY);
nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
: - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY);
(ss+1)->skipNullMove = false;
pos.undo_null_move();
@ -868,7 +866,7 @@ namespace {
Depth d = (PvNode ? depth - 2 * ONE_PLY : depth / 2);
ss->skipNullMove = true;
search<PvNode>(pos, ss, alpha, beta, d);
search<PvNode ? PV : NonPV>(pos, ss, alpha, beta, d);
ss->skipNullMove = false;
tte = TT.probe(posKey);
@ -878,12 +876,12 @@ namespace {
split_point_start: // At split points actual search starts from here
// Initialize a MovePicker object for the current position
MovePickerExt<SpNode, Root> mp(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));
MovePickerExt<SpNode, RootNode> mp(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));
CheckInfo ci(pos);
Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
ss->bestMove = MOVE_NONE;
futilityBase = ss->eval + ss->evalMargin;
singularExtensionNode = !Root
singularExtensionNode = !RootNode
&& !SpNode
&& depth >= SingularExtensionDepth[PvNode]
&& ttMove != MOVE_NONE
@ -919,7 +917,7 @@ split_point_start: // At split points actual search starts from here
else
moveCount++;
if (Root)
if (RootNode)
{
// This is used by time management
FirstRootMove = (moveCount == 1);
@ -941,7 +939,7 @@ split_point_start: // At split points actual search starts from here
}
// At Root and at first iteration do a PV search on all the moves to score root moves
isPvMove = (PvNode && moveCount <= (Root ? depth <= ONE_PLY ? 1000 : MultiPV : 1));
isPvMove = (PvNode && moveCount <= (RootNode ? depth <= ONE_PLY ? 1000 : MultiPV : 1));
givesCheck = pos.move_gives_check(move, ci);
captureOrPromotion = pos.move_is_capture(move) || move_is_promotion(move);
@ -999,7 +997,7 @@ split_point_start: // At split points actual search starts from here
// Value based pruning
// We illogically ignore reduction condition depth >= 3*ONE_PLY for predicted depth,
// but fixing this made program slightly weaker.
Depth predictedDepth = newDepth - reduction<NonPV>(depth, moveCount);
Depth predictedDepth = newDepth - reduction<PvNode>(depth, moveCount);
futilityValueScaled = futilityBase + futility_margin(predictedDepth, moveCount)
+ H.gain(pos.piece_on(move_from(move)), move_to(move));
@ -1049,10 +1047,11 @@ split_point_start: // At split points actual search starts from here
if (isPvMove)
{
// Aspiration window is disabled in multi-pv case
if (Root && MultiPV > 1)
if (RootNode && MultiPV > 1)
alpha = -VALUE_INFINITE;
value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth);
value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
: - search<PV>(pos, ss+1, -beta, -alpha, newDepth);
}
else
{
@ -1072,8 +1071,8 @@ split_point_start: // At split points actual search starts from here
if (ss->reduction)
{
Depth d = newDepth - ss->reduction;
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d);
value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO)
: - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d);
doFullDepthSearch = (value > alpha);
}
ss->reduction = DEPTH_ZERO; // Restore original reduction
@ -1092,7 +1091,8 @@ split_point_start: // At split points actual search starts from here
ss->reduction = 3 * ONE_PLY;
Value rAlpha = alpha - 300;
Depth d = newDepth - ss->reduction;
value = -search<NonPV>(pos, ss+1, -(rAlpha+1), -rAlpha, d);
value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(rAlpha+1), -rAlpha, DEPTH_ZERO)
: - search<NonPV>(pos, ss+1, -(rAlpha+1), -rAlpha, d);
doFullDepthSearch = (value > rAlpha);
ss->reduction = DEPTH_ZERO; // Restore original reduction
}
@ -1101,13 +1101,15 @@ split_point_start: // At split points actual search starts from here
if (doFullDepthSearch)
{
alpha = SpNode ? sp->alpha : alpha;
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth);
value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO)
: - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth);
// Step extra. pv search (only in PV nodes)
// Search only for possible new PV nodes, if instead value >= beta then
// parent node fails low with value <= alpha and tries another move.
if (PvNode && value > alpha && (Root || value < beta))
value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth);
if (PvNode && value > alpha && (RootNode || value < beta))
value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
: - search<PV>(pos, ss+1, -beta, -alpha, newDepth);
}
}
@ -1131,7 +1133,7 @@ split_point_start: // At split points actual search starts from here
if (SpNode)
sp->bestValue = value;
if (!Root && value > alpha)
if (!RootNode && value > alpha)
{
if (PvNode && value < beta) // We want always alpha < beta
{
@ -1153,7 +1155,7 @@ split_point_start: // At split points actual search starts from here
}
}
if (Root)
if (RootNode)
{
// Finished searching the move. If StopRequest is true, the search
// was aborted because the user interrupted the search or because we
@ -1192,10 +1194,10 @@ split_point_start: // At split points actual search starts from here
else
mp.rm->pv_score = -VALUE_INFINITE;
} // Root
} // RootNode
// Step 18. Check for split
if ( !Root
if ( !RootNode
&& !SpNode
&& depth >= Threads.min_split_depth()
&& bestValue < beta
@ -1255,9 +1257,12 @@ split_point_start: // At split points actual search starts from here
// search function when the remaining depth is zero (or, to be more precise,
// less than ONE_PLY).
template <NodeType PvNode>
template <NodeType NT>
Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth) {
const bool PvNode = (NT == PV);
assert(NT == PV || NT == NonPV);
assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE);
assert(beta >= -VALUE_INFINITE && beta <= VALUE_INFINITE);
assert(PvNode || alpha == beta - 1);
@ -1417,7 +1422,7 @@ split_point_start: // At split points actual search starts from here
// Make and search the move
pos.do_move(move, st, ci, givesCheck);
value = -qsearch<PvNode>(pos, ss+1, -beta, -alpha, depth-ONE_PLY);
value = -qsearch<NT>(pos, ss+1, -beta, -alpha, depth-ONE_PLY);
pos.undo_move(move);
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
@ -1596,7 +1601,7 @@ split_point_start: // At split points actual search starts from here
// any case are marked as 'dangerous'. Note that also if a move is not
// extended, as example because the corresponding UCI option is set to zero,
// the move is marked as 'dangerous' so, at least, we avoid to prune it.
template <NodeType PvNode>
template <bool PvNode>
Depth extension(const Position& pos, Move m, bool captureOrPromotion,
bool moveIsCheck, bool* dangerous) {
@ -2178,9 +2183,9 @@ void ThreadsManager::idle_loop(int threadID, SplitPoint* sp) {
(ss+1)->sp = tsp;
if (tsp->pvNode)
search<PV, true, false>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
search<SplitPointPV>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
else
search<NonPV, true, false>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
search<SplitPointNonPV>(pos, ss+1, tsp->alpha, tsp->beta, tsp->depth);
assert(threads[threadID].state == Thread::SEARCHING);