From be872135a308ad605f609a90248976aa2dce197b Mon Sep 17 00:00:00 2001 From: Jan Popelka Date: Wed, 29 Mar 2023 00:28:29 +0200 Subject: [PATCH] unload engines, cmake, messages; tenchou no igo wine example --- CMakeLists.txt | 11 ++++------ data/config.json | 25 +++++++++++++++++++--- engine/README.md | 44 -------------------------------------- src/GameThread.cpp | 8 +------ src/GameThread.h | 8 ++++++- src/GobanControl.cpp | 1 + src/gtpclient.cpp | 50 +++++++++++++++++++++++++++++--------------- src/gtpclient.h | 5 ++++- src/player.h | 4 ++-- 9 files changed, 74 insertions(+), 82 deletions(-) delete mode 100644 engine/README.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 4078681..356f649 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,9 +162,7 @@ function(build_libsgfcplusplus) GIT_REPOSITORY https://github.com/popojan/libsgfcplusplus.git GIT_TAG master CMAKE_ARGS ${CL_ARGS} - BUILD_COMMAND - ${CMAKE_COMMAND} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ${CMAKE_SOURCE_DIR}/deps/libsgfcplusplus -DENABLE_TESTS=0 + BUILD_COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ${CMAKE_SOURCE_DIR}/deps/libsgfcplusplus -DENABLE_TESTS=0 COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/deps/libsgfcplusplus --config ${CMAKE_BUILD_TYPE} SOURCE_DIR ${CMAKE_SOURCE_DIR}/deps/libsgfcplusplus BINARY_DIR ${CMAKE_BINARY_DIR}/deps/libsgfcplusplus @@ -175,7 +173,6 @@ function(build_libsgfcplusplus) #COMMAND git checkout sgfc INSTALL_COMMAND echo Skipping install step for libsgfcplusplus ) - ExternalProject_Get_Property(project_libsgfcplusplus SOURCE_DIR) ExternalProject_Get_Property(project_libsgfcplusplus BINARY_DIR) set(libsgfcplusplus_inc_dir "${SOURCE_DIR}/include" "${BINARY_DIR}/src" PARENT_SCOPE) @@ -200,7 +197,7 @@ function(fetch_json) include(FetchContent) FetchContent_Declare(json - GIT_REPOSITORY git://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent.git + GIT_REPOSITORY https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent.git GIT_TAG v3.7.3) FetchContent_GetProperties(json) @@ -224,7 +221,7 @@ endfunction() function(fetch_spdlog) FetchContent_Declare(spdlog - GIT_REPOSITORY git://github.com/gabime/spdlog.git + GIT_REPOSITORY https://github.com/gabime/spdlog.git GIT_TAG v1.6.0) FetchContent_GetProperties(spdlog) @@ -236,7 +233,7 @@ endfunction() function(fetch_clipp) FetchContent_Declare(clipp - GIT_REPOSITORY git://github.com/muellan/clipp.git + GIT_REPOSITORY https://github.com/muellan/clipp.git GIT_TAG 2c32b2f1f7cc530b1ec1f62c92f698643bb368db) FetchContent_GetProperties(clipp) diff --git a/data/config.json b/data/config.json index 4ac88d1..7e4a4a3 100644 --- a/data/config.json +++ b/data/config.json @@ -12,8 +12,8 @@ }, { "name": "Pachi 12.60", - "path": "./engine/Pachi-12.60", - "command": "pachi.exe", + "path": "./engine/pachi", + "command": "pachi-12.60-amd64", "parameters": "-r japanese --smart-pass", "enabled": 0 }, @@ -21,7 +21,7 @@ "name": "Katago #kata1 b40", "path": "./engine/katago", "command": "katago", - "parameters": "gtp -model ./engine/katago/models/kata1-b40c256-s10359230464-d2525387336.bin.gz -config ./engine/katago/default_gtp.cfg", + "parameters": "gtp -model ./engine/katago/kata1-b40c256-s11101799168-d2715431527.bin.gz -config ./engine/katago/default_gtp.cfg", "enabled": 0, "kibitz": 0, "messages": [ @@ -39,9 +39,28 @@ "output": " " } ] + }, + { + "name": "Zen 6", + "path": "./engine/zen", + "command": "wine", + "parameters": "./engine/zen/gtp4zen.exe -z 6 -t 2 -T 120 -s 2147483647 -r 25", + "enabled": 0, + "kibitz": 0, + "main": 0 + }, + { + "name": "Zen 7", + "path": "./engine/zen", + "command": "wine", + "parameters": "./engine/zen/gtp4zen.exe -z 7 -t 2 -T 120 -s 2147483647 -r 25", + "enabled": 0, + "kibitz": 0, + "main": 0 } ], "controls" : [ + {"key": 1, "command": "play once"}, {"key": 81, "command": "quit"}, {"key": 17, "command": "toggle_fullscreen"}, {"key": 35, "command": "fps"}, diff --git a/engine/README.md b/engine/README.md deleted file mode 100644 index 5db38af..0000000 --- a/engine/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# GTP Engines - -See [GoAIRatings](https://github.com/breakwa11/GoAIRatings) for inspiration. - -## GnuGo 3.8 -Please install GnuGo 3.8 from the official package. - -It is required as the coach engine enforcing game rules. - -## KataGo - -Set `logToStderr = true` and goban will display katago's internal scoring after opponent moves. -``` -#!/bin/bash -echo KataGo v1.4.2 opencl linux x64 - -src=https://github.com/lightvector/KataGo/releases/download/v1.4.2 -file=katago-v1.4.2-opencl-linux-x64.zip -dir=katago - -mkdir "$dir" -cd "$dir" -wget "$src/$file" -unzip "$file" -chmod +x katago -sed -i "s/^logToStderr = false/logToStderr = true/" default_gtp.cfg -sed -i "s/^rules = tromp-taylor/rules = japanese/" default_gtp.cfg - -src=https://github.com/lightvector/KataGo/releases/download/v1.4.0 -file=g170-b20c256x2-s4384473088-d968438914.bin.gz -dir=models - -mkdir models -cd models -wget "$src/$file" -``` - -## Pachi - - - -## Zenith Go - -Time to try gtp4zen wrapper. \ No newline at end of file diff --git a/src/GameThread.cpp b/src/GameThread.cpp index 3e72559..f29a155 100644 --- a/src/GameThread.cpp +++ b/src/GameThread.cpp @@ -390,13 +390,7 @@ void GameThread::loadEngines(const std::shared_ptr config) { int role = Player::SPECTATOR; if(!command.empty()) { - auto engine = new GtpEngine(command, parameters, path, name); - for(auto &&msg: messages) { - engine->addOutputFilter( - msg.value("regex", ""), - msg.value("output", ""), - msg.value("var", "")); - } + auto engine = new GtpEngine(command, parameters, path, name, messages); std::size_t id = addEngine(engine); if (main) { diff --git a/src/GameThread.h b/src/GameThread.h index 9bf0fe1..f3efc49 100644 --- a/src/GameThread.h +++ b/src/GameThread.h @@ -62,7 +62,7 @@ class GameThread int getActivePlayer(int which); Move getLocalMove(const Position& coord); - Move getLocalMove(const Move::Special move); + Move getLocalMove(Move::Special move); void reset(); void addGameObserver(GameObserver* pobserver) { @@ -74,6 +74,12 @@ class GameThread std::vector getEngines() { return engines;} std::vector getPlayers() { return players;} + void unloadEngines() { + for(auto& engine: engines) { + dynamic_cast(engine)->issueCommand("quit"); + } + } + private: std::vector gameObservers; GobanModel& model; diff --git a/src/GobanControl.cpp b/src/GobanControl.cpp index 689dcad..8b94d2c 100644 --- a/src/GobanControl.cpp +++ b/src/GobanControl.cpp @@ -86,6 +86,7 @@ bool GobanControl::command(const std::string& cmd) { if(cmd == "quit") { model.game.saveAs(""); exit = true; + engine.unloadEngines(); Shell::RequestExit(); } else if (cmd == "toggle_fullscreen") { diff --git a/src/gtpclient.cpp b/src/gtpclient.cpp index 64a55d8..9580ca6 100644 --- a/src/gtpclient.cpp +++ b/src/gtpclient.cpp @@ -1,13 +1,14 @@ #include "gtpclient.h" #include -GtpClient::GtpClient(const std::string& exe, const std::string& cmdline, const std::string& path) +GtpClient::GtpClient(const std::string& exe, const std::string& cmdline, + const std::string& path, const nlohmann::json& messages) : exe(exe), vars({}) { spdlog::info("Starting GTP client [{}/{}]", path, exe); std::vector where(::boost::this_process::path()); - where.push_back(path); + where.emplace_back(path); boost::filesystem::path file(boost::process::search_path(exe, where)); spdlog::info("About to run GTP engine [{}]", file.generic_path().string()); @@ -17,36 +18,52 @@ GtpClient::GtpClient(const std::string& exe, const std::string& cmdline, const s std::istream_iterator()); spdlog::info("running child [{} {}]", file.generic_path().string(), cmdline); - c = boost::process::child(file, params, - boost::process::std_out > pos, - boost::process::std_in < pis, - boost::process::std_err > pes); - reader = new InputThread(pes); - reader->bind(*this); + initFilters(messages); + + if(outputFilters.empty()) { // do not capture stderr if not needed + c = boost::process::child(file, params, + boost::process::std_out > pos, + boost::process::std_in < pis); + reader = nullptr; + } else { + c = boost::process::child(file, params, + boost::process::std_out > pos, + boost::process::std_in < pis, + boost::process::std_err > pes); + reader = new InputThread(pes); + reader->bind(*this); + } } +void GtpClient::initFilters(const nlohmann::json& messages) { + for(auto &&msg: messages) { + addOutputFilter( + msg.value("regex", ""), + msg.value("output", ""), + msg.value("var", "")); + } +} void replaceAll(std::string& out, const std::string& what, const std::string& by) { size_t index(0); - while (true) { + while (index != std::string::npos) { spdlog::trace("replace [{}] by [{}] in [{}]", what, by, out); index = out.find(what, index); - if (index == std::string::npos) break; - out.replace(index, what.size(), by); - index += what.size(); + if (index != std::string::npos) { + out.replace(index, what.size(), by); + index += what.size(); + } } } -std::string& ltrim(std::string & str) -{ +std::string& ltrim(std::string & str) { auto it2 = std::find_if(str.begin(), str.end(), [](char ch){return !std::isspace(ch , std::locale::classic());}); str.erase(str.begin(), it2); return str; } -std::string & rtrim(std::string & str) -{ +std::string & rtrim(std::string & str) { auto it1 = std::find_if(str.rbegin(), str.rend(), [](char ch){ return !std::isspace(ch , std::locale::classic());}); str.erase(it1.base(), str.end()); @@ -54,7 +71,6 @@ std::string & rtrim(std::string & str) } void GtpClient::operator()(const std::string& line) { - //TODO spdlog::debug("gtp err = {}", line); for (auto &re: outputFilters) { std::smatch m; diff --git a/src/gtpclient.h b/src/gtpclient.h index 3d67f19..0d0b496 100644 --- a/src/gtpclient.h +++ b/src/gtpclient.h @@ -37,7 +37,8 @@ class GtpClient { public: typedef std::vector CommandOutput; - GtpClient(const std::string& exe, const std::string& cmdline, const std::string& path); + GtpClient(const std::string& exe, const std::string& cmdline, + const std::string& path, const nlohmann::json& messages); ~GtpClient(); @@ -45,6 +46,8 @@ class GtpClient { void operator()(const std::string& line); + void initFilters(const nlohmann::json& messages); + void compileFilters(); void addOutputFilter(const std::string& msg, const std::string& format, const std::string& var); diff --git a/src/player.h b/src/player.h index abb3618..e17bb8e 100644 --- a/src/player.h +++ b/src/player.h @@ -98,8 +98,8 @@ class GtpEngine : public Engine, public GtpClient { public: GtpEngine(const std::string& exe, const std::string& cmdline, const std::string& path = "", - const std::string& nameExtra = "") - : Engine(nameExtra), GtpClient(exe, cmdline, path) + const std::string& nameExtra = "", const nlohmann::json& messages = {}) + : Engine(nameExtra), GtpClient(exe, cmdline, path, messages) { //setEngineName(nameExtra); }