Module 3 Programming Assignment – OO Design (50 points) Our Battleship game need
ID: 3912557 • Letter: M
Question
Module 3 Programming Assignment – OO Design (50 points)
Our Battleship game needs several different kinds of ship – we need a type to store the ships and information about it.
Create a base class called Ship.
Create child classes for each of the ship types in the game (https://en.wikipedia.org/wiki/Battleship_(game)#Description) that inherit from Ship.
Ships should have the following properties:
A private array of positions
A Position is composed of an X and Y coordinate – you should create a struct to encapsulate this.
A read-only length
The constructor for each inherited type should set this to the correct length for the ship type.
A read-only color to be drawn in
The constructor for each inherited type should set this to a different ConsoleColor for drawing.
A flag called Sunk
This should default to false for all ships.
A property called IsBattleship
This property should be overridden by each child type. Only the BattleShip should return true.
A method called Reset
This method should reset the members to their empty defaults
A method called Place(Position start, Direction direction)
Direction should be an enumeration of either Horizontal or Vertical.
This will complete the Position array with the set of coordinates that the ship is covering. E.g., place (new Position(1, 1), Direction.Horizontal) on a patrol boat will fill the array with the points (1, 1) and (2, 1).
Notes:
This is a separate program from previous weeks’. You do not need to consider or implement anything to do with the grid or guessing.
You should choose the correct types and access modifiers for each type.
Create a test program that can run code such as the following:
AircraftCarrier ac = new AircraftCarrier();
Console.WriteLine(ac.IsBattleShip);
ac.Place(new Position(1, 1), Direction.Horizontal);
ac.Reset();
You should write additional code to test all the methods and ship types.
Given that the positions array is private, how can you test that the values are correct?
can some one help me with this i need in C# and complete codes please thanks.
Explanation / Answer
Board.java
package com.tn.board;
import com.tn.field.IGameField;
import com.tn.field.WaterField;
import com.tn.ship.Ship;
import com.tn.field.ShipField;
import com.tn.ship.ShipSize;
import java.awt.*;
import java.util.Scanner;
public class Board {
private static final char WATER = '~';
private static final int BOARD_SIZE = 10;
private static final char[] BOARD_LETTERS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
private static final String HORIZONTAL = "H";
private static final String VERTICAL = "V";
private Scanner scanner;
private IGameField[][] board;
private static final Ship[] ships;
static {
ships = new Ship[] {
new Ship("Carrier", ShipSize.CARRIER),
new Ship("Battleship", ShipSize.BATTLESHIP),
new Ship("Cruiser", ShipSize.CRUISER),
new Ship("Submarine", ShipSize.SUBMARINE),
new Ship("Destroyer", ShipSize.DESTROYER)
};
}
public Board() {
this.scanner = new Scanner(System.in);
this.board = new IGameField[BOARD_SIZE][BOARD_SIZE];
for(int i = 0; i < BOARD_SIZE; i++) {
for(int j = 0; j < BOARD_SIZE; j++) {
board[i][j] = new WaterField();
}
}
}
public void placeShipsOnBoard() {
for(Ship ship : ships) {
boolean horizontal = askValidShipDirection();
Point startingPoint = askValidStartingPoint(ship, horizontal);
placeValidShip(ship, startingPoint, horizontal);
printBoard();
}
}
public IGameField getField(int x, int y) {
if(!isInsideBoard(x, y)) {
throw new IllegalArgumentException("Outside board - try again: ");
}
return board[y][x];
}
public void printBoard() {
System.out.print(" ");
for(int i = 0; i < BOARD_SIZE; i++) {
System.out.print(BOARD_LETTERS[i] + " ");
}
System.out.println();
for(int i = 0; i < BOARD_SIZE; i++) {
System.out.print((i+1) + " ");
for(int j = 0; j < BOARD_SIZE; j++) {
System.out.print(board[i][j].getIcon() + " ");
}
System.out.println();
}
}
private boolean askValidShipDirection() {
System.out.printf("%nDo you want to place the ship horizontally (H) or vertically (V)?");
String direction;
do {
direction = scanner.nextLine().trim();
}while (!HORIZONTAL.equals(direction) && !VERTICAL.equals(direction));
return HORIZONTAL.equals(direction);
}
private Point askValidStartingPoint(Ship ship, boolean horizontal) {
Point from;
do {
System.out.printf("%nEnter position of %s (length %d): ", ship.getName(), ship.getSize());
from = new Point(scanner.nextInt(), scanner.nextInt());
} while(!isValidStartingPoint(from, ship.getSize(), horizontal));
return from;
}
private boolean isValidStartingPoint(Point from, int length, boolean horizontal) {
int xDiff = 0;
int yDiff = 0;
if(horizontal) {
xDiff = 1;
} else {
yDiff = 1;
}
int x = (int)from.getX() - 1;
int y = (int)from.getY() - 1;
if(!isInsideBoard(x, y) ||
(!isInsideBoard(x + length,y) && horizontal) ||
(!isInsideBoard(x, y + length) && !horizontal)
) {
return false;
}
for(int i = 0; i < length; i++) {
if(board[(int)from.getY() + i *yDiff - 1]
[(int)from.getX() + i *xDiff - 1].getIcon() != WATER){
return false;
}
}
return true;
}
private void placeValidShip(Ship ship, Point startingPoint, boolean horizontal) {
int xDiff = 0;
int yDiff = 0;
if(horizontal) {
xDiff = 1;
} else {
yDiff = 1;
}
for(int i = 0; i < ship.getSize() ; i++) {
board[(int)startingPoint.getY() + i*yDiff - 1]
[(int)startingPoint.getX()+ i*xDiff - 1] = new ShipField(ship);
}
}
private boolean isInsideBoard(int x, int y){
return x <= BOARD_SIZE && x >= 0
&& y <= BOARD_SIZE && y >= 0;
}
}
IGameField.java
package com.tn.field;
import com.tn.game.Result;
public interface IGameField {
char getIcon();
Result shootAt();
}
ShipField.java
package com.tn.field;
import com.tn.game.Result;
import com.tn.ship.Ship;
public class ShipField implements IGameField {
private final Ship ship;
public ShipField(Ship ship) {
this.ship = ship;
}
@Override
public char getIcon() {
char icon;
Result shipState = ship.getState();
switch (shipState) {
case PARTIAL_HIT: icon = 'O';
break;
case DESTROYED: icon = 'O';
break;
case NO_HIT: icon = 'X';
break;
default: icon = ' ';
break;
}
return icon;
}
@Override
public Result shootAt() {
ship.hit();
return ship.getState();
}
}
WaterField.java
package com.tn.field;
import com.tn.game.Result;
public class WaterField implements IGameField {
private boolean isThisFieldHit = false;
@Override
public char getIcon() {
return isThisFieldHit ? 'M' : '~';
}
@Override
public Result shootAt() {
isThisFieldHit = true;
return Result.NO_HIT;
}
}
IPlayer.java
package com.tn.player;
public interface IPlayer {
void placeShips();
void fireAt(IPlayer opponent);
int getTotalLivesLeft();
}
HumanPlayer.java
package com.tn.player;
import com.tn.board.Board;
import com.tn.game.Result;
import java.awt.*;
import java.util.Scanner;
public class HumanPlayer implements IPlayer {
private int totalLivesLeft = 17;
private int id;
private Board board;
private Scanner scanner;
public HumanPlayer(int id) {
this.id = id;
this.board = new Board();
this.scanner = new Scanner(System.in);
}
public int getId() {
return id;
}
public Board getBoard() {
return board;
}
@Override
public void placeShips() {
System.out.printf("%n======== Player %d - Time to place out your ships ========%n", id);
board.placeShipsOnBoard();
}
@Override
public void fireAt(IPlayer opponent) {
System.out.printf("%n Alright Player %d - Enter coordinates for your attack: ", id);
boolean isPointValid = false;
while(!isPointValid) {
try {
Point point = new Point(scanner.nextInt(), scanner.nextInt());
int x = (int)point.getX() - 1;
int y = (int)point.getY() - 1;
Result result = ((HumanPlayer)opponent)
.getBoard()
.getField(x, y)
.shootAt();
if(result == Result.PARTIAL_HIT || result == Result.DESTROYED) {
totalLivesLeft--;
}
isPointValid = true;
} catch(IllegalArgumentException e) {
System.out.printf(e.getMessage());
}
}
}
@Override
public int getTotalLivesLeft() {
return totalLivesLeft;
}
}
Ship.java
package com.tn.ship;
import com.tn.game.Result;
public class Ship {
private final String name;
private final int size;
private int lives;
public Ship(String name, int size) {
this.name = name;
this.size = size;
this.lives = size;
}
public void hit() {
if(lives > 0) {
System.out.printf("%nGood shot! The %s was hit", name);
lives--;
} else {
System.out.println("Ship is destroyed");
}
}
public Result getState() {
if(lives == 0) {
return Result.DESTROYED;
} else if(lives < size) {
return Result.PARTIAL_HIT;
} else {
return Result.NO_HIT;
}
}
public String getName() {
return name;
}
public int getSize() {
return size;
}
}
ShipSize.java
package com.tn.ship;
public class ShipSize {
private ShipSize() {
}
public static final int CARRIER = 5;
public static final int BATTLESHIP = 4;
public static final int CRUISER = 3;
public static final int SUBMARINE = 3;
public static final int DESTROYER = 2;
}
Result.java
package com.tn.game;
public enum Result {
NO_HIT,
PARTIAL_HIT,
DESTROYED
}
Game.java
package com.tn.game;
import com.tn.player.HumanPlayer;
public class Game {
private HumanPlayer[] players;
public Game() {
this.players = new HumanPlayer[]{
new HumanPlayer(1),
new HumanPlayer(2)
};
}
public void start() {
int i = 0;
int j = 1;
int len = players.length;
HumanPlayer player = null;
this.players[i].placeShips();
this.players[j].placeShips();
while(players[0].getTotalLivesLeft() > 0 &&
players[1].getTotalLivesLeft() > 0) {
players[i++ % len].fireAt(players[j++ % len]);
player = (players[0].getTotalLivesLeft() < players[1].getTotalLivesLeft()) ?
players[1] :
players[0];
}
System.out.printf("Congrats Player %d, you won!",player.getId());
}
}
Main.java
import com.tn.game.Game;
public class Main {
public static void main(String[] args) {
Game game = new Game();
game.start();
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.