AP Computer Science Programming Project—TicTacToe

AP Computer Science
Programming Project—TicTacToe
ASSIGNMENT OVERVIEW
In this assignment you’ll be creating a package of programs TicTacToe which will allow a user to play the
game of Tic-Tac-Toe against another player, against the computer, or to watch the computer play against
itself.
This assignment is worth 50 points and is due on the crashwhite.polytechnic.org server at 23:59:59 on the date
given in class.
BACKGROUND
The game of Tic-Tac-Toe is well known: players take turns placing Xs and Os in the spaces of a 3-by-3
grid, and the first player to get three in a row across, down, or diagonally, wins. The game is known for
being impossible to win (against a competent opponent), and the fact was a key in the final scene of the
movie Wargames where the computer Joshua learns that “the only winning move is not to play.”
The relative simplicity of this game makes it ideal for exploring some of the more complex topics that
we’ve learned about in this course, including interfaces and inheritance. The game is also a great place to solve
some logical puzzles: what are some of the ways that a game can exhibit a simple “artificial intelligence”?
This assignment takes place in five separate stages, with each stage relying on successful completion of the
previous stage.
PROGRAM SPECIFICATION
Create a Java package (collection of classes) that:
a. includes appropriate APIs for all classes and methods
b. uses AbstractGrid to implement the GridInterface
c. uses TicTacToeBoard to extend AbstractGrid
d. includes a Location class
e. includes a HumanPlayer class
f. includes a ComputerPlayer class
g. includes several TicTacToeGame classes as described below that conduct games of TicTacToe
DELIVERABLES
TicTacToe.zip
This single file will be a zipped directory (folder) of your BlueJ project. It will include as a minimum the
classes described above along with any other classes you create during the development of your program,
and a package.BlueJ file.
To submit your assignment for grading, copy your file to your directory in
/home/rwhite/apcs/Public/Dropbox/ at crashwhite.polytechnic.org before the deadline.
ASSIGNMENT NOTES
• Creating this package will involve working your way through a series of five activities, each of
which build on the previous work. Some of the activities will ask you to write your own testers for
the classes you’re writing, and some will come with testers supplied. A zipped folder for each
activity is available from the instructor.
•
The activity begins with a a little brainstorming and trial coding before moving onto a
GridInterface and AbstractGrid file that you’ll be using for the remaining activities. You are
welcome to write your own interfaces and superclasses if you’d like to experiment with that
process, but use the provided files as the foundation for this activity.
•
Use the Activity descriptions below to guide your work for each stage of the project. It’s important
to complete one activity before moving on to the next in order to avoid spoilers. Subsequent
activities may include clean, working code to use in place of what you what you’ve already
developed.
ACTIVITIES
1. Design Considerations (Activity 1)
Take a few moments to consider how you would design and program a game that allows the user to
play Tic-Tac-Toe against the computer. What classes will we create? What methods will those
classes have? Should we jump straight into designing a computer player, or should we get humans
playing against each other first so that we can get the game mechanics down, and then figure out
how to make a computer play? Should it be a graphics version or a text-based version?
Command decision: initially, we'll make it a text-based version, ie. the board will be displayed as:
X | O |
---+---+--O |
|
---+---+--| X |
Discuss with others various strategies for working through this project, and begin some initial
forays into coding things. Do you prefer beginning with the small scale classes—writing a
Location class that you can use to track locations on the board?—or do you prefer to start by
writing the main program that’s going to use all the classes that we’ll be writing?
Regardless of what you do during this first exploratory activity, it’s guaranteed that we’ll end up
rewriting some or all of what you’ve done. That’s okay. That’s part of the process, and this
assignment, unlike most of the assignments that we’ve worked on, allows for that kind of
refactoring to happen as we go.
2. The Problem Refined (Activity 2)
Our textbook's description of a TicTacToe class and runner is reasonable for a first pass through
the problem.
a) The constructor for the TicTacToe class creates a 3 x 3 board.
b) A .set() method allows for placing an X or O on the board at a specified position.
c) A .toString() method allows for the current state of the board to be printed out.
Follow-up activities in the Programming Exercises section ask you to:
a) Add a .getWinner() method that tries to identify who, if anyone, has won the game.
b) Write an application (a Runner) that allows two people to play the game.
If you’ve done that assignment then you’ve got two classes, TicTacToe and TicTacToeRunner,
and that’s a nice little introduction to some of what we’ll be doing here. (If you haven’t done that
assignment, that’s fine. We’ll be covering the same topics here in a slightly different form.)
Consider these two questions:
a) Many games consist of a grid surface that is split up into rows and columns just like the tictac-toe game is: checkers, chess, Chutes & Ladders (Snakes & Ladders), Scrabble, Boggle,
etc. All of these games consist of a two-dimensional grid with locations addressable by a
location, indicated by a row-column pair of indices. Wouldn't it make sense to create a
superclass that we could extend for use in different types of games?
b) Continuing this idea, How will we re-design our TicTacToe game so that the computer can
play against the user? Will we need new methods? New classes? A new Runner?
Download the Activity2.zip folder and examine the classes in there. Start with the Location
class, then examine the GridInterface, AbstractGrid, and TicTacToeBoard classes to
investigate how these pieces fit together.
Based on your preliminary investigation, what methods does our TicTacToeBoard class still need
to have added to it?
For this Activity:
1. Write the following four methods for the TicTacToeBoard class.
1. .getWinner()
2. .checkRows()
3. .checkColumns()
4. .checkDiagonals()
2. Override the .toString() method from the AbstractGrid class so that we can display a
more reasonable representation of the TicTacToe game on the screen.
3. Consider writing a DevelopmentTester class that you can use as a temporary tester for
these methods as you're writing them.
3. Adding a HumanPlayer (Activity 3)
Now that we've got the basic game mechanics of a TicTacToe board up and running, it's time to
write the Player classes. In the end we'll want a HumanPlayer class and a ComputerPlayer class so
that we can play against the Computer, but for now, let's just get the HumanPlayer class going.
Download the Activity3.zip folder.
Because we're going to be getting input from the user, we'll definitely want to use a Scanner for
the HumanPlayer class. We'll also want to incorporate some means of checking the validity of our
moves.
Write another DevelopmentTester that allows you to interact with your classes as you write them.
4. Adding a ComputerPlayer (Activity 4)
The only difference between a human Player and the computer as a player is that the computer has
to somehow make decisions about where it wants to move. Artificial Intelligence!
Before we go all Skynet, though (look it up if you didn't get that reference), let's write a computer
player that just makes random moves. They have to be legal random moves, though.
Download Activity4.zip and write the ComputerPlayer1 class.
Then write HumanVsComputer1 that allows a HumanPlayer to play against our random
ComputerPlayer1.
If you have time, write a ComputerVsComputer1 class that pits two random ComputerPlayer
objects against each other.
5. Artificial Intelligence (Activity 5)
We're finally at a point where we can start thinking about how to make our Robot make smart
moves.
What is it that determines a smart move? Download Activity5.zip and use that to explore these
possibilities.
Offensively, if we have the opportunity to win, we should make that move. We need to be able to
program into our ComputerPlayer2 the ability to say "If I move at this available location, will I
win?" An alternate strategy is to give that class the ability to say, “Are there any rows, columns, or
diagonals in which I have two spots already taken and there is a third spot open for me to play in?”
If we can’t win on the next move, we definitely don’t want to lose. Defensively, if we have the
opportunity to block the other player’s win, we should make that move. Our ComputerPlayer2
needs to say "If I don't move to this location, will the other player win next?" Or equivalently, “Are
there any rows, columns, or diagonals in which the opponent has two spots taken and there is a
third spot open for me to play in?”
If neither of events occurs, then we’ll just move randomly.
Write a HumanVsComputer2 runner that allow a HumanPlayer to play against the intelligent
ComputerPlayer2.
Write a ComputerVsComputer2 class that pits a ComputerPlayer1 objects against a
ComputerPlayer2 object.
6. Going Further (Optional)
We’d be hard-pressed to call our ComputerPlayer intelligent: it only recognizes board patterns that
we’ve taken a lot of trouble to write code for. It doesn’t recognize more general patterns, and it
certainly doesn’t have the ability to learn, ie. adapt its behavior based on previous outcomes.
Could we give our program the ability to learn, however? How would we do that? How does
machine learning work?
Consider what features you’d need to include for a ComputerPlayer to learn over time.
7. Going Further (Option 2)
There’s a certain throwback charm to playing Tic-Tac-Toe in the console (command-line Terminal),
but most people prefer a point-and-click interface for a game like this. Convert your Tic-Tac-Toe
game to a graphical form that uses (as much as possible) your existing code.
QUESTIONS FOR YOU TO CONSIDER (NOT HAND IN)
1. What is refactoring? What are the benefits of refactoring your code? What are the drawbacks?
2. In popular culture, what movie does the term Skynet refer to?
3. What does Ray Kurzweil’s technological singularity refer to?
4. What defines machine learning?
5. What does the phrase Model-View-Controller refer to? Consider the phrase in the context of a TicTac-Toe game that is text-based vs. graphics-based.
SAMPLE INTERACTIONS
|
|
---+---+--|
|
---+---+--|
|
X's turn
Your move!
Column coordinate: 0
Row coordinate: 0
X |
|
---+---+--|
|
---+---+--|
|
O's turn
Choosing random move...
X | O |
---+---+--|
|
---+---+--|
|
X's turn
Your move!
Column coordinate: 0
Row coordinate: 3
Invalid move
Column coordinate: 0
Row coordinate: 2
X | O |
---+---+--|
|
---+---+--X |
|
O's turn
Playing to block!
X | O |
---+---+--O |
|
---+---+--X |
|
X's turn
Your move!
Column coordinate: 2
Row coordinate: 2
X | O |
---+---+--O |
|
---+---+--X |
| X
O's turn
Playing to block!
X | O |
---+---+--O |
|
---+---+--X | O | X
X's turn
Your move!
Column coordinate: 1
Row coordinate: 1
X | O |
---+---+--O | X |
---+---+--X | O | X
The winner is X