Depth depth, int ply, int threadID);
void sp_search(SplitPoint *sp, int threadID);
void sp_search_pv(SplitPoint *sp, int threadID);
- void init_node(const Position &pos, SearchStack ss[], int ply, int threadID);
+ void init_node(SearchStack ss[], int ply, int threadID);
void update_pv(SearchStack ss[], int ply);
void sp_update_pv(SearchStack *pss, SearchStack ss[], int ply);
bool connected_moves(const Position &pos, Move m1, Move m2);
// Initialize, and make an early exit in case of an aborted search,
// an instant draw, maximum ply reached, etc.
- init_node(pos, ss, ply, threadID);
+ init_node(ss, ply, threadID);
// After init_node() that calls poll()
if (AbortSearch || thread_should_stop(threadID))
// Initialize, and make an early exit in case of an aborted search,
// an instant draw, maximum ply reached, etc.
- init_node(pos, ss, ply, threadID);
+ init_node(ss, ply, threadID);
// After init_node() that calls poll()
if (AbortSearch || thread_should_stop(threadID))
&& !move_is_castle(move)
&& !move_is_killer(move, ss[ply]))
{
- // LMR dynamic reduction
- Depth R = (moveCount >= 2 * LMRNonPVMoves && depth > 7*OnePly ? 2*OnePly : OnePly);
-
- ss[ply].reduction = R;
- value = -search(pos, ss, -(beta-1), newDepth-R, ply+1, true, threadID);
+ ss[ply].reduction = OnePly;
+ value = -search(pos, ss, -(beta-1), newDepth-OnePly, ply+1, true, threadID);
}
else
value = beta; // Just to trigger next condition
// Initialize, and make an early exit in case of an aborted search,
// an instant draw, maximum ply reached, etc.
- init_node(pos, ss, ply, threadID);
+ init_node(ss, ply, threadID);
// After init_node() that calls poll()
if (AbortSearch || thread_should_stop(threadID))
return VALUE_DRAW;
// Transposition table lookup, only when not in PV
+ TTEntry* tte = NULL;
bool pvNode = (beta - alpha != 1);
if (!pvNode)
{
- const TTEntry* tte = TT.retrieve(pos);
+ tte = TT.retrieve(pos);
if (tte && ok_to_use_TT(tte, depth, beta, ply))
+ {
+ assert(tte->type() != VALUE_TYPE_EVAL);
+
return value_from_tt(tte->value(), ply);
+ }
}
// Evaluate the position statically
EvalInfo ei;
+ Value staticValue;
bool isCheck = pos.is_check();
- Value staticValue = (isCheck ? -VALUE_INFINITE : evaluate(pos, ei, threadID));
+ ei.futilityMargin = Value(0); // Manually initialize futilityMargin
+
+ if (isCheck)
+ staticValue = -VALUE_INFINITE;
+
+ else if (tte && tte->type() == VALUE_TYPE_EVAL)
+ {
+ // Use the cached evaluation score if possible
+ assert(tte->value() == evaluate(pos, ei, threadID));
+ assert(ei.futilityMargin == Value(0));
+
+ staticValue = tte->value();
+ }
+ else
+ staticValue = evaluate(pos, ei, threadID);
if (ply == PLY_MAX - 1)
return evaluate(pos, ei, threadID);
Value bestValue = staticValue;
if (bestValue >= beta)
+ {
+ // Store the score to avoid a future costly evaluation() call
+ if (!isCheck && !tte && ei.futilityMargin == 0)
+ TT.store(pos, value_to_tt(bestValue, ply), Depth(-127*OnePly), MOVE_NONE, VALUE_TYPE_EVAL);
+
return bestValue;
+ }
if (bestValue > alpha)
alpha = bestValue;
// Initialize a MovePicker object for the current position, and prepare
// to search the moves. Because the depth is <= 0 here, only captures,
// queen promotions and checks (only if depth == 0) will be generated.
- MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth, isCheck ? NULL : &ei);
+ MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth);
Move move;
int moveCount = 0;
Bitboard dcCandidates = mp.discovered_check_candidates();
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
// Update transposition table
- TT.store(pos, value_to_tt(bestValue, ply), depth, MOVE_NONE, VALUE_TYPE_EXACT);
+ if (!pvNode)
+ {
+ Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
+ if (bestValue < beta)
+ TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_UPPER);
+ else
+ TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_LOWER);
+ }
// Update killers only for good check moves
Move m = ss[ply].currentMove;
// NodesBetweenPolls nodes, init_node() also calls poll(), which polls
// for user input and checks whether it is time to stop the search.
- void init_node(const Position &pos, SearchStack ss[], int ply, int threadID) {
+ void init_node(SearchStack ss[], int ply, int threadID) {
assert(ply >= 0 && ply < PLY_MAX);
assert(threadID >= 0 && threadID < ActiveThreads);
|| ( !FailHigh && !fail_high_ply_1() && !Problem
&& t > 6*(MaxSearchTime + ExtraSearchTime));
- if ( (Iteration >= 2 && (!InfiniteSearch && overTime))
+ if ( (Iteration >= 3 && (!InfiniteSearch && overTime))
|| (ExactMaxTime && t >= ExactMaxTime)
|| (Iteration >= 3 && MaxNodes && nodes_searched() >= MaxNodes))
AbortSearch = true;
void ponderhit() {
int t = current_search_time();
PonderSearch = false;
- if(Iteration >= 2 &&
+ if(Iteration >= 3 &&
(!InfiniteSearch && (StopOnPonderhit ||
t > AbsoluteMaxSearchTime ||
(RootMoveNumber == 1 &&