X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fsearch.cpp;h=d419cd30ede15e192142b040de9caf14d8b8005c;hb=ee0371f86e319aa24bc1d32f02d9495eea79aa72;hp=8f074ca6923c6c21e68ceef098dd55dd5f63fa76;hpb=27efc5ac996ffc679395317c8bbb16aca996296c;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index 8f074ca6..d419cd30 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -66,14 +66,14 @@ namespace { enum NodeType { Root, PV, NonPV }; // Razoring and futility margin based on depth - inline Value razor_margin(Depth d) { return Value(512 + 32 * d); } - inline Value futility_margin(Depth d) { return Value(200 * d); } + Value razor_margin(Depth d) { return Value(512 + 32 * d); } + Value futility_margin(Depth d) { return Value(200 * d); } // Futility and reductions lookup tables, initialized at startup int FutilityMoveCounts[2][16]; // [improving][depth] Depth Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber] - template inline Depth reduction(bool i, Depth d, int mn) { + template Depth reduction(bool i, Depth d, int mn) { return Reductions[PvNode][i][std::min(d, 63 * ONE_PLY)][std::min(mn, 63)]; } @@ -181,6 +181,18 @@ void Search::init() { } +/// Search::reset() clears all search memory, to obtain reproducible search results + +void Search::reset () { + + TT.clear(); + History.clear(); + CounterMovesHistory.clear(); + Gains.clear(); + Countermoves.clear(); +} + + /// Search::perft() is our utility to verify move generation. All the leaf nodes /// up to the given depth are generated and counted and the sum returned. template @@ -339,10 +351,6 @@ namespace { beta = VALUE_INFINITE; TT.new_search(); - History.clear(); - CounterMovesHistory.clear(); - Gains.clear(); - Countermoves.clear(); size_t multiPV = Options["MultiPV"]; Skill skill(Options["Skill Level"]); @@ -850,7 +858,7 @@ moves_loop: // When in check and at SpNode search starts from here captureOrPromotion = pos.capture_or_promotion(move); givesCheck = type_of(move) == NORMAL && !ci.dcCandidates - ? ci.checkSq[type_of(pos.piece_on(from_sq(move)))] & to_sq(move) + ? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move) : pos.gives_check(move, ci); dangerous = givesCheck @@ -960,10 +968,9 @@ moves_loop: // When in check and at SpNode search starts from here ss->reduction = reduction(improving, depth, moveCount); if ( (!PvNode && cutNode) - || History[pos.piece_on(to_sq(move))][to_sq(move)] < VALUE_ZERO - || ( History[pos.piece_on(to_sq(move))][to_sq(move)] - + CounterMovesHistory[pos.piece_on(prevMoveSq)][prevMoveSq] - [pos.piece_on(to_sq(move))][to_sq(move)] < VALUE_ZERO)) + || ( History[pos.piece_on(to_sq(move))][to_sq(move)] < VALUE_ZERO + && CounterMovesHistory[pos.piece_on(prevMoveSq)][prevMoveSq] + [pos.piece_on(to_sq(move))][to_sq(move)] <= VALUE_ZERO)) ss->reduction += ONE_PLY; if (move == countermove) @@ -1068,7 +1075,6 @@ moves_loop: // When in check and at SpNode search starts from here rm.score = -VALUE_INFINITE; } - bool newBestMove = false; if (value > bestValue) { bestValue = SpNode ? splitPoint->bestValue = value : value; @@ -1081,7 +1087,6 @@ moves_loop: // When in check and at SpNode search starts from here && (move != EasyMove.get(pos.key()) || moveCount > 1)) EasyMove.clear(); - newBestMove = true; bestMove = SpNode ? splitPoint->bestMove = move : move; if (PvNode && !RootNode) // Update pv even in fail-high case @@ -1101,7 +1106,7 @@ moves_loop: // When in check and at SpNode search starts from here } } - if (!SpNode && !captureOrPromotion && !newBestMove && quietCount < 64) + if (!SpNode && !captureOrPromotion && move != bestMove && quietCount < 64) quietsSearched[quietCount++] = move; // Step 19. Check for splitting the search @@ -1147,7 +1152,7 @@ moves_loop: // When in check and at SpNode search starts from here : inCheck ? mated_in(ss->ply) : DrawValue[pos.side_to_move()]; // Quiet best move: update killers, history and countermoves - else if (bestMove != MOVE_NONE && !pos.capture_or_promotion(bestMove)) + else if (bestMove && !pos.capture_or_promotion(bestMove)) update_stats(pos, ss, bestMove, depth, quietsSearched, quietCount); tte->save(posKey, value_to_tt(bestValue, ss->ply), @@ -1276,7 +1281,7 @@ moves_loop: // When in check and at SpNode search starts from here assert(is_ok(move)); givesCheck = type_of(move) == NORMAL && !ci.dcCandidates - ? ci.checkSq[type_of(pos.piece_on(from_sq(move)))] & to_sq(move) + ? ci.checkSquares[type_of(pos.piece_on(from_sq(move)))] & to_sq(move) : pos.gives_check(move, ci); // Futility pruning @@ -1405,9 +1410,12 @@ moves_loop: // When in check and at SpNode search starts from here *pv = MOVE_NONE; } - // update_stats() updates killers, history, countermove history and countermoves stats for a quiet best move. - void update_stats(const Position& pos, Stack* ss, Move move, Depth depth, Move* quiets, int quietsCnt) { + // update_stats() updates killers, history, countermove history and + // countermoves stats for a quiet best move. + + void update_stats(const Position& pos, Stack* ss, Move move, + Depth depth, Move* quiets, int quietsCnt) { if (ss->killers[0] != move) {