|
|
Course Project
This homework will continue to develop the course project, which is the
game of Battleship.
We have developed a number of classes so far:
- Ship (HW J6): Represents a ship, of course. This can be any
size ship, placed anywhere on the board.
- Cell (HW J6): A cell is a single spot on a board. Thus, a
sample board could have a 15x15 grid of cells.
- Descriptions (Lab 9): This class allows one to pick the names of
their ships.
- ShipList (HW J7): A list of ships. For example, each player
(human or computer) will have a list of 5 (or so) ships that were placed
on the board.
- Parser (Lab 10): This class reads in commands from the keyboard, and
figures out (or 'parses') what the player means by them.
In this homework, you will develop two classes:
- AI (HW J8): This class represents the computer player in the game
(AI stands for Artificial Intelligence). It is responsible for
making the decisions as to which move to make next.
- Human (HW J8): A class to represent the player in the game.
This class will be in charge of reading in input from the keyboard as to
where to take the next shot, for example
We will provide you with one class for this homework:
- Game: The class with the main() method that will run the game.
It ties together all the other classes.
The remaining assignments will develop the remaining classes:
- Board (HW J9): This class represents the board that players place
their ships on, and takes shots on as well.
- MapPrinter (Lab 11): This allows easy printing of the board to the
text-based screen.
Purpose
For this homework, you are responsible for implementing the AI class.
You must submit this class, along with the Game.java file.
We are only providing skeleton code for Game.java.
Because this homework was released late, we are providing the
Human.java code; your job is just to implement the
AI class (and the testing in Game.java). This homework was originally
designed to have you implement both classes. Even though you still
have to implement only one, the description still talks about the Human
class implementation as well.
If any of the descriptions below are confusing as
to what is required for AI.java, take a look at the code for Human.java --
that will often help clarify it.
Files
You will need a number of files for this homework:
Board.java, Game.java,
Human.java, MapPrinter.java,
Parser.class, Ship.java,
ShipList.java. Note that many of these
files include just the minimum that will allow this homework to compile.
You are welcome to use your own code instead. You should save all
your code in a separate directory than the previous labs and homeworks, so you do not overwrite your
files.
You will need to import the java.awt library to use the Point class.
You will need to import the java.util class for the Vector and/or Random
classes.
Documentation
As one develops more classes for this project, they start relying more
and more upon previously defined methods. This is especially true for
the Human class, which will call many of the methods in the Parser class.
Thus, people will often need to refer to the details of the previously
defined classes. To this end, we have provided
documentation of all the classes online.
The format of this documentation is the same as the Java SDK.
Background
During the game, there will be an object created to represent each
player. So if a human is playing the computer, then there will be a
single Human object and a single AI object. Each object is
responsible for determining which move to make next (the Human object will
do so by using keyboard input; the AI object will decide for itself).
As we will see later in the homework, we can easily make two AI players play
against each other -- in this case, there would be two AI object, each
representing different players in the game.
Human and AI Classes: common methods
Both classes will need to provide ALL of the following methods. How
each method works will be different for the Human and the AI. The AI
class will need to provide a few additional methods, as described below. All
fields must be private. All methods must be
public; none should be static.
Properties
No properties are required for the Human class. Feel free to add
ones, if you feel are necessary.
Each AI object should have a measure of intelligence. We'll use an
integer instance variable. In this course, we will see intelligence
levels of 0, 1, and 2 -- a higher number means that the computer player is
"smarter" at playing the game. You will be in charge of implementing
the methods for intelligence levels 0 and 1, below. We will show you
the code for intelligence level 2 in lecture.
Constructors
Both classes must have a default constructor (which won't do much for the
Human class). The AI class must also have a specific constructor that
takes in a single int parameter, and sets the AI's intelligence to that
value.
Accessors and Mutators
As the Human class does not have any fields, it does not need any
accessors or mutators. The AI class should have methods to set and get the intelligence of the AI object
(called setIntelligence() and getIntelligence(), respectively).
Other Methods
As you will see below, you will have to implement the same methods in
both the Human and AI classes -- thus, the descriptions here explain how the
methods would work for both classes.
- Board setupBoard(int x, int y): This method is in
charge of setting up the board for the Human or AI. It needs to
create a new board, set it up, and then return it. The AI version
is easy: just create the board, then call call to
board.generateRandomBoard() method in the Board class (which
you will implement in HW J9). The parameter to this method is the
number of ships (for now, that number is a constant in the Game class).
Remember that you can look at the documentation for the Board class
here.
For the Human version, we first need to check to see if the player
wants to place his or her own ships. If not, then generate a
random board as with the AI. If so, then allow the player to setup
his or her own board. Note that the methods for this are already
written: Parser.setupBoard() will ask the player if
s/he wants to place their own ships. The Parser.placeShips()
method will handle the player's setup of the ships. This
method should not be more than 10 lines -- if it is, then you are doing
something wrong.
- Point getNextShot(): This method is in charge of
determining the next location for the player to shoot at. For the
player, one can just call the Parser.getLocation() method. How
this method works for the AI is described below.
- String getName(): This method will return the name
of the player: either "You" for the Human class, or "The computer" for
the AI class. Something that can be used in the sentence
getName() + " wins". It's bad grammar for "You wins", but it's
easier than implementing an additional method called
printThatYouWin(). This is used to explain who is doing what during the
game. Note that the AI version will be modified a bit, as
described below.
- String getIntro(): This method will just return a
String such as "You fire a shot at" or "The computer fires a shot at".
Something that can be used in the sentence getIntro() + "
location (0,0)". This is used to properly explain who is shooting where during the game.
Note that the AI version will be modified a bit, as described below.
- String getPronoun(): This method will return either
"Your" or "The computer's". Something that can
be used in the sentence getPronoun() + " ship has sunk". Note that the AI version will be
modified a bit, as described below.
- void print(Board board): This method will print the
board for the player (i.e. it will show the ships). This is done
via a call to a method in the MapPrinter class, and is the same in both
the Human and AI classes.
- void printForOpponent(Board board): This method will
print the board for the opponent (i.e. it will NOT show the ships).
This is done via a call to a method in the MapPrinter class, and is the
same in both the Human and AI classes.
- void reportStatus (int status): This method will
print out the status of the last shot. This is just a single call
to Parser.displayResult().
AI Class
A bit more info for the AI class...
Other Methods
Please make sure you spell naive properly (think of it like "Evian"
backwards) -- if you don't, our code that tests your homework will not
realize that you wrote the method, and you will receive points off.
- String getName(): The getName() method should return either the String "The
computer" (if intelligence is equal to zero) or "The computer w/ AI x",
if the intelligence is greater than zero (replace x with the
intelligence level, of course). This should also be the case with
getPronoun() and getIntro().
- Point getNextShot(): There will be three methods for the varying levels of
intelligence: getNextShotNaive(), getNextShotNaiveWithMemory(), and getNextShotWithGridStrategy(). These methods have the same
prototype (i.e return type, parameters, etc.) as getNextShot(). The getNextShot()
method is just going to be a switch or
if-else-if statement: if the
intelligence is 0, then getNextShotNaive() is called; if it's 1, then getNextShotNaiveWithMemory()
is called; if it's 2, then getNextShotWithGridStrategy()
is called; if it's anything else, you can
just return null.
- Point getNextShotNaive(): This method will just return a random spot on
the board. You need to use the Game.rand object to generate your
random values. See the
documentation for the Random class if you forget how to generate a
random integer. This method does not keep track of what spots it
already hit.
- Point getNextShotNaiveWithMemory(): This method operates like the last
(returning a random value), but it keeps track of previous spots that it
already shot at. Thus, if a randomly generated spot has already
been shot at, it will choose again (and again and again) until it finds
a spot that has not already been shot at. There are a number of
ways to keep track of the shots previously shot at. One way is to
use a two dimensional boolean array (if we get to that topic in lecture
in time). Another way is to keep a Vector of Points -- every time
a new location is about to be returned, it is also inserted into the
Vector. You can then search the Vector for a given Point via the
contains() method (you have to provide a Point object to that method
-- it will then return true or false if
a Point object with the same values is in the Vector). Both
of these would have to be instance variables in the AI class.
- getNextShotWithGridStrategy(): This method is one we will be
presenting in class. For this homework, you can just have it
return null.
Game class, Revisited
Your main() method in the Game.java file should test all
of the methods that you implement. In previous homeworks, you did this for
various classes.
This homework requires the same, but for the AI class. We have
provided you with code that will run the AI class through a number of calls
to getNextShot(). It will be much easier if you implement a
method at a time, then write the test code in Game.java to ensure that it
works correctly! You
Good Programming Practices
All the good
programming practices from HW J1 should be included here as well.
Since you are providing code in the
main() method of the Game class to test your other code, you don't need
to include execution runs as comments.
Submission
When you are finished,
submit
AI.java and Game.java.
|
|