# tavolo-scopa Scopa — the classic Italian fishing game — in its two-player form and in the four-player fixed-partnership variant (*scopa a quattro*), as [`tavolo-platform`](../tavolo-platform/README.md) game implementations. The optional *asso pigliatutto* creation option turns either variant into **scopa d'assi**. ## Contents - `state.py` — `ScopaState` (pure game data: phases, players, hands, table, the deck persisting between rounds, 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, round re-dealing, hand scoring (carte, denara, settebello, primiera, scope), the optional asso pigliatutto capture, hand-end acknowledgements. Deterministic and I/O-free apart from logging, so the whole rule set is unit-testable. - `errors.py` — scopa-specific errors (`CardNotInHand`); every other failure mode is a shared `tavolo.platform.errors` subclass. - `plugin.py` — `ScopaEngine` (two players) and `ScopaQuattroEngine` (four players in fixed partnerships): the platform-facing adapters. They translate create/join/websocket actions/deadlines into rules-engine calls and back, validate the `target_score`/`asso_pigliatutto` creation options (the match target defaults to the traditional 11 points for two-player scopa and 21 for scopa a quattro), and extract 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-scopa/tests .venv/bin/python -m mypy -p tavolo.scopa ``` `test_engine.py` covers the pure rules; `test_plugin.py` covers the platform contract (actions, deadlines, serialization, results).