Move the game-independent machinery (lobby, live-game store, websocket, deadline scheduler, match history, leaderboards) into a new tavolo-platform distribution behind a GameEngine contract, the scopone scientifico rules plus a platform adapter into tavolo-scopone, and keep only the composition root in tavolo-app. The three distributions share the tavolo namespace (PEP 420, kaya-style monorepo). Match history becomes fully generic: Match carries the engine's result JSON and MatchPlayer points/details instead of scopone-shaped team columns (migration 3 backfills existing rows). Lobby creation takes an opaque per-game options object and websocket actions dispatch to the session's engine. Tests: platform suite runs against a DummyEngine toy game, scopone keeps the rules tests plus new adapter tests, server/tests covers the wired stack end to end (194 tests, was 143).
37 lines
1.6 KiB
Markdown
37 lines
1.6 KiB
Markdown
# tavolo-scopone
|
|
|
|
Scopone scientifico — the four-player, fixed-partnership Italian card
|
|
game — as a [`tavolo-platform`](../tavolo-platform/README.md) game
|
|
implementation.
|
|
|
|
## Contents
|
|
|
|
- `state.py` — `ScoponeState` (pure game data: phases, players, hands,
|
|
table, scores, deadlines), `PlayerState`, `Card`, `Move`, with JSON
|
|
(de)serialization. No session envelope, no transport, no I/O.
|
|
- `engine.py` — the pure rules engine: deck, legal captures, plays,
|
|
auto-play, hand scoring (carte, denara, settebello, primiera, scope,
|
|
napola), hand-end acknowledgements. Deterministic and I/O-free apart
|
|
from logging, so the whole rule set is unit-testable.
|
|
- `errors.py` — scopone-specific errors (`CardNotInHand`); every other
|
|
failure mode is a shared `tavolo.platform.errors` subclass.
|
|
- `plugin.py` — `ScoponeEngine(GameEngine)`: the platform-facing adapter.
|
|
It translates create/join/websocket actions/deadlines into rules-engine
|
|
calls and back, validates the `target_score`/`napola` creation options,
|
|
and extracts the `MatchResult` (teams, winner, per-player scores and the
|
|
match summary persisted as the match's JSON `result`).
|
|
|
|
Timeouts are constructor arguments (`turn_timeout_seconds`,
|
|
`hand_ack_timeout_seconds`), wired from the environment by the
|
|
application composition root.
|
|
|
|
## Development (from `server/`)
|
|
|
|
```sh
|
|
.venv/bin/python -m unittest discover -s packages/tavolo-scopone/tests
|
|
.venv/bin/python -m mypy -p tavolo.scopone
|
|
```
|
|
|
|
`test_engine.py` covers the pure rules; `test_plugin.py` covers the
|
|
platform contract (actions, deadlines, serialization, results).
|