using std::string;
using std::cout;
using std::endl;
+using Eval::evaluate;
using namespace Search;
namespace {
bool connected_moves(const Position& pos, Move m1, Move m2);
Value value_to_tt(Value v, int ply);
Value value_from_tt(Value v, int ply);
- bool can_return_tt(const TTEntry* tte, Depth depth, Value beta, int ply);
+ bool can_return_tt(const TTEntry* tte, Depth depth, Value ttValue, Value beta);
bool connected_threat(const Position& pos, Move m, Move threat);
- Value refine_eval(const TTEntry* tte, Value defaultEval, int ply);
+ Value refine_eval(const TTEntry* tte, Value ttValue, Value defaultEval);
Move do_skill_level();
string score_to_uci(Value v, Value alpha = -VALUE_INFINITE, Value beta = VALUE_INFINITE);
void pv_info_to_log(Position& pos, int depth, Value score, int time, Move pv[]);
Position& pos = RootPosition;
Chess960 = pos.is_chess960();
- EvalRootColor = pos.side_to_move();
+ Eval::RootColor = pos.side_to_move();
SearchTime.restart();
- TimeMgr.init(Limits, pos.startpos_ply_counter());
+ TimeMgr.init(Limits, pos.startpos_ply_counter(), pos.side_to_move());
TT.new_search();
H.clear();
log << "\nSearching: " << pos.to_fen()
<< "\ninfinite: " << Limits.infinite
<< " ponder: " << Limits.ponder
- << " time: " << Limits.time
- << " increment: " << Limits.increment
- << " moves to go: " << Limits.movesToGo
+ << " time: " << Limits.times[pos.side_to_move()]
+ << " increment: " << Limits.incs[pos.side_to_move()]
+ << " moves to go: " << Limits.movestogo
<< endl;
}
- Threads.set_size(Options["Threads"]);
+ Threads.wake_up();
// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
// We're ready to start searching. Call the iterative deepening loop function
id_loop(pos);
- // Stop timer and send all the slaves to sleep, if not already sleeping
- Threads.set_timer(0);
- Threads.set_size(1);
+ Threads.set_timer(0); // Stop timer
+ Threads.sleep();
if (Options["Use Search Log"])
{
ss->currentMove = MOVE_NULL; // Hack to skip update gains
// Iterative deepening loop until requested to stop or target depth reached
- while (!Signals.stop && ++depth <= MAX_PLY && (!Limits.maxDepth || depth <= Limits.maxDepth))
+ while (!Signals.stop && ++depth <= MAX_PLY && (!Limits.depth || depth <= Limits.depth))
{
// Save last iteration's scores before first PV line is searched and all
// the move scores but the (new) PV are set to -VALUE_INFINITE.
Move ttMove, move, excludedMove, bestMove, threatMove;
Depth ext, newDepth;
Bound bt;
- Value bestValue, value, oldAlpha;
+ Value bestValue, value, oldAlpha, ttValue;
Value refinedValue, nullValue, futilityBase, futilityValue;
bool isPvMove, inCheck, singularExtensionNode, givesCheck;
bool captureOrPromotion, dangerous, doFullDepthSearch;
{
tte = NULL;
ttMove = excludedMove = MOVE_NONE;
+ ttValue = VALUE_ZERO;
sp = ss->sp;
bestMove = sp->bestMove;
threatMove = sp->threatMove;
// Step 2. Check for aborted search and immediate draw
// Enforce node limit here. FIXME: This only works with 1 search thread.
- if (Limits.maxNodes && pos.nodes_searched() >= Limits.maxNodes)
+ if (Limits.nodes && pos.nodes_searched() >= Limits.nodes)
Signals.stop = true;
if (( Signals.stop
posKey = excludedMove ? pos.exclusion_key() : pos.key();
tte = TT.probe(posKey);
ttMove = RootNode ? RootMoves[PVIdx].pv[0] : tte ? tte->move() : MOVE_NONE;
+ ttValue = tte ? value_from_tt(tte->value(), ss->ply) : VALUE_ZERO;
// 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. We don't probe at Root nodes otherwise
// we should also update RootMoveList to avoid bogus output.
if (!RootNode && tte && (PvNode ? tte->depth() >= depth && tte->type() == BOUND_EXACT
- : can_return_tt(tte, depth, beta, ss->ply)))
+ : can_return_tt(tte, depth, ttValue, beta)))
{
TT.refresh(tte);
ss->currentMove = ttMove; // Can be MOVE_NONE
- value = value_from_tt(tte->value(), ss->ply);
- if ( value >= beta
+ if ( ttValue >= beta
&& ttMove
&& !pos.is_capture_or_promotion(ttMove)
&& ttMove != ss->killers[0])
ss->killers[1] = ss->killers[0];
ss->killers[0] = ttMove;
}
- return value;
+ return ttValue;
}
// Step 5. Evaluate the position statically and update parent's gain statistics
ss->eval = tte->static_value();
ss->evalMargin = tte->static_value_margin();
- refinedValue = refine_eval(tte, ss->eval, ss->ply);
+ refinedValue = refine_eval(tte, ttValue, ss->eval);
}
else
{
&& move == ttMove
&& pos.pl_move_is_legal(move, ci.pinned))
{
- Value ttValue = value_from_tt(tte->value(), ss->ply);
-
if (abs(ttValue) < VALUE_KNOWN_WIN)
{
Value rBeta = ttValue - int(depth);
StateInfo st;
Move ttMove, move, bestMove;
- Value bestValue, value, evalMargin, futilityValue, futilityBase;
+ Value ttValue, bestValue, value, evalMargin, futilityValue, futilityBase;
bool inCheck, enoughMaterial, givesCheck, evasionPrunable;
const TTEntry* tte;
Depth ttDepth;
// pruning, but only for move ordering.
tte = TT.probe(pos.key());
ttMove = (tte ? tte->move() : MOVE_NONE);
+ ttValue = tte ? value_from_tt(tte->value(),ss->ply) : VALUE_ZERO;
- if (!PvNode && tte && can_return_tt(tte, ttDepth, beta, ss->ply))
+ if (!PvNode && tte && can_return_tt(tte, ttDepth, ttValue, beta))
{
ss->currentMove = ttMove; // Can be MOVE_NONE
- return value_from_tt(tte->value(), ss->ply);
+ return ttValue;
}
// Evaluate the position statically
kingAtt = pos.attacks_from<KING>(ksq);
pc = pos.piece_moved(move);
- occ = pos.occupied_squares() & ~(1ULL << from) & ~(1ULL << ksq);
+ occ = pos.pieces() ^ from ^ ksq;
oldAtt = pos.attacks_from(pc, from, occ);
newAtt = pos.attacks_from(pc, to, occ);
ksq = pos.king_square(pos.side_to_move());
if ( piece_is_slider(p1)
&& (squares_between(t1, ksq) & f2)
- && (pos.attacks_from(p1, t1, pos.occupied_squares() ^ f2) & ksq))
+ && (pos.attacks_from(p1, t1, pos.pieces() ^ f2) & ksq))
return true;
return false;
// can_return_tt() returns true if a transposition table score can be used to
// cut-off at a given point in search.
- bool can_return_tt(const TTEntry* tte, Depth depth, Value beta, int ply) {
-
- Value v = value_from_tt(tte->value(), ply);
+ bool can_return_tt(const TTEntry* tte, Depth depth, Value v, Value beta) {
return ( tte->depth() >= depth
|| v >= std::max(VALUE_MATE_IN_MAX_PLY, beta)
// refine_eval() returns the transposition table score if possible, otherwise
// falls back on static position evaluation.
- Value refine_eval(const TTEntry* tte, Value defaultEval, int ply) {
+ Value refine_eval(const TTEntry* tte, Value v, Value defaultEval) {
assert(tte);
- Value v = value_from_tt(tte->value(), ply);
-
if ( ((tte->type() & BOUND_LOWER) && v >= defaultEval)
|| ((tte->type() & BOUND_UPPER) && v < defaultEval))
return v;
|| stillAtFirstMove;
if ( (Limits.use_time_management() && noMoreTime)
- || (Limits.maxTime && e >= Limits.maxTime))
+ || (Limits.movetime && e >= Limits.movetime))
Signals.stop = true;
}