X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=7075c3373a2c90eec8a021e45d8552544f529ab7;hp=19cb3b511a27f4844caba4916f1cc4b3a8a4fc8c;hb=0118623495e2ef8a29cbe6ac76609521417490d2;hpb=f7742669cb52dff7a64bd1a9ba466e333abb87bc diff --git a/src/search.cpp b/src/search.cpp index 19cb3b51..7075c337 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1,7 +1,7 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) - Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad + Copyright (C) 2008-2014 Marco Costalba, Joona Kiiski, Tord Romstad Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,6 +94,7 @@ namespace { void id_loop(Position& pos); Value value_to_tt(Value v, int ply); Value value_from_tt(Value v, int ply); + void update_stats(Position& pos, Stack* ss, Move move, Depth depth, Move* quiets, int quietsCnt); string uci_pv(const Position& pos, int depth, Value alpha, Value beta); struct Skill { @@ -566,27 +567,10 @@ namespace { TT.refresh(tte); ss->currentMove = ttMove; // Can be MOVE_NONE - // Update killers, history, and counter move on TT hit - if ( ttValue >= beta - && ttMove - && !pos.capture_or_promotion(ttMove) - && !inCheck) - { - if (ss->killers[0] != ttMove) - { - ss->killers[1] = ss->killers[0]; - ss->killers[0] = ttMove; - } - - Value bonus = Value(int(depth) * int(depth)); - History.update(pos.moved_piece(ttMove), to_sq(ttMove), bonus); + // If ttMove is quiet, update killers, history, and counter move on TT hit + if (ttValue >= beta && ttMove && !pos.capture_or_promotion(ttMove) && !inCheck) + update_stats(pos, ss, ttMove, depth, NULL, 0); - if (is_ok((ss-1)->currentMove)) - { - Square prevMoveSq = to_sq((ss-1)->currentMove); - Countermoves.update(pos.piece_on(prevMoveSq), prevMoveSq, ttMove); - } - } return ttValue; } @@ -1063,29 +1047,8 @@ moves_loop: // When in check and at SpNode search starts from here depth, bestMove, ss->staticEval); // Quiet best move: update killers, history and countermoves - if ( bestValue >= beta - && !pos.capture_or_promotion(bestMove) - && !inCheck) - { - if (ss->killers[0] != bestMove) - { - ss->killers[1] = ss->killers[0]; - ss->killers[0] = bestMove; - } - - // Increase history value of the cut-off move and decrease all the other - // played non-capture moves. - Value bonus = Value(int(depth) * int(depth)); - History.update(pos.moved_piece(bestMove), to_sq(bestMove), bonus); - for (int i = 0; i < quietCount - 1; ++i) - { - Move m = quietsSearched[i]; - History.update(pos.moved_piece(m), to_sq(m), -bonus); - } - - if (is_ok((ss-1)->currentMove)) - Countermoves.update(pos.piece_on(prevMoveSq), prevMoveSq, bestMove); - } + if (bestValue >= beta && !pos.capture_or_promotion(bestMove) && !inCheck) + update_stats(pos, ss, bestMove, depth, quietsSearched, quietCount - 1); assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); @@ -1318,6 +1281,35 @@ moves_loop: // When in check and at SpNode search starts from here } + // update_stats() updates killers, history and countermoves stats after a fail-high + // of a quiet move. + + void update_stats(Position& pos, Stack* ss, Move move, Depth depth, Move* quiets, int quietsCnt) { + + if (ss->killers[0] != move) + { + ss->killers[1] = ss->killers[0]; + ss->killers[0] = move; + } + + // Increase history value of the cut-off move and decrease all the other + // played quiet moves. + Value bonus = Value(int(depth) * int(depth)); + History.update(pos.moved_piece(move), to_sq(move), bonus); + for (int i = 0; i < quietsCnt; ++i) + { + Move m = quiets[i]; + History.update(pos.moved_piece(m), to_sq(m), -bonus); + } + + if (is_ok((ss-1)->currentMove)) + { + Square prevMoveSq = to_sq((ss-1)->currentMove); + Countermoves.update(pos.piece_on(prevMoveSq), prevMoveSq, move); + } + } + + // When playing with a strength handicap, choose best move among the MultiPV // set using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.