# tavolo-briscola Briscola — the Italian trick-taking game — as a [`tavolo-platform`](../tavolo-platform/README.md) game implementation. Two variants share one rules core: - `briscola` — the classic two-player game; - `briscola_a_quattro` — four-player fixed-partnership briscola. ## Contents - `state.py` — `BriscolaState` (pure game data: phases, players, hands, stock, face-up briscola, tricks, scores, deadlines), `PlayerState`, `Card`, `TrickCard`, `Trick`, with JSON (de)serialization. No session envelope, no transport, no I/O. - `engine.py` — the pure rules engine: deck, deals, trick resolution (trump first, then the led suit; strength ace > three > king > horse > jack > 7 > 6 > 5 > 4 > 2), the draw order (trick winner first, the face-up briscola last), card points (ace 11, three 10, king 4, horse 3, jack 2), patta re-deals and the target-score match end, deal-end acknowledgements and auto-play. Deterministic and I/O-free apart from logging, so the whole rule set is unit-testable. - `errors.py` — briscola-specific errors (`CardNotInHand`); every other failure mode is a shared `tavolo.platform.errors` subclass. - `plugin.py` — `BriscolaEngine` and `BriscolaQuattroEngine` (`GameEngine`): the platform-facing adapters. They validate the `target_score` creation option (61–120, default 61) 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. ## Rules - Three cards per player; the next card is turned face up: its suit is the trump (briscola) for the deal and it is the last card drawn. - The winner of a trick is the highest trump, or the highest card of the led suit when no trump was played. The winner takes the trick and leads the next one. - After each trick everyone draws back up to three cards, starting with the trick winner. - Card points total 120 per deal; a 60–60 deal is a *patta*, its points are discarded and the deal is replayed. The first team to the target score wins; a tie at or above the target is broken by another deal. - Between deals of an unfinished match every player acknowledges the summary (or the hand-end timeout deals on), exactly like scopone. ## Development (from `server/`) ```sh .venv/bin/python -m unittest discover -s packages/tavolo-briscola/tests .venv/bin/python -m mypy -p tavolo.briscola ``` `test_engine.py` covers the pure rules; `test_plugin.py` covers the platform contract (actions, deadlines, serialization, results).