Over the last few months at Hyper Luminal we have been working on a puzzle game. We have prototyped, tested and implemented over 15 puzzles for the game so far but sadly some of them just didn’t make the cut. So I decided to do a blog post on one of my favourite puzzles that didn’t make it! We will be distributing the source code via the Unity Asset Store hopefully at some point next week but I’ll update this post once it is available.
The puzzle in question is the sliding tile puzzle below:
This was one of the first puzzles we implemented and in my opinion is a classic puzzle concept. Slide the tiles around to build the correct image. The puzzle as a concept fits well into our game; it takes a decent amount of time to solve, its simple enough for children but still challenging for adults and it can be made to look really nice! We however haven’t been able to properly thematically link it to our game so it hasn’t been used.
The puzzle itself is fully automated, simply select the image you want to use for the puzzle and hit play. The code will slice the image up into tiles, place them in the world, mix up the puzzle for you and remove a piece so it is playable.
Once the puzzle is running you simply select the piece you would like to move into the empty space. Once they are all arranged correctly as per the source image the puzzle will complete with a charming little debug statement. Sorry this isn’t any fancier!
The most interesting part of the puzzle for me is slicing up the image into the tiles. By slicing it programmatically it means any size of puzzle can be produced (3 by 3, 4 by 4 or even crazy ones such as 5 by 3 for non-square tiles). The puzzles can use different shaders for lighting or cartoon/outlined effects on the tiles themselves.
- The first step in the process is to make a new material with the selected shader.
- Then assign our selected puzzle image to that material.
- Next we set the texture offset and scale.
- This is the important part that allows only a section of the whole image to be displayed on the tile. As we iterate over the tiles the Width and Height variables of the puzzle are used to offset and scale the image correctly for each section.
- The newly created material with the unique offset is then applied to the tile piece.
Below is the code extract:
This combined with the grid generation code will produce an image like:
Now that we have the image displayed in a puzzle context we now need to make the puzzle!
Some of you might know this already but I certainly didn’t. Not all of these puzzles are actually possible, there is a formula that determines whether a puzzle is possible or not. The various heuristics used to determine if the puzzle is solvable include counting the number of misplaced tiles and finding the sum of the taxicab distances between each block and its position in the goal configuration. Now without getting into too much boring detail this is a rather complex evaluation procedure for such a simple puzzle.
Here is an impossible example: LINK TO WEBGL VERSION
My solution was much easier! Start with the completed puzzle and make a set amount of moves backwards to mix up the puzzle again. The nature of this puzzle and size of the grid means that this is a perfectly legitimate method to create a randomised puzzle, best of all it is 100% solvable because every move made to mix it up is a legal move itself. The left puzzle has had 20 random legal moves made to it, the puzzle on the right has been totally randomised but there is no guarantee it is solvable. There is very little difference in perceived complexity and the end user would never know the difference (Unless it was unsolvable of course!).
In case anyone was wondering apparently these valid puzzles can be solved in maximum of 31 single-tile moves for 3 by 3 tile puzzles.
The framework I developed also has some attributes for general position and scale of the entire puzzle to make moving them around a bit easier as well as some other useful extras. It is made in pure Unity features so no additional plugins are required and I’m sure with a few nice images this could help make an easy game!
I hope this was interesting and look out for the release on the Asset Store!