X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fsearch.cpp;h=697c8cfed1f3100eb25f80b7ab43cbb50c6c87fa;hb=3322349c1a3dbe2f4c42f84141745c4d94efde2e;hp=c2d35796231b0b9ebcb4a5645553e343a28d46b5;hpb=76e1e8fd39a08c0586259a76c880c3267cb85f62;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index c2d35796..697c8cfe 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -745,8 +745,8 @@ namespace { } // Set up the improving flag, which is true if current static evaluation is - // bigger than the previous static evaluation at our turn (if we were in - // check at our previous move we look at static evaluaion at move prior to it + // bigger than the previous static evaluation at our turn (if we were in + // check at our previous move we look at static evaluation at move prior to it // and if we were in check at move prior to it flag is set to true) and is // false otherwise. The improving flag is used in various pruning heuristics. improving = (ss-2)->staticEval != VALUE_NONE ? ss->staticEval > (ss-2)->staticEval @@ -985,32 +985,13 @@ moves_loop: // When in check, search starts here if ( !givesCheck && lmrDepth < 7 && !ss->inCheck - && ss->staticEval + 197 + 248 * lmrDepth + PieceValue[EG][pos.piece_on(to_sq(move))] + && ss->staticEval + 197 + 248 * lmrDepth + PieceValue[pos.piece_on(to_sq(move))] + captureHistory[movedPiece][to_sq(move)][type_of(pos.piece_on(to_sq(move)))] / 7 < alpha) continue; - Bitboard occupied; - // SEE based pruning (~11 Elo) - if (!pos.see_ge(move, occupied, Value(-205) * depth)) - { - if (depth < 2 - capture) - continue; - // Don't prune the move if opponent Queen/Rook is under discovered attack after the exchanges - // Don't prune the move if opponent King is under discovered attack after or during the exchanges - Bitboard leftEnemies = (pos.pieces(~us, KING, QUEEN, ROOK)) & occupied; - Bitboard attacks = 0; - occupied |= to_sq(move); - while (leftEnemies && !attacks) - { - Square sq = pop_lsb(leftEnemies); - attacks |= pos.attackers_to(sq, occupied) & pos.pieces(us) & occupied; - // Don't consider pieces that were already threatened/hanging before SEE exchanges - if (attacks && (sq != pos.square(~us) && (pos.attackers_to(sq, pos.pieces()) & pos.pieces(us)))) - attacks = 0; - } - if (!attacks) - continue; - } + // SEE based pruning for captures and checks (~11 Elo) + if (!pos.see_ge(move, Value(-205) * depth)) + continue; } else { @@ -1037,7 +1018,7 @@ moves_loop: // When in check, search starts here lmrDepth = std::max(lmrDepth, 0); // Prune moves with negative SEE (~4 Elo) - if (!pos.see_ge(move, Value(-27 * lmrDepth * lmrDepth - 16 * lmrDepth))) + if (!pos.see_ge(move, Value(-31 * lmrDepth * lmrDepth))) continue; } } @@ -1099,15 +1080,11 @@ moves_loop: // When in check, search starts here // If we are on a cutNode, reduce it based on depth (negative extension) (~1 Elo) else if (cutNode) - extension = depth > 8 && depth < 17 ? -3 : -1; + extension = depth < 17 ? -3 : -1; // If the eval of ttMove is less than value, we reduce it (negative extension) (~1 Elo) else if (ttValue <= value) extension = -1; - - // If the eval of ttMove is less than alpha, we reduce it (negative extension) (~1 Elo) - else if (ttValue <= alpha) - extension = -1; } // Check extensions (~1 Elo) @@ -1375,8 +1352,9 @@ moves_loop: // When in check, search starts here // Bonus for prior countermove that caused the fail low else if (!priorCapture && prevSq != SQ_NONE) { - int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 113 * depth) + ((ss-1)->moveCount > 12); + int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 800) + ((ss-1)->moveCount > 12); update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus); + thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << stat_bonus(depth) * bonus / 2; } if (PvNode) @@ -1413,6 +1391,18 @@ moves_loop: // When in check, search starts here assert(PvNode || (alpha == beta - 1)); assert(depth <= 0); + // Check if we have an upcoming move that draws by repetition, or + // if the opponent had an alternative move earlier to this position. + if ( depth < 0 + && pos.rule50_count() >= 3 + && alpha < VALUE_DRAW + && pos.has_game_cycle(ss->ply)) + { + alpha = value_draw(pos.this_thread()); + if (alpha >= beta) + return alpha; + } + Move pv[MAX_PLY+1]; StateInfo st; ASSERT_ALIGNED(&st, Eval::NNUE::CacheLineSize); @@ -1499,7 +1489,7 @@ moves_loop: // When in check, search starts here if (bestValue > alpha) alpha = bestValue; - futilityBase = bestValue + 200; + futilityBase = std::min(ss->staticEval, bestValue) + 200; } const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory, @@ -1545,7 +1535,7 @@ moves_loop: // When in check, search starts here if (moveCount > 2) continue; - futilityValue = futilityBase + PieceValue[EG][pos.piece_on(to_sq(move))]; + futilityValue = futilityBase + PieceValue[pos.piece_on(to_sq(move))]; if (futilityValue <= alpha) { @@ -1793,7 +1783,7 @@ moves_loop: // When in check, search starts here // RootMoves are already sorted by score in descending order Value topScore = rootMoves[0].score; - int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValueMg); + int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValue); int maxScore = -VALUE_INFINITE; double weakness = 120 - 2 * level;