Workshop › Sudoku › Step 21 of 28
Now the computer invents puzzles: make a random full grid, then empty cells in random order. After each removal, check with the solver that the puzzle still has exactly one solution; if not, put the digit back.
```js
const HOLES = 50 // how many cells are emptied
const copy = (board) => board.map((row) => row.slice())
// A random full grid, then empty cells one by one, keeping only removals that leave exactly one solution.
function makePuzzle() {
const full = Array.from({ length: 9 }, () => Array(9).fill(0))
countSolutions(full, 1, true)
const puzzle = copy(full)
let removed = 0
for (const cell of shuffle([...Array(81).keys()])) {
if (removed === HOLES) break
const r = Math.floor(cell / 9)
const c = cell % 9
const digit = puzzle[r][c]
puzzle[r][c] = 0
if (countSolutions(copy(puzzle), 2) === 1) removed++
else puzzle[r][c] = digit // two solutions: put it back
}
return { puzzle, full }
}
```copy makes a new grid with the same digits, so the solver can scribble on it without spoiling the puzzle.[...Array(81).keys()] is the list 0 to 80, one number per cell; shuffled, it is a random order of cells.n is row Math.floor(n / 9), column n % 9.TOP, write HOLES.shuffle, write copy, the comment and makePuzzle.Skills: Functions, Loops
← Random order A new puzzle every game →