Slider Puzzle
Recreating a classic slider puzzle with JavaScript
The finished product:
What is a slider puzzle?
A slider puzzle, also known as a sliding block puzzle or n puzzle, is a type of combination puzzle that involves rearranging pieces by sliding them around a board. The puzzle consists of a grid or board with various pieces that can be moved horizontally or vertically.
To solve a slider puzzle, you typically start with a scrambled arrangement of pieces with a goal of rearranging the pieces in a specific order or pattern. The most common pattern is to arrange the pieces in numerical or sequential order.
A simpler visualization of the above puzzle might look something like this:
with the end goal being:
There are many variations of the slider puzzle, such as the 15- or 25-puzzle, but it realistically could be any form of an n2 - 1 square.
Solving a slider puzzle
Are slider puzzles always solvable? The answer, surprisingly, is no. Obviously, slider puzzles that do not contain an empty space are unsolvable since you wouldn't even be able to make any moves, but even seemingly normal looking puzzles can be unsolvable. Don't believe me? Test your luck on the modified puzzle below. You're welcome to cheat and even use the Solve
button.
Why does this happen? It all stems from the number of inversions the puzzle has. An inversion occurs when two pieces in the puzzle are out of their desired order. For example, if a number 3 tile appears before a number 2 tile in a numerical slider puzzle, it is considered an inversion. If the number of inversions in a puzzle is odd, the puzzle is considered unsolvable.
Each time you make an inversion in the puzzle, you are creating an even number of inversions. This is because the number of inversions changes by an even amount (+2 or -2) with each move. Therefore, if a puzzle starts with an even number of inversions, it can only be solved with an even number of additional moves, resulting in a solvable puzzle. Similarly, if a puzzle starts with an odd number of inversions, it can only be solved with an odd number of additional moves, which is impossible.
Checking for solvability
This leads to our first bit of code. Obviously, we want to ensure that a player doesn't waste their time on an unsolvable puzzle, so let's make sure that never happens by creating a function that takes an initial shuffled puzzle state and counts the number of inversions.
The initial board could be any arbitrary shape as long as it follows the guidelines I've explained above. For this example, I've decided to structure my board state as an object with the keys
being the final index the piece should be in (i.e. the correct index) and the values
being the current index. I've also decided to create an empty
key to represent the empty tile.
Now that we've properly handled an important edge case, we can move on to generating a shuffled board.
Shuffling the board
You can choose any method you'd like to randomize an array, but the way I chose is called the Fisher-Yates Shuffle, which involves selecting a random element in an array and swapping it with the last element. Since we now have the functionality to determine whether the randomized array is a solvable combination, we can easily just recursively call the randomizer if the combination is unsolvable.
Shifting echoes, a fragmented dance; patterns emerge, secrets in motion