"""The project's referee. check: the route's brain against the season's field, every opening, both colours; the score is the share of points won (a win 1, a draw 0.5), each field brain a subtask. practice: one opening each, both colours, a replay of every game in replays/. python3 -I referee/play.py check|practice """ import json, os, sys ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(ROOT, 'kit')) sys.path.insert(0, os.path.join(ROOT, 'referee')) import league # noqa: E402 from gomoku import match # noqa: E402 PY = [sys.executable, '-s'] def brain(folder): """A folder's brain: an executable named pbrain (any language, as Gomocup brains are), else bot.py.""" exe = os.path.join(folder, 'pbrain') if os.path.isfile(exe) and os.access(exe, os.X_OK): return [exe], folder if os.path.isfile(os.path.join(folder, 'bot.py')): return [*PY, 'bot.py'], folder sys.exit(f'No brain in {folder}: add bot.py (a Gomocup brain in Python) or an executable pbrain') def openings(): with open(os.path.join(ROOT, 'referee', 'openings.txt')) as f: return [[tuple(map(int, p.split(','))) for p in l.split()] for l in f if l.strip() and not l.startswith('#')] def main(mode, route): me = brain(league.bot_dir(route)) name = league.route_name() ops = openings() if mode == 'check' else openings()[:1] reps = league.Replays() if mode == 'practice' else None subtasks = {} for opp in league.field(os.path.join(ROOT, 'field')): them = brain(os.path.join(ROOT, 'field', opp)) points = 0.0 for k, op in enumerate(ops): for black in (0, 1): # 0: the route plays black seats = [me, them] if black == 0 else [them, me] r = match(seats, op) mine = black # the route's colour index: 0 black, 1 white points += 1.0 if r['winner'] == mine else 0.5 if r['winner'] is None else 0.0 if reps: who = [name, opp] if black == 0 else [opp, name] r['players'] = who end = 'a draw' if r['winner'] is None else f'{who[r["winner"]]} wins ({r["reason"]})' reps.add(f'{opp}-{k}-{"black" if black == 0 else "white"}.json', r, f'{who[0]} (black) vs {who[1]} (white), opening {k + 1}', who, f'{end} in {len(r["moves"]) - r["opening"]} moves') subtasks[opp] = points / (2 * len(ops)) league.write_metrics(sum(subtasks.values()) / len(subtasks), subtasks) if __name__ == '__main__': main(sys.argv[1], sys.argv[2])