X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fsearch.cpp;h=d0cedb82601d5b2526bdc608cd3f50106a00b793;hb=7903495b0a6a182f9b79dc70df2496beadf3adfd;hp=cd4bf3e4d26faad6a5f3a3c7f5e535d4bab13e14;hpb=c0136fb7286416be2ec179b4787f53d77023eeaf;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index cd4bf3e4..d0cedb82 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -302,8 +302,8 @@ namespace { bool value_is_mate(Value value); bool move_is_killer(Move m, SearchStack* ss); bool ok_to_do_nullmove(const Position& pos); - bool ok_to_prune(const Position& pos, Move m, Move threat); bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply); + bool connected_threat(const Position& pos, Move m, Move threat); Value refine_eval(const TTEntry* tte, Value defaultEval, int ply); void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount); void update_killers(Move m, SearchStack* ss); @@ -1229,6 +1229,11 @@ namespace { // Initialize a MovePicker object for the current position MovePicker mp = MovePicker(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta)); CheckInfo ci(pos); + bool singularExtensionNode = depth >= SingularExtensionDepth[PvNode] + && tte && tte->move() + && !excludedMove // Do not allow recursive singular extension search + && is_lower_bound(tte->type()) + && tte->depth() >= depth - 3 * OnePly; // Step 10. Loop through moves // Loop through all legal moves until no moves remain or a beta cutoff occurs @@ -1251,13 +1256,9 @@ namespace { // Singular extension search. We extend the TT move if its value is much better than // its siblings. To verify this we do a reduced search on all the other moves but the // ttMove, if result is lower then ttValue minus a margin then we extend ttMove. - if ( depth >= SingularExtensionDepth[PvNode] - && tte + if ( singularExtensionNode && move == tte->move() - && !excludedMove // Do not allow recursive singular extension search - && ext < OnePly - && is_lower_bound(tte->type()) - && tte->depth() >= depth - 3 * OnePly) + && ext < OnePly) { Value ttValue = value_from_tt(tte->value(), ply); @@ -1286,7 +1287,7 @@ namespace { { // Move count based pruning if ( moveCount >= futility_move_count(depth) - && ok_to_prune(pos, move, ss->threatMove) + && !(ss->threatMove && connected_threat(pos, move, ss->threatMove)) && bestValue > value_mated_in(PLY_MAX)) continue; @@ -1328,9 +1329,9 @@ namespace { ss->reduction = reduction(depth, moveCount); if (ss->reduction) { - Depth r = newDepth - ss->reduction; - value = r < OnePly ? -qsearch(pos, ss+1, -(alpha+1), -alpha, Depth(0), threadID) - : - search(pos, ss+1, -(alpha+1), -alpha, r, true, threadID); + Depth d = newDepth - ss->reduction; + value = d < OnePly ? -qsearch(pos, ss+1, -(alpha+1), -alpha, Depth(0), threadID) + : - search(pos, ss+1, -(alpha+1), -alpha, d, true, threadID); doFullDepthSearch = (value > alpha); } @@ -1346,12 +1347,12 @@ namespace { value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, true, threadID); doFullDepthSearch = (value > alpha); } + ss->reduction = Depth(0); // Restore original reduction } // Step 15. Full depth search if (doFullDepthSearch) { - ss->reduction = Depth(0); value = newDepth < OnePly ? -qsearch(pos, ss+1, -(alpha+1), -alpha, Depth(0), threadID) : - search(pos, ss+1, -(alpha+1), -alpha, newDepth, true, threadID); @@ -1681,7 +1682,7 @@ namespace { { // Move count based pruning if ( moveCount >= futility_move_count(sp->depth) - && ok_to_prune(pos, move, ss->threatMove) + && !(ss->threatMove && connected_threat(pos, move, ss->threatMove)) && sp->bestValue > value_mated_in(PLY_MAX)) { lock_grab(&(sp->lock)); @@ -1978,24 +1979,19 @@ namespace { } - // ok_to_prune() tests whether it is safe to forward prune a move. Only - // non-tactical moves late in the move list close to the leaves are - // candidates for pruning. + // connected_threat() tests whether it is safe to forward prune a move or if + // is somehow coonected to the threat move returned by null search. - bool ok_to_prune(const Position& pos, Move m, Move threat) { + bool connected_threat(const Position& pos, Move m, Move threat) { assert(move_is_ok(m)); - assert(threat == MOVE_NONE || move_is_ok(threat)); + assert(threat && move_is_ok(threat)); assert(!pos.move_is_check(m)); assert(!pos.move_is_capture_or_promotion(m)); assert(!pos.move_is_passed_pawn_push(m)); Square mfrom, mto, tfrom, tto; - // Prune if there isn't any threat move - if (threat == MOVE_NONE) - return true; - mfrom = move_from(m); mto = move_to(m); tfrom = move_from(threat); @@ -2003,7 +1999,7 @@ namespace { // Case 1: Don't prune moves which move the threatened piece if (mfrom == tto) - return false; + return true; // Case 2: If the threatened piece has value less than or equal to the // value of the threatening piece, don't prune move which defend it. @@ -2011,16 +2007,16 @@ namespace { && ( pos.midgame_value_of_piece_on(tfrom) >= pos.midgame_value_of_piece_on(tto) || pos.type_of_piece_on(tfrom) == KING) && pos.move_attacks_square(m, tto)) - return false; + return true; // Case 3: If the moving piece in the threatened move is a slider, don't // prune safe moves which block its ray. if ( piece_is_slider(pos.piece_on(tfrom)) && bit_is_set(squares_between(tfrom, tto), mto) && pos.see_sign(m) >= 0) - return false; + return true; - return true; + return false; }