Download code/docs/interfaces.md from nima1/stackcraft-clef-flash-lora: direct link, hf CLI and curl.
- Browser
- Download file 3.59 kB
-
https://huggingface.co/nima1/stackcraft-clef-flash-lora/resolve/main/code/docs/interfaces.md
- Command line
-
hf download hf://nima1/stackcraft-clef-flash-lora/code/docs/interfaces.md
-
curl -L -o interfaces.md https://huggingface.co/nima1/stackcraft-clef-flash-lora/resolve/main/code/docs/interfaces.md
Initial implementation contract
The Python engine is authoritative. These names are shared across independently implemented engine, service, and UI. All board coordinates have x increasing right and y increasing down; rows are top to bottom. Board cells are 0 for empty or 1 through 7 for piece colors. Board width is 10, height is 20. Four normalized orientations are enumerated and duplicate shapes removed.
schema.py defines frozen dataclasses: Placement(id: str, rotation: int, x: int, y: int, cells: tuple[tuple[int,int], ...]); GameState(board: tuple[tuple[int,...],...], seed: int, piece_index: int, current: str, next_piece: str, score: int=0, lines: int=0, terminal: bool=False); Transition(state: GameState, action: Placement, cleared: int).
pieces.py: piece_at(seed: int, index: int) -> str, rotations(piece: str) -> tuple[tuple[tuple[int,int],...],...]. Piece colors map in order I,O,T,S,Z,J,L to 1..7. Deterministic sequence is versioned, uses a local random generator, and is identical regardless of player pace.
engine.py: new_game(seed: int) -> GameState, legal_actions(state: GameState) -> tuple[Placement,...], step(state: GameState, action_id: str) -> Transition. Action IDs are r{rotation}x{x}. Placements are straight vertical hard drops starting fully within the board. No legal placement means terminal. An illegal or terminal-state action raises ValueError without mutating state. legal_actions includes landing y and absolute cell positions so clients can display a ghost without computing game rules. Clear rows simultaneously, score 100/300/500/800 for 1/2/3/4 lines, advance piece index, and detect next-piece top-out.
replay.py: make_replay(seed: int, actions: list[str]) -> dict computes a JSON-serializable artifact containing schema_version: 1, rules_version: "stackcraft-v1", seed, action IDs, and final score/lines/pieces/terminal. replay_states(artifact: dict) -> list[GameState] validates versions and actions and returns initial plus successive states; validate final summary if provided.
Service HTTP endpoints (all JSON unless noted): GET / serves the game; POST /api/games with {seed: int} returns a session snapshot; POST /api/games/{id}/moves with {action_id: str, expected_pieces: int} returns its next snapshot; GET /api/games/{id} snapshot; GET /api/games/{id}/replay returns replay artifact; POST /api/replays with an artifact returns {frames: [snapshot_without_id,...]}. GET /health returns {status:"ok"}. Snapshots contain id, board, current, next_piece, score, lines, pieces (piece index), terminal, legal_actions (serialized Placement). Error responses have readable detail; unknown session 404, invalid action/replay 422, stale expected_pieces 409. On uncertain move response the client refreshes state before allowing another move; replay retries must not advance a second piece. API never reveals future piece stream to model adapters (seed exists only in server storage/replay).
UI uses these routes directly with fetch; no second simulator. Arrow left/right selects legal placements at current rotation, up rotates selection, space/Enter drops. Buttons allow all actions. Restart requests the seed input again. Download replay and load replay use the above endpoints, with frame stepping. UI source belongs in src/stackcraft/web/ and uses vanilla JS/CSS/HTML to avoid a second package manager. Label the game as turn-based placement; no hold, tucks, kicks, T-spin bonuses or gravity timer. Comparison boards will be added after baselines.