#!/usr/bin/env python3 """compare.py -- oracle check of the C++ walker against the reference reader. usage: compare.py --reader SAVE_READER.py --saves DIR --dumps DIR [--python PY] For every DIR/*.sav it runs `save_reader.py SAVE --dump --padding joint` and reads the C++ dump written by test_save (`.cpp.dump` in --dumps), then reports two agreement figures per save: exact lines identical (including the `?` guess marks and `(alt ...)`) canonical lines identical after normalising what is presentation only: guess marks and alt readings dropped, 4-byte words compared by their raw bytes (an int reading and a float reading of the same word are the same datum), strings compared by content. The typed summary (game name, turn, numSys, players) is compared as well. Exit status 1 when any canonical line differs or a summary disagrees. """ import argparse import ast import glob import json import os import re import shlex import struct import subprocess import sys LINE = re.compile(r"^@([0-9a-f]{8}) (\s*)(\S+|) (\S+?)(\??) ?(.*)$") def canon(line: str) -> str: m = LINE.match(line) if not m: return line off, indent, name, kind, _guess, rest = m.groups() rest = re.sub(r"\s+\(alt .*\)$", "", rest) if kind in ("int", "float"): try: raw = struct.pack("