Battleship Introduction Battleship is a two player game of strategy and luck. Ea
ID: 3823527 • Letter: B
Question
Battleship
Introduction
Battleship is a two player game of strategy and luck. Each player deploys a fleet of ships on their board, and the goal of the game is to sink all of the other player's ships before they sink your ships! The game of Battleship dates back to the 1800's. In 1967, the popular Battleship board game was released by Milton Bradley, who subsequently released an electronic version of the game in 1977.
In the Battleship game, each player's board is divided into a grid of squares. Play begins with each player arranging their ships on their board, which is not visible to the other player. The ships vary in size and occupy one or more squares in a straight line, either vertically or horizontally. The players then take turns "firing" at a square on the other player's board. If the square contains a ship or part of a ship, the ship has been "hit." When all parts of a ship have been hit, it is sunk. Gameplay ends when all of the ships in one player's fleet have been sunk. The other player wins!
Requirements
In our version of the Battleship game, a human player plays against the computer. Each player has the following ships that occupy the given number of squares on the player's board:
Submarine (1 Square)
Destroyer (2 Squares)
Cruiser (3 Squares)
Battleship (4 Squares)
An initial setup stage allows the human player to place their fleet of ships. Ships are placed one at a time and can be placed with either a horizontal (default) or vertical orientation. The human player selects the upper left coordinate of where they want their ship to be placed. If the ship cannot be placed in the location due to another ship or the edge of the board, an error message is displayed.
After all the ships are placed, gameplay begins automatically. The computer gets to make the first move. We're providing you with a simple game AI for the computer player. After the computer player makes a move, the human board is updated to show the move. A white circle indicates a miss, and a red circle indicates a hit. After the computer's turn, the human player gets to choose a move by clicking on one of the computer's squares. Gameplay continues, alternating between the computer and the human player.
The game ends when either the human player has sunk all of the computer's ships (a win) or the computer has sunk all of the human player's ships (a loss). The human player is informed of the result of the game with a message below the game boards.
The board below illustrates what the GUI looks like in the middle of a typical game.
The Battleship program will be executed as follows
For testing purposes, it will be executed with a command line argument that provides an integer seed for the random number generator. As explained in the testing section, this will let you run the program repeatedly with the same results each time:
Design
We're providing four of the seven classes required by this project, which uses the Model-View-Controller (MVC) design pattern. The Graphical User Interface, which makes up the View-Controller part of the program, is provided to you in BattleshipGUI.java, and Grid.java. The "artificial intelligence" for the computer's play is provided in BattleshipAI.java. The Battleship Model class is provided in Battleship.java. Do not change the four provided classes. You will write the other three Model classes: Ship, Square,andBoard.
Shown below is a simple UML (Universal Modeling Language) Class Diagram that illustrates the relationships between the seven classes followed by a explanation of these relationships.
Model Classes: The Battleship class has an "aggregate relationship" with the Board class because it contains a Board object. Likewise, the Board class has an aggregate relationship with the Square and Ship classes because it contains objects of those classes. The Battleship class has a "dependency relationship" the BattleshipAI class because it depends on the BattleshipAI. The BattleshipAI class has a dependency relationship with the Board class and the Square class has a dependency relationship with the Ship class.
View-Controller Classes: There is a dependency relationship between the BattleshipGUI class and the Battleship class, an aggregate relationship between the BattleshipGUI class and the Grid class, and dependency relationships between the Grid class and both the Board and BattleshipGUI classes.
Notice that while the View-Controller classes depend on some of the Model classes, the Model classes are not dependent on any ofthe View-Controller classes. This makes it very easy to change to a different View-Controller for the Battleship Game.
Implementation
The model code that you will be creating by implementing the classes below keeps track of information about the game. This information is used by the GUI to display the current state of the game. Also, the mouse clicks on the GUI generate method calls to the model that need to be implemented correctly in order for the game to proceed as required. Therefore, it is extremely important that you implement every method of every class exactly as we specify in the following class descriptions. You are encouraged to implement other private methods to simplify your code.
Ship class
The Ship class represents a single ship. The following are descriptions of the instance fields, followed by the methods of the Ship class. Complete each item in the following order.
Instance Fields
Declare the following private instance fields:
the length of the Ship
the number of times the Ship has been hit
the Ship's orientation (horizontal or vertical)
the row containing the upper left corner of the Ship
the column containing the upper left corner of the Ship
Methods
The following is the list of methods you must complete.
public Ship(int length, boolean isHorizontal, int startRow, int startCol): This constructor must initialize the class's instance variables using the parameter values. Throw an IllegalArgumentException if length < 1, startRow < 0, or startCol < 0.
public int getLength(): returns the length of the ship.
public boolean isHorizontal(): returns true if the ship has horizontal orientation, false otherwise.
public int getStartRow(): returns the row of the upper left corner of the Ship.
public int getStartCol(): returns the column of the upper left corner of the Ship.
public void hit(): simulates hitting the ship (updates the appropriate instance variable)
public boolean isSunk(): returns true if the ship is sunk (has been hit as many times as its length).
public String toString(): Returns a String representation of a Ship that lists its length, location, orientation, number of times hit, if the ship is sunk. This will allow you to print all the information you need about the ship when testing the class. The format of the String is up to you.
Unit Testing
You will not be submitting a formal test of the Ship class, but you should still test your class and methods before moving on to the next class. An easy way to do this is to add a main() method to the Ship class. In the main() method, create some Ship objects and test the methods on them. You can execute this main() method as follows:
Square class (Do not begin this class until you have completed and tested the Ship class!)
The Square class represents a location in a Battleship board.
The following are the class and instance fields, followed by the methods of the Square class. Complete each item in the following order.
Instance Fields
Declare the following private instance fields:
if the Square has been hit by enemy fire
the Ship located in the Square (if there is a Ship). NOTE that because a Ship occupies several Square's, other Square's will contain a reference to the same Ship object.
Methods
The following is the list of methods you must complete.
public Square(): Providing a constructor for this class is optional. Java will provide one if you choose not to, setting the instance variable keeping track of whether the square has been hit to false and setting the reference to a Ship to null.
public boolean hasBeenHit(): returns true if the Square has been hit by enemy fire, false otherwise.
public Ship getShip(): returns a Ship instance if there is a ship that includes this square or null if there is no such ship
public void fireAt(): the Square should update the fact that it has been hit. If a ship is occupying the square, it should also call the ship's hit() method to let it know that it has been hit.
public boolean hasShip(): returns true if the Square contains a Ship.
public void addShip(Ship ship): add the given Ship to the Square.
public String toString(): Returns a single-character string indicating the state of the square. The string will be one of the following:
"-" (if the square does not contain a ship and has not been hit)
"W" (if the square has been hit and does not contain a ship; W stands for White)
"R" (if the square has been hit and contains a ship; R stands for Red)
"1","2","3", or "4" (if the square has not been hit and contains a ship -- the number returned should correspond to the length of the ship)
These single-character representations allow a Board object to be printed in a compact form.
Unit Testing
You will not be submitting a formal test of the Square class, but you should still test your class and methods before moving on to the next class. An easy way to do this is to add a main() method to the Square class. In the main() method, create some Square objects and test the methods on them. You can execute this main() method as follows:
Board class (Do not begin this class until you have completed and tested the Square class!)
The Board class is a model template for the human player's and computer's boards in Battleship. It uses a 2D array of Square objects to represent the squares in the board.
The following are the instance fields, followed by the methods of the Board class. Complete each item in the following order.
Instance Fields
Declare the following private instance fields:
the number of rows in the 2 dimensional array of Squares
the number of columns in the 2 dimensional array of Squares
a 2 dimensional array of Squares
the maximum number of Ships on the board
an array of Ships
the number of Ships on the board
Methods
The following is the list of methods you must complete.
public Board(int numberOfRows, int numberOfColumns, int maximumNumberOfShips): This is the constructor of the Board class. The fields listed above should be initialized. Throw an IllegalArgumentException if numberOfRows < 1, numberOfColumns < 1, or maximumNumberOfShips < 0.
public boolean addShip(int length, boolean isHorizontal, int startRow, int startCol): adds a Ship to the board. This means that all Squares the length of the ship starting at the startRow and startCol must be updated appropriately. The isHorizontal determines which direction to fill Squares. The method returns true if the Ship is successfully added to the Board and false if the Ship could not be added due to another Ship in the way, reaching a Board boundary, or if the array of Ship's is full. If the Ship cannot be placed, then the Squares should not change.
public int getNumberOfShips(): returns the number of Ships deployed on the Board.
public Ship[] getShips(): returns an array of the Ships deployed on the Board.
public boolean fireAtLocation(int row, int col):If the Square located at the specified row and column has not been previously hit, the Square should be fired at and true should be returned. If the Square has already been hit, it should not be hit again and false should be returned. Throw an IllegalArgumentException if row < 0, col < 0, row >= number of rows, or col >= number of columns.
public boolean hasBeenHit(int row, int col): returns true if the enemy has already fired on the Square located at the specified row and column. Throw an IllegalArgumentException if row < 0, col < 0, row >= number of rows, or col >= number of columns.
public boolean areAllShipsSunk(): returns true if all of the Ship's on the Board have been sunk by enemy fire.
public int getNumberOfRows(): returns the number of rows in the Board.
public int getNumberOfColumns(): returns the number of columns in the Board.
public String toString(): returns a String representation of a Board. HINT: Using the toString() method of the Square class, you can easily create a String representation of the Board similar to the following, which will come in handy for testing and debugging:
Explanation / Answer
Ship:
Code
package battlefield;
public class Ship {
private int length = 0;
private int startRow = 0;
private int startCol = 0;
private int numHit = 0;
private boolean isHorizontal = false;
private boolean isHit = false;
private boolean isSunk = false;
public Ship(int length, boolean isHorizontal, int startRow, int startCol) {
this.length = length;
this.isHorizontal = isHorizontal;
this.startRow = startRow;
this.startCol = startCol;
}
public int getLength() {
return length;
}
public boolean isHorizontal() {
return isHorizontal;
}
public int getStartRow() {
return startRow;
}
public int getStartCol() {
return startCol;
}
public void setHit(boolean value) {
isHit = value;
numHit++;
}
public boolean getHit() {
return isHit;
}
public void setSunk(boolean value) {
isSunk = value;
}
public boolean getSunk() {
return isSunk;
}
@Override
public String toString() {
String temp = "Ship Length: " + length;
temp += "Number Of Times Hit: " + numHit + " Current Direction: ";
if(this.isHorizontal()) {
temp += "Horizontal";
}
else {
temp += "Not Horizontal";
}
temp += " Are We Sunk?: " + this.getSunk();
return temp;
}
}
Squares:
Code
package battlefield;
public class Square{
private int xPos = 0;
private int yPos = 0;
private boolean beenHit = false;
private Ship myShip;
public Square(int xPos, int yPos) {
this.xPos = xPos;
this.yPos = yPos;
}
public int getXPos() {
return xPos;
}
public int getYPos() {
return yPos;
}
public void firedAt() {
beenHit = true;
if(this.hasShip()) {
myShip.setHit(true);
}
}
public boolean hasBeenHit() {
return beenHit;
}
public boolean hasShip() {
if(myShip != null)
return true;
else
return false;
}
public void addShip(Ship ship) {
if(myShip != null) {
myShip = ship;
}
else
System.out.println("There is a ship here already. Error??");
}
public Ship getShip() {
return myShip;
}
@Override
public String toString() {
if(!this.hasShip() && !this.hasBeenHit())
return "-";
else if(this.hasBeenHit() && this.hasShip())
return "W";
else if(this.hasBeenHit() && this.hasShip())
return "R";
else if(this.hasShip()) {
switch(myShip.getLength()) {
case 1:
return "1";
case 2:
return "2";
case 3:
return "3";
case 4:
return "4";
}
}
return "Error";
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.