Java Programming   Java Programming
 |Sofia Home | Content Gallery |
Home
Syllabus
Schedule
Lessons
Assignments
Resources

Assignment 8 - Working with Arrays

The Sun Java Development Kit (JDK) comes with a sample program that plays TicTacToe. The JDK program includes sounds and comes with cool graphics. It can be a little slow, however, and the code is not the easiest to understand.

In this homework, you'll build your own version of TicTacToe using Labels, GridLayout, and a couple arrays. Before you get started, however, why don't you take a minute to play a game?

  • To complete the homework, you'll have to understand how to: 
  • Declare a two-dimensional array of primitive values.
  • Declare a two-dimensional array of object references.
  • Initialize each of the elements in a two-dimensional array of object references.
  • Use a pair of nested for loops to process the elements in a two-dimensional array.
Much of the TicTacToe program is already written for you. Start by downloading the starter file, TicTacToe.java, and then follow the steps outlined below. If you notice "strange" characters when you download the TicTacToe program, or if the file contains no "plus" signs, it means your browser is having a "hard time" when it transfers the file from the server to your hard disk. If this happens to you, then simply click on the link, display the file in your browser, and then copy and paste from your browser window into Notepad or another text editor. If you are using IE, it is possible that there is a problem delivering the file because of the extension. In that case, download TicTacToe.txt, but remember to rename it on your disk.
Back to Top

Step-By-Step Instructions 

Step 1

Define your applet's attributes. The TicTacToe program has three different kinds of fields that you must define before you can compile the program successfully. Make sure you define your fields and are able to compile without warnings or errors, before you attempt to go further.

Here are the three kinds of fields:

1. Program Arrays

The TicTacToe program has two "parallel", 3 x 3, two dimensional arrays. Start your programming by defining these two arrays:

  • The first of these is an array of Label objects. This array, named grid, is used to display the actual Xs and Os on your screen. Each Label will display an X, and O, or a blank.
  • The second array is an array of char primitives. This array, named game, is used to simplify keeping score as the game is played. Each element in game contains a space ' ' if the position has yet to be played, an 'X', if the position contains an X, and an 'O' if the position contains an O. 
2. Graphical User-interface Fields

In addition to the Labels that make up the array named grid, the TicTacToe applet contains the following user-interface elements. Define these elements after you've finished defining your arrays:

  • A Button object named restart. The user can restart the game by clicking this Button.
  • A Panel named p. Use the default constructor to create p; it will hold the Labels in grid
  • A Label named status. This will keep the user informed of the game's progress. You might want to initialize status to a helpful welcome message.
3. Primitive Fields

Your program will contain the following primitive fields which you'll use as you play the game:

  • An int named numClicks that will keep track of how many X's and O's are displayed.
  • A boolean named isDone which is used to determine when the game is finished. Initialize isDone to false.
  • A boolean named isXTurn which is used to determine whose turn it is to click. Initialize isXTurn to true--we'll assume that X always goes first.

Once you've defined these fields, make sure your program compiles without error. If it does not, then you've made a mistake defining the fields; go back and double-check your work until the compiler quits complaining.

Step 2

Write the init() method. There are four tasks to complete in this step. You may want to compile after each task, just to make sure you're on the right track. After you've finished writing the init() method, compile one last time before going on. When you finish this step, you should be able to run your applet and see that its appearance is satisfactory.

1. Set the Layout

Your applet will use BorderLayout for the applet itself, even though the Panel that contains the game's labels will use GridLayout. Use setLayout() to initialize your applet's layout.

2. Add the Status Label

Add the Label named status to the top of your applet. When you do so, also change the Label's appearance like this:

  • Set the Label background to yellow, the foreground to blue
  • Set the Label font to a nice 12pt bold Helvetica
3. Initialize the main Panel

You want to display the Label objects in the grid array using a 3 x 3 grid on the screen. Fortunately, Java's GridLayout is just what you need. Before you add the Label objects to your Panel, however, there are a few things you need to do to prepare your main Panel.

  • Use the setLayout() method to change the Panel object p so that it uses a GridLayout. Leave three pixels between cells in the grid. 
  • Change the font used by the Panel to a 32 point, bold Helvetica
  • Change the Panel's background color to black. (This adds the lines between Labels.)
  • Add the Panel to the center of your applet.
4. Initialize the grid

In Step 1, you created a 3 x 3 array of Label references named grid. Each of the elements in grid, however, is not yet a Label; instead grid is populated with 9 null Label  references. To fix that, you need to use a pair of nested for loops to create 9 Label objects and place them into your array.

Here's what you do. Write a pair of nested for loops. Use row for the outer loop index and have it go from 0 to 2. Use col for the inner loop index and have it go from 0 to 2. Inside the inner loop, do the following:

  • Create a Label object using new, and place it in the corresponding element in the array. (grid[row][col]). Examine the note in the source code to see how this should look.
  • Attach a MouseListener to the Label object using addMouseListener(this). Note that this is different than using MouseMotionListener.
  • Set the background of the Label to white
  • Add the Label to the Panel named p.
  • While you are still in the inner loop, place a space in the current element of the char array named game. Because both grid and game have the same number of dimensions, you can use the [row][col] indexes on game as well as grid.

At this point, your init() method is finished. Compile your program, clean up the syntax errors, and then take it for a ride.

Click here to see what your program should look like at this point. Nothing should happen when you click on any of the Labels, but the basic structure and layout of the applet should look correct.

Back to Top
Step 3

Handle the mouse clicks.  Because the TicTacToe applet uses the Java 1.1 MouseListener interface, the code to handle mouse clicks is placed in a method named mouseClicked(). You could have placed the code in the methods mousePressed() or mouseReleased() as well. Under Java 1.0 you could have used the mouseDown() or mouseUp() methods. Unfortunately, Java 1.0 does not reliable deliver mouse clicks on Label objects.

This is a fairly complex method, but much of it has been written for you. You will have to write the code to display the X or the O, but the nested for loops in this method have already been completed. Locate the comment marked "a." in the code, and then complete these four tasks:

1. Handle Invalid Moves

For a move to be valid, the Label must be blank. You can check if the Label is blank by using the getText() method to retrieve the Label's text, and then using the equals() method to see if it contains a single space. [Alternatively, you can check to see if the element game[row][col] is a single space.]

You can use the identifier clicked to refer to the Label object that was clicked. The variable clicked is a local Label variable that is initialized at the start of the mouseClicked() method, using Event.getSource(). [This part of the code, creating the local variable named clicked, was written for you.]

If the Label named clicked is not blank then:

  • Print an error message telling the user that the move is illegal. 
  • Use the Label object named status to display the message.
  • Use the statement break next; to leave the entire set of nested loops. [Note that next: is a label defined before the outer loop. This form of break is called a labeled break.]
2. Handle 'X' Moves

Add this code inside the mouseClicked() method, under the comment section that is labeled b. In the previous task, you checked to see if the Label named clicked was blank; if it was not blank, you printed an error message and left the loop. In this section, you put the code to draw an 'X' if it is the 'X' player's turn. 

Here's what you do. First, check if it is the 'X' player's turn. Do that by testing the value of the field isXTurn. If it is the 'X' player's turn then:

  • Set the text in the Label named clicked to "X". (Use the setText() method.)
  • Set the foreground color of the Label named clicked to red.
  • Set the element game[row][col] to 'X'.
3. Handle 'O' Moves

Add this code inside the mouseClicked() method, under the comment section that is labeled c. In the previous task, you checked to see if it was the 'X' player's turn. In this section, you'll write code to handle the case where it is not the 'X' player's turn. Here's what you do:

You don't have to check if it's the 'X' player's turn; you already checked that in the last task. Place the code in this task inside an else statement, connected to the if statement in task 2. Inside your else block:

  • Set the text in the Label named clicked to "O". (Use the setText() method.)
  • Set the foreground color of the Label named clicked to blue.
  • Set the element game[row][col] to 'O'.
4. Finish Up

After drawing the 'X' or the 'O', you need to do a little bit of housekeeping. This part is really simple. Find the section labeled d, and add these lines:

  • If isXTurn is true, then change it to false; if it is already false, change it to true. You can do this easily by using the logical NOT operator (!).
  • Increment the number of clicks. This is stored in the field numClicks.

At this point, you're all finished except for resetting the game after the one game is finished. You'll handle that in the next step. Before you go on, however, make sure your program compiles and that it works OK. It's easier to fix problems at this stage than after you've written the code for the next step.

Click here to examine the TicTacToe program as it should look at this juncture.

Back to Top
Step 4

Write the resetGame() method. This method is called to "clear out" all of the Labels whenever a game is finished, or when the user presses the "Reset" button. Here's all you need to write:

  • Write a nested for loop. Use row and col for your indexes.
  • For each element in the Label array named grid, set the text to a single blank space using the setText() method. [Make sure you don't set it to more than one space or to the empty String accidentally.]
  • Inside the same nested loop, set each element in the char array named game to a single space as well. Here you'll have to use a char literal like this ' ', while in the previous step you need to use a space contained inside a String like this " ".
  • Set the field named numClicks to zero.
  • Set the field named isXTurn to true.
That's it. Compile it up, test it out, and you're finished.

Finishing Up 

Post your applet. Once you've tested your applet locally, add it to the Assignment 8 HTML file on your Web site. Remember that you must send the .class file as well as an updated HTML file. When you use FTP to send up your .class file, remember that it must be transferred using binary mode, not ASCII. 

 

Back to Top