X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=fb5d375e8e591a58a91fb0e9afe8a147846b426c;hp=f71b54bc7d0fa6e22dc539b3b25f48d53c2ac666;hb=f8224fc7d31324376c36c4788f1935a341d2187b;hpb=161c6b025e763d6bcc8339a614be312f2b173437 diff --git a/src/search.cpp b/src/search.cpp index f71b54bc..fb5d375e 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -48,6 +48,7 @@ namespace Search { using std::string; using std::cout; using std::endl; +using Eval::evaluate; using namespace Search; namespace { @@ -135,9 +136,9 @@ 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[]); @@ -251,6 +252,7 @@ void Search::think() { Position& pos = RootPosition; Chess960 = pos.is_chess960(); + Eval::RootColor = pos.side_to_move(); SearchTime.restart(); TimeMgr.init(Limits, pos.startpos_ply_counter()); TT.new_search(); @@ -276,17 +278,6 @@ void Search::think() { } } - // Read UCI options: GUI could change UCI parameters during the game - read_evaluation_uci_options(pos.side_to_move()); - Threads.read_uci_options(); - - TT.set_size(Options["Hash"]); - if (Options["Clear Hash"]) - { - Options["Clear Hash"] = false; - TT.clear(); - } - UCIMultiPV = Options["MultiPV"]; SkillLevel = Options["Skill Level"]; @@ -551,7 +542,7 @@ namespace { 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; @@ -573,6 +564,7 @@ namespace { { tte = NULL; ttMove = excludedMove = MOVE_NONE; + ttValue = VALUE_ZERO; sp = ss->sp; bestMove = sp->bestMove; threatMove = sp->threatMove; @@ -622,19 +614,19 @@ namespace { 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]) @@ -642,7 +634,7 @@ namespace { 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 @@ -654,7 +646,7 @@ namespace { 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 { @@ -887,8 +879,6 @@ split_point_start: // At split points actual search starts from here && 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); @@ -1148,7 +1138,7 @@ split_point_start: // At split points actual search starts from here 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; @@ -1172,11 +1162,12 @@ split_point_start: // At split points actual search starts from here // 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 @@ -1344,14 +1335,14 @@ split_point_start: // At split points actual search starts from here kingAtt = pos.attacks_from(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); // Rule 1. Checks which give opponent's king at most one escape square are dangerous b = kingAtt & ~pos.pieces(them) & ~newAtt & ~(1ULL << to); - if (!(b && (b & (b - 1)))) + if (single_bit(b)) // Catches also !b return true; // Rule 2. Queen contact check is very dangerous @@ -1412,7 +1403,7 @@ split_point_start: // At split points actual search starts from here 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; @@ -1494,9 +1485,7 @@ split_point_start: // At split points actual search starts from here // 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) @@ -1510,12 +1499,10 @@ split_point_start: // At split points actual search starts from here // 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;