From e2279628e551e5c82f70c739f6c02671e6ccd9fd Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Fri, 15 Feb 2019 12:11:33 +0100 Subject: Feature 'write_lines' -- UNTESTED! --- main.cpp | 6 ++++++ referee.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++++++------------ referee.h | 16 ++++++++++++++ 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 ¶ms) { 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> 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 response = proc.readLine(); + optional 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 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> Referee::playerWriteLines() { + return writeLinesList; +} + bool Referee::gameEnded() { return isEnd; } +optional Referee::readLine() { + while (true) { + optional 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 line = proc.readLine(); + optional 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 #include #include +#include #include "process.h" using namespace std; @@ -14,6 +15,10 @@ class Referee { bool isEnd = false; vector scores; + bool featureWriteLines = false; + vector> writeLinesList; + + optional 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> playerWriteLines(); bool gameEnded(); optional> 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 ' 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 ' ' to stdout, where is the index of the + player on whose stdin to write . 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. */ -- cgit v1.2.3