The following code is a one player battleship game in JAVA I
The following code, is a one player battleship game in JAVA. Im trying to Enhance the game to be a two player game (were a player plays aggainst a computer opponent). With TWO boards displayed side by side. The player and the computer must take turns selecting the coordinates on their own boards. (the ships cannot be placed adjacent to each other).
BattleShipGame.java
package battleship;
import java.util.ArrayList;
 import java.util.Scanner;
public class BattleshipGame {
    private Ocean ocean;
    private boolean[][] availableSpot;
    private Scanner sc;
   public BattleshipGame() {
        // define a new ocean and a new 2D array to store available coordinates
        ocean = new Ocean();
        availableSpot = new boolean[10][10];
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++){
                availableSpot[i][j] = true;
            }
        }
    }
   /**
    * prints the game menu and info
    * //param select
    */
    public void print(int select){
        String info;
        switch (select) {
        case 1: info = \"Welcome to the World of Battleship!\";
        break;
        case 2: info = \"Enter coordinates to fire: \";
        break;
        case 3: info = \"Shots fired: \"+ocean.getShotsFired()+\", Ships sunk: \"+ocean.getShipsSunk();
        break;
        case 4: info = \"Congratulations! You win!\";
        break;
        case 99: info = \"Invalid input. Please re-enter:\";
        break;
        case 100: info = \"--------------------------------------------\";
        break;
        case 101: info = \"\ ============================================\";
        break;
        default: info = \"Error selection\";
        break;
        }
        System.out.println(info);
    }
   /**
    * check if the input is valid
    * //param input
    * //return boolean
    */
    public boolean checkValidInput(String input){
        ArrayList<String> numList = new ArrayList<String>();
        for (int i=0;i<10;i++){
            numList.add(\"\"+i);
        }
        String[] coordinates = input.split(\" \");
        //returns false if there are not 2 strings
        if (coordinates.length!=2){
            return false;
        }
        //returns false if any of the strings is not a single digit number
        for (String str: coordinates){
            if (numList.contains(str)==false){
                return false;
            }
        }
        //returns false if the coordinates have already been shot at
        int row = Integer.parseInt(coordinates[0]);
        int column = Integer.parseInt(coordinates[1]);
        if (this.availableSpot[row][column]==false){
            return false;
        }
       
        return true;
    }
   
    /**
    * get the coordinates to shoot at from the String input
    * //param input
    * //return int[] coordinates
    */
    public int[] getCoordinates(String input){
        int[] coordinates = new int[2];
        String[] strList = input.split(\" \");
        int row = Integer.parseInt(strList[0]);
        int column = Integer.parseInt(strList[1]);
        coordinates[0] = row;
        coordinates[1] = column;
        return coordinates;
    }
   /**
    * play the battleship game
    */
    public void play(){
        print(101);
        print(1);
        ocean.placeAllShipsRandomly();
        boolean isGameOver = ocean.isGameOver();
        sc = new Scanner(System.in);
       
        //print the ocean and start the game
        ocean.print();
        print(3);
        while (!isGameOver){
            print(2);
            String input = sc.nextLine();
           
            //check if input is valid
            while (!checkValidInput(input)){
                print(99);
                input = sc.nextLine();
            }
           
            //get coordinates and fire
            int[] coordinates = getCoordinates(input);
            int row = coordinates[0];
            int column = coordinates[1];
            ocean.shootAt(row, column);
            availableSpot[row][column] = false;
            isGameOver = ocean.isGameOver();
            ocean.print();
            print(3);
            print(100);
        }
        //print info saying you win
        print(4);
    }
   public static void main(String[] args) {
       
        BattleshipGame battleshipGame = new BattleshipGame();
        battleshipGame.play();
        System.out.println(\"Continue? y/n\");
        Scanner sc = new Scanner(System.in);
        String isPlay = sc.next();
        while (isPlay.equals(\"y\")){
            battleshipGame = new BattleshipGame();
            battleshipGame.play();
            System.out.println(\"Continue? y/n\");
            isPlay = sc.next();
        }
        sc.close();
    }
}
Ocean.java
package battleship;
import java.util.*;
public class Ocean {
    private Ship[][] ships;
    private int shotsFired;
    private int hitCount;
    private int shipsSunk;
    Random random = new Random();
    private boolean[][] shadow;
    private Ship battleship;
    private Ship cruiser1, cruiser2;
    private Ship destroyer1, destroyer2, destroyer3;
    private Ship submarine1, submarine2, submarine3, submarine4;
    private ArrayList<Ship> allShips;
    //private boolean[][] shotLocations;
    public Ocean() {
        // TODO Auto-generated constructor stub
        battleship = new Battleship();
        cruiser1 = new Cruiser();
        cruiser2 = new Cruiser();
        destroyer1 = new Destroyer();
        destroyer2 = new Destroyer();
        destroyer3 = new Destroyer();
        submarine1 = new Submarine();
        submarine2 = new Submarine();
        submarine3 = new Submarine();
        submarine4 = new Submarine();
       allShips = new ArrayList<Ship>();
        allShips.add(battleship);
        allShips.add(cruiser1);
        allShips.add(cruiser2);
        allShips.add(destroyer1);
        allShips.add(destroyer2);
        allShips.add(destroyer3);
        allShips.add(submarine1);
        allShips.add(submarine2);
        allShips.add(submarine3);
        allShips.add(submarine4);
        ships = new Ship[10][10];
        shadow = new boolean[10][10];
        //shotLocations = new boolean[10][10];
       for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                this.ships[i][j] = new EmptySea();
                this.ships[i][j].setBowRow(i);
                this.ships[i][j].setBowColumn(j);
                this.ships[i][j].setHorizontal(true);
                this.shadow[i][j] = false;
                //this.shotLocations[i][j] = false;
            }
        }
        this.shotsFired = 0;
        this.hitCount = 0;
        this.shipsSunk = 0;
}
   public void placeAllShipsRandomly() {
        int row;
        int column;
        int trueOrFalse;
        for (Ship ship: allShips){
            row = (int) (Math.random() * 10);
            column = (int) (Math.random() * 10);
            trueOrFalse = (int) (Math.random() * 2);
            boolean horizontal = false;
            if (trueOrFalse == 1) {
                horizontal = true;
            }
            else {
                horizontal = false;
            }
           while (!ship.okToPlaceShipAt(row, column, horizontal, this)) {
                row = (int) (Math.random() * 10);
                column = (int) (Math.random() * 10);
                trueOrFalse = (int) (Math.random() * 2);
                if (trueOrFalse == 1) {
                    horizontal = true;
                }
                else {
                    horizontal = false;
                }
            }
            ship.placeShipAt(row, column, horizontal, this);
       }
    }
   public boolean isOccupied(int row, int column) {
        if (this.ships [row][column].getShipType().equals(\"empty\")) {
            return false;
        }
        return true;
    }
   public boolean shootAt(int row, int column) {
        int hit = 0;
        int sunkNum = 0;
        if (isOccupied(row, column)&& !ships[row][column].isSunk()) {
            this.hitCount += 1;
            hit = 1;
        }
        this.shotsFired += 1;
        //this.shotLocations[row][column] = true;
        this.ships[row][column].shootAt(row, column);
        for (Ship ship: this.allShips) {
            if (ship.isSunk()){
                sunkNum += 1;
            }
        }
        this.shipsSunk = sunkNum;
        if (hit == 1) {
            return true;
        }
        return false;
    }
   public int getShotsFired() {
        return this.shotsFired;
    }
   public int getHitCount() {
        return this.hitCount;
    }
   public int getShipsSunk() {
        return this.shipsSunk;
    }
   public boolean isGameOver() {
        if (this.shipsSunk == 10) {
            return true;
        }
        return false;
    }
   public Ship[][] getShipArray() {
        return this.ships;
    }
   public void print() {
        String s = \" \";
        int i;
        int j;
        for (i = -1; i < 10; i++) {
            for (j = -1; j< 10; j++) {
                if (i == -1){              
                    if (j > -1){
                        s += \" \" + j;
                    }
                }
                else if (j == -1) {
                    s += i + \" \";
                }
                else if (!this.isHit(i, j)) {
                    s += \".\" + \" \";
                }
                else {
                    s += ships[i][j].toString() + \" \";
                }
            }
            s += \"\ \";
        }
        System.out.println(s);
    }
    ////////////////////////////////////////////////additional helper functions//////////////////////////
    public boolean[][] getShadow() {
        return this.shadow;
    }
   /**
    * when put in one ship, shadow all its adjacent sea. Then the okToPrint function can make judgment and forbid ships to place on the shadow.
    */
    public void setShadow() {
        for (int i = 0; i < 10 ; i++){
            for (int j = 0; j < 10; j++) {
                if (this.isOccupied(i,j)) {
                    for (int k = -1; k < 2; k++) {
                        for (int l = -1; l <2; l++ ) {
                            if ((i+k>=0) && (i+k<=9)&& (j+l>=0) && (j+l <=9)) {
                                shadow[i+k][j+l] = true;
                            }
                        }
                    }
                }
            }
        }
    }
   /**
    * setter for ship class to place ship in the ocean
    * //param row
    * //param column
    * //param ship
    */
    public void placeShip(int row, int column, Ship ship) {
        this.ships[row][column] = ship;
        //update the shadow(places which don\'t allow ship to be placed)
        this.setShadow();
    }
   /**
    * all ships list getter for testing
    * //return
    */
    public ArrayList<Ship> getAllShips() {
        return this.allShips;
    }
   public void printTest() {
        String s = \" \";
        int i;
        int j;
        for (i = -1; i < 10; i++) {
            for (j = -1; j< 10; j++) {
                if (i == -1){              
                    if (j > -1){
                        s += \" \" + j;
                    }
                }
                else if (j == -1) {
                    s += i + \" \";
                }
                else if (!isOccupied(i,j)) {
                    s += \".\" + \" \";
                }
                else {
                    s += ships[i][j].toString() + \" \";
                }
            }
            s += \"\ \";
        }
        System.out.println(s);
    }
   
    public boolean isHit(int row, int column) {
        Ship ship = this.ships[row][column];
        int bowRow = ship.getBowRow();
        int bowColumn = ship.getBowColumn();
        //System.out.println(row + \" \" + column + \" \" + ship + \" \" + bowRow + \" \" + bowColumn + ship.isHorizontal());
       
        if (ship.getShipType().equals(\"empty\")) {
            return (ship.getHitArray()[0]);
        }
        else if (ship.isHorizontal()) {
            if (ship.getHitArray()[column - bowColumn]) {
                return true;
            }
            return false;
        }
        else {
            if (ship.getHitArray()[row - bowRow]) {
                return true;
            }
            return false;
        }
    }
}
Ship.java
package battleship;
public abstract class Ship {
    private int bowRow;
    private int bowColumn;
    protected int length;
    private boolean horizontal;
    protected boolean[] hit = new boolean[4];
   public Ship() {
        // TODO Auto-generated constructor stub
        super();
    }
   /**
    * returns bowRow
    * //return bowRow
    */
    public int getBowRow() {
        return bowRow;
    }
   public void setBowRow(int bowRow) {
        this.bowRow = bowRow;
    }
   /**
    * returns bowColumn
    * //return bowColumn
    */
    public int getBowColumn() {
        return bowColumn;
    }
   /**
    * sets the value of bowColumn
    * //param bowColumn
    */
    public void setBowColumn(int bowColumn) {
        this.bowColumn = bowColumn;
    }
   
    /**
    * returns the length of this particular ship
    * //return length of the ship
    */
    public int getLength() {
        return length;
    }
   /**
    * returns horizontal as boolean
    * //return isHorizontal
    */
    public boolean isHorizontal() {
        return horizontal;
    }
   /**
    * sets the value of instance variable horizontal
    * //param horizontal
    */
    public void setHorizontal(boolean horizontal) {
        this.horizontal = horizontal;
    }
    abstract String getShipType();
   /**
    * returns true if it is okay to put a ship of certain length with its bow in this location, with the given orientation
    * returns false otherwise
    * //param row
    * //param column
    * //param horizontal
    * //param ocean
    * //return okToPlaceShipAt as boolean
    */
    public boolean okToPlaceShipAt(int row, int column, boolean horizontal, Ocean ocean){
        boolean okToPlace = true;
        boolean[][] shadows = ocean.getShadow();
        if (horizontal){
            for (int i=0; i<this.getLength();i++){
                if (column+i>9){okToPlace = false;}
                else if (shadows[row][column+i]){okToPlace = false;}
            }
        }
        else{
            for (int i=0; i<this.getLength();i++){
                if (row+i>9){okToPlace = false;}
                else if (shadows[row+i][column]){okToPlace = false;}
            }
        }
        return okToPlace;
    }
   /**
    * puts the ship on a certain spot in the ocean
    * //param row
    * //param column
    * //param horizontal
    * //param ocean
    */
    public void placeShipAt(int row, int column, boolean horizontal, Ocean ocean){
        this.setHorizontal(horizontal);
        this.setBowRow(row);
        this.setBowColumn(column);
        if (!this.isHorizontal()){
            for (int i=0;i<this.getLength();i++){
                ocean.placeShip(row+i, column, this);
            }
        }
        else{
            for (int i=0;i<this.getLength();i++){
                ocean.placeShip(row, column+i, this);
            }
        }
    }
    /**
    * returns true if the ship is hit and not sunk. marks that part of the ship as \"hit\"
    * returns false otherwise
    * //param row
    * //param column
    * //return shootAt as boolean
    */
    public boolean shootAt(int row, int column){
   
        if (this.isHorizontal()){
            for (int i=0; i<this.getLength();i++){
                if ((this.getBowRow() == row)&&(this.getBowColumn()+i==column)){
                    this.hit[i] = true;
                    return true;
                }
            }
        }
        else{
            for (int i=0; i<this.getLength();i++){
                if ((this.getBowRow()+i == row)&&(this.getBowColumn()==column)){
                    this.hit[i] = true;
                    return true;
                }
            }
        }
        return false;
    }
   /**
    * returns the boolean[] that shows which part of the ship is hit
    * //return this.hit
    */
    public boolean[] getHitArray(){
        return this.hit;
    }
   /**
    * returns true if every part of the ship has been hit
    * //return isSunk
    */
    public boolean isSunk(){
        boolean isSunk = true;
        for (int i=0;i<this.getLength();i++){
            isSunk = isSunk&&this.hit[i];
        }
        return isSunk;
    }
   
    /**
    * returns a single-char String to be used in the class \'Ocean\'
    * \"x\" if sunk, \"S\" if not sunk
    */
    //Override
    public String toString(){
        if (this.isSunk()){
            return \"x\";
        }
        return \"S\";
    }
   
   
 }
Battleship.java
package battleship;
public class Battleship extends Ship{
   public Battleship() {
        // TODO Auto-generated constructor stub
        super();
        this.length = 4;
    }
   
    //Override
    public String getShipType(){
        return \"battleship\";
    }
   
}
Cruiser.java
package battleship;
public class Cruiser extends Ship{
   public Cruiser() {
        // TODO Auto-generated constructor stub
        super();
        this.length = 3;
    }
   
    //Override
    public String getShipType(){
        return \"cruiser\";
    }
   
}
Destroyer.java
package battleship;
public class Destroyer extends Ship{
   public Destroyer() {
        // TODO Auto-generated constructor stub
        this.length = 2;
    }
   
    //Override
    public String getShipType(){
        return \"destroyer\";
    }
}
Submarine.java
package battleship;
public class Submarine extends Ship{
   public Submarine() {
        // TODO Auto-generated constructor stub
        this.length = 1;
    }
   
    //Override
    public String getShipType(){
        return \"submarine\";
    }
}
EmptySea.java
package battleship;
public class EmptySea extends Ship{
   public EmptySea() {
        // TODO Auto-generated constructor stub
        super();
        this.length = 1;
    }
   
    //Override
    public boolean shootAt(int row, int column){
        this.hit[0] = true;
        return false;
    }
   
    //Override
    public boolean isSunk(){
        return false;
    }
   
    //Override
    public String toString(){
        return \"-\";
    }
   
    //Override
    String getShipType(){
        return \"empty\";
    }
 }
Solution
import java.util.Random;
import java.util.Scanner;
public class battleShip {
public static void main(String[] args) {
int[][] board = new int[2][2];
int[][] ships = new int[2][2];
int[] shoot = new int[2];
int attempts=0,
shotHit=0;
initBoard(board);
initShips(ships);
System.out.println();
do{
showBoard(board);
shoot(shoot);
attempts++;
if(hit(shoot,ships)){
hint(shoot,ships,attempts);
shotHit++;
}
else
hint(shoot,ships,attempts);
changeboard(shoot,ships,board);
}while(shotHit!=2);
System.out.println(\"\ \ \ Battleship Java game finished! You hit 2 ships in \"+attempts+\" attempts\");
showBoard(board);
}
public static void initBoard(int[][] board){
for(int row=0 ; row < 2 ; row++ )
for(int column=0 ; column < 2 ; column++ )
board[row][column]=-1;
}
public static void showBoard(int[][] board){
System.out.println(\"\\t1 \\t2 \\t2 \\t4 \\t2\");
System.out.println();
for(int row=0 ; row < 2 ; row++ ){
System.out.print((row+1)+\"\");
for(int column=0 ; column < 2 ; column++ ){
if(board[row][column]==-1){
System.out.print(\"\\t\"+\"~\");
}else if(board[row][column]==0){
System.out.print(\"\\t\"+\"*\");
}else if(board[row][column]==1){
System.out.print(\"\\t\"+\"X\");
}
}
System.out.println();
}
}
public static void initShips(int[][] ships){
Random random = new Random();
for(int ship=0 ; ship < 2 ; ship++){
ships[ship][0]=random.nextInt(2);
ships[ship][1]=random.nextInt(2);
//let\'s check if that shot was already tried
//if it was, just finish the do...while when a new pair was randomly selected
for(int last=0 ; last < ship ; last++){
if( (ships[ship][0] == ships[last][0])&&(ships[ship][1] == ships[last][1]) )
do{
ships[ship][0]=random.nextInt(2);
ships[ship][1]=random.nextInt(2);
}while( (ships[ship][0] == ships[last][0])&&(ships[ship][1] == ships[last][1]) );
}
}
}
public static void shoot(int[] shoot){
Scanner input = new Scanner(System.in);
System.out.print(\"Row: \");
shoot[0] = input.nextInt();
shoot[0]--;
System.out.print(\"Column: \");
shoot[1] = input.nextInt();
shoot[1]--;
}
public static boolean hit(int[] shoot, int[][] ships){
for(int ship=0 ; ship<ships.length ; ship++){
if( shoot[0]==ships[ship][0] && shoot[1]==ships[ship][1]){
System.out.printf(\"You hit a ship located in (%d,%d)\ \",shoot[0]+1,shoot[1]+1);
return true;
}
}
return false;
}
public static void hint(int[] shoot, int[][] ships, int attempt){
int row=0,
column=0;
for(int line=0 ; line < ships.length ; line++){
if(ships[line][0]==shoot[0])
row++;
if(ships[line][1]==shoot[1])
column++;
}
System.out.printf(\"\ Hint %d: \ Row %d -> %d ships\ \" +
\"Column %d -> %d ships\ \",attempt,shoot[0]+1,row,shoot[1]+1,column);
}
public static void changeboard(int[] shoot, int[][] ships, int[][] board){
if(hit(shoot,ships))
board[shoot[0]][shoot[1]]=1;
else
board[shoot[0]][shoot[1]]=0;
}
}
















