Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
template <NodeType PvNode>
- inline Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply) {
- return search<PvNode, false>(pos, ss, alpha, beta, depth, ply);
- }
+ Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
template <NodeType PvNode>
- Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
+ inline Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply) {
+
+ return depth < ONE_PLY ? qsearch<PvNode>(pos, ss, alpha, beta, DEPTH_ZERO, ply)
+ : search<PvNode, false>(pos, ss, alpha, beta, depth, ply);
+ }
template <NodeType PvNode>
Depth extension(const Position& pos, Move m, bool captureOrPromotion, bool moveIsCheck, bool singleEvasion, bool mateThreat, bool* dangerous);
int64_t nodes;
Move move;
Depth depth, ext, newDepth;
- Value value, evalMargin, alpha, beta;
+ Value value, alpha, beta;
bool isCheck, moveIsCheck, captureOrPromotion, dangerous;
int researchCountFH, researchCountFL;
// Step 5. Evaluate the position statically
// At root we do this only to get reference value for child nodes
- ss->eval = isCheck ? VALUE_NONE : evaluate(pos, evalMargin);
+ ss->evalMargin = VALUE_NONE;
+ ss->eval = isCheck ? VALUE_NONE : evaluate(pos, ss->evalMargin);
// Step 6. Razoring (omitted at root)
// Step 7. Static null move pruning (omitted at root)
Key posKey;
Move ttMove, move, excludedMove, threatMove;
Depth ext, newDepth;
- Value bestValue, value, evalMargin, oldAlpha;
+ Value bestValue, value, oldAlpha;
Value refinedValue, nullValue, futilityBase, futilityValueScaled; // Non-PV specific
bool isCheck, singleEvasion, singularExtensionNode, moveIsCheck, captureOrPromotion, dangerous;
bool mateThreat = false;
{
sp = ss->sp;
tte = NULL;
- evalMargin = VALUE_ZERO;
ttMove = excludedMove = MOVE_NONE;
threatMove = sp->threatMove;
mateThreat = sp->mateThreat;
// Step 5. Evaluate the position statically and
// update gain statistics of parent move.
if (isCheck)
- ss->eval = evalMargin = VALUE_NONE;
+ ss->eval = ss->evalMargin = VALUE_NONE;
else if (tte)
{
assert(tte->static_value() != VALUE_NONE);
ss->eval = tte->static_value();
- evalMargin = tte->static_value_margin();
+ ss->evalMargin = tte->static_value_margin();
refinedValue = refine_eval(tte, ss->eval, ply);
}
else
{
- refinedValue = ss->eval = evaluate(pos, evalMargin);
- TT.store(posKey, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, MOVE_NONE, ss->eval, evalMargin);
+ refinedValue = ss->eval = evaluate(pos, ss->evalMargin);
+ TT.store(posKey, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, MOVE_NONE, ss->eval, ss->evalMargin);
}
// Save gain for the parent non-capture move
pos.do_null_move(st);
(ss+1)->skipNullMove = true;
-
- nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
- : - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY, ply+1);
+ nullValue = -search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY, ply+1);
(ss+1)->skipNullMove = false;
pos.undo_null_move();
// Initialize a MovePicker object for the current position
// FIXME currently MovePicker() c'tor is needless called also in SplitPoint
- MovePicker mpBase = MovePicker(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));
+ MovePicker mpBase(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));
MovePicker& mp = SpNode ? *sp->mp : mpBase;
CheckInfo ci(pos);
ss->bestMove = MOVE_NONE;
singleEvasion = !SpNode && isCheck && mp.number_of_evasions() == 1;
- futilityBase = ss->eval + evalMargin;
+ futilityBase = ss->eval + ss->evalMargin;
singularExtensionNode = !SpNode
&& depth >= SingularExtensionDepth[PvNode]
&& tte
// Step extra. pv search (only in PV nodes)
// The first move in list is the expected PV
if (!SpNode && PvNode && moveCount == 1)
- value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
- : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
+ value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
else
{
// Step 14. Reduced depth search
{
alpha = SpNode ? sp->alpha : alpha;
Depth d = newDepth - ss->reduction;
- value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
- : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, ply+1);
+ value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, ply+1);
doFullDepthSearch = (value > alpha);
}
if (doFullDepthSearch)
{
alpha = SpNode ? sp->alpha : alpha;
- value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
- : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1);
+ value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1);
// 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 && value < beta)
- value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
- : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
+ value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
}
}
sp->alpha = value;
}
- if (!SpNode && value == value_mate_in(ply + 1))
+ if (value == value_mate_in(ply + 1))
ss->mateKiller = move;
ss->bestMove = move;
ValueType vt = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT);
move = (bestValue <= oldAlpha ? MOVE_NONE : ss->bestMove);
- TT.store(posKey, value_to_tt(bestValue, ply), vt, depth, move, ss->eval, evalMargin);
+ TT.store(posKey, value_to_tt(bestValue, ply), vt, depth, move, ss->eval, ss->evalMargin);
// Update killers and history only for non capture moves that fails high
if ( bestValue >= beta
#if !defined(_MSC_VER)
pthread_t pthread[1];
ok = (pthread_create(pthread, NULL, init_thread, (void*)(&i)) == 0);
+ pthread_detach(pthread[0]);
#else
ok = (CreateThread(NULL, 0, init_thread, (LPVOID)(&i), 0, NULL) != NULL);
#endif
// Initialize search stack
init_ss_array(ss, PLY_MAX_PLUS_2);
- ss[0].eval = VALUE_NONE;
+ ss[0].eval = ss[0].evalMargin = VALUE_NONE;
count = 0;
// Generate all legal moves