From bdf7ba1e40a87bf153456621f6ac8f83cb81d614 Mon Sep 17 00:00:00 2001 From: xoto10 <23479932+xoto10@users.noreply.github.com> Date: Thu, 25 Apr 2024 10:54:58 +0100 Subject: [PATCH] Use less time on recaptures, credit to peregrine in Discord. Bench 1836777 --- src/engine.cpp | 11 +++++++++-- src/engine.h | 5 +++-- src/search.cpp | 4 +++- src/search.h | 1 + src/uci.cpp | 20 +++++++++++--------- src/uci.h | 6 +++--- 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 4625e00a816..b581e2e0088 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -97,11 +97,12 @@ void Engine::set_on_bestmove(std::functionwait_for_search_finished(); } -void Engine::set_position(const std::string& fen, const std::vector& moves) { +Square Engine::set_position(const std::string& fen, const std::vector& moves) { // Drop the old state and create a new one states = StateListPtr(new std::deque(1)); pos.set(fen, options["UCI_Chess960"], &states->back()); + Square capSq = SQ_NONE; for (const auto& move : moves) { auto m = UCIEngine::to_move(pos, move); @@ -111,7 +112,13 @@ void Engine::set_position(const std::string& fen, const std::vector states->emplace_back(); pos.do_move(m, states->back()); + + capSq = SQ_NONE; + DirtyPiece& dp = states->back().dirtyPiece; + if (dp.dirty_num > 1 && dp.to[1] == SQ_NONE) + capSq = m.to_sq(); } + return capSq; } // modifiers @@ -172,4 +179,4 @@ std::string Engine::visualize() const { return ss.str(); } -} \ No newline at end of file +} diff --git a/src/engine.h b/src/engine.h index 041f5678585..a591ffca6ce 100644 --- a/src/engine.h +++ b/src/engine.h @@ -57,7 +57,8 @@ class Engine { // blocking call to wait for search to finish void wait_for_search_finished(); // set a new position, moves are in UCI format - void set_position(const std::string& fen, const std::vector& moves); + // If last of moves is a capture, the capture square is returned + Square set_position(const std::string& fen, const std::vector& moves); // modifiers @@ -104,4 +105,4 @@ class Engine { } // namespace Stockfish -#endif // #ifndef ENGINE_H_INCLUDED \ No newline at end of file +#endif // #ifndef ENGINE_H_INCLUDED diff --git a/src/search.cpp b/src/search.cpp index 893daab20e6..797ee19fd8b 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -446,9 +446,11 @@ void Search::Worker::iterative_deepening() { double reduction = (1.48 + mainThread->previousTimeReduction) / (2.17 * timeReduction); double bestMoveInstability = 1 + 1.88 * totBestMoveChanges / threads.size(); int el = std::clamp((bestValue + 750) / 150, 0, 9); + double recapture = + limits.capSq != SQ_NONE && limits.capSq == rootMoves[0].pv[0].to_sq() ? 0.898 : 0.945; double totalTime = mainThread->tm.optimum() * fallingEval * reduction - * bestMoveInstability * EvalLevel[el]; + * bestMoveInstability * EvalLevel[el] * recapture; // Cap used time in case of a single legal move for a better viewer experience if (rootMoves.size() == 1) diff --git a/src/search.h b/src/search.h index 0fd778b47e6..02dd67d3955 100644 --- a/src/search.h +++ b/src/search.h @@ -128,6 +128,7 @@ struct LimitsType { int movestogo, depth, mate, perft, infinite; uint64_t nodes; bool ponderMode; + Square capSq; }; diff --git a/src/uci.cpp b/src/uci.cpp index cb686a027db..e15bb320eb4 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -97,6 +97,7 @@ UCIEngine::UCIEngine(int argc, char** argv) : void UCIEngine::loop() { std::string token, cmd; + Square capSq = SQ_NONE; for (int i = 1; i < cli.argc; ++i) cmd += std::string(cli.argv[i]) + " "; @@ -129,9 +130,9 @@ void UCIEngine::loop() { else if (token == "setoption") setoption(is); else if (token == "go") - go(is); + go(is, capSq); else if (token == "position") - position(is); + capSq = position(is); else if (token == "ucinewgame") engine.search_clear(); else if (token == "isready") @@ -177,11 +178,12 @@ void UCIEngine::loop() { } while (token != "quit" && cli.argc == 1); // The command-line arguments are one-shot } -Search::LimitsType UCIEngine::parse_limits(std::istream& is) { +Search::LimitsType UCIEngine::parse_limits(std::istream& is, Square capSq) { Search::LimitsType limits; std::string token; limits.startTime = now(); // The search starts as early as possible + limits.capSq = capSq; while (is >> token) if (token == "searchmoves") // Needs to be the last command on the line @@ -216,9 +218,9 @@ Search::LimitsType UCIEngine::parse_limits(std::istream& is) { return limits; } -void UCIEngine::go(std::istringstream& is) { +void UCIEngine::go(std::istringstream& is, Square capSq) { - Search::LimitsType limits = parse_limits(is); + Search::LimitsType limits = parse_limits(is, capSq); if (limits.perft) perft(limits); @@ -255,7 +257,7 @@ void UCIEngine::bench(std::istream& args) { << std::endl; if (token == "go") { - Search::LimitsType limits = parse_limits(is); + Search::LimitsType limits = parse_limits(is, SQ_NONE); if (limits.perft) nodes = perft(limits); @@ -306,7 +308,7 @@ std::uint64_t UCIEngine::perft(const Search::LimitsType& limits) { return nodes; } -void UCIEngine::position(std::istringstream& is) { +Square UCIEngine::position(std::istringstream& is) { std::string token, fen; is >> token; @@ -320,7 +322,7 @@ void UCIEngine::position(std::istringstream& is) { while (is >> token && token != "moves") fen += token + " "; else - return; + return SQ_NONE; std::vector moves; @@ -329,7 +331,7 @@ void UCIEngine::position(std::istringstream& is) { moves.push_back(token); } - engine.set_position(fen, moves); + return engine.set_position(fen, moves); } namespace { diff --git a/src/uci.h b/src/uci.h index 55d580f9727..48a1033225a 100644 --- a/src/uci.h +++ b/src/uci.h @@ -50,7 +50,7 @@ class UCIEngine { static std::string to_lower(std::string str); static Move to_move(const Position& pos, std::string str); - static Search::LimitsType parse_limits(std::istream& is); + static Search::LimitsType parse_limits(std::istream& is, Square capSq); auto& engine_options() { return engine.get_options(); } @@ -58,10 +58,10 @@ class UCIEngine { Engine engine; CommandLine cli; - void go(std::istringstream& is); + void go(std::istringstream& is, Square capSq); void bench(std::istream& args); - void position(std::istringstream& is); void setoption(std::istringstream& is); + Square position(std::istringstream& is); std::uint64_t perft(const Search::LimitsType&); static void on_update_no_moves(const Engine::InfoShort& info);