CS 107 (Spring '09)
[Schedule] [Programs] [Notes & Reference] [Examples][Syllabus] [Lab & TA] [Tests] [Grades]

Program #3: 9 Tiles

Prof. Reed, CS 107, Spring '09
Due Monday 3/9 at 1:00 PM

Write a program to play the 9 tiles puzzle (examples can be played online here). Running the program looks like what is shown below, where the user input is provided in the text window at right, and the results of the user input are shown graphically in the window at left.

board1

board2

 

board3

 

board4

You need to know the following concepts in order to write this program:

Everything from the previous program; Classes & methods; Random number generator. Using arrays is not necessary, but could be helpful.

Notes:

  1. You can only move a square that is adjacent (up, down, left, or right) to the blank square. The board starts out in a pre-set configuration, always. An option is given to subsequently randomize the tile labels if desired.
  2. I suggest you write the program in the following stages, compiling it and running your code at each stage. Use the following classes to write this program:
    Class diagram
    Canvas.java and Square.java are supplied for you. You must create Board.java and PlayGame.java. I encourage you to look at last semester's program #3, where a board was created for that assignment as well. That program illustrates how to use variables to determine square placement.

    The number of run-time points (out of 55 total) for an otherwise perfect program are shown below. Note that unless your program doesn't run substantially according to program requirements, you don't get any points at all (score of 0 for the entire program.)

    1. (0 points) Draw the board. This code should be in a constructor inside the Board class. Declare the values you will likely need to keep track of for the board (e.g. 9 Square variables for the playing tiles). These values should be instance variables for the Board class. Create the squares, being careful to place them in the correct positions, using the default position labels (see program run above). Your program must start with this configuration, or else you will have a 15 point deduction. Have a separate variable for the invisible square.

    2. (10 points) Create the PlayGame class, that should have an instance variable of type Board. When the board is created, such as:
                Board theBoard = new Board();
      then the Board constructor code you wrote in the above step will be executed, causing the board to be displayed.

    3. (5 points) Create the main loop in the PlayGame class that asks for user input, converting it to upper case. Before doing anything else check to see if the user entered 'x' to exit, and handle exiting the main loop. If the user enters 'r' to randomize the board, for now just display a message indicating that option was chosen, but don't actually try and change the board around yet.

    4. (25 points) Add a method to the Board class that allows making a move. This should be a method that receives as a parameter the integer representing the piece to be moved. You should consider having this method return a value to the code in the PlayGame class, where this return value will signify whether or not the move was a valid move. This method will have the effect of showing a tile slide to the correct position. Note that sliding is accomplished by calling the Square class slowMoveHorizontal() and slowMoveVertical() methods, sending the correct values to have it end up in the right place. I recommend that you not only have the indicated tile slide into the blank spot, but you also have the invisible tile that is currently at the blank spot slide into the spot where the other tile came from. In other words, they swap places.
           One approach you could take to do this is to create a method in the Board class that returns a Square, given an index. In other words if you send it the integer 3, it returns a reference to the Square that has "3" as its label. Returning a "reference" simply means that the return type of this method should be Square, and that at some point in the method you will "return" the particular square that has "3" as its label.
           Using the above method, you can find a particular square, and you should already have a reference to the invisible square, which should have been set when the Board constructor code was executed. You can then call the getX() and getY() methods for these two squares and find the difference between them. This should tell you if the desired tile to move is adjacent to the open square on the board. These differences can also be used in the slowMoveHorizontal() and slowMoveVertical() methods to actually move the tiles, implementing the swap.
           Now call this method from the main loop in the PlayGame class, thus implementing user moves.

    5. (5 points) Add the code that does error checking, giving a warning message and allowing a retry when the user move is incorrect. Some of this code could be in the PlayGame class, and other parts could be in the Board class method where you make a move.

    6. (10 points) Create a method in the Board class that randomizes the tile labels. To do this I suggest you generate two random numbers indicating two board tiles, and then swap the labels for those two tiles, repeating this multiple times. Sample code for generating random numbers can be found here. Add the code to call this from the PlayGame class when the user enteres 'r' to randomize the board.

    7. You do not need to write the code to check and see when the game is done. The user can determine this.

  3. Turnin your program electronically using the "turnin" command from your CS account on ernie.cs.uic.edu as follows:
  4. turnin -c cs107 -p program3 9Tiles
    where the directory containing the multiple files for the solution for this project is called 9Tiles. Failure to use turnin to submit this program will result in at least a 5 point deduction.


[CS Dept] [UIC] [Prof. Reed]