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.
© Copyright 2026 Paperzz