Add briscola: classic two-player and briscola a quattro
CI / Build and push docker image (push) Successful in 1m45s
CI / Build and push docker image (push) Successful in 1m45s
New tavolo-briscola distribution implementing briscola on the platform: - pure rules (state.py, engine.py): 3-card deals, a face-up trump that is the last card drawn, trump-first trick resolution (A > 3 > K > H > J > 7 > 6 > 5 > 4 > 2), 120 points per deal, 60-60 patta re-deals, a configurable target score (default 61), deal-end acknowledgements and turn auto-play; - BriscolaEngine (briscola, 2 players) and BriscolaQuattroEngine (briscola_a_quattro, 4 players in fixed partnerships) adapters; - registered in tavolo-app, packaged in the Docker image, documented. Platform fixes surfaced by a two-player lobby: - the websocket state and snapshot payloads now carry seats_open (they were only in the REST lobby payload), so lobbies with player counts other than four render correctly; seats_open is clamped at zero; - the web client logs unparseable server messages instead of silently dropping them. Web client: briscola table for both variants (stock, face-up trump, trick, last-trick banner), deal summary modal and game-over overlay. Tests: tavolo-briscola rules/adapter suites, app integration tests (lobby, websocket play, turn timeout, deal-end acks, persistence), a platform seats_open test and frontend model parsing tests.
This commit is contained in:
34 files changed
+3610
-90
No files matched your search
@@ -2,14 +2,15 @@
|
||||
|
||||
The deployable tavolo application: the composition root wiring
|
||||
[`tavolo-platform`](../tavolo-platform/README.md) to the
|
||||
[`tavolo-scopone`](../tavolo-scopone/README.md) game.
|
||||
[`tavolo-scopone`](../tavolo-scopone/README.md) and
|
||||
[`tavolo-briscola`](../tavolo-briscola/README.md) games.
|
||||
|
||||
## Contents
|
||||
|
||||
- `app.py` — assembles the `KayaApp` (session/OIDC/Tortoise/OpenAPI
|
||||
mixins plus `PlatformMixin` and the deadline scheduler), registers the
|
||||
`ScoponeEngine` with its configured timeouts, and exposes
|
||||
`tavolo.app:app` for granian.
|
||||
`ScoponeEngine`, `BriscolaEngine` and `BriscolaQuattroEngine` with
|
||||
their configured timeouts, and exposes `tavolo.app:app` for granian.
|
||||
- `config.py` — environment-driven frozen `Settings`.
|
||||
- `telemetry.py` — the optional OpenTelemetry wiring beyond kaya-otel:
|
||||
meter/tracer/logger providers, the
|
||||
|
||||
@@ -5,12 +5,13 @@ build-backend = "setuptools.build_meta"
|
||||
[project]
|
||||
name = "tavolo-app"
|
||||
version = "0.1.0"
|
||||
description = "Tavolo multiplayer card-game application: platform + scopone game wiring"
|
||||
description = "Tavolo multiplayer card-game application: platform + games wiring"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"tavolo-platform",
|
||||
"tavolo-scopone",
|
||||
"tavolo-briscola",
|
||||
"kaya-core",
|
||||
"kaya-cors",
|
||||
"kaya-session",
|
||||
|
||||
@@ -39,6 +39,7 @@ from kaya.oidc import OIDCConfig, OIDCProviders
|
||||
from kaya.openapi import OpenAPIMixin
|
||||
from kaya.session import SessionMixin
|
||||
from redis.asyncio import Redis
|
||||
from tavolo.briscola import BriscolaEngine, BriscolaQuattroEngine
|
||||
from tavolo.platform import GameRegistry, Platform, PlatformMixin
|
||||
from tavolo.platform.deadlines import DeadlineScheduler, DeadlineSchedulerMixin
|
||||
from tavolo.platform.store import GameStore, InMemoryGameStore, RedisGameStore
|
||||
@@ -131,9 +132,21 @@ registry.register(
|
||||
hand_ack_timeout_seconds=settings.hand_ack_timeout_seconds,
|
||||
)
|
||||
)
|
||||
registry.register(
|
||||
BriscolaEngine(
|
||||
turn_timeout_seconds=settings.turn_timeout_seconds,
|
||||
hand_ack_timeout_seconds=settings.hand_ack_timeout_seconds,
|
||||
)
|
||||
)
|
||||
registry.register(
|
||||
BriscolaQuattroEngine(
|
||||
turn_timeout_seconds=settings.turn_timeout_seconds,
|
||||
hand_ack_timeout_seconds=settings.hand_ack_timeout_seconds,
|
||||
)
|
||||
)
|
||||
log.info("registered games: %s", ", ".join(e.id for e in registry.all()))
|
||||
log.debug(
|
||||
"scopone timeouts: hand_ack=%ds turn=%ds",
|
||||
"game timeouts: hand_ack=%ds turn=%ds",
|
||||
settings.hand_ack_timeout_seconds,
|
||||
settings.turn_timeout_seconds,
|
||||
)
|
||||
|
||||
@@ -215,12 +215,12 @@ class Settings:
|
||||
# are served by Granian under /static (GRANIAN_STATIC_PATH_* env vars).
|
||||
static_dir: str
|
||||
# Seconds the between-hands scoring summary waits for acknowledgements
|
||||
# before dealing the next hand anyway (wired into the ScoponeEngine;
|
||||
# before dealing the next hand anyway (wired into the game engines;
|
||||
# see tavolo.app).
|
||||
hand_ack_timeout_seconds: int
|
||||
# Seconds a player has to play before the server plays a random legal
|
||||
# card for them, covering disconnects and idle players (wired into the
|
||||
# ScoponeEngine; see tavolo.app).
|
||||
# game engines; see tavolo.app).
|
||||
turn_timeout_seconds: int
|
||||
# Upper bound on how long the deadline consumer sleeps between polls
|
||||
# when nothing else wakes it. Enqueued deadlines are announced over a
|
||||
|
||||
Reference in new issue
Block a user