ulrail.gif

HW J6: Class Creation

  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 is the first part of the course project, which is to implement a computer-based version of the game Battleship.  If you are not familiar with the game, then you should read the article at that link.

There are a number of classes that will be required for this project, split among the next few homeworks and labs.

  • 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.
  • 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.
  • Board (HW J9): This class represents the board that players place their ships on, and takes shots on as well.
  • Descriptions (Lab 9): This class allows one to pick the names of their ships.
  • Parser (Lab 10): This class reads in commands from the keyboard, and figures out (or 'parses') what the player means by them.
  • Human (HW J8): A class to represent the human 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
  • MapPrinter (Lab 11): This allows easy printing of the board to the text-based screen.
  • 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.
  • Game: The class with the main() method that will run the game.  It ties together all the other classes.

 

Purpose

For this homework, you are responsible for implementing the Ship and Cell classes.  You must submit these two, along with the Game.java file.  We are not providing skeleton code for Ship.java and Cell.java.

 

Getting Started

You will need to download two files: Game.java and Descriptions.class (right click on the links and select "save as...").  Their usage is described below.  You will need to implement (and submit) a Ship class (in Ship.java) and a Cell class (in Cell.java), as well as develop the main() method in Game.java.

Note that the ONLY thing in this homework that should be static is your main() method.  If anything else is static, you are doing something wrong.

 

Game class

We provide a Game.java file, which includes a number of things that you will need for the homework.

Random Values

To choose a random value, you will need to use the Random class.  We have provided a object of class Random for you to use.  YOU MUST USE THIS ONE, as we will need that for testing and grading.  In order to create a random integer, you would call Game.rand.nextInt(x), where x is any integer value.  This will return a random number between 0 and x-1.  So if you call Game.rand.nextInt(15), it will return a random number between 0 and 14.  You can choose a random boolean via Game.rand.nextBoolean(), etc.

Game constants

The Game class also defines a few constants that will be used in this homework.  In particular, it defines the size of the board.  BOARD_X_COORDINATE is the width of the board, and BOARD_Y_COORDINATE is the height of the board.  Although they are both set to 15, you should not assume that they will be set to those values during testing.  Thus, you should use Game.BOARD_X_COORDINATE as the width of the board, and not 15.

main() method

You will have to modify the main() method, as described below.  You should read the homework through before you begin, as completing the main() method will be easier if done while developing your Cell and Ship classes.

 

Descriptions class

This class is responsible for generating the names and lengths of the ships, which are used in the Ship's default constructor, below.  You will be implementing it in lab 10.  In the meantime, the one we provide has two methods that are needed for this assignment:

  • static String getNextShipName(): This method will return a String that is the next chosen name of the Ship.  The provided file will cycle through the following names: "Destroyer", "Submarine", "Cruiser", "Battleship", "Carrier", "Dinghy", "Rowboat", "Canoe", "Kayak", "Raft"
  • static int getShipLength (String ship): Given the name of a ship (i.e. the name returned from the previous method), this will return the length of the ship.

Because the methods are static, you need to call them by the class name, not the object name.  Thus, to find the name of a ship, you call Descriptions.getNextShipName().  This returns a String.  To find the length of that ship, you call Descriptions.getShipLength(), passing in the name of the ship that you just got via the previous method.

Once you finish your Descriptions.java file from lab 9, you can use that instead of the Descriptions.class file that we provide.

 

Cell class

The first class you must implement represents a single spot on the Battleship board.  As with the Ship class, nothing should be static, all fields must be private, and all methods public.  Note that because this class uses the Ship class (developed next), it will not compile unless you have a Ship.java file.  It doesn't have to have much in it yet -- it can just be public class Ship { }.

Nothing should be static.  All fields must be private.  Unless specified otherwise, all methods must be public.

Properties

The Cell class only has two properties:

  • Ship shipOnCell: A reference to a Ship object.  It is null if there is no ship on that cell.
  • boolean isHit: This field is true if that cell has been hit, false otherwise.

Constructors

There is only a need for the default constructor in this class. Your constructors should call the mutators instead of setting the fields directly! &nbps;You may explicitly initialize the instance variables when they are declared, of course.

  • Cell(): Sets isHit to false, and shipOnCell to null.

Accessors and Mutators

Your class needs to have an accessor and mutator for EACH of the properties listed above.  The methods must following the standard naming scheme (i.e. getIsHit(), setShipOnCell(), etc.)

Other Methods

No other methods are required for this class.

 

Ship Class

The second class you must implement is the Ship class.  Your Ship class needs to be declared public, and in a Ship.java file.

Nothing should be static.  All fields must be private.  Unless specified otherwise, all methods must be public.

Properties

It should have the following properties.

  • boolean isHorizontal: this field is true if the ship is laid-out left-to-right, and false if it is laid-out top-to-bottom.
  • int length: the size of the ship.  Typically, it will range from 2 to 5 units in size.
  • String name: the name of the Ship: 'Battleship', 'Canoe', etc.
  • int xPosition: the x-coordinate of the upper-left corner of the ship.  Note that (0,0) is the upper-left most square.
  • int yPosition: the y-coordinate of the upper-left corner of the ship.  Note that (0,0) is the upper-left most square.
  • int hits: the number of hits the ship has received; initially zero.

Please make sure you understand what each of those properties does -- if you don't, then you will have trouble with the rest of the assignment.

Constructors

Your ship class needs to have two constructors: a default constructor and a specific constructor.  Your constructors should call the mutators instead of setting the fields directly! You may explicitly initialize the instance variables when they are declared, of course.

  • Ship(String s, int xpos, int ypos, int length, boolean horiz): This constructor is the easier of the two: it takes in five parameters, and sets the fields of the class equal to those values.  The remaining field, hits, is always set to zero.
     
  • Ship(): The default constructor, it will choose random values for the Ship.  You will need to implement the placeHorizontally() and placeVertically() methods, below, BEFORE you implement this constructor.  This constructor should pick a random value for isHorizontal (see above for a description of random values).  The name and length fields are chosen via the Descriptions class, as described above.  Lastly, the (x,y) position of the ship is placed by the placeHorizontally() or placeVertically() method, depending on the value in isHorizontal.

Accessors and Mutators

Your class needs to have an accessor and mutator for EACH of the properties listed above.  The methods must following the standard naming scheme (i.e. getIsHorizontal(), setName(), getYPosition(), etc.).  Your mutators should check to make sure that the variables are not set to invalid values!  For example, you can't set the x-coordinate to less than zero, or greater than or equal to the board width.  We didn't mention this in the Cell class, as there aren't really any invalid values that one can set the variables to.  But in the Ship class, there are a bunch (length, x and y positions, in particular).

Other Methods

Note that two of these methods are private (placeHorizontally() and placeVertically()).

  • void hit(): This method is called when the ship is hit, and just increments the hits field.
     
  • boolean isSunk(): Returns true or false, depending if the ship is sunk or not.  A ship is sunk when the number of hits it has received is equal to its length.
     
  • String toString(): This method returns a String representation of the Ship.  For example, "Dinghy @ (3,4)" or "Carrier @ (10, 12)".
     
  • private void placeHorizontally(): This method will choose random values (see above) for the x and y coordinates of the ship.  Note that it has to ensure that the ship does not go off the right side of the board. For example, assume the board is 15x15 (so the cells are numbered 0 to 14). A ship placed at (13,1) of length 4 would go off the side of the board by two spots. Recall that the upper-left spot is (0,0). Thus, the maximum x value to place a ship of length 4 is 11 (the board width minus the ship length).
     
  • private void placeVertically(): Same as placeHorizontally(), but needs to check that the ship doesn't run off the bottom of the board.
     
  • boolean hasPoint(int x, int y): This method will return true if the (x,y) point is within the ship's bounds.  Thus, it will have to operate slightly differently, depending on whether the ship is vertical or horizontal.  Think about how one would figure this out without a computer.  You know the (x,y) coordinates of the upper-left corner of the ship, and whether the ship is horizontal or vertical.

 

Game class, Revisited

Your main() method in the Game.java file should test all of the methods that you implement.  You will notice that it currently tests all of the Cell methods.  The basic idea is to call a method, and verify that it does what it was supposed to do by calling an accessor method.  For example, by calling the Ship's specific constructor, it is supposed to set a number of values.  You need to verify this by calling the accessor method, and checking to see that they return the right values.  You can use specific values for these tests -- i.e., you can create a Ship called 'Catalan', and then check to see that the name of the ship is indeed 'Catalan'.

 

Where to Start

While the main() method may seem like a lot of work, there are a couple of things that will make it much easier.  If you add the code to Game.java as you go along, it will make it much easier.  The idea is to implement a method or two, and then add the test code to Game.java.  Then make sure it compiles and works properly.  Then go onto adding more methods.  If you get stuck in a method (i.e. can't get it to work, it won't compile, etc.), then move onto another one, and come back to the one that is giving you problems.

Also note that the code for the testing of the accessors and mutators is going to be very similar -- you can just copy-and-paste the code, then modify it to use the other accessors/mutators.

Lastly, this homework will be much easier if you work through it one method at a time.  Write the first method, and then sufficiently test it in your main() method.  Then write the second method, and sufficiently test it in your main() method.  This will make the entire homework much easier, and it will take much less time to complete.

 

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 the Ship.java, Cell.java, and Game.java files.

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