Skip to content

Commit

Permalink
feat: uci compliance, also check for id name and author (#744)
Browse files Browse the repository at this point in the history
  • Loading branch information
Disservin authored Oct 11, 2024
1 parent 2fddf46 commit 0902fe7
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 19 deletions.
2 changes: 2 additions & 0 deletions app/src/engine/compliance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ bool compliant(const std::string &path) {
std::vector<std::pair<std::string, std::function<bool()>>> steps = {
{"Start the engine", [&uci_engine] { return uci_engine.start(); }},
{"Check if engine is ready", [&uci_engine] { return uci_engine.isready() == process::Status::OK; }},
{"Check id name", [&uci_engine] { return uci_engine.idName().has_value(); }},
{"Check id author", [&uci_engine] { return uci_engine.idAuthor().has_value(); }},
{"Send ucinewgame", [&uci_engine] { return uci_engine.ucinewgame(); }},
{"Set position to startpos", [&uci_engine] { return uci_engine.writeEngine("position startpos"); }},
{"Check if engine is ready after startpos",
Expand Down
44 changes: 44 additions & 0 deletions app/src/engine/uci_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,50 @@ bool UciEngine::ucinewgame() {
return isready(ucinewgame_time_) == process::Status::OK;
}

std::optional<std::string> UciEngine::idName() {
if (!uci()) {
Logger::warn<true>("Warning; Engine {} didn't respond to uci.", config_.name);
return std::nullopt;
}

if (!uciok()) {
Logger::warn<true>("Warning; Engine {} didn't respond to uci.", config_.name);
return std::nullopt;
}

// get id name
for (const auto &line : output_) {
if (line.line.find("id name") != std::string::npos) {
// everything after id name
return line.line.substr(line.line.find("id name") + 8);
}
}

return std::nullopt;
}

std::optional<std::string> UciEngine::idAuthor() {
if (!uci()) {
Logger::warn<true>("Warning; Engine {} didn't respond to uci.", config_.name);
return std::nullopt;
}

if (!uciok()) {
Logger::warn<true>("Warning; Engine {} didn't respond to uci.", config_.name);
return std::nullopt;
}

// get id author
for (const auto &line : output_) {
if (line.line.find("id author") != std::string::npos) {
// everything after id author
return line.line.substr(line.line.find("id author") + 10);
}
}

return std::nullopt;
}

bool UciEngine::uci() {
Logger::trace<true>("Sending uci to engine {}", config_.name);
const auto res = writeEngine("uci");
Expand Down
3 changes: 3 additions & 0 deletions app/src/engine/uci_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class UciEngine : protected process::Process {
// Restarts the engine, if necessary and reapplies the options.
bool refreshUci();

[[nodiscard]] std::optional<std::string> idName();
[[nodiscard]] std::optional<std::string> idAuthor();

// Returns false in case of failure.
[[nodiscard]] bool uci();
// Returns false in case of failure.
Expand Down
2 changes: 2 additions & 0 deletions app/tests/mock/engine/dummy_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ int main(int argc, char const *argv[]) {
} else if (cmd == "isready") {
cout << "readyok" << endl;
} else if (cmd == "uci") {
cout << "id name Dummy Engine" << endl;
cout << "id author FastChess" << endl;
cout << "line0" << endl;
cout << "line1" << endl;
cout << "uciok" << endl;
Expand Down
1 change: 1 addition & 0 deletions app/tests/mock/engine/random_mover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void uci_line(Board &board, const std::string &line) {
}
} else if (tokens[0] == "uci") {
std::cout << "id name random_move" << std::endl;
std::cout << "id author fastchess" << std::endl;
std::cout << "option name Hash type spin default 16 min 1 max 33554432" << std::endl;
std::cout << "uciok" << std::endl;
} else if (tokens[0] == "isready") {
Expand Down
52 changes: 33 additions & 19 deletions app/tests/uci_engine_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ TEST_SUITE("Uci Engine Communication Tests") {
std::cout << line.line << std::endl;
}

CHECK(uci_engine.output().size() == 6);
CHECK(uci_engine.output().size() == 8);
CHECK(uci_engine.output()[0].line == "argv[1]: arg1");
CHECK(uci_engine.output()[1].line == "argv[2]: arg2");
CHECK(uci_engine.output()[2].line == "argv[3]: arg3");

CHECK(uci_engine.idName().has_value());
CHECK(uci_engine.idName().value() == "Dummy Engine");

CHECK(uci_engine.idAuthor().has_value());
CHECK(uci_engine.idAuthor().value() == "FastChess");
}

TEST_CASE("Test engine::UciEngine Args Complex") {
Expand All @@ -69,7 +75,7 @@ TEST_SUITE("Uci Engine Communication Tests") {
std::cout << line.line << std::endl;
}

CHECK(uci_engine.output().size() == 9);
CHECK(uci_engine.output().size() == 11);
CHECK(uci_engine.output()[0].line == "argv[1]: --backend=multiplexing");
CHECK(uci_engine.output()[1].line ==
"argv[2]: --backend-opts=backend=cuda-fp16,(gpu=0),(gpu=1),(gpu=2),(gpu=3)");
Expand All @@ -92,7 +98,7 @@ TEST_SUITE("Uci Engine Communication Tests") {

CHECK(uci_engine.start());

CHECK(uci_engine.output().size() == 6);
CHECK(uci_engine.output().size() == 8);
CHECK(uci_engine.output()[0].line == "argv[1]: arg1");
CHECK(uci_engine.output()[1].line == "argv[2]: arg2");
CHECK(uci_engine.output()[2].line == "argv[3]: arg3");
Expand All @@ -104,10 +110,12 @@ TEST_SUITE("Uci Engine Communication Tests") {
auto uciOutput = uci_engine.output();

CHECK(uci);
CHECK(uciOutput.size() == 3);
CHECK(uciOutput[0].line == "line0");
CHECK(uciOutput[1].line == "line1");
CHECK(uciOutput[2].line == "uciok");
CHECK(uciOutput.size() == 5);
CHECK(uciOutput[0].line == "id name Dummy Engine");
CHECK(uciOutput[1].line == "id author FastChess");
CHECK(uciOutput[2].line == "line0");
CHECK(uciOutput[3].line == "line1");
CHECK(uciOutput[4].line == "uciok");
CHECK(uci_engine.isready() == engine::process::Status::OK);

CHECK(uci_engine.writeEngine("sleep"));
Expand Down Expand Up @@ -136,10 +144,12 @@ TEST_SUITE("Uci Engine Communication Tests") {
const auto res = uci_engine.readEngine("uciok");

CHECK(res == engine::process::Status::OK);
CHECK(uci_engine.output().size() == 3);
CHECK(uci_engine.output()[0].line == "line0");
CHECK(uci_engine.output()[1].line == "line1");
CHECK(uci_engine.output()[2].line == "uciok");
CHECK(uci_engine.output().size() == 5);
CHECK(uci_engine.output()[0].line == "id name Dummy Engine");
CHECK(uci_engine.output()[1].line == "id author FastChess");
CHECK(uci_engine.output()[2].line == "line0");
CHECK(uci_engine.output()[3].line == "line1");
CHECK(uci_engine.output()[4].line == "uciok");

CHECK(uci_engine.writeEngine("isready"));
const auto res2 = uci_engine.readEngine("readyok");
Expand Down Expand Up @@ -175,20 +185,24 @@ TEST_SUITE("Uci Engine Communication Tests") {
const auto res = uci_engine.readEngine("uciok");

CHECK(res == engine::process::Status::OK);
CHECK(uci_engine.output().size() == 3);
CHECK(uci_engine.output()[0].line == "line0");
CHECK(uci_engine.output()[1].line == "line1");
CHECK(uci_engine.output()[2].line == "uciok");
CHECK(uci_engine.output().size() == 5);
CHECK(uci_engine.output()[0].line == "id name Dummy Engine");
CHECK(uci_engine.output()[1].line == "id author FastChess");
CHECK(uci_engine.output()[2].line == "line0");
CHECK(uci_engine.output()[3].line == "line1");
CHECK(uci_engine.output()[4].line == "uciok");

uci_engine.restart();

CHECK(uci_engine.writeEngine("uci"));
const auto res2 = uci_engine.readEngine("uciok");

CHECK(res2 == engine::process::Status::OK);
CHECK(uci_engine.output().size() == 3);
CHECK(uci_engine.output()[0].line == "line0");
CHECK(uci_engine.output()[1].line == "line1");
CHECK(uci_engine.output()[2].line == "uciok");
CHECK(uci_engine.output().size() == 5);
CHECK(uci_engine.output()[0].line == "id name Dummy Engine");
CHECK(uci_engine.output()[1].line == "id author FastChess");
CHECK(uci_engine.output()[2].line == "line0");
CHECK(uci_engine.output()[3].line == "line1");
CHECK(uci_engine.output()[4].line == "uciok");
}
}

0 comments on commit 0902fe7

Please sign in to comment.