Getting started
Overview
Mental model — Board, PuzzleEngine, meta constraints, and when to use BatchEngine.
Overview
@reetesh/sudoku-engine is a library for generating, validating, playing, and solving Sudoku puzzles in TypeScript. It ships no UI — you render boards yourself.
Current version: 3.0.0
Concepts
| Concept | Meaning |
|---|---|
| Board | (number | null)[][] — null = empty cell |
| House | Fixed set of cells that must contain unique digits (row, column, box, diagonal, window, jigsaw region, …) |
| Variant | Grid size + digit set + houses (+ optional meta / playable mask) |
| PuzzleEngine | Interactive API scoped to one variant (createEngine) |
| Meta constraints | Per-puzzle rules (cages, thermos, Kropki dots) — not part of the fixed house map |
| BatchEngine | Seeded bulk generation (not for move/hint loops) |
Two entry points
Classic 9×9 only → import { generatePuzzle, solve, … } from "@reetesh/sudoku-engine"
Any variant → createEngine({ variant: "…" }) → PuzzleEngineTop-level helpers always mean classic 9×9. Using them on a 6×6 or Samurai board will silently use the wrong rules.
Variants
Classic Sudoku (classic)
- Grid: 9×9 · Digits: 1–9 · Regions: nine 3×3 boxes
- Default for all top-level exports
6×6 Sudoku (6x6)
- Grid: 6×6 · Digits: 1–6 · Regions: six 2×3 boxes
- Separate clue bands (36 cells total)
Diagonal / Sudoku X (diagonal)
- Classic houses + both main diagonals unique
- Tighter generation (higher clue targets, more retries)
Hyper Sudoku (hyper)
- Classic + four edge-centered 3×3 windows
Top(1–3,3–5), Left(3–5,1–3), Right(3–5,5–7), Bottom(5–7,3–5)(0-indexed)
Windoku (windoku)
- Classic + four inner-corner 3×3 windows at
(1,1),(1,5),(5,1),(5,5) - Different layout from Hyper — do not treat them as aliases
Jigsaw (jigsaw)
- Rows + columns + nine irregular 9-cell regions (
DEFAULT_JIGSAW_REGION_MAP) - No 3×3 boxes
- Custom maps:
buildIrregularRegionHouses/jigsawSudokuHouses+defineVariant
Killer (killer)
- Classic houses + cage sums (digits unique in each cage)
- Cages are per puzzle →
GeneratedPuzzle.metaConstraints - You must call
engine.withMeta(metaConstraints)before solve / validate / candidates
Thermo (thermo)
- Classic houses + thermometer paths (bulb → tip, strictly increasing)
- Per-puzzle
metaConstraints+withMeta
Kropki (kropki)
- Classic houses + black (ratio 2) / white (consecutive) dots on adjacent pairs
- Per-puzzle
metaConstraints+withMeta
Samurai (samurai)
- Canvas: 21×21 · Digits: 1–9
- Five overlapping 9×9 blocks (four corners + center)
- ~369 playable cells; inactive cells stay
nulland are ignored by solve / complete checks - Completion only requires playable cells filled
Which API should I use?
| Need | Use |
|---|---|
| Ship a classic game fast | Top-level generatePuzzle, applyMove, solve, … |
| Any non-classic variant | createEngine({ variant }) |
| Killer / Thermo / Kropki | generatePuzzle → withMeta(metaConstraints) → play/solve |
| Samurai / 6×6 / X / Hyper / Windoku / Jigsaw | createEngine for all methods |
| Seeded packs / daily catalog | BatchEngine or dailyPuzzle |
| Custom region map | defineVariant + composeHouses → createEngine({ definition }) |
Full recipes: Guides · lookup: API · failures: Troubleshooting
Guarantees
- Successful generation (
generatePuzzle/BatchEngine) returns a puzzle with exactly one solution under that variant’s rules (and meta when attached). Boardnever uses0for empty — alwaysnull.- Library is zero runtime dependencies, ESM + CJS, TypeScript types included.
Non-goals
- UI components or canvas rendering
- Puzzle databases / PDF export
- Arbitrary constraint DSLs beyond houses + the three meta kinds
See Architecture and Roadmap.