summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.cpp6
-rw-r--r--referee.cpp70
-rw-r--r--referee.h16
3 files changed, 79 insertions, 13 deletions
diff --git a/main.cpp b/main.cpp
index 2d3f828..a4b47ed 100644
--- a/main.cpp
+++ b/main.cpp
@@ -296,11 +296,17 @@ static void playMatch(Player &p1, Player &p2, int index, const Params &params) {
throw StopCompetitionError();
}
+ for (const auto &p : referee.playerWriteLines()) {
+ assert(0 <= p.first && p.first < 2);
+ procs[p.first].writeLine(p.second);
+ }
+
if (referee.gameEnded()) {
mres.status = MatchResult::Status::ok;
optional<vector<int>> oscores = referee.getScores();
assert(oscores);
+ assert(oscores->size() == 2);
mres.sc1 = oscores->at(0);
mres.sc2 = oscores->at(1);
diff --git a/referee.cpp b/referee.cpp
index 7bf3a93..15f49c3 100644
--- a/referee.cpp
+++ b/referee.cpp
@@ -39,21 +39,45 @@ bool Referee::moveValid(int player, const string_view line) {
proc.writeLine(s);
- optional<string> response = proc.readLine();
+ optional<string> response = readLine();
if (response) {
- if (referee_verbose) {
- cout << "REF(" << proc.getPid() << ") read <" << *response << ">" << endl;
- }
-
+ bool result;
if (*response == "valid end") {
isEnd = true;
readScores();
- return true;
+ result = true;
} else if (*response == "valid") {
- return true;
+ result = true;
} else {
- return false;
+ result = false;
+ }
+
+ if (featureWriteLines) {
+ writeLinesList.clear();
+
+ while (true) {
+ optional<string> line = readLine();
+ if (!line) {
+ if (referee_verbose) {
+ cout << "REF(" << proc.getPid() << ") EOF!" << endl;
+ }
+ return false;
+ }
+
+ if (line == "write_end") break;
+
+ size_t idx = line->find(' ');
+ if (idx == string::npos) {
+ cerr << "Referee feature_write_lines protocol violation!" << endl;
+ exit(1);
+ }
+
+ int player = stoi(line->substr(0, idx));
+ writeLinesList.emplace_back(player, line->substr(idx + 1));
+ }
}
+
+ return result;
} else {
if (referee_verbose) {
cout << "REF(" << proc.getPid() << ") EOF!" << endl;
@@ -62,21 +86,41 @@ bool Referee::moveValid(int player, const string_view line) {
}
}
+vector<pair<int, string>> Referee::playerWriteLines() {
+ return writeLinesList;
+}
+
bool Referee::gameEnded() {
return isEnd;
}
+optional<string> Referee::readLine() {
+ while (true) {
+ optional<string> line = proc.readLine();
+ if (!line) return line;
+
+ if (referee_verbose) {
+ cout << "REF(" << proc.getPid() << ") read <" << *line << ">" << endl;
+ }
+
+ if (line->substr(0, 8) != "feature ") return line;
+
+ string featname = line->substr(8);
+ if (featname == "write_lines") featureWriteLines = true;
+ else {
+ cerr << "Referee requested unsupported feature '" << featname << "'" << endl;
+ exit(1);
+ }
+ }
+}
+
void Referee::readScores() {
- optional<string> line = proc.readLine();
+ optional<string> line = readLine();
if (!line) {
cerr << "Referee stopped before providing scores" << endl;
exit(1);
}
- if (referee_verbose) {
- cout << "REF(" << proc.getPid() << ") readScores <" << *line << ">" << endl;
- }
-
size_t cursor = 0;
while (cursor < line->size()) {
size_t idx = line->find(' ', cursor);
diff --git a/referee.h b/referee.h
index 0121196..891021d 100644
--- a/referee.h
+++ b/referee.h
@@ -4,6 +4,7 @@
#include <string>
#include <string_view>
#include <optional>
+#include <utility>
#include "process.h"
using namespace std;
@@ -14,6 +15,10 @@ class Referee {
bool isEnd = false;
vector<int> scores;
+ bool featureWriteLines = false;
+ vector<pair<int, string>> writeLinesList;
+
+ optional<string> readLine();
void readScores();
public:
@@ -22,6 +27,7 @@ public:
// player: 0 = first player, 1 = second player
bool moveValid(int player, const string_view line);
+ vector<pair<int, string>> playerWriteLines();
bool gameEnded();
optional<vector<int>> getScores();
@@ -45,4 +51,14 @@ then write a line to stdout that is equal to either 'valid', 'invalid', or
'valid end', the referee should write a line containing as many integers
(separated by spaces) as there are players, giving their scores at the end of
the game.
+
+FEATURES
+At any time the referee may write 'feature <name>' to stdout, which enables the
+protocol feature with the given name. The following features are supported:
+- 'write_lines': After a move validity judgement, the referee should write lines
+ of the form '<player> <line>' to stdout, where <player> is the index of the
+ player on whose stdin to write <line>. The referee should signal the end of
+ this list by writing a line 'write_end' to stdout.
+ This allows the referee to write additional data to players' inputs after they
+ have written their moves.
*/