Create a Java program plays tic-tac-toe (or, as the British call it, "noughts and crosses").
If you have never played tic-tac-toe, read the description of the game in the next section; otherwise, skip to the assignment specifications.
Tic-tac-toe is played on a 3 x 3 grid. Two players take turns at selecting squares on the grid, the first marking his or her moves with an "O" (British, "nought"), the second, with "X" ("cross"). The first player to select three squares in a row -- horizontally, vertically, or diagonally -- wins the game.
Your program should draw the game board using a simple representation, with the squares numbered from 1 to 9, such as:
1 | 2 | 3
-----------
4 | 5 | 6
-----------
7 | 8 | 9
It should then prompt the user to select one of the squares, by number. It should check that a valid selection has been made (i.e., the number is in range and was not previously selected by either player) and, if not, print an appropriate message and prompt again. The following example illustrates such an interaction:
X | X | 3
-----------
4 | O | 6
-----------
7 | O | 9
Your move? 2
Please enter one of the digits shown on the board.
Your move? 17
Please enter one of the digits shown on the board.
Your move? 3
Once the human player has made a valid selection, the program should choose a square for its move. It should then indicate which square was selected and print an updated representation of the board, indicating the human player's moves with O's and its own moves with X's. The next round of play then commences with another prompt to the human player, as in:
I chose square 4.
X | X | O
-----------
X | O | 6
-----------
7 | O | 9
Your move?
After each move -- both the human's and its own -- the program should check for a winner. If a player has won, an appropriate message should be printed and the game ends.
For example, if the human player wins, it might print:
X | X | O
-----------
4 | O | 6
-----------
O | 8 | 9
Congratulations. You won.
If the computer wins, it might print the following:
X | X | O
-----------
X | O | O
-----------
X | O | 9
I won. Let's play again soon.
The program should also check for a no-win condition, in which all squares have been selected, but neither player has won:
X | O | X
-----------
X | O | O
-----------
O | X | 9
Your move? 9
The game ended with no winner.
The playing grid could be represented internally with an array of size 9. However, because the human player marks squares with an 'O', it is not a good idea to number the squares 0 through 8 instead of 1 through 9. In order to avoid the nuisance of adjusting player selections in the range 1 ... 9 onto the array indices 0 ... 8, it is probably a good idea to create an array of size 10, and only use elements 1 ... 9.
You could represent the board with a two-dimensional (3 x 3) array, but this is probably more trouble than it is worth, because you would have to map the user's selections onto pairs of row and column numbers. It's easier to write a board printing routine that starts a new row after each set of three squares.
There are several ways one could keep track of which squares have been selected by which player and which are still available. One of the simplest is to declare the array as of type char[] (i.e., an array of characters). If the array is then initialized with the characters '1' through '9' and player moves are recorded by storing an 'X' or an 'O' in place of the appropriate digit character, it is easy to print the 3 x 3 representation of the current state of the grid.
If this method is chosen, be careful to note the distinction between the numbers 1, 2, ..., 9 and the characters '1', '2', ..., '9'.
You are not required to make the program play intelligently. You could have it choose the first available square on each of its moves. This doesn't make it very much fun to play against the computer, but if you need to play tic-tac-toe with a computer in order to have fun, your life is too sad and miserable for you to notice that the computer is not playing intelligently.
Remember to declare all your functions to be static. Using several small functions makes it much easier to write the program. At minimum, you will want a function to print the current state of the playing grid, and another to determine if some player has won.
You could put the whole tic-tac-toe game procedure in an outer loop that allows the human to play multiple games against the computer, and keeps score over all games in the tournament.
You could use a different representation for the game board if you think it has some advantages. For example, David Green, an MSc student at Edinburgh University in 1991, represented the playing grid as a 3 x 3 "magic square", as follows:
8 3 4 1 5 9 6 7 2
This representation has the property that each winning line has a total sum of 15; that is, each sum of three digits that equals 15 defines one of the winning positions of the game.
If you can figure out a way to make use of that fact, good for you.
You could make the computer play more intelligently by at least recognizing a threat -- two of the opponent's marks in the same row, column, or diagonal -- and blocking the win by the human player.
You could have the computer recognize a tie game before prompting the user to enter the number of the only remaining grid square. It's more work, and it won't earn you any more points, but you could do that.
Your Java code will be marked out of 20 points. Of that total, 10 points will be awarded for the correctness of execution of your program, and the other 10 points will be for style and documentation.
Pay careful attention to the indentation of the various lines of your Java program -- the level of indentation should indicate which parts of the program are nested inside other program structures. Also, use comments to document your code where you think that would be appropriate. Reasonable formatting of the output produced by the program is also expected; for example, each output statement should appear on a separate line.
It is good style to keep computation and decision-making separate from I/O. For example, it is appropriate to have a function to print the grid, but it should only print the grid; it should not also check the user's input selection and update the internal representation of the grid. Similarly, it is appropriate to define a function to check whether one of the players has won the game, but it should not also print a message to the output declaring the winner; rather, it should return a value (probably true or false) to the game control code in main and, based on that value, main should print the appropriate output message or continue play.
Submit your Java program in electronic form using the following submission form.
Note that you must submit your text file (with a .java extension), not the .class file that results from compiling the Java program.
Your assignment submissions are password-protected. These passwords apply only to form data submitted via the Web server for Jonathan Mohr's courses. They are separate from (and typically different from) your network password or the password. To change your Web password, press the following button:
Copyright © 2004 Jonathan Mohr