Sudoku Enjoyer
Twelve Sudoku variants, async multiplayer, and a generator that guarantees every puzzle is solvable by hand.
Status: Deployed on AWS, public release pending
Built with
- Flutter
- Dart
- C# / .NET 8
- AWS CDK
- DynamoDB
- Cognito
- Next.js
A Sudoku platform rather than a Sudoku app: twelve variants, asynchronous multiplayer races, global and per-puzzle leaderboards, and a community puzzle library. All free, with no ads and no payment code anywhere in the repository.
The hard part is the generator, not the UI
Twelve variants: classic 9×9, a 6×6 practice grid, X-Sudoku, Hyper (Windoku), Killer, Jigsaw, Even-Odd, Consecutive, Greater-Than, Arrow, Samurai (five overlapping grids, 369 unique cells) and a hexadecimal 16×16 board, across up to six difficulty tiers.
Every generated puzzle has to satisfy two properties, not one: a unique solution, and a path to that solution using human techniques alone. The same technique ladder that grades difficulty powers the hints, so a puzzle that cannot be reasoned through is one the hint system could not explain either.
Most variants extend the topology and reuse the solver unchanged. Killer is a real constraint extension: cages, sum pruning and the 45-rule, graded by a cage-aware search. It is also the one documented deviation from the human-technique pledge, because the human ladder has no cage techniques, and it is marked as such rather than quietly glossed over.
Deterministic puzzle identity
Every puzzle has a canonical SHA-256 identity. Two devices that generate the same board agree on its hash, which is what makes a per-puzzle leaderboard possible at all, and what lets the server reject a duplicate community submission and offer "play it" or "rate it" instead.
Offline-first, with the backend doing only what needs a server
The entire game engine, every variant included, is pure Dart running on the device. Solo play, local statistics and your own ratings work with no account and no connection.
The backend exists for what genuinely needs an identity: accounts, async multiplayer lobbies (up to eight players by join code, each playing on their own schedule), leaderboards and community publishing. Guests never write to it.
Run as a non-profit, with cost as a design constraint
The app was originally designed around banner ads and a subscription. That was reversed deliberately: the ad SDK, the entitlement enum, the server-side premium policy and the client subscriber flag were deleted rather than left dormant behind a feature flag. There is no monetization code left to thaw.
With no revenue to scale against, the hosting bill is bounded structurally instead: API throttling, anonymous usage instrumentation to size infrastructure honestly, and budget alarms on the account.
Stack
Client: a Flutter melos workspace split into four packages (engine, models, API client, storage), so the game logic is testable without a widget tree.
Backend: C#/.NET 8 on AWS, deployed with CDK. An HTTP API and a WebSocket API behind API Gateway, Cognito for identity, DynamoDB for state.
Web: a Next.js static-export marketing site on a private S3 bucket behind CloudFront, with the Flutter web build served at /play.