MattParkerJigsawPuzzleProblem
Documentation for MattParkerJigsawPuzzleProblem.
In this YouTube video Matt Parker asks for a program to help design and solve jigsaw puzzles.
The idea is to produce a set of jigsaw puzzle pieces where the pieces can be assembled in more than one way, and, ideally, in exactly two ways.
This is an attempt at that.
Usage
Here is a simple usage example:
using MattParkerJigsawPuzzleProblem
begin
# Degenerate example of a puzzle, 2 × 2 grid
# with 4 possible solutions:
puzzle = MultipleSolutionPuzzle(2, 2, 4)
pieces = map(ImmutablePuzzlePiece, puzzle_pieces(puzzle))
# Find the solutions and show them in HTML:
solver = Solver(size(puzzle), pieces)
solve(solver)
writing_html_file("two_by_two_example.html") do
grids_to_html(solver.solved_grids)
end
length(solver.solved_grids)
end
64
See the resulting solution grids: twobytwo_example.html
The rest of the documentation (see the menu in the corner above) presents the theory of operation.
Index
MattParkerJigsawPuzzleProblem.ALL_EDGE_TYPES
MattParkerJigsawPuzzleProblem.AbstractPuzzlePiece
MattParkerJigsawPuzzleProblem.BallOrSocket
MattParkerJigsawPuzzleProblem.Edge
MattParkerJigsawPuzzleProblem.EdgeType
MattParkerJigsawPuzzleProblem.GridCell
MattParkerJigsawPuzzleProblem.ImmutablePuzzlePiece
MattParkerJigsawPuzzleProblem.MultipleSolutionPuzzle
MattParkerJigsawPuzzleProblem.MutablePuzzlePiece
MattParkerJigsawPuzzleProblem.add_one_piece
MattParkerJigsawPuzzleProblem.edge_index
MattParkerJigsawPuzzleProblem.edges_mate
MattParkerJigsawPuzzleProblem.fit_piece
MattParkerJigsawPuzzleProblem.get_neighboring_edge
MattParkerJigsawPuzzleProblem.grid_to_html
MattParkerJigsawPuzzleProblem.grids_to_html
MattParkerJigsawPuzzleProblem.mating_piece_indices
MattParkerJigsawPuzzleProblem.new_grid
MattParkerJigsawPuzzleProblem.opposite
MattParkerJigsawPuzzleProblem.perimeter_edge_indices
MattParkerJigsawPuzzleProblem.perimeter_edge_indices
MattParkerJigsawPuzzleProblem.perimeters
MattParkerJigsawPuzzleProblem.piece_edge
MattParkerJigsawPuzzleProblem.puzzle_pieces
MattParkerJigsawPuzzleProblem.rotation
MattParkerJigsawPuzzleProblem.solve
MattParkerJigsawPuzzleProblem.terserep
MattParkerJigsawPuzzleProblem.writing_html_file
Descriptions
MattParkerJigsawPuzzleProblem.ALL_EDGE_TYPES
— ConstantALL_EDGE_TYPES
ALL_EDGE_TYPES
is a vector of all of the EdgeType
s that have been created.
MattParkerJigsawPuzzleProblem.AbstractPuzzlePiece
— TypeAbstractPuzzlePiece
AbstractPuzzlePiece is the abstract supertype for all types of jigsaw puzzle piece.
MattParkerJigsawPuzzleProblem.BallOrSocket
— TypeBallOrSocket
Ball
Socket
Straight
MattParkerJigsawPuzzleProblem.Edge
— TypeEdge(::EdgeType, ::BallOrSocket)
Edge
represents one edge of a puzzle piece. It has an edge_type
. The bs
field indicates whether the edge is a ball or socket.
MattParkerJigsawPuzzleProblem.EdgeType
— TypeEdgeType(isperimeter::Bool)
Creates a unique EdgeType
.
isperimeter
indicates if the EdgeType is for an edge on the perimeter of the puzzle.
MattParkerJigsawPuzzleProblem.GridCell
— TypeGridCell(::AbstractPuzzlePiece, rotation::Int)
A GridCell is the container for a puzzle piece in a puzzle grid.
MattParkerJigsawPuzzleProblem.ImmutablePuzzlePiece
— TypeImmutablePuzzlePiece(from::MutablePuzzlePiece)
Constructs an ImmutablePuzzlePiece
from a MutablePuzzlePiece
.
MattParkerJigsawPuzzleProblem.MultipleSolutionPuzzle
— TypeMultipleSolutionPuzzle(number_of_rows, number_of_columns, number_of_grids)
MultipleSolutionPuzzle is used to generate jigsaw puzzles with the specified numnber of rows and colukmns. It will attempy to generate number_of_grids
puzzles with the same pieces. The pieces that are generated can be assembled least that number of of different ways. One must run the solver to see how many ways the pieces can actually be assembled.
Use puzzle_pieces
to get the pieces.
MattParkerJigsawPuzzleProblem.MutablePuzzlePiece
— TypeMutablePuzzlePiece()
Constructs a MutablePuzzlePiece
with no edges defined yet.
MattParkerJigsawPuzzleProblem.add_one_piece
— Methodadd_one_piece(solver::Solver, grid::Grid)
Looks for a piece to fit into the grid. If there is more than one mating piece then additional grids are created for them.
MattParkerJigsawPuzzleProblem.edge_index
— Methodedge_index(::Int)::Int
Turns the argument value into a valid edge index using the modulus operator. This allows us to use aritmetic on edge indices and still get a valid index.
MattParkerJigsawPuzzleProblem.edges_mate
— Methodedges_mate(::Edge, ::Edge)::Bool
Two Edge
s mate if they have the same EdgeType
and their bs
s are opposites.
MattParkerJigsawPuzzleProblem.fit_piece
— Methodfit_piece(continuation, grid::Grid, row::Int, col::Int,
piece::ImmutablePuzzlePiece)
Attempts to fit piece
into the specified location of grid
. continuation
is called for each rotation of piece
that fits.
MattParkerJigsawPuzzleProblem.get_neighboring_edge
— Methodgetneighboringedge(grid::Grid, row::Int, col::Int, direction::CardinalDirection)
Returns the Edge
of the "neighboring cell" to the specified grid location. If that location is out of bounds then Edge(EdgeType(true, 0), Straight())
is returned. Otherwise, if there is no GridCell at the specified location yet, then missing
is returned.
MattParkerJigsawPuzzleProblem.grid_to_html
— Functiongrid_to_html(grid::Grid, piece_numbers=nothing)
Generates HTML representing a tabular view of grid
.
If piece_numbers
is specified it is a Dict mapping from a puzzle piece to s small integer id to be printed in the center of the piece.
MattParkerJigsawPuzzleProblem.grids_to_html
— Methodgrids_to_html(grids::Vector{Grid})
Generates HTML elements for the grids.
MattParkerJigsawPuzzleProblem.mating_piece_indices
— Methodmating_piece_indices(continuation, piece1::ImmutablePuzzlePiece, piece1::ImmutablePuzzlePiece)
for each Edge
of piece1
that mates with an Edge
of piece2
, Calls continuation
, on the indices into those two pieces of those mating edges.
MattParkerJigsawPuzzleProblem.new_grid
— Methodnew_grid(number_of_rows, number_of_columns)::Grid
Creates an empty puzzle grid of the specified dimensions.
MattParkerJigsawPuzzleProblem.opposite
— Methodopposite(::CardinalDirection)::CardinalDirection
Returns the opposite direction. N()
and S()
are opposites. E()
and W()
are opposites.
MattParkerJigsawPuzzleProblem.perimeter_edge_indices
— Methodperimeter_edge_indices(p::AbstractPuzzlePiece)
Returns a vector of the indices of edges of the puzzle piece p
that are perimeter edges.
MattParkerJigsawPuzzleProblem.perimeter_edge_indices
— Methodperimeter_edge_indices(grid::Grid, row::int, col::Int)
Returns a vector of the indices of edges of the specified cell of grid
that are perimeter edges.
MattParkerJigsawPuzzleProblem.perimeters
— Methodperimeters(puzzle::MultipleSolutionPuzzle, row::Int, col::Int)
Returns a four element vector indicating for each direction (N, E, S, W) whether that side of the cell at row
, col
is a perimeter of the puzzle.
MattParkerJigsawPuzzleProblem.piece_edge
— Methodpiece_edge(puzzle_piece, index)::Edge
Returns the Edge
of puzzle_piece
which corresponds to the specified edge_index
.
MattParkerJigsawPuzzleProblem.puzzle_pieces
— Methodpuzzle_pieces(puzzle::MultipleSolutionPuzzle)::Vector{MutablePuzzlePiece}
Returns a vector of all of the MutablePuzzlePiece
s of puzzle
.
MattParkerJigsawPuzzleProblem.rotation
— Methodrotation(rot::Int)
Normalizes the rotation of the placement of a puzzle piece to one of 0, 1, 2, or 3.
MattParkerJigsawPuzzleProblem.solve
— Methodsolve(solver::Solver)
Run the solver to find solutions to the jigsaw puzzle.
MattParkerJigsawPuzzleProblem.terserep
— Methodterserep(puzzle)
Output a terse printed representation of the puzzle.
MattParkerJigsawPuzzleProblem.writing_html_file
— Methodwriting_html_file(body, filename)
Write an HTML file to filename
.
body
is a vector of elements to be included in the HTML document.