diff --git a/src/benchmark.cpp b/src/benchmark.cpp index 50f8612d..267a6b4b 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -23,8 +23,6 @@ #include #include -#include "position.h" - namespace { // clang-format off @@ -108,7 +106,7 @@ namespace Stockfish { // bench 64 1 100000 default nodes : search default positions for 100K nodes each // bench 64 4 5000 current movetime : search current position with 4 threads for 5 sec // bench 16 1 5 blah perft : run a perft 5 on positions in file "blah" -std::vector setup_bench(const Position& current, std::istream& is) { +std::vector setup_bench(const std::string& currentFen, std::istream& is) { std::vector fens, list; std::string go, token; @@ -126,7 +124,7 @@ std::vector setup_bench(const Position& current, std::istream& is) fens = Defaults; else if (fenFile == "current") - fens.push_back(current.fen()); + fens.push_back(currentFen); else { diff --git a/src/benchmark.h b/src/benchmark.h index 86f8a0ad..8905fcb1 100644 --- a/src/benchmark.h +++ b/src/benchmark.h @@ -25,9 +25,7 @@ namespace Stockfish { -class Position; - -std::vector setup_bench(const Position&, std::istream&); +std::vector setup_bench(const std::string&, std::istream&); } // namespace Stockfish diff --git a/src/engine.cpp b/src/engine.cpp index 12fa5c3f..325b971e 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "evaluate.h" #include "misc.h" @@ -146,8 +148,6 @@ void Engine::save_network(const std::pair, std::strin // utility functions -OptionsMap& Engine::get_options() { return options; } - void Engine::trace_eval() const { StateListPtr trace_states(new std::deque(1)); Position p; @@ -158,4 +158,16 @@ void Engine::trace_eval() const { sync_cout << "\n" << Eval::trace(p, networks) << sync_endl; } +OptionsMap& Engine::get_options() { return options; } + +std::string Engine::fen() const { return pos.fen(); } + +void Engine::flip() { pos.flip(); } + +std::string Engine::visualize() const { + std::stringstream ss; + ss << pos; + return ss.str(); +} + } \ No newline at end of file diff --git a/src/engine.h b/src/engine.h index f74209d9..7122ee59 100644 --- a/src/engine.h +++ b/src/engine.h @@ -79,6 +79,9 @@ class Engine { void trace_eval() const; OptionsMap& get_options(); + std::string fen() const; + void flip(); + std::string visualize() const; private: const std::string binaryDirectory; diff --git a/src/search.h b/src/search.h index d1464840..d30a06fe 100644 --- a/src/search.h +++ b/src/search.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "misc.h" #include "movepick.h" @@ -121,11 +122,11 @@ struct LimitsType { bool use_time_management() const { return time[WHITE] || time[BLACK]; } - std::vector searchmoves; - TimePoint time[COLOR_NB], inc[COLOR_NB], npmsec, movetime, startTime; - int movestogo, depth, mate, perft, infinite; - uint64_t nodes; - bool ponderMode; + std::vector searchmoves; + TimePoint time[COLOR_NB], inc[COLOR_NB], npmsec, movetime, startTime; + int movestogo, depth, mate, perft, infinite; + uint64_t nodes; + bool ponderMode; }; diff --git a/src/thread.cpp b/src/thread.cpp index 85a2bcbb..1438c9f9 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "misc.h" #include "movegen.h" @@ -33,6 +34,7 @@ #include "tt.h" #include "types.h" #include "ucioption.h" +#include "uci.h" namespace Stockfish { @@ -182,10 +184,18 @@ void ThreadPool::start_thinking(const OptionsMap& options, increaseDepth = true; Search::RootMoves rootMoves; + const auto legalmoves = MoveList(pos); - for (const auto& m : MoveList(pos)) - if (limits.searchmoves.empty() - || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m)) + for (const auto& uciMove : limits.searchmoves) + { + auto move = UCIEngine::to_move(pos, uciMove); + + if (std::find(legalmoves.begin(), legalmoves.end(), move) != legalmoves.end()) + rootMoves.emplace_back(move); + } + + if (rootMoves.empty()) + for (const auto& m : legalmoves) rootMoves.emplace_back(m); Tablebases::Config tbConfig = Tablebases::rank_root_moves(options, pos, rootMoves); diff --git a/src/uci.cpp b/src/uci.cpp index a15bc7d4..8f697836 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -22,8 +22,6 @@ #include #include #include -#include -#include #include #include #include @@ -98,11 +96,7 @@ UCIEngine::UCIEngine(int argc, char** argv) : void UCIEngine::loop() { - Position pos; - std::string token, cmd; - StateListPtr states(new std::deque(1)); - - pos.set(StartFEN, false, &states->back()); + std::string token, cmd; for (int i = 1; i < cli.argc; ++i) cmd += std::string(cli.argv[i]) + " "; @@ -135,9 +129,9 @@ void UCIEngine::loop() { else if (token == "setoption") setoption(is); else if (token == "go") - go(pos, is); + go(is); else if (token == "position") - position(pos, is); + position(is); else if (token == "ucinewgame") engine.search_clear(); else if (token == "isready") @@ -146,11 +140,11 @@ void UCIEngine::loop() { // Add custom non-UCI commands, mainly for debugging purposes. // These commands must not be used during a search! else if (token == "flip") - pos.flip(); + engine.flip(); else if (token == "bench") - bench(pos, is); + bench(is); else if (token == "d") - sync_cout << pos << sync_endl; + sync_cout << engine.visualize() << sync_endl; else if (token == "eval") engine.trace_eval(); else if (token == "compiler") @@ -183,7 +177,7 @@ void UCIEngine::loop() { } while (token != "quit" && cli.argc == 1); // The command-line arguments are one-shot } -Search::LimitsType UCIEngine::parse_limits(const Position& pos, std::istream& is) { +Search::LimitsType UCIEngine::parse_limits(std::istream& is) { Search::LimitsType limits; std::string token; @@ -192,7 +186,7 @@ Search::LimitsType UCIEngine::parse_limits(const Position& pos, std::istream& is while (is >> token) if (token == "searchmoves") // Needs to be the last command on the line while (is >> token) - limits.searchmoves.push_back(to_move(pos, token)); + limits.searchmoves.push_back(to_lower(token)); else if (token == "wtime") is >> limits.time[WHITE]; @@ -222,13 +216,13 @@ Search::LimitsType UCIEngine::parse_limits(const Position& pos, std::istream& is return limits; } -void UCIEngine::go(Position& pos, std::istringstream& is) { +void UCIEngine::go(std::istringstream& is) { - Search::LimitsType limits = parse_limits(pos, is); + Search::LimitsType limits = parse_limits(is); engine.go(limits); } -void UCIEngine::bench(Position& pos, std::istream& args) { +void UCIEngine::bench(std::istream& args) { std::string token; uint64_t num, nodes = 0, cnt = 1; uint64_t nodesSearched = 0; @@ -239,7 +233,7 @@ void UCIEngine::bench(Position& pos, std::istream& args) { on_update_full(i, options["UCI_ShowWDL"]); }); - std::vector list = setup_bench(pos, args); + std::vector list = setup_bench(engine.fen(), args); num = count_if(list.begin(), list.end(), [](const std::string& s) { return s.find("go ") == 0 || s.find("eval") == 0; }); @@ -253,11 +247,11 @@ void UCIEngine::bench(Position& pos, std::istream& args) { if (token == "go" || token == "eval") { - std::cerr << "\nPosition: " << cnt++ << '/' << num << " (" << pos.fen() << ")" + std::cerr << "\nPosition: " << cnt++ << '/' << num << " (" << engine.fen() << ")" << std::endl; if (token == "go") { - go(pos, is); + go(is); engine.wait_for_search_finished(); nodes += nodesSearched; nodesSearched = 0; @@ -268,7 +262,7 @@ void UCIEngine::bench(Position& pos, std::istream& args) { else if (token == "setoption") setoption(is); else if (token == "position") - position(pos, is); + position(is); else if (token == "ucinewgame") { engine.search_clear(); // search_clear may take a while @@ -294,7 +288,7 @@ void UCIEngine::setoption(std::istringstream& is) { engine.get_options().setoption(is); } -void UCIEngine::position(Position& pos, std::istringstream& is) { +void UCIEngine::position(std::istringstream& is) { std::string token, fen; is >> token; @@ -317,7 +311,6 @@ void UCIEngine::position(Position& pos, std::istringstream& is) { moves.push_back(token); } - pos.set(fen, engine.get_options()["UCI_Chess960"], pos.state()); engine.set_position(fen, moves); } @@ -425,9 +418,14 @@ std::string UCIEngine::move(Move m, bool chess960) { } +std::string UCIEngine::to_lower(std::string str) { + std::transform(str.begin(), str.end(), str.begin(), [](auto c) { return std::tolower(c); }); + + return str; +} + Move UCIEngine::to_move(const Position& pos, std::string str) { - if (str.length() == 5) - str[4] = char(tolower(str[4])); // The promotion piece character must be lowercased + str = to_lower(str); for (const auto& m : MoveList(pos)) if (str == move(m, pos.is_chess960())) diff --git a/src/uci.h b/src/uci.h index fa359db4..ee8c2814 100644 --- a/src/uci.h +++ b/src/uci.h @@ -46,9 +46,10 @@ class UCIEngine { static std::string square(Square s); static std::string move(Move m, bool chess960); static std::string wdl(Value v, const Position& pos); + static std::string to_lower(std::string str); static Move to_move(const Position& pos, std::string str); - static Search::LimitsType parse_limits(const Position& pos, std::istream& is); + static Search::LimitsType parse_limits(std::istream& is); auto& engine_options() { return engine.get_options(); } @@ -56,9 +57,9 @@ class UCIEngine { Engine engine; CommandLine cli; - void go(Position& pos, std::istringstream& is); - void bench(Position& pos, std::istream& args); - void position(Position& pos, std::istringstream& is); + void go(std::istringstream& is); + void bench(std::istream& args); + void position(std::istringstream& is); void setoption(std::istringstream& is); static void on_update_no_moves(const Engine::InfoShort& info);