X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=882fee6f0ee8ec5940c54b2601f085581dd88918;hp=4592ac084ebc56d60a59b83415167bd2f75af146;hb=2a14123550eb6ebce6be3a0c4d3938e533e748b2;hpb=b638f6b0354ea124dc80e5e38189474d34141e2d diff --git a/src/search.cpp b/src/search.cpp index 4592ac08..882fee6f 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1101,14 +1101,13 @@ namespace { tte = TT.retrieve(pos.get_key()); } - // Step 10. Loop through moves - // Loop through all legal moves until no moves remain or a beta cutoff occurs - // Initialize a MovePicker object for the current position mateThreat = pos.has_mate_threat(opposite_color(pos.side_to_move())); MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply]); CheckInfo ci(pos); + // Step 10. Loop through moves + // Loop through all legal moves until no moves remain or a beta cutoff occurs while ( alpha < beta && (move = mp.get_next_move()) != MOVE_NONE && !TM.thread_should_stop(threadID)) @@ -1325,12 +1324,12 @@ namespace { } // Step 6. Razoring - if ( !value_is_mate(beta) + if ( refinedValue < beta - razor_margin(depth) + && ttMove == MOVE_NONE + && ss[ply - 1].currentMove != MOVE_NULL + && depth < RazorDepth && !isCheck - && depth < RazorDepth - && refinedValue < beta - razor_margin(depth) - && ss[ply - 1].currentMove != MOVE_NULL - && ttMove == MOVE_NONE + && !value_is_mate(beta) && !pos.has_pawn_on_7th(pos.side_to_move())) { Value rbeta = beta - razor_margin(depth); @@ -1343,11 +1342,13 @@ namespace { // Step 7. Static null move pruning // We're betting that the opponent doesn't have a move that will reduce - // the score by more than fuility_margin(depth) if we do a null move. - if ( !isCheck - && allowNullmove - && depth < RazorDepth - && refinedValue - futility_margin(depth, 0) >= beta) + // the score by more than futility_margin(depth) if we do a null move. + if ( allowNullmove + && depth < RazorDepth + && !isCheck + && !value_is_mate(beta) + && ok_to_do_nullmove(pos) + && refinedValue >= beta + futility_margin(depth, 0)) return refinedValue - futility_margin(depth, 0); // Step 8. Null move search with verification search @@ -1363,8 +1364,6 @@ namespace { { ss[ply].currentMove = MOVE_NULL; - pos.do_null_move(st); - // Null move dynamic reduction based on depth int R = 3 + (depth >= 5 * OnePly ? depth / 8 : 0); @@ -1372,19 +1371,25 @@ namespace { if (refinedValue - beta > PawnValueMidgame) R++; + pos.do_null_move(st); + nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID); pos.undo_null_move(); if (nullValue >= beta) { + // Do not return unproven mate scores + if (nullValue >= value_mate_in(PLY_MAX)) + nullValue = beta; + if (depth < 6 * OnePly) - return beta; + return nullValue; // Do zugzwang verification search Value v = search(pos, ss, beta, depth-5*OnePly, ply, false, threadID); if (v >= beta) - return beta; + return nullValue; } else { // The null move failed low, which means that we may be faced with // some kind of threat. If the previous move was reduced, check if @@ -1414,13 +1419,12 @@ namespace { tte = TT.retrieve(posKey); } - // Step 10. Loop through moves - // Loop through all legal moves until no moves remain or a beta cutoff occurs - // Initialize a MovePicker object for the current position MovePicker mp = MovePicker(pos, ttMove, depth, H, &ss[ply], beta); CheckInfo ci(pos); + // Step 10. Loop through moves + // Loop through all legal moves until no moves remain or a beta cutoff occurs while ( bestValue < beta && (move = mp.get_next_move()) != MOVE_NONE && !TM.thread_should_stop(threadID)) @@ -1443,7 +1447,7 @@ namespace { if ( depth >= SingularExtensionDepthAtNonPVNodes && tte && move == tte->move() - && !excludedMove // Do not allow recursive single-reply search + && !excludedMove // Do not allow recursive singular extension search && ext < OnePly && is_lower_bound(tte->type()) && tte->depth() >= depth - 3 * OnePly) @@ -1493,8 +1497,8 @@ namespace { // Step 13. Make the move pos.do_move(move, st, ci, moveIsCheck); - // Step 14. Reduced search - // if the move fails high will be re-searched at full depth. + // Step 14. Reduced search, if the move fails high + // will be re-searched at full depth. bool doFullDepthSearch = true; if ( depth >= 3*OnePly @@ -1548,11 +1552,11 @@ namespace { } // Step 19. Check for mate and stalemate - // All legal moves have been searched and if there were + // All legal moves have been searched and if there are // no legal moves, it must be mate or stalemate. - // If one move was excluded return fail low. + // If one move was excluded return fail low score. if (!moveCount) - return excludedMove ? beta - 1 : (pos.is_check() ? value_mated_in(ply) : VALUE_DRAW); + return excludedMove ? beta - 1 : (isCheck ? value_mated_in(ply) : VALUE_DRAW); // Step 20. Update tables // If the search is not aborted, update the transposition table, @@ -1672,8 +1676,7 @@ namespace { enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame; futilityBase = staticValue + FutilityMarginQS + ei.futilityMargin[pos.side_to_move()]; - // Loop through the moves until no moves remain or a beta cutoff - // occurs. + // Loop through the moves until no moves remain or a beta cutoff occurs while ( alpha < beta && (move = mp.get_next_move()) != MOVE_NONE) { @@ -1742,7 +1745,7 @@ namespace { // All legal moves have been searched. A special case: If we're in check // and no legal moves were found, it is checkmate. - if (!moveCount && pos.is_check()) // Mate! + if (!moveCount && isCheck) // Mate! return value_mated_in(ply); // Update transposition table