X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=af01050212ceca3ef4c9a4225c4952ede31b683b;hp=a1e1cea5c9c6a948977728575ee1ddb638e8a01c;hb=58aee9a9ea522cd9eb40b6a4cc888e37e2da54c5;hpb=4fc773454759081c2cd921e460d542f2dfd4aa24 diff --git a/src/search.cpp b/src/search.cpp index a1e1cea5..af010502 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -296,9 +296,12 @@ namespace { Value bestValue, alpha, beta, delta; memset(ss-1, 0, 4 * sizeof(Stack)); - depth = BestMoveChanges = 0; - bestValue = delta = -VALUE_INFINITE; (ss-1)->currentMove = MOVE_NULL; // Hack to skip update gains + + depth = BestMoveChanges = 0; + bestValue = delta = alpha = -VALUE_INFINITE; + beta = VALUE_INFINITE; + TT.new_search(); History.clear(); Gains.clear(); @@ -328,17 +331,12 @@ namespace { // MultiPV loop. We perform a full root search for each PV line for (PVIdx = 0; PVIdx < PVSize; PVIdx++) { - // Set aspiration window default width - if (depth >= 5 && abs(RootMoves[PVIdx].prevScore) < VALUE_KNOWN_WIN) + // Reset aspiration window starting size + if (depth >= 5) { delta = Value(16); - alpha = RootMoves[PVIdx].prevScore - delta; - beta = RootMoves[PVIdx].prevScore + delta; - } - else - { - alpha = -VALUE_INFINITE; - beta = VALUE_INFINITE; + alpha = std::max(RootMoves[PVIdx].prevScore - delta,-VALUE_INFINITE); + beta = std::min(RootMoves[PVIdx].prevScore + delta, VALUE_INFINITE); } // Start with a small aspiration window and, in case of fail high/low, @@ -366,35 +364,28 @@ namespace { if (Signals.stop) return; - // In case of failing high/low increase aspiration window and + // In case of failing low/high increase aspiration window and // research, otherwise exit the loop. - if (bestValue > alpha && bestValue < beta) - break; - - // Give some update (without cluttering the UI) before to research - if (Time::now() - SearchTime > 3000) - sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl; - - if (abs(bestValue) >= VALUE_KNOWN_WIN) + if (bestValue <= alpha) { - alpha = -VALUE_INFINITE; - beta = VALUE_INFINITE; + alpha = std::max(bestValue - delta, -VALUE_INFINITE); + + Signals.failedLowAtRoot = true; + Signals.stopOnPonderhit = false; } else if (bestValue >= beta) - { - beta += delta; - delta += delta / 2; - } + beta = std::min(bestValue + delta, VALUE_INFINITE); + else - { - Signals.failedLowAtRoot = true; - Signals.stopOnPonderhit = false; + break; - alpha -= delta; - delta += delta / 2; - } + delta += delta / 2; assert(alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE); + + // Give some update (without cluttering the UI) before to research + if (Time::now() - SearchTime > 3000) + sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl; } // Sort the PV lines searched so far and update the GUI @@ -521,7 +512,7 @@ namespace { assert(splitPoint->bestValue > -VALUE_INFINITE && splitPoint->moveCount > 0); - goto split_point_start; + goto moves_loop; } bestValue = -VALUE_INFINITE; @@ -590,7 +581,10 @@ namespace { // Step 5. Evaluate the position statically and update parent's gain statistics if (inCheck) + { ss->staticEval = ss->evalMargin = eval = VALUE_NONE; + goto moves_loop; + } else if (tte) { @@ -627,7 +621,6 @@ namespace { // Step 6. Razoring (is omitted in PV nodes) if ( !PvNode && depth < 4 * ONE_PLY - && !inCheck && eval + razor_margin(depth) < beta && ttMove == MOVE_NONE && abs(beta) < VALUE_MATE_IN_MAX_PLY @@ -647,7 +640,6 @@ namespace { if ( !PvNode && !ss->skipNullMove && depth < 4 * ONE_PLY - && !inCheck && eval - futility_margin(depth, (ss-1)->futilityMoveCount) >= beta && abs(beta) < VALUE_MATE_IN_MAX_PLY && abs(eval) < VALUE_KNOWN_WIN @@ -658,7 +650,6 @@ namespace { if ( !PvNode && !ss->skipNullMove && depth > ONE_PLY - && !inCheck && eval >= beta && abs(beta) < VALUE_MATE_IN_MAX_PLY && pos.non_pawn_material(pos.side_to_move())) @@ -720,7 +711,6 @@ namespace { // prune the previous move. if ( !PvNode && depth >= 5 * ONE_PLY - && !inCheck && !ss->skipNullMove && abs(beta) < VALUE_MATE_IN_MAX_PLY) { @@ -749,7 +739,7 @@ namespace { // Step 10. Internal iterative deepening if ( depth >= (PvNode ? 5 * ONE_PLY : 8 * ONE_PLY) && ttMove == MOVE_NONE - && (PvNode || (!inCheck && ss->staticEval + Value(256) >= beta))) + && (PvNode || ss->staticEval + Value(256) >= beta)) { Depth d = depth - 2 * ONE_PLY - (PvNode ? DEPTH_ZERO : depth / 4); @@ -761,7 +751,7 @@ namespace { ttMove = tte ? tte->move() : MOVE_NONE; } -split_point_start: // At split points actual search starts from here +moves_loop: // When in check and at SpNode search starts from here Square prevMoveSq = to_sq((ss-1)->currentMove); Move countermoves[] = { Countermoves[pos.piece_on(prevMoveSq)][prevMoveSq].first, @@ -820,12 +810,7 @@ split_point_start: // At split points actual search starts from here givesCheck = pos.move_gives_check(move, ci); 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)); + || type_of(move) == CASTLE; // Step 12. Extend checks and, in PV nodes, also dangerous moves if (PvNode && dangerous) @@ -1156,8 +1141,7 @@ split_point_start: // At split points actual search starts from here ttDepth = InCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS : DEPTH_QS_NO_CHECKS; - // Transposition table lookup. At PV nodes, we don't use the TT for - // pruning, but only for move ordering. + // Transposition table lookup posKey = pos.key(); tte = TT.probe(posKey); ttMove = tte ? tte->move() : MOVE_NONE;