rust-sixtysix
Minimal backend engine + HTTP API for the traditional 24-card trick-taking game Sixty-six (AKA Schnapsen variant family). Built in Rust for frontend clients (web, mobile, CLI bots) that want a stateless, deterministic core.
This is a Rust adaptation of go-sixtysix, matching its functionality and API surface.
Rules reference: Wikipedia – Sixty-six. This implementation models a standard two-player deal with marriages, closing the stock, trump exchange, and last trick bonus.
Contents
- Features
- Install
- Quick Start
- Container Image
- Concepts
- HTTP API
- Game Rules Summary
- Frontend Integration Ideas
- Project Layout
- Contributing
- Security
- License
Features
- Deterministic game state creation (seeded RNG) for reproducible replays
- Lightweight in-memory session store (pluggable trait interface)
- Clear
Gametrait (validate + apply immutable state transitions) - HTTP API with small surface (sessions + actions) via axum
- Test coverage across engine, store, rules, and API
- Simple deployment (single binary)
Install
Requires Rust 1.70+.
Add as dependency:
[]
= { = "https://github.com/rumendamyanov/rust-sixtysix" }
Or clone and use directly:
Typical usage:
use Engine;
use SixtySix;
use Memory;
use Arc;
Quick Start
- Build the project:
cargo build - Run the demo server:
- Create a session (seed optional):
|
- List sessions:
|
- Play a card (
cardis an encoded intsuit*100+rankValue):
|
- Close stock:
More examples: see docs/api.md.
Container Image
Build locally (multi-stage):
Run:
Pass a different listen port:
Concepts
Engine pieces:
| Piece | Purpose |
|---|---|
engine::Game |
Rule set trait: initial_state, validate, apply |
engine::Engine |
Registers games, manages sessions, dispatches actions |
store::Store |
Persistence trait (memory impl provided) |
api::create_router |
Minimal HTTP adapter (serves JSON via axum) |
Card encoding: suit*100 + rankValue where suits: Clubs=0, Diamonds=1, Hearts=2, Spades=3; rank values: A=11, 10=10, K=4, Q=3, J=2, 9=0.
HTTP API
Core endpoints:
| Method | Path | Description |
|---|---|---|
| GET | /healthz |
Liveness probe |
| GET | /games |
List registered games |
| POST | /sessions?game=sixtysix&seed=SEED |
Create session |
| GET | /sessions?game=sixtysix&offset=0&limit=20 |
Page sessions |
| GET | /sessions/{id} |
Fetch session (state snapshot) |
| POST | /sessions/{id} |
Apply action {type,payload} |
| DELETE | /sessions/{id} |
Delete session |
Schemas + examples: docs/api.md.
Actions
| Type | Payload | Effect |
|---|---|---|
play |
{card:int} |
Play a card; resolves trick after 2 plays |
closeStock |
- | Close stock: no further drawing; must follow suit |
declare |
{suit:int} |
Marriage (K+Q) scoring (20 / 40 trump) at lead |
exchangeTrump |
- | Swap 9 of trump with upcard (while stock open, at lead) |
Game Rules Summary
Short form (see docs/rules.md for detail):
- 24-card deck (A 10 K Q J 9 in four suits). Deal 6 each (3+3), stock remainder, last card face-up = trump.
- Leader plays any card when stock open; follower may play any card until stock closed or empty; then must follow suit if possible.
- Trick winner: higher of suit led; trumps beat non-trumps.
- Winner scores captured card values; first to 66 ends deal; +10 last trick bonus.
- Marriage declaration at lead (holding K+Q) scores 20 (non-trump) or 40 (trump).
- Trump 9 exchange allowed at lead while stock open.
Frontend Integration Ideas
- Maintain local optimistic state while posting actions (server returns authoritative state version).
- Use the seed to recreate initial hands client-side for replay / spectator mode.
- Visual mapping for encoded cards:
suit = c/100,rankValue = c%100-> show face; build a lookup table. - Implement WebSocket push wrapper watching session updates for real-time UI (out of scope here, easy extension).
See docs/integration.md for architecture suggestions.
Project Layout
src/
lib.rs # Crate root, module exports
game.rs # Sixty-six game rules implementation
engine.rs # Core engine + session orchestration
store/ # In-memory store (trait for alt backends)
mod.rs
memory.rs
api/ # HTTP server wiring (axum)
mod.rs
server.rs
examples/
server.rs # Example executable (demo server)
docs/ # Extended docs (rules, API, integration)
Extended documents:
Future ideas: persistence backends, matchmaking service, WebSocket streaming, multi-deal match structure.
Infrastructure Philosophy
This repository intentionally ships only:
- A minimal HTTP example (
examples/server.rs) - A single multi-stage
Dockerfile - An optional ergonomic
Makefile(build/test/run/docker shortcuts)
Rationale: keep the core game engine small, dependency-light, and easy to embed.
Contributing
See CONTRIBUTING.md. Please follow the Code of Conduct.
Security
Report vulnerabilities privately – process described in SECURITY.md.
Funding / Support
If you find this useful, see FUNDING.md.
License
MIT – see LICENSE.md.