Quickstart

Install the package:

pip install pencil-puzzles

Everything is in one module:

import pencil_puzzles as pp

Generate a puzzle

>>> g = pp.generate("sudoku", (4, 4), difficulty="easy", seed=1)
>>> print(g.puzzle)
3 1 | . .
. . | . .
----+----
. . | . .
. . | 3 4

generate returns the puzzle together with its solution and rating. Leave out the shape for the genre’s standard size, the difficulty for any level and the seed for a random puzzle.

>>> g.solution.cells
((3, 1, 4, 2), (2, 4, 1, 3), (4, 3, 2, 1), (1, 2, 3, 4))
>>> g.rating.level
<Difficulty.EASY: 'easy'>

Save and load it

A puzzle’s ID holds the whole puzzle:

>>> g.puzzle.id
'sudoku:4x4:31............34'
>>> puzzle = pp.Puzzle.from_id('sudoku:4x4:31............34')

Solve and rate it

>>> pp.solve(puzzle) == g.solution
True
>>> pp.rate(puzzle).techniques
('hidden_single',)

Check a player’s answer

An answer is a grid of rows, with 0 for an empty cell:

>>> answer = pp.Solution("sudoku", ((3, 1, 3, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 3, 4)))
>>> pp.check(puzzle, answer)
[Violation(rule=1, place={'row': 0}, values={'filled': 3, 'size': 4}), Violation(rule=2, place={'col': 2}, values={'filled': 2, 'size': 4})]

check lists the rules the answer breaks: the 3 repeats in row 0 (rule 1) and in column 2 (rule 2). The rule numbers are the ones on the Sudoku page.

>>> answer = pp.Solution("sudoku", ((3, 1, 4, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 3, 4)))
>>> pp.check(puzzle, answer)
[]
>>> pp.hint(puzzle, answer)
Step(level=<Difficulty.EASY: 'easy'>, technique='hidden_single', removed=((1, 2, '2'), (1, 3, '2'), (2, 3, '2')))

hint gives the next step a solver would take from the answer.

Next