"""Bounded real Gomocup subprocess comparison; no score or production data writes. Example: .venvs/gomoku/bin/python games/gomoku/tests/compare.py --output /tmp/gomoku.json Use --season for the six benchmark openings, or --openings 10 for fresh paired ones. """ import argparse import json import pathlib import random import sys import time ROOT = pathlib.Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / 'referee')) from gomoku import match parser = argparse.ArgumentParser() parser.add_argument('--season', action='store_true') parser.add_argument('--seed', type=int, default=20261023) parser.add_argument('--openings', type=int, default=10) parser.add_argument('--output', type=pathlib.Path) args = parser.parse_args() if not 1 <= args.openings <= 30: parser.error('--openings must be between 1 and 30') if args.season: openings = [[tuple(map(int, p.split(','))) for p in line.split()] for line in (ROOT / 'referee/openings.txt').read_text().splitlines() if line and not line.startswith('#')] else: rng = random.Random(args.seed) pool = [(x, y) for x in range(4, 11) for y in range(4, 11) if (x, y) != (7, 7)] openings = [[(7, 7), *rng.sample(pool, 2)] for _ in range(args.openings)] new = ([sys.executable, str(ROOT / 'field/threats/bot.py')], str(ROOT)) old = ([sys.executable, str(ROOT / 'tests/fixtures/legacy_threats.py')], str(ROOT)) results, started = [], time.monotonic() for opening in openings: for colour in (0, 1): r = match([new, old] if colour == 0 else [old, new], opening) results.append({'opening': opening, 'colour': colour, 'winner': r['winner'], 'won': r['winner'] == colour, 'moves': len(r['moves']), 'max_ms': max(m[2] for m in r['moves']), 'reason': r['reason']}) print(json.dumps({'games': len(results), 'wins': sum(r['won'] for r in results)}), flush=True) summary = {'games': len(results), 'wins': sum(r['won'] for r in results), 'max_ms': max(r['max_ms'] for r in results), 'seconds': time.monotonic() - started} print(json.dumps(summary)) if args.output: args.output.write_text(json.dumps({'summary': summary, 'games': results}, indent=2))