Skip to content

Commit 5ed51c5

Browse files
authored
feat: additional compliance check (#839)
1 parent bb04116 commit 5ed51c5

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

app/src/engine/compliance.hpp

+42-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,40 @@
22

33
#include <functional>
44
#include <iostream>
5+
#include <sstream>
56
#include <string>
67
#include <vector>
78

89
#include <engine/uci_engine.hpp>
910

1011
namespace fastchess::engine {
1112

13+
bool isValidInfoLine(const std::string &infoLine) {
14+
std::istringstream iss(infoLine);
15+
std::string token;
16+
17+
if (!(iss >> token) || token != "info") {
18+
std::cerr << "\r\nInvalid info line format: " << infoLine << std::endl;
19+
return false;
20+
}
21+
22+
while (iss >> token) {
23+
if (token == "time" || token == "nps" || token == "score") {
24+
if (!(iss >> token)) {
25+
std::cerr << "\r\nNo value after token: " << token << std::endl;
26+
return false;
27+
}
28+
29+
if (token.find('.') != std::string::npos) {
30+
std::cerr << "\r\nTime/NPS/Score value is not an integer: " << token << std::endl;
31+
return false;
32+
}
33+
}
34+
}
35+
36+
return true;
37+
}
38+
1239
inline bool compliant(int argc, char const *argv[]) {
1340
int step = 0;
1441

@@ -52,6 +79,7 @@ inline bool compliant(int argc, char const *argv[]) {
5279
{"Send go wtime 100", [&uci_engine] { return uci_engine.writeEngine("go wtime 100"); }},
5380
{"Read bestmove", [&uci_engine] { return uci_engine.readEngine("bestmove") == process::Status::OK; }},
5481
{"Check if engine prints an info line", [&uci_engine] { return !uci_engine.lastInfoLine().empty(); }},
82+
{"Verify info line format is valid", [&uci_engine] { return isValidInfoLine(uci_engine.lastInfoLine()); }},
5583
{"Verify info line contains score",
5684
[&uci_engine] { return str_utils::contains(uci_engine.lastInfoLine(), "score"); }},
5785
{"Set position to black to move",
@@ -63,6 +91,8 @@ inline bool compliant(int argc, char const *argv[]) {
6391
[&uci_engine] { return uci_engine.readEngine("bestmove") == process::Status::OK; }},
6492
{"Check if engine prints an info line after go btime 100",
6593
[&uci_engine] { return !uci_engine.lastInfoLine().empty(); }},
94+
{"Verify info line format is valid after go btime 100",
95+
[&uci_engine] { return isValidInfoLine(uci_engine.lastInfoLine()); }},
6696
{"Check if engine prints an info line with the score after go btime 100",
6797
[&uci_engine] { return str_utils::contains(uci_engine.lastInfoLine(), "score"); }},
6898
{"Send go wtime 100 winc 100 btime 100 binc 100",
@@ -71,6 +101,8 @@ inline bool compliant(int argc, char const *argv[]) {
71101
[&uci_engine] { return uci_engine.readEngine("bestmove") == process::Status::OK; }},
72102
{"Check if engine prints an info line after go wtime 100 winc 100",
73103
[&uci_engine] { return !uci_engine.lastInfoLine().empty(); }},
104+
{"Verify info line format is valid after go wtime 100 winc 100",
105+
[&uci_engine] { return isValidInfoLine(uci_engine.lastInfoLine()); }},
74106
{"Check if engine prints an info line with the score after go wtime 100 winc 100",
75107
[&uci_engine] { return str_utils::contains(uci_engine.lastInfoLine(), "score"); }},
76108
{"Send go btime 100 binc 100 wtime 100 winc 100",
@@ -79,6 +111,8 @@ inline bool compliant(int argc, char const *argv[]) {
79111
[&uci_engine] { return uci_engine.readEngine("bestmove") == process::Status::OK; }},
80112
{"Check if engine prints an info line after go btime 100 binc 100",
81113
[&uci_engine] { return !uci_engine.lastInfoLine().empty(); }},
114+
{"Verify info line format is valid after go btime 100 binc 100",
115+
[&uci_engine] { return isValidInfoLine(uci_engine.lastInfoLine()); }},
82116
{"Check if engine prints an info line with the score after go btime 100 binc 100",
83117
[&uci_engine] { return str_utils::contains(uci_engine.lastInfoLine(), "score"); }},
84118
{"Check if engine prints an info line after go btime 100 binc 100",
@@ -91,12 +125,17 @@ inline bool compliant(int argc, char const *argv[]) {
91125
[&uci_engine] {
92126
return uci_engine.readEngine("bestmove") == process::Status::OK && uci_engine.bestmove() != std::nullopt;
93127
}},
128+
{"Verify info line format is valid after go wtime 100 btime 100",
129+
[&uci_engine] { return isValidInfoLine(uci_engine.lastInfoLine()); }},
94130
{"Set position to startpos moves e2e4 e7e5",
95131
[&uci_engine] { return uci_engine.writeEngine("position startpos moves e2e4 e7e5"); }},
96132
{"Send go wtime 100 btime 100", [&uci_engine] { return uci_engine.writeEngine("go wtime 100 btime 100"); }},
97-
{"Read bestmove after position startpos moves e2e4 e7e5", [&uci_engine] {
133+
{"Read bestmove after position startpos moves e2e4 e7e5",
134+
[&uci_engine] {
98135
return uci_engine.readEngine("bestmove") == process::Status::OK && uci_engine.bestmove() != std::nullopt;
99-
}}};
136+
}},
137+
{"Verify info line format is valid after position startpos moves e2e4 e7e5",
138+
[&uci_engine] { return isValidInfoLine(uci_engine.lastInfoLine()); }}};
100139

101140
for (const auto &[description, action] : steps) {
102141
if (!executeStep(description, action)) {
@@ -109,4 +148,4 @@ inline bool compliant(int argc, char const *argv[]) {
109148
return true;
110149
}
111150

112-
} // namespace fastchess::engine
151+
} // namespace fastchess::engine

0 commit comments

Comments
 (0)