About
Hi all,
Evil Sudoku - https://evilsudoku.online - free browser Sudoku, no signup, desktop and mobile. The generation architecture is the part that actually took work, so that's what I'll write about.
The design decision. Most Sudoku games ship three or four difficulty buckets. I went with a continuous slider instead: 31 steps, from 30 to 60 removed cells. Difficulty N means N cells stripped from a completed grid, so the slider runs from 51 clues down to 21 - near the practical floor, given that 17 is the proven minimum for a uniquely solvable puzzle.
I know the objection, so let me get ahead of it: clue count is not the same thing as logical difficulty, and a technique-ranked solver would grade far more accurately. That's a deliberate tradeoff. What a slider buys you is something buckets can't: a player who finds 44 too easy moves to 45, not to a category that's twice as hard. Difficulty becomes something you dial while you play rather than something you pick from a menu before you start - and "More Evil" turns out to be a much better button than "Hard".
Generation. Nothing is pre-baked or fetched - every puzzle is generated on demand in the browser. A backtracking solver builds a full grid and strips cells down to the requested count. The problem is that cost is violently non-linear: difficulty 30 lands in a few milliseconds, difficulty 50 can take seconds, because most attempts fail and get thrown away.
The fix is a pool of five web workers racing the same request. First valid grid wins, the others get cancelled. Because attempts are independent and the runtime distribution has a long right tail, racing five of them improves the felt latency far more than a 5× speedup would - you're sampling the minimum of five draws, not dividing the mean by five. The main thread never blocks, so the board stays responsive even at the top of the slider.
Everything else is the standard kit: pencil-mark notes, live timer, mistake counter, plus strategy guides from singles up through Swordfish.
What I'd take feedback on: whether five is the right pool size - I landed on it empirically and never tuned it against actual core counts - and whether anyone has a cheap trick for tightening the tail at 55+ removed without going full constraint propagation.
