Gameplay (legal moves, move application, pressure maps, PGN parsing) now runs entirely in the browser via a chess.js port of engine.py (static/engine.js + vendored chess.min.js). The app no longer calls the server during play, so it stays instant and works even when the backend is scaled to zero or offline. - engine.js: line-for-line port of engine.py; parity-verified identical output (pressure, FEN, status, SAN/UCI) across all 10 built-in games / 829 frames. - app.js: replace all /api fetches with local engine calls; graceful PGN parse errors; asset paths moved to root for static serving. - Save games to localStorage + load from the game dropdown; export any game as a .pgn file. Minimal additive UI in the existing export row. - games.json generated from games.py (scripts/export_games.py). - Production Dockerfile -> static-web-server (~9MB image, was ~150MB python). - make dev -> bun static server; add make games / make parity targets. - app.py kept as optional fallback (serves static app + /api routes). - parity/: automated JS-vs-python engine parity test. git diff stat: 16 files changed, 722 insertions(+), 128 deletions(-)
27 lines
633 B
Python
27 lines
633 B
Python
"""Dump python-chess engine output for every built-in game as JSON on stdout.
|
|
|
|
Consumed by check.js to verify the JS engine produces identical results.
|
|
Run from the package root: `uv run python parity/dump_python.py`.
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
|
|
from chess_pressure.engine import parse_pgn
|
|
from chess_pressure.games import GAMES
|
|
|
|
out = []
|
|
for g in GAMES:
|
|
parsed = parse_pgn(g["pgn"])
|
|
out.append(
|
|
{
|
|
"id": g["id"],
|
|
"pgn": g["pgn"],
|
|
"moves": parsed["moves"],
|
|
"frames": parsed["frames"],
|
|
"result": parsed["result"],
|
|
}
|
|
)
|
|
|
|
json.dump(out, sys.stdout)
|