| Assignment
3: Tic-tac-toe Fall 2007, David Matuszek |
Write a program to allow the human to play tic-tac-toe (also called "naughts
and crosses") with the computer. The computer will always play 'X';
the human will always play 'O'. The computer and human will
alternate taking the first move, with the computer having the first move
in the first game. After each game, print out how many games have been won
by each player, and how many ended in a tie.
Use Eclipse.
In Eclipse, create a project with this name: LastName_FirstInitial_TicTacToe,
where LastName and FirstInitial are
the name of one (either one) of the partners. Use the default package.
Use the following classes and methods. Put both your names in (separate)
@author tags in the comment for the TicTacToe class. Be
very careful with spelling and capitalization; your names and parameter lists
must match the specification exactly. You may write additional methods if
you like.
class TicTacToe
public static void main(String[] args)- Creates an object of type
TicTacToeand tells it torun().
void run()- Does all the top-level organization of playing multiple tic-tac-toe games:
Most of this work is done by talking to the
- Creates a new board for each game.
- Keeps track of whose turn it is to start the game.
- Keeps track of whose turn it is to play.
- Tells each player when to make a move.
- Prints the game board after each move.
- Test whether the game is over.
- When a game ends, prints who won.
- When a game ends, prints how many games were won, lost, and tied.
- Decides whether to play again.
HumanPlayer, theComputerPlayer, and theTicTacToeBoard.
class TicTacToeBoard
The following methods and constructor have been provided for you here, because they require the use of an array, and we haven't covered arrays yet. Your additional methods should use these predefined methods, and should not directly access the array.
TicTacToeBoard()- Constructor for a
TicTacToeBoard. This constructor has been provided for you.
void set(int row, int column, char ch)- Sets the square in the given row and column of the tic-tac-toe board to the given character. The row and column must be integers in the range 1 to 3; the character must be either
'X'or'O'.
char get(int row, int column)- Returns the character in the given row (1, 2, or 3) and the given column (1, 2, or 3) of the tic-tac-toe board. The return value will be one of
'X','O', or' '(space).
boolean isEmpty(int row, int column)- Tests whether the square in the given row and column of the tic-tac-toe board is empty, that is, available to be moved in.
void print()- Prints the tic-tac-toe board.
The following methods should be added by you or by your partner.
boolean gameIsOver()- Tests whether the game is over, either because someone has won, or because there is no remaining move possible.
boolean computerHasWon()- Tests if the computer has won the game.
boolean humanHasWon()- Tests if the human has won the game.
class HumanPlayer
Use the default constructor,
new HumanPlayer(), for this class.
void makeMove(TicTacToeBoard board)- Asks the player for a row and a column and, if that move is legal, puts an
'O'in that location.
boolean ask(String question)- Asks the player a yes-no question, and returns
truefor a yes answer,falsefor a no answer. (This is for use in asking whether to play another game.)
You are using a
Scannerin theTicTacToeclass, but thatScanneris not immediately available here. I'm told that it is okay to have more than oneScanner, so that you can create anew Scannerin theHuman'saskmethod. (I still want to check this out myself.)Better than creating a new
Scannerevery time you callask, you might just create a staticScannerin theHumanclass (not in a method of the class):
static Scanner scanner = new Scanner(System.in);
and use that.
class ComputerPlayer
void makeMove(TicTacToeBoard board)- Makes a move for the computer. Here is the logic you should use:
- If the center square is available, move there.
- [optional] If there is a move that will win the game for the computer, move there.
- [optional] If there is a move that would win the game for the human, prevent the win by moving there.
- If there is a corner square available, move there.
- If there is an edge square available (and there should be, because you shouldn't call this method if there are no more moves possible), move there.
The
makeMovemethod should do its job by calling "helper" methods. Use these method signatures:
private boolean makeCenterMove(TicTacToeBoard board)private boolean makeWinningMove(TicTacToeBoard board) // optional methodprivate boolean makeForcedMove(TicTacToeBoard board) // optional methodprivate boolean makeCornerMove(TicTacToeBoard board)private boolean makeEdgeMove(TicTacToeBoard board)For each of these, the method should return
trueif the requested move was made, andfalseif it was not possible. (This is so themakeMovemethod knows whether it is done, or whether it should keep trying.) I have marked two methods "optional" because, while they will improve the computer's play, the methods are likely to be quite long and tedious, and you won't learn that much from writing them.
Thursday, September 27, before midnight. Turn in your program electronically, using Blackboard. (See my Instructions for Using Zip Files and Blackboard). Put your partner's name in Blackboard's comment field when you submit the program. Only assignments submitted via Blackboard will be accepted--do not send your program by email. The usual late penalty of 5 points per day (out of 100 points) will apply.