I have a wooden puzzle that consists of a square base and buildings that are to be arranged on it. All of the buildings only fit on it if they are arranged precisely; the object of the puzzle is to figure out what the arrangement needs to be.
Needless to say, I suck at this puzzle, and this is my attempt to write a computer program to solve it.
Here are the puzzle pieces grouped by piece shape:
Here are the same pieces with names added:
The puzzle consists of the board and 12 pieces:
The board defines a 7 x 7 cell matrix upon which the pieces must all be arranged.
A tee is shaped like a flattend "T" character and occupies 4 places in the matrix as follows:
There are 3 of these.
An ell looks like an "L":
There are 3 of these.
A lell looks like a reversed "L" (i.e. the 'foot' is facing left):
There is only 1 of these.
A left looks like it zigzags left then straightens out:
There are 2 of these.
A right looks like it zigzags right then straightens out:
There are 2 of these.
A plus has a center and 4 spokes:
There is only 1 of these and it is unusual in that it only has one unique position.
After thinking about this A LOT, here's my my approach:
-
Preorder the list of pieces to try in order.
-
Find the first piece that fits in the top-left cell of the board. If rotating the piece's orientation helps it to fit, then do so.
-
Similarly find the next piece that fits the next cell to the right without violating the board's boundary, nor overlap the previously-placed piece to its left
-
Repeat this process for the remainder of the first row so that:
-
All the cells in the first row are filled.
-
No pieces overlap each other.
-
None of the pieces placements spill outside the board's boundary.
-
-
Repeat for the remaining rows.
-
When you cannot find a piece to play, backup to the previous piece (including the previous row) and see if any of the following work:
-
Can the previous piece be reoriented successfully? If so, keep it in its new orientation and solve the next piece.
-
If not, select the next available piece type and see if you can replace the current piece with it. If so, keep the replacement. If not, repeat this process for the "previous previous" piece.
-
-
The currently played pieces are on a stack. When you get stuck, you back up the stack to a piece orientation or type that you haven't tried yet in that stack position and try that.
-
When the stack contains all the pieces and no cells are left unoccupied, then the game is solved.
I get the idea above, but it needs polishing.
For each piece, it is always placed on the board in the topmost leftmost open square. That means that, for each of a piece's orientations, the piece's top square must be the one placed in the board's current topmost leftmost open square. This is because all other squares in the piece cannot be placed there because they will possibly:
-
Overlap a board square that has already been filled by a previous-placed piece.
-
Spill outside the board's playing area.
If the piece has more than one topmost square for a given orientation, then the only one that can be used is the leftmost top square. This is because any other top square, by definition, would either overlap a previous piece's square or would spill outside the board's playing area.
So we need to define the notion of how orientation is used.
-
Should we just associate and enumeration with each possible orientation for the piece type?
-
The "T's", "L's" and "Z's" each have 4 possible orientations. So when we need to update a type, before we do we have to step through the existing candidate through each of its candidate orientations first.
-
Each orientation needs to have the associated topleft position to determine how to assign the piece.
-
Here are the orientation candidates for each of the pieces:
1 | 2 |
---|---|
1 | 2 |
---|---|
1 | 2 | 3 | 4 |
---|---|---|---|
Only one:
1 | 2 | 3 | 4 |
---|---|---|---|
1 | 2 | 3 | 4 |
---|---|---|---|