summaryrefslogtreecommitdiff
path: root/referee.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'referee.cpp')
-rw-r--r--referee.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/referee.cpp b/referee.cpp
new file mode 100644
index 0000000..3f15b6b
--- /dev/null
+++ b/referee.cpp
@@ -0,0 +1,92 @@
+#include <iostream>
+#include <cstdlib>
+#include "referee.h"
+#include "params.h"
+
+
+Referee::Referee(const string_view execname, const vector<string> &players)
+ : proc(execname) {
+
+ proc.run();
+
+ if (referee_verbose) {
+ cout << "REF(" << proc.getPid() << ") starting for:";
+ for (const string &p : players) cout << " " << p;
+ cout << endl;
+ }
+
+ proc.writeLine(to_string(players.size()));
+ for (const string &p : players) {
+ proc.writeLine(p);
+ }
+}
+
+Referee::~Referee() {
+ if (referee_verbose) {
+ cout << "REF(" << proc.getPid() << ") stopping" << endl;
+ }
+ proc.wait();
+ proc.terminate();
+}
+
+bool Referee::moveValid(int player, const string_view line) {
+ string s = to_string(player) + " ";
+ s.append(line);
+
+ if (referee_verbose) {
+ cout << "REF(" << proc.getPid() << ") write <" << s << ">" << endl;
+ }
+
+ proc.writeLine(s);
+
+ optional<string> response = proc.readLine();
+ if (response) {
+ if (referee_verbose) {
+ cout << "REF(" << proc.getPid() << ") read <" << *response << ">" << endl;
+ }
+
+ if (*response == "valid end") {
+ isEnd = true;
+ readScores();
+ return true;
+ } else if (*response == "valid") {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if (referee_verbose) {
+ cout << "REF(" << proc.getPid() << ") EOF!" << endl;
+ }
+ return false;
+ }
+}
+
+bool Referee::gameEnded() {
+ return isEnd;
+}
+
+void Referee::readScores() {
+ optional<string> line = proc.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);
+ if (idx == string::npos) idx = line->size();
+ scores.push_back(stoi(line->substr(cursor, idx - cursor)));
+ cursor = idx + 1;
+ }
+}
+
+optional<vector<int>> Referee::getScores() {
+ if (isEnd) return scores;
+ else return nullopt;
+}