From f5d9fe6211bd397deb0ac19b634f551edfa0f6b8 Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Sun, 30 Jan 2022 20:19:02 +0100 Subject: Initialize project --- src/UCI.cpp | 281 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 src/UCI.cpp (limited to 'src/UCI.cpp') diff --git a/src/UCI.cpp b/src/UCI.cpp new file mode 100644 index 0000000..7318f81 --- /dev/null +++ b/src/UCI.cpp @@ -0,0 +1,281 @@ +#include "UCI.hpp" + +namespace uciadapter { + +Info::Info() + : depth(-1), seldepth(-1), multipv(-1), score_cp(-1), score_mate(-1), + score_lowerbound(-1), score_upperbound(-1), cp(-1), nodes(-1), nps(-1), + tbhits(-1), time(-1), hashfull(-1), cpuload(-1), currmovenumber(-1) + +{} + +Go::Go() + : wtime(-1), btime(-1), winc(-1), binc(-1), movestogo(-1), depth(-1), + nodes(-1), mate(-1), movetime(-1), infinite(false) {} + +UCI::UCI(std::string engine_path) { + INIT_PROCESS(p); + p->Start(engine_path); + // Init UCI + p->Write("uci\n"); + uciok = false; + registration_required = false; + copyprotection_failed = false; + registered = false; + Sync(); + if (!uciok) { + throw EngineError("failed to start engine in uci mode"); + } + Sync(); // Check copy protection + if (copyprotection_failed) { + throw EngineError("Copy protection check failed"); + } +} + +UCI::~UCI() { + p->Kill(); + delete p; +} + +void UCI::Sync() { + p->Write("isready\n"); + bool readyok = false; + std::string token; + while (!readyok) { + std::istringstream iss(p->ReadLine()); + buffer += iss.str(); + while (iss >> token) { + if (token == "readyok") { + readyok = true; + } else if (token == "uciok") { + uciok = true; + } else if (token == "id") { + ParseId(iss.str()); + } else if (token == "option") { + ParseOption(iss.str()); + } else if (token == "copyprotection") { + iss >> token; + if (token == "error") { + copyprotection_failed = true; + } else if (token == "ok") { + registered = true; + } + } else if (token == "registration") { + if (iss.str() == "registration error\n") + registration_required = true; + } else if (token == "bestmove") { + iss >> token; + bestmove = token; + iss >> token; + if (token == "ponder") { + iss >> token; + ponder = token; + } + } else if (token == "info") { + ParseInfo(iss.str()); + } + } + } +} + +void UCI::Command(std::string cmd) { + p->Write(cmd + "\n"); + Sync(); +} + +bool UCI::IsRegistered() { return (registered); } + +void UCI::SyncAfter(int ms) { + if (ms <= 0) { + Sync(); + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); + Sync(); + } +} + +void UCI::ParseInfo(std::string line) { + Info info; + std::istringstream iss(line); + std::string token; + while (iss >> token) { + if (token == "depth") { + iss >> info.depth; + } else if (token == "string") { + std::string line; + while (iss >> token) { + line += token + " "; + } + line = line.substr(0, line.size() - 1); // Remove trailing space + infostrings.push_back(line); + return; + } else if (token == "seldepth") { + iss >> info.seldepth; + } else if (token == "refutation") { + while (iss >> token) { + refutations.push_back(token); + } + return; + } else if (token == "nps") { + iss >> info.nps; + } else if (token == "multipv") { + iss >> info.multipv; + } else if (token == "nodes") { + iss >> info.nodes; + } else if (token == "time") { + iss >> info.time; + } else if (token == "tbhits") { + iss >> info.tbhits; + } else if (token == "hashfull") { + iss >> info.hashfull; + } else if (token == "cpuload") { + iss >> info.cpuload; + } else if (token == "currmove") { + iss >> info.currmove; + } else if (token == "currmovenumber") { + iss >> info.currmovenumber; + } else if (token == "score") { + iss >> token; + if (token == "cp") { + iss >> info.score_cp; + } else if (token == "mate") { + iss >> info.score_mate; + } else if (token == "lowerbound") { + iss >> info.score_lowerbound; + } else if (token == "upperbound") { + iss >> info.score_upperbound; + } + } else if (token == "pv") { + while (iss >> token) { + info.pv.push_back(token); + } + } + } + + // Save line + if (info.pv.size() > 0) { + lines[info.multipv] = info; + } +} + +std::vector UCI::GetInfoStrings() { return (infostrings); } +void UCI::ParseOption(std::string line) { + std::istringstream iss(line); + std::string token; + Option opt; + iss >> token; // option token + std::string *entry = NULL; + while (iss) { + if (token == "name") { + entry = &opt.name; + } else if (token == "type") { + entry = &opt.type; + } else if (token == "default") { + entry = &opt.default_value; + } else if (token == "min") { + entry = &opt.min; + } else if (token == "max") { + entry = &opt.max; + } else if (token == "var") { + entry = &opt.var; + } else { + iss >> token; + } + if (entry != NULL) { + iss >> token; + while (!IS_OPT_PARAM(token) && iss) { + (*entry) += token + " "; + iss >> token; + } + *entry = entry->substr(0, entry->size() - 1); // Remove trailing space + entry = NULL; + } + } + options.push_back(opt); +} + +void UCI::ParseId(std::string line) { + std::istringstream iss(line); + std::string token; + iss >> token; // id + iss >> token; // name or author + if (token == "name") { + while (iss >> token) { + name += token + " "; + } + name = name.substr(0, name.size() - 1); + } else { + while (iss >> token) { + author += token + " "; + } + author = author.substr(0, author.size() - 1); + } +} + +std::unordered_map UCI::GetLines() { return (lines); } +std::vector