File size: 3,018 Bytes
4be6a52 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | """Small CLI that keeps optional model dependencies out of the game path."""
import argparse
import json
from pathlib import Path
def main() -> None:
parser = argparse.ArgumentParser(description="Stackcraft: play, replay, and measure decisions.")
parser.add_argument("--version", action="version", version="stackcraft 0.1.0")
commands = parser.add_subparsers(dest="command", required=True)
serve = commands.add_parser("serve", help="Start the local game and replay service")
serve.add_argument("--host", default="127.0.0.1")
serve.add_argument("--port", type=int, default=8080)
tournament = commands.add_parser("tournament", help="Run paired offline development baselines")
tournament.add_argument("--seed-start", type=int, default=1000)
tournament.add_argument("--episodes", type=int, default=20)
tournament.add_argument("--max-pieces", type=int, default=100)
tournament.add_argument("--output", type=Path, required=True)
generate = commands.add_parser("generate-data", help="Generate and audit expert-labelled data")
generate.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
if args.command == "serve":
import uvicorn
uvicorn.run("stackcraft.server:create_app", factory=True, host=args.host, port=args.port)
elif args.command == "tournament":
from stackcraft.players import HeuristicPlayer, RandomPlayer
from stackcraft.tournament import run_tournament
if args.episodes < 1 or args.max_pieces < 1:
parser.error("--episodes and --max-pieces must be positive")
if args.output.exists():
parser.error(f"output already exists: {args.output}; choose a new path")
seeds = list(range(args.seed_start, args.seed_start + args.episodes))
result = run_tournament(
{"random": RandomPlayer, "heuristic": HeuristicPlayer}, seeds, args.max_pieces
)
args.output.parent.mkdir(parents=True, exist_ok=True)
with args.output.open("x") as output:
json.dump(result, output, indent=2, allow_nan=False)
output.write("\n")
print(f"Saved {args.episodes} paired development episodes to {args.output}")
elif args.command == "generate-data":
from stackcraft.data import DatasetConfig, generate_dataset, write_dataset
from stackcraft.provenance import source_identity
if args.output.exists():
parser.error(f"output already exists: {args.output}; choose a new path")
try:
identity = source_identity(Path(__file__).resolve().parents[2])
except ValueError as error:
parser.error(str(error))
commit = identity["source_commit"] + ("+working-tree" if identity["source_dirty"] else "")
bundle = generate_dataset(DatasetConfig(), source_commit=commit)
write_dataset(bundle, args.output)
print(f"Saved expert dataset and manifest to {args.output}")
if __name__ == "__main__":
main()
|