#include #include #include "referee.h" #include "params.h" Referee::Referee(const string_view execname, const vector &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 response = readLine(); if (response) { bool result; if (*response == "valid end") { isEnd = true; readScores(); result = true; } else if (*response == "valid") { result = true; } else { 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; } return false; } } 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 = readLine(); if (!line) { cerr << "Referee stopped before providing scores" << endl; exit(1); } 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> Referee::getScores() { if (isEnd) return scores; else return nullopt; } void Referee::terminate() { proc.terminate(); }