ulrail.gif

HW J8: Class Creation II

  ur-2c.gif urrail.gif
blrail-nonavbar.gif

Home | Resources | Homeworks | Exams
Lectures | Labs | Contacts | Submit | TAs

br-2a.gif   br-2c.gif brrail.gif
spacer.gif spacer.gif

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.

spacer.gif
spacer.gif footer-middle.gif spacer.gif