Skip to content
All projects

Nine to One

A real-time multiplayer card game for two to five players, built for the phone. Empty seats fill up with bots, including one trained by self-play.

Game
Completed
2026
1 semaines
  • Next.js
  • TypeScript
  • FastAPI
  • WebSocket
  • PyTorch
  • NumPy
  • PostgreSQL
  • Tailwind CSS
Nine to One

A card game I play with my friends that nobody had brought online. You enter a nickname, create a table and share its code: no account, no install, the address opens in a phone browser and the game starts.

Real time

Every table lives in the server's memory and talks to players over WebSocket. The server is the only referee: it applies the rules, computes the legal moves and sends each player strictly what they are allowed to see. The client holds no game logic, it renders a state and forwards intentions.

The rules engine is covered by 68 tests. A card game is mostly a long list of edge cases, and each one earned its test after catching me out mid-game.

The bots

Three levels. The first plays a random legal move, the second follows a hand-written heuristic, the third is a neural network trained by self-play with reinforcement learning, then exported to NumPy so production runs without PyTorch. When its turn comes, it refines the decision with a search over the cards it cannot see.

That bot does not cheat: it gets exactly the view of a player sitting in its seat. It thinks in a separate thread, with a bounded time budget and a cap on concurrent searches, so the network loop keeps serving the other tables meanwhile. The whole process fits in 75 MB, network weights included, on a VPS shared with my other sites.