The interesting problem
Writing a Sudoku solver is a known exercise: backtracking search finishes in milliseconds. But a solver that brute-forces the answer cannot teach anyone anything, because "the answer is 7 because I tried every branch" is not a reason.
So the engine here solves the way a person does. It models candidates per cell and applies human techniques in ascending order of difficulty - naked single, hidden single, then pointing pairs, box/line reduction, and further - returning the simplest technique that makes progress on the current board, along with the cells that justify it.
That constraint, explainability over speed, is what makes the design non-trivial. The hint system and the difficulty grader fall out of it: a puzzle's rating is the hardest technique required to solve it without guessing.
Where the tests are
The logic is separated from the UI precisely so it can be tested as logic. Six unit-tested modules cover the core:
| Module | What it proves |
|---|---|
sudokuCore / sudokuEngine | Constraint propagation and validity |
sudokuGrader | Difficulty rating matches required technique |
nextHint | The right technique is chosen, with correct justification |
score | Scoring and streak rules |
dailyPuzzle | Deterministic daily generation |
Four Playwright specs cover the parts unit tests cannot: game flow, pausing, preferences, and resuming an interrupted session.
The rest
Installable PWA that works offline, keyboard-driven controls, pencil-mark notes with auto-fill, undo, and a bilingual interface. Deployed to GitHub Pages on every push.
