paul_geromini_final_project_writeup

Arbitrarily Sized Sliding Block Puzzle Solver
Paul Geromini
University Of Massachusetts: Lowell
5 Beatrice Road, Franklin MA
ABSTRACT
Given an arbitrarily sized game board, (three by three, four by four, etc) with a randomly distributed series of numbers and a
blank space, find the series of moves needed to arrange all the numbers in numerical order from lowest to highest. Use three
different search algorithms: depth-first, breadth-first, and A*, to find the moves needed to correctly arrange the board quickly
and efficiently.
Author Keywords
Breadth-first, Depth-first, A*, Search, Sliding Block
INTRODUCTION
A simple child's game is the sliding block puzzle. Generally these boards are four numbers across and high. This is know as a
15 puzzle, since there are 15 numbers to sort. The 16th space in a 4x4 puzzle is the blank space. The idea is to take the
randomly distributed numbers on the game board and arrange them from least highest number (one) at the top all the way to
highest number (15) at the bottom. The blank space can end up anywhere. This project's goal is to solve a variety of different
puzzles using three types of search algorithms: depth-first, breadth-first, and A*. This kind of work is similar to the work
pursued by Linda Wilkens1 who used the 15 puzzle to teach programming to high schoolers, and related to the findings of
Daniel Ratner and Manfred Warmuth2 who discovered that finding the shortest solution to a 15 puzzle is NP complete.
Image of Application:
Permission to make digital or hard copies of all or part of this work for
personal or classroom use is granted without fee provided that copies are
not made or distributed for profit or commercial advantage and that copies
bear this notice and the full citation on the first page. To copy otherwise,
or republish, to post on servers or to redistribute to lists, requires prior
specific permission and/or a fee.
CHI 2009, April 4–9, 2009, Boston, Massachusetts, USA.
Copyright 2009 ACM 978-1-60558-246-7/09/04...$5.00.
PROJECT DESCRIPTION
The number of possible states that can be created by a game board will always be finite. A very large number, but always
finite. Therefore given that it is simple to create the next states from one initial state we can create all the possible states a
game board will ever be in. If we can create all the states we can inspect each state and find the state that satisfies the success
conditions. That is to say the state where all the numbers are arranged from lowest at the top to highest at the bottom. The
blank space can be anywhere. If we keep a list of all the moves that lead to that particular state then we have the order of the
moves needed to go from the initial start state to the winning end state (or goal state). There are however a lot of states to
inspect, n!/2 to be precise.
The data set is generated by the application itself. The program is given a board size (say 4) and will create a n by n sized
board (4 by 4 in this case, or 16 squares). The numbers on the board will then be randomly distributed and will go from one
to n (1 – 15 in this case). The application will also leave an empty space on the board. Furthermore the application will only
create game boards that can be solved. This is done by calculating the number of inversions on the game board. An inversion
is the count of numbers less than the number in question from the spot of the number in question to the end of the list (a list is
basically a flattened grid in this case). For example given this list of numbers 2, 3, 7, 8, 9, 1 ,4, 6, 5, the number 7 has 4
inversions since there are four numbers (1, 4, 6, 5) less than 7 between it and the end of the list. If the grid has an odd width
(say a 3x3)the number of inversions must be even to be solvable. If the board width is even (and the blank space is on an
even which is always true in this case) the number of inversions must be odd . An even board would be a 4x4.
This project produced a fully playable GUI based sliding number game. A user can create an arbitrarily large game board and
play the game to completion in the application. A user can click to make moves and is informed when they have won the
game, or if their move is invalid. An invalid move is when a user attempts to click on a piece or square that is not near the
blank space. Furthermore, there is an option to have the AI take whatever state the board is in (either the initial generated
state or a state the user has placed it in)and solve it using three different search algorithms (breadth-first search, depth-first
search, and A*). Once the algorithm has solved the board it shows the moves it took to get to the winning state, the number
of boards it inspected, and the time it took. It will then step through each move showing how all the moves reach the end goal
state.
The breadth-first and depth-first search algorithms follow the standard implementation for the most part. There is an
interesting edge case for breadth-first and depth-first searches. For boards of 3x3 and higher it is possible that these searches
start generating very little progress if they start generating moves that go in a loop. For instance it is possible for a series of
moves like 1, 2, 3 to start repeating in a circle. In other words it is possible that the AI just keeps making the same series of
moves over and over ad infinitum. This is a very hard edge case to detect. To solve it requires storing all the past moves of a
search which as discussed later on is not very feasible. Because of this the strength of breadth-first search is severely limited
past 3x3 puzzles. The application attempts to circumvent this issue by implementing a storage method to collect all the
boards a search algorithm has already look at. This was implemented as an option for depth-first search, but not for breadthfirst.
The A* search algorithm follows the standard implementation pattern. For heuristics there are two options: the total number
of numbers that are in the wrong position or the total distance all the numbers are from their end position (commonly called
the Manhattan distance). These two heuristics are both effective, but on average the Manhattan distance heuristic tends to be
a bit faster than the first heuristic.
ANALYSIS OF RESULTS
Each search works, but each type has an upper limit of the board they are able to analyze. For the breadth-first search it is
only able to solve a 2x2 puzzle. This puzzle can have up to 4!/2 states. Any puzzle beyond that size will cause the program to
crash as it runs out of heap memory. The JAVA heap memory size can be increased via some runtime command options
(such as -Xmx1024), but this only delays the inevitable stack overflow exception. It is however able to solve the puzzle in
less than a second after analyzing only a few boards. For depth-first search it is able to solve up to a three by three puzzle.
That puzzle can have up to 9!/2 (181,440) states. It usually takes about 1 second to solve and it looks at anywhere from
200,000+ boards to as low as 50,000 boards. Well it does appear that depth-first looks at more boards then can possible exist
this is because of the circular move issue mentioned earlier. Essentially the algorithm starts looking at moves that go in a
circle (1, 2 ,3, 1, 2, 3, etc). This is very hard to detect and is a significant limiting factor for the strength of these two searches.
For A* it can solve up to a 4x4 board which has around 16!/2 states (around 10 trillion). The time it takes for A* to solve
these game boards can very greatly. It can take as little as 10 seconds or as much as 7 minutes. It also analyzes as few as
7000 boards, to over 100,000+. On average it takes around 30 seconds to find a solution and it looks at around 20,000 boards.
For the heuristics A* used total number of pieces out of place and total offset positions, the second heuristic was generally
slightly better. On average it tends to look at slightly fewer boards and do it slightly faster. The end result is hardly
noticeably however to the user.
As mentioned previously it is possible to circumvent the circular moves issues that bogs down both depth-first and breadthfirst algorithms. This space saving optimization was only implemented for the depth-first algorithm and the unpromising
results that the search yield indicated further attempts would not be any more fruitful. Well this strategy was able to
significantly reduce the number of boards the depth-first algorithm looked at, it took a problem that was normally solved in a
second or so to taking several minutes. This happens because as the list of checked boards grows every one of these boards
has to be checked any time we are considering looking at a new board. This operation becomes increasingly time expensive
to the point where any space benefits become moot compared to the amount of time it is taking determining if a board has
been looked at or not.
DISCUSSION
It was interesting to me to take the algorithms we had learned and adopted them to solve this search problem. It is always
rewarding when you take class knowledge about some programming and attempt to actually implement it. You learn the little
ins and outs that the textbook glosses over which gives me a very deep knowledge of the algorithms. Its very apparent to see
how each of the three algorithms (depth-first, breadth-first, and A*) evolved off of each other . For instance the difference
between depth-first search and breadth-first search is just a change in the kind of structure used to store the nodes to look at
next. For A* all it does is optimize what nodes it is going to look at next. The main idea behind all three functions is
generally the same: look at a bunch of different nodes. It is also worth noting that finding the shortest possible path to
solving a 4x4 puzzle is NP hard (Ratner). This is significant because it shows how a seemingly simple puzzle like the 15
puzzle can have an impact on actual CS research.
I also found it very surprising how hard it was to detect the circular moves issue and just how negatively it was impacting my
performance. I attribute this issue to the relatively poor performance I observed of both the depth-first and breadth-first
search algorithms on larger game boards like the 3x3 for breadth first, and the 4x4 for depth search.
For the actual GUI I implemented a learned a lot about JAVA Swing. I had never used Swing before and I choose JAVA
mainly for my familiarity with the language and to try and learn a bit more about swing. For the most part it was very easy to
get the swing of things. Swing is very similar to other GUI frameworks that I have worked with in the past. The only difficult
thing was getting my program to make a move and then have the GUI update with just that one move being made. This is
what you see when the AI solves a problem, the moves being made one every half second. This was very tricky to do and I
had to become very familiar with the way JAVA schedules work and how it manipulates threads. The solution is also the
only part of this program we makes use of an outside class3.
CONCLUSION
Essentially I was able to solve a sliding block puzzle of size 4x4 which has around 10 trillion different valid possibilities. I
was able to do so utilizing an A* search algorithm which is able to compute most answers in around 30 seconds.
The impact is limited given that this is just a game. It has been done before. However, it was a good learning exercise for me
and it exposed me to a variety of different algorithms and possible solutions. If I had more time I would like to see if I can
implement some solution to the circular move problem. Perhaps if I can improve the way past boards are stored. It may also
be possible to improve the way new boards are generated to limit how often a circular move comes up. In addition to this my
program is a good candidate for multithreading. Right now it is limited to using just one CPU core. If I could get the rest of a
machine's cores into action I could significantly improve the run of the application.
ACKNOWLEDGMENTS
The work described in this paper was conducted as part of a Fall 2012 Artificial Intelligence course, taught in the Computer
Science department of the University of Massachusetts Lowell by Prof. Fred Martin.
REFERENCES
1.Wilkens, L. (2010). On slider puzzle projects with. NET collection classes: poster session. Journal of Computing Sciences
in Colleges, 25(6), 259-260.
2.Ratner, D., & Warmuth, M. (1990). Finding a shortest solution for the N× N extension of the 15-puzzle is intractable.
Journal of Symbolic Computation, 10, 111-137.
3. Jhamb, Y. (2010, January 10). The Great Rat Race: Throttling the SwingWorker using an ExecutorService. The Great Rat
Race. Retrieved December 1, 2012, from http://greatratrace.blogspot.com/2010/01/throttling-swingworker-using.html
4. Russell, S. J., Norvig, P., & Davis, E. (2010). In Artificial intelligence: A modern approach (3rd ed., p. 1132). Upper
Saddle River: Prentice Hall.