puzzles
Logic-puzzle generator and solver pack (pure JavaScript, zero dependencies). Generate, solve and validate classic pencil-and-paper puzzles: Sudoku (generate by difficulty easy/medium/hard/expert...
puzzles — logic-puzzle generator + solver pack
Pure JavaScript (zero npm dependencies, Node built-ins only) adapter system for generating, solving and validating classic logic puzzles. Every randomized tool accepts an optional seed for reproducible, deterministic output. All results are plain JSON-serializable objects.
Contract: export default { metadata, adapters: { <tool>: (args) => result } }. Each tool takes a single args object (an HTTP POST body maps 1:1 onto a call).
Tools
| Tool | Args | Returns | |||
|---|---|---|---|---|---|
sudokuGenerate | `{ difficulty?: 'easy'\ | 'medium'\ | 'hard'\ | 'expert', seed? }` | { puzzle, solution, clues, blanks, string } — a uniquely-solvable 9×9 puzzle + its solution |
sudokuSolve | { puzzle } (2D array, flat 81 array, or 81-char string; 0/. = blank) | { solved, unique, solution, string } | |||
sudokuValidate | { puzzle } | { valid, complete, filled, blanks, conflicts } — checks row/col/box conflicts | |||
mazeGenerate | { width?=15, height?=15, seed? } | { grid, ascii, svg, start, end, width, height } — a perfect maze | |||
mazeSolve | { maze } (an object from mazeGenerate) | { solved, path, length, start, end } — BFS shortest path | |||
wordSearchGenerate | { words?, size?, theme?, directions?=8, seed? } | { grid, rows, words, unplaced, answerKey, size } | |||
nonogramFromGrid | { grid } (2D truthy/1/#/x) | { rowClues, colClues, width, height, filled, solution } | |||
magicSquare | { n } (odd, doubly-even, or singly-even; not 2) | { square, magicConstant, verified, n } | |||
nQueens | { n } (n≥4 for solutions, ≤20) | { count, first, board, allSolutions?, n } | |||
knightsTour | { n, start?=[0,0] } | { board, path, complete, visited, n } — Warnsdorff's heuristic | |||
listThemes | {} | { themes, counts } — word-search word banks |
Encodings
- Sudoku boards:
0(or.) is a blank.stringoutput is the 81-char row-major form. - Maze
grid[y][x]is a wall bitmask —N=1, E=2, S=4, W=8; a cleared bit is an open
passage. start is [0,0], end is [width-1, height-1]. ascii uses # walls / spaces; svg is a self-contained inline SVG string.
- Word search
answerKeyentries are{ word, row, col, dx, dy }; the word occupies
grid[row + dyi][col + dxi] for i = 0..len-1. directions: 4 = orthogonal only, 8 = with diagonals. When words is omitted, words are drawn from the theme bank (see listThemes).
- Magic square covers all three parities: Siamese method (odd
n), diagonal-flip (doubly-even
n % 4 === 0), Strachey method (singly-even n % 4 === 2). verified re-checks every row, column and both diagonals against magicConstant.
- N-Queens
firstis an array where index = row and value = the queen's column. Forn ≤ 12
all solutions are enumerated (allSolutions + full count); for larger n the exact count is still returned but only the first board is materialized.
- Knight's tour
board[r][c]is the move index (0-based) at which the knight lands there.
Usage
import puzzles from './index.js';
const { adapters } = puzzles;
const sudoku = adapters.sudokuGenerate({ difficulty: 'hard', seed: 42 });
const solved = adapters.sudokuSolve({ puzzle: sudoku.puzzle });
const maze = adapters.mazeGenerate({ width: 20, height: 20, seed: 7 });
const route = adapters.mazeSolve({ maze }); // route.path = [[x,y], …]
adapters.wordSearchGenerate({ words: ['CAT', 'DOG'], size: 12, seed: 3 });
adapters.magicSquare({ n: 5 }); // → { magicConstant: 65, verified: true, … }
adapters.nQueens({ n: 8 }); // → { count: 92, … }
adapters.knightsTour({ n: 8 }); // → { complete: true, visited: 64, … }
DRY boundary
This pack owns logic puzzles: deterministic puzzle structure + constraint solving. It does not overlap its neighbors:
diceowns generic randomness — dice rolls, shuffles, coin flips, weighted loot, random
pick. If you just need a random draw, use dice, not this pack.
fortuneowns novelty & trivia — fortune cookies, Magic 8-Ball, would-you-rather, trivia
Q&A, jokes. The themed word banks in data/wordbanks.json here are grid fodder for word searches, not a trivia/quiz dataset.
Randomness inside this pack exists only to generate a puzzle instance; it is always reproducible via seed.
Files
index.js— all tools + inlined helpers (seeded mulberry32 PRNG, solvers). No cross-pack imports.metadata.json— discovery metadata;inputs[0].optionslists every tool name.data/wordbanks.json— themed uppercase word banks forwordSearchGenerate.