Simon Hall
brought up to date for Java 1.4 by Aidan Harding
This exercise involves a well-known puzzle often referred to as the 'Puzzle of Fifteen'. The exact origin of the puzzle is unknown, but it first came to popularity in America during the 1870s. The puzzle consists of fifteen square tiles, labelled numerically from 1 to 15. They are arranged in a random ordering within a square tray that is just large enough to hold sixteen tiles in a 4 x 4 grid (see fig 1). The tiles should then be slid around the tray until they are in the correct ordering as shown in fig 2, with the blank space at the bottom-right hand corner. The tiles must not be picked out of the tray.
6
1
10
2
7
11
4
14
5
9
15
8
12
13
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sam Loyd was an American puzzle-inventor during the 1870s. He was regarded by many as the greatest puzzle-maker in the world. In 1878, Loyd marketed his own version of the Puzzle of Fifteen - 'Loyd's Fifteen' (also called the 14-15 game). In essence it was the same game, but the difference Loyd made was to provide an initial tile arrangement. Loyd's initial set-up was as if the game had been completed, but then the 14 and 15 tiles were swapped (see fig 3). The aim of the game was as before- to arrange the tiles in ascending order. Loyd offered $1000 to anyone who could demonstrate their solution to the game. A craze for the puzzle hit the world, one which was not rivalled until the Rubik's Cube of the 1980's. People from all walks of life became hooked on the puzzle whose solution always seemed to be just around the next corner. However, no-one managed to solve the problem. Several years (and many puzzle sales), later, the impossibility of Loyd's puzzle was mathematically proven.
1
2
3
4
5
6
7
8
9
10
11
12
13
15
14
Sam Loyd had taken advantage of the fact that there are two state spaces involved in this game. A state space is a set of states (ie. tile arrangements) where every element can be transformed into any other element of that set through the normal transformation procedures. However, no state can be transformed legally into an element of a different state space. In the 'Puzzle of Fifteen', exactly half of all arrangements belong in state space 'A', (including the solution arrangement), and exactly half belong in state space 'B', (including, of course, Loyd's arrangement!). It turns out that when given a tile arrangement that belongs to the unsolvable state space, a new arrangement can be generated that belongs to the solvable state space by simply swapping two adjacent tiles (without disturbing any others). The opposite, of course, is also true. So it is not possible to swap two adjacent tiles without upsetting the arrangement of other tiles. That is why Loyd's Fifteen cannot be solved. This concept is not simple even for the educated minds of today, so it is hardly surprising that Loyd had so many people fooled back in the nineteenth century!
Over the 124 years since Sam Loyd's puzzle kick-started the sliding tile game market, many more tile puzzles have been devised. One of particular interest is the 'Rate Your Mind Pal' puzzle, which, again, involves a 4 x 4 grid of sliding tiles. This time, the tiles are labelled with characters, initially forming the phrase 'RATE YOUR MIND PLA', as shown in fig 4. The task is to rearrange the tiles to form the corrected phrase 'RATE YOUR MIND PAL', with the blank space in its usual position at the bottom right of the grid. At a first glance, this seems to be identical to the 14-15 puzzle, and therefore appears impossible. However, there is a subtle difference, and the 'Rate Your Mind Pal' game can be solved. See if you can spot the subtle difference and solve the problem.
R
A
T
E
Y
O
U
R
M
I
N
D
P
L
A
Your task is to create a working 'Puzzle of Fifteen' game. Many versions of the game use a tiled image instead of numbers, simply because it is more pleasing to the eye. Your solution will follow this example by allowing the user to play the game with any jpg or gif image he chooses.
The exercise is split into five parts. You are all expected to have a good attempt at the first three. However, to reach the higher marks, you must complete part four, which requires you to develop a quality user interface. The experts among you should relish the challenge of part five, which will stretch even the most experienced of programmers.
You should use javadoc comments throughout this exercise. To generate documentation for your classes based on your comments, use
kanga% javadoc *.java
There are several 'good' ways of solving this exercise, and a considerable deviation from the model answer is expected. However, there are also many pitfalls and ways to get lost when writing a program of this complexity. So plan everything on paper before you code it, keep your method and variable names consistent and meaningful, make use of static class variables where appropriate and, above all, endeavour to uphold modularity. This means making sure your classes and methods do exactly what they are supposed to do and no more. Most methods have only one function to perform. Do not add 'extra' instructions into methods that cause it to perform more than one function. Decide well in advance which classes will have access to which other classes. Declare private as many of your instance variables as you can.
Write a program called SliderGame that can display an image in a frame. Let the user specify the image in the command line arguments. So, the following line at the xterm prompt
kanga% java SliderGame test.jpg
should display a window containing the JPEG image named 'test.jpg'.
To create a BufferedImage
object, use
some code like the following:
ImageIO.read( new File( "foo.jpg" ) );You can get the dimensions of the image using the methods
getWidth()
and getHeight() from the
class ImageIO.
Hints
JPanel class to the content
pane of the JFrame class (e.g. getContentPane().add(p),
where p is your panel.).paintComponent(Graphics)
method in JPanel to display your image. The Graphics class has a method drawImage(). ImageObserver object as
an argument to a method, use null. Adapt your program so that it creates a 4 x 4 grid of tiles, each displaying a piece of the full image. Create only fifteen tiles, as the bottom right tile space should be left blank. Display your tiles on screen in their correct order, as they would appear if you had succesfully completed the Puzzle of Fifteen. Each tile should have a black border of width 1 pixel.
You will need to write a Tile
class. The most important method in this class will be a draw
method. This will accept a Graphics object as one of its
arguments. The draw method is where the image and a
border will be drawn.
You should adapt your JPanel
class constructor so that it creates and stores the tiles needed for
the game. Use a 4 x 4 grid by default. Think about how and where in
your program you will define this default setting so that it will be
easy to modify.
getSubImage() method of the BufferedImage class.Tile class,
bear in mind that at some later stage in your program's development,
you will need to write a method that decides when a game is won.
Because of this, you will need to have some way of knowing which Tile
belongs in which grid cell.
Remember to use Javadoc comments as you develop your classes.
Hints
paintComponent method
so that it draws all the Tile objects. Have the tiles shuffled into a random, yet
solvable, configuration of positions. Construct an implementation of
the MouseListener interface to allow the user to make
moves using the mouse. Do not worry about using the mouse to drag a
tile- simply clicking on a tile is enough to indicate the move the user
wishes to make as there is only one possible place where a tile could
move to (the blank). Only legal moves should be allowed, by which it is
meant that clicking a tile that is not adjacent to the blank space
should not have any effect. Once the game is solved, prevent the user
from making any more moves.
Think very carefully about how to approach this part- it is the most important part of the exercise. You may need to improve the way you store the state of the game, but hopefully you can just build on what you already have.
You will need to write a method to shuffle your tiles around. There are more than one ways of doing this, although whatever method you choose, be sure to always leave the tiles in a solvable arrangement. You may find it helpful to read up on some of the theory of the game. Try http://kevingong.com/Math/SixteenPuzzle.html.
Write a method for moving tiles. If you wish, you may write another method that causes the tiles to slide across the screen as well as updating the internal game structure. There are no marks for this, but it will improve the visual impact of the game tremendously.
You should write a class to implement MouseListener.
If you make it an inner class it will have access to the variables of
the outer class. All new Java books have sections on MouseListeners
and how to use them. Try Chapter 8 in Core Java, by Horstmann &
Cornell, for example.
Hints
MyClickExample.java from the Swing lecture of the Red Hot
Java Course, which tiles a frame in a slightly different way to here
and reports on where the user clicks the mouse. Thread.sleep(int) method to
cause your program to pause for a specific length of time. Implement a user interface for your game. Allow the user to change the number of tiles on the grid, start a new game or exit the program. When the game is won your program should let the user know by way of a popup message.
This part is left mostly up to you as to how you allow users to choose these options. There is a lot of scope at this stage for experimenting with the vast Swing libraries that Java provides. Refer to the API and Java textbooks for information on using Swing. Horstmann & Cornell's Core Java has a substantial chapter on Swing. If you have the time, feel free to develop your program further, adding more varied options.
Hints
JOptionPane class. It has some very
useful static methods for you to use to display a popup message. Implement a function for automatically solving the puzzle. Make this function accessible through your user interface. The tiles must be seen to be moving around the screen in the usual manner.
This part is very hard, and not worth very many marks. It is up to you how you attempt to solve this part. You are not expected to produce an optimal solution. Try searching the web for strategies for solving the puzzle.
| Preliminaries |
|
| 5 points
if your viva is on Tuesday. 2 points if it is on Thursday. None for
Friday. |
5 |
| Student ready for viva when viva
began? Or did demonstrator have to wait while student figured our how
to run the program, how to load the right files, how to submit in the
right place. |
5 |
| Design |
|
| Clarity and neatness of the diagram showing the classes and
their relationships |
5 |
| Content, clarity and brevity of narrative explaining design,
including explanation of data representation |
5 |
| Choice of classes: do they
correspond to natural concepts or actors, are they named as nouns |
5 |
| Choice of classes: low coupling
between classes and high cohesion of each class |
5 |
| Subtotal | 20 |
| Coding |
|
| The code implements the design |
7 |
| Methods do one job. Variable names are sensible. Classes
begin Uppercase, variables and methods begin lowercase |
3 |
| Subtotal |
10 |
| Javadoc | |
| Code has Javadoc in it |
5 |
| Student has compiled Javadoc into a meaningful set of web
pages |
5 |
| Subotal | 10 |
| Total |
45 |
Does a JFrame window appear? |
2 |
| Is the window an appropriate size? | 1 |
| Is the specified image displayed in the window? | 5 |
| Does the program terminate if the window is closed? | 2 |
| Total | 10 |
| Does the image get cropped correctly? | 3 |
Can the student explain how they chose their data structure
for storing Tile objects? |
2 |
| Is it possible to change the grid size through a constant in the code? | 3 |
| Do the tiles get drawn on the screen in the correct places? | 2 |
| Total | 10 |
| Are the tiles shuffled well? | 5 |
| Are the starting arrangements always solvable? Ask the student to explain how (s)he can guarantee this. | 5 |
| Do tiles move correctly when you click them? Check that clicking on grid-locked tiles or the blank does nothing. | 5 |
| Does the computer know when the game is over? Does it prevent any further moves? | 5 |
| Total | 20 |
| Does clicking 'New Game' start a new game that works properly? Test this by playing the game. | 3 |
| Is it possible to specify the number of tiles? Accept programs that allow a choice of preset sizes, as well as those that let you type in a number. | 2 |
| Is there an appropriate notice telling you when you have won? | 3 |
| Award marks for a sensible use of GUI components. Only lose marks here if the interface is difficult to use. | 2 |
| Total | 10 |
| Can the student explain his/ her strategy for solving the game? | 2 |
| Can the computer make moves by itself (don't have to be sensible moves, although they must be seen on screen)? | 1 |
| Does the computer get close to a solution? | 1 |
| Can the computer solve any (solvable) arrangement of the tiles? | 1 |
| Total | 5 |