X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=a3d8781889a690e15e0b91c4044c0243245f90d1;hp=4fd6c899de47446b182807e98d3314fb5516ddc7;hb=189b6fc270f91f4111c1a8049c97455093f8be97;hpb=bbaef048cdef6096e35ec33e6ce70931b719b3ae diff --git a/src/search.cpp b/src/search.cpp index 4fd6c899..a3d87818 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -104,36 +104,11 @@ 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 ttValue, Value beta); bool connected_threat(const Position& pos, Move m, Move threat); Value refine_eval(const TTEntry* tte, Value ttValue, Value defaultEval); Move do_skill_level(); string uci_pv(const Position& pos, int depth, Value alpha, Value beta); - // is_dangerous() checks whether a move belongs to some classes of known - // 'dangerous' moves so that we avoid to prune it. - FORCE_INLINE bool is_dangerous(const Position& pos, Move m, bool captureOrPromotion) { - - // Castle move? - if (type_of(m) == CASTLE) - return true; - - // Passed pawn move? - if ( type_of(pos.piece_moved(m)) == PAWN - && pos.pawn_is_passed(pos.side_to_move(), to_sq(m))) - return true; - - // Entering a pawn endgame? - if ( captureOrPromotion - && type_of(pos.piece_on(to_sq(m))) != PAWN - && type_of(m) == NORMAL - && ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) - - PieceValue[Mg][pos.piece_on(to_sq(m))] == VALUE_ZERO)) - return true; - - return false; - } - } // namespace @@ -199,8 +174,9 @@ void Search::think() { Position& pos = RootPosition; Chess960 = pos.is_chess960(); Eval::RootColor = pos.side_to_move(); - Eval::ValueDraw[ Eval::RootColor] = VALUE_DRAW - Eval::ContemptFactor; - Eval::ValueDraw[~Eval::RootColor] = VALUE_DRAW + Eval::ContemptFactor; + int scaledCF = Eval::ContemptFactor * MaterialTable::game_phase(pos) / PHASE_MIDGAME; + Eval::ValueDraw[ Eval::RootColor] = VALUE_DRAW - Value(scaledCF); + Eval::ValueDraw[~Eval::RootColor] = VALUE_DRAW + Value(scaledCF); TimeMgr.init(Limits, pos.startpos_ply_counter(), pos.side_to_move()); TT.new_search(); H.clear(); @@ -567,8 +543,11 @@ namespace { // 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, ttValue, beta))) + if ( !RootNode + && tte && tte->depth() >= depth + && ( PvNode ? tte->type() == BOUND_EXACT + : ttValue >= beta ? (tte->type() & BOUND_LOWER) + : (tte->type() & BOUND_UPPER))) { TT.refresh(tte); ss->currentMove = ttMove; // Can be MOVE_NONE @@ -800,10 +779,17 @@ split_point_start: // At split points actual search starts from here << " currmovenumber " << moveCount + PVIdx << sync_endl; } + ext = DEPTH_ZERO; captureOrPromotion = pos.is_capture_or_promotion(move); givesCheck = pos.move_gives_check(move, ci); - dangerous = givesCheck || is_dangerous(pos, move, captureOrPromotion); - ext = DEPTH_ZERO; + dangerous = givesCheck + || pos.is_passed_pawn_push(move) + || type_of(move) == CASTLE + || ( captureOrPromotion // Entering a pawn endgame? + && type_of(pos.piece_on(to_sq(move))) != PAWN + && type_of(move) == NORMAL + && ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) + - PieceValue[Mg][pos.piece_on(to_sq(move))] == VALUE_ZERO)); // Step 12. Extend checks and, in PV nodes, also dangerous moves if (PvNode && dangerous) @@ -843,7 +829,8 @@ split_point_start: // At split points actual search starts from here && !inCheck && !dangerous && move != ttMove - && (bestValue > VALUE_MATED_IN_MAX_PLY || bestValue == -VALUE_INFINITE)) + && (bestValue > VALUE_MATED_IN_MAX_PLY || ( bestValue == -VALUE_INFINITE + && alpha > VALUE_MATED_IN_MAX_PLY))) { // Move count based pruning if ( depth < 16 * ONE_PLY @@ -1110,7 +1097,10 @@ split_point_start: // At split points actual search starts from here // only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS. ttDepth = inCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS : DEPTH_QS_NO_CHECKS; - if (!PvNode && tte && can_return_tt(tte, ttDepth, ttValue, beta)) + if ( tte && tte->depth() >= ttDepth + && ( PvNode ? tte->type() == BOUND_EXACT + : ttValue >= beta ? (tte->type() & BOUND_LOWER) + : (tte->type() & BOUND_UPPER))) { ss->currentMove = ttMove; // Can be MOVE_NONE return ttValue; @@ -1434,20 +1424,6 @@ 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 v, Value beta) { - - return ( tte->depth() >= depth - || v >= std::max(VALUE_MATE_IN_MAX_PLY, beta) - || v < std::min(VALUE_MATED_IN_MAX_PLY, beta)) - - && ( ((tte->type() & BOUND_LOWER) && v >= beta) - || ((tte->type() & BOUND_UPPER) && v < beta)); - } - - // refine_eval() returns the transposition table score if possible, otherwise // falls back on static position evaluation.