Ask a Question
Ask Question Login
Corporate Training
  1. Community
  2. Java
  3. Question
Java

Give the details of the battleship game java.

Asked by Richard Young Oct 13, 2022 1.2K views 1 answer
Share

About this question

 I wanted to make a simple console game in order to practice OOP. I would really appreciate a review that looks at readability, maintenance, and best practices.

What annoys me a little bit with this code is I don't use interfaces, abstract classes, or inheritance, but I couldn't find a good use case for them here.

Board.java

package com.tn.board;


import com.tn.constants.Constants;

import com.tn.ship.Ship;

import com.tn.utils.Position;

import com.tn.utils.Utils;


import java.awt.Point;

import java.util.Scanner;



public class Board {
    private static final Ship[] ships;
    private char[][] board;
    /**
     * Initialise ships (once).
     *
     */
    static {
        ships = new Ship[]{
                new Ship("Carrier", Constants.CARRIER_SIZE),
                new Ship("Battleship", Constants.BATTLESHIP_SIZE),
                new Ship("Cruiser", Constants.CRUISER_SIZE),
                new Ship("Submarine", Constants.SUBMARINE_SIZE),
                new Ship("Destroyer", Constants.DESTROYER_SIZE)
        };
    }


    /**
     * Constructor
     */
    public Board() {
        board = new char[Constants.BOARD_SIZE][Constants.BOARD_SIZE];
        for(int i = 0; i < Constants>            for(int j = 0; j < Constants>                board[i][j] = Constants.BOARD_ICON;
            }
        }
        placeShipsOnBoard();
    }


    /**

     * Target ship ship.

     *

     * @param point the point

     * @return ship

     */

    public Ship targetShip(Point point) {

        boolean isHit = false;

        Ship hitShip = null;

        for(int i = 0; i < ships>

            Ship ship = ships[i];

            if(ship.getPosition() != null) {

                if(Utils.isPointBetween(point, ship.getPosition())) {

                    isHit = true;

                    hitShip = ship;

                    break;

                }


            }

        }

        final char result = isHit ? Constants.SHIP_IS_HIT_ICON : Constants.SHOT_MISSED_ICON;

        updateShipOnBoard(point, result);

        printBoard();


        return (isHit) ? hitShip : null;

    }


    /**

     * Place ships on board.

     */

    private void placeShipsOnBoard() {

        System.out.printf("%nAlright - Time to place out your ships%n%n");

        Scanner s = new Scanner(System.in);


        for(int i = 0; i < ships>

            Ship ship = ships[i];

            boolean isShipPlacementLegal = false;


            System.out.printf("%nEnter position of %s (length  %d): ", ship.getName(), ship.getSize());


            while(!isShipPlacementLegal) {

                try {

                    Point from = new Point(s.nextInt(), s.nextInt());

                    Point to = new Point(s.nextInt(), s.nextInt());


                    while(ship.getSize() != Utils.distanceBetweenPoints(from, to)) {

                        System.out.printf("The ship currently being placed on the board is of length: %d. Change your coordinates and try again",

                                ship.getSize());


                        from = new Point(s.nextInt(), s.nextInt());

                        to = new Point(s.nextInt(), s.nextInt());

                    }

                    Position position = new Position(from, to);


                    if(!isPositionOccupied(position)) {

                        drawShipOnBoard(position);

                        ship.setPosition(position);

                        isShipPlacementLegal = true;

                    } else {

                        System.out.println("A ship in that position already exists - try again");

                    }


                } catch(IndexOutOfBoundsException e) {

                    System.out.println("Invalid coordinates - Outside board");

                }

            }

        }


    }



    private void updateShipOnBoard(Point point, final char result) {

        int x = (int) point.getX() - 1;

        int y = (int) point.getY() - 1;

        board[y][x] = result;

    }


    /**

     *

     * @param position

     * @return

     */

    private boolean isPositionOccupied(Position position) {

        boolean isOccupied = false;

        Point from = position.getFrom();

        Point to = position.getTo();


        outer:

        for(int i = (int) from.getY() - 1; i < to>

            for(int j = (int) from.getX() - 1; j < to>

                if(board[i][j] == Constants.SHIP_ICON) {

                    isOccupied = true;

                    break outer;

                }

            }

        }



        return isOccupied;

    }


    /**

     *

     * @param position

     */

    private void drawShipOnBoard(Position position) {

        Point from = position.getFrom();

        Point to = position.getTo();

        for(int i = (int) from.getY() - 1; i < to>

            for(int j = (int) from.getX() - 1; j < to>

                board[i][j] = Constants.SHIP_ICON;

            }

        }

        printBoard();

    }



    /**

     * Print board.

     */

    private void printBoard() {

        System.out.print("t");


        for(int i = 0; i < Constants>

            System.out.print(Constants.BOARD_LETTERS[i] + "t");

        }


        System.out.println();


        for(int i = 0; i < Constants>

            System.out.print((i+1) + "t");

            for(int j = 0; j < Constants>

                System.out.print(board[i][j] + "t");

            }

            System.out.println();

        }

    }


}

Constants.java


package com.tn.constants;



public class Constants {


    private Constants() {}


    public static final int PLAYER_LIVES = 17; //sum of all the ships


    public static final int CARRIER_SIZE = 5;

    public static final int BATTLESHIP_SIZE = 4;

    public static final int CRUISER_SIZE = 3;

    public static final int SUBMARINE_SIZE = 3;

    public static final int DESTROYER_SIZE = 2;


    public static final char SHIP_ICON = 'X';

    public static final char BOARD_ICON = '-';

    public static final char SHIP_IS_HIT_ICON = 'O';

    public static final char SHOT_MISSED_ICON = 'M';


    public static final char[] BOARD_LETTERS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};

    public static final int BOARD_SIZE = 10;

}

Player.java


package com.tn.player;


import com.tn.board.Board;

import com.tn.constants.Constants;

import com.tn.ship.Ship;


import java.awt.Point;

import java.util.HashMap;

import java.util.Map;

import java.util.Scanner;



public class Player {

    private int id;

    private int lives;

    private Board board;

    private Map targetHistory;

    private Scanner scanner;


    /**

     * Instantiates a new Player.

     *

     * @param id the id

     */

    public Player(int id) {

        System.out.printf("%n=== Setting up everything for Player %s ====", id);

        this.id = id;

        this.lives = Constants.PLAYER_LIVES;

        this.board = new Board();

        this.targetHistory = new HashMap<>();

        this.scanner = new Scanner(System.in);

    }


    /**

     * Get id.

     *

     * @return the id

     */

    public int getId() {

        return id;

    }


    /**

     * Get lives.

     *

     * @return the lives

     */

    public int getLives() {

        return lives;

    }


    /**

     * Decrement live by one.

     */

    public void decrementLiveByOne() {

        lives--;

    }


    /**

     * Turn to play.

     *

     * @param opponent the opponent

     */

    public void turnToPlay(Player opponent) {

        System.out.printf("%n%nPlayer %d, Choose coordinates you want to hit (x y) ", id);

        Point point = new Point(scanner.nextInt(), scanner.nextInt());


        while(targetHistory.get(point) != null) {

            System.out.print("This position has already been tried");

            point = new Point(scanner.nextInt(), scanner.nextInt());

        }


        attack(point, opponent);

    }


    /**

     * Attack

     *

     * @param point

     * @param opponent

     */

    private void attack(Point point, Player opponent) {

        Ship ship = opponent.board.targetShip(point);

        boolean isShipHit = (ship != null) ? true : false;


        if(isShipHit) {

            ship.shipWasHit();

            opponent.decrementLiveByOne();

        }

        targetHistory.put(point, isShipHit);

        System.out.printf("Player %d, targets (%d, %d)",

                id,

                (int)point.getX(),

                (int)point.getY());

        System.out.println("...and " + ((isShipHit) ? "HITS!" : "misses..."));

    }

}

Ship.java


package com.tn.ship;


import com.tn.utils.Position;


}

Player.java


package com.tn.player;


import com.tn.board.Board;

import com.tn.constants.Constants;

import com.tn.ship.Ship;


import java.awt.Point;

import java.util.HashMap;

import java.util.Map;

import java.util.Scanner;



public class Player {

    private int id;

    private int lives;

    private Board board;

    private Map targetHistory;

    private Scanner scanner;


    /**

     * Instantiates a new Player.

     *

     * @param id the id

     */

    public Player(int id) {

        System.out.printf("%n=== Setting up everything for Player %s ====", id);

        this.id = id;

        this.lives = Constants.PLAYER_LIVES;

        this.board = new Board();

        this.targetHistory = new HashMap<>();

        this.scanner = new Scanner(System.in);

    }


    /**

     * Get id.

     *

     * @return the id

     */

    public int getId() {

        return id;

    }


    /**

     * Get lives.

     *

     * @return the lives

     */

    public int getLives() {

        return lives;

    }


    /**

     * Decrement live by one.

     */

    public void decrementLiveByOne() {

        lives--;

    }


    /**

     * Turn to play.

     *

     * @param opponent the opponent

     */

    public void turnToPlay(Player opponent) {

        System.out.printf("%n%nPlayer %d, Choose coordinates you want to hit (x y) ", id);

        Point point = new Point(scanner.nextInt(), scanner.nextInt());


        while(targetHistory.get(point) != null) {

            System.out.print("This position has already been tried");

            point = new Point(scanner.nextInt(), scanner.nextInt());

        }


        attack(point, opponent);

    }


    /**

     * Attack

     *

     * @param point

     * @param opponent

     */

    private void attack(Point point, Player opponent) {

        Ship ship = opponent.board.targetShip(point);

        boolean isShipHit = (ship != null) ? true : false;


        if(isShipHit) {

            ship.shipWasHit();

            opponent.decrementLiveByOne();

        }

        targetHistory.put(point, isShipHit);

        System.out.printf("Player %d, targets (%d, %d)",

                id,

                (int)point.getX(),

                (int)point.getY());

        System.out.println("...and " + ((isShipHit) ? "HITS!" : "misses..."));

    }

}

Ship.java


package com.tn.ship;


import com.tn.utils.Position;



public class Ship {

    private String name;

    private int size;

    private int livesLeft;

    private boolean isSunk;

    private Position position;


    public Ship(String name, int size) {

        this.name = name;

        this.size = size;

        this.livesLeft = size;

        this.isSunk = false;

    }


    public String getName() {
        return name;
    }
    public int getSize() {
        return size;
    }
    public int getLivesLeft() {
        return livesLeft;
    }
    public boolean isSunk() {
        return isSunk;
    }
    public void setSunk(boolean sunk) {
        isSunk = sunk;
    }
    public Position getPosition() {
        return position;
    }
    public void setPosition(Position position) {
        this.position = position;
    }
    public void shipWasHit() {
        if(livesLeft == 0) {
            isSunk = true;
            System.out.println("You sunk the " + name);
            return;
        }
        livesLeft--;
    }
}
Position.java
package com.tn.utils;
import com.tn.constants.Constants;
import java.awt.Point;
public class Position {
    private Point from;
    private Point to;
    /**
     * Instantiates a new Position.
     *
     * @param from the from
     * @param to   the to
     */
    public Position(Point from, Point to) {
        if(from.getX() > Constants.BOARD_SIZE || from.getX() < 0>                || from.getY() > Constants.BOARD_SIZE || from.getY() < 0>                || to.getX() > Constants.BOARD_SIZE || to.getX() < 0>                || to.getY() > Constants.BOARD_SIZE || to.getY() < 0>            throw new ArrayIndexOutOfBoundsException();
        }
        this.from = from;
        this.to = to;
    }
    /**
     * Gets from.
     *
     * @return the from
     */
    public Point getFrom() {
        return from;
    }
    /**
     * Get to.
     *
     * @return the to
     */
    public Point getTo() {
        return to;
    }
}
Utils.java
package com.tn.utils;
import java.awt.Point;


public class Utils {
    private Utils() {
    }
    /**
     * Distance between points doubles.
     *
     * @param from the from
     * @param to   the to
     * @return the double
     */
    public static double distanceBetweenPoints(Point from, Point to) {
        double x1 = from.getX();
        double y1 = from.getY();
        double x2 = to.getX();
        double y2 = to.getY();
        return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)) + 1;
    }


    /**

     * Is the point between booleans.

     *

     * @param point    the point

     * @param position the position

     * @return the boolean

     */

    public static boolean isPointBetween(Point point, Position position) {

        Point from = position.getFrom();

        Point to = position.getTo();


        return from.getY() <= point.getY()

                && to.getY() >= point.getY()

                && from.getX() <= point.getX()

                && to.getX() >= point.getX();

    }


}

Game.java


package com.tn.game;


import com.tn.player.Player;



public class Game {

    private Player[] players;


    /**

     * Instantiates a new Game.

     */

    public Game() {

        players = new Player[]{

                new Player(1),

                new Player(2)

        };

    }


    /**

     * Start.

     */

    public void start() {

        int i = 0;

        int j = 1;

        int size = players.length;

        Player player = null;


        while(players[0].getLives() > 0 && players[1].getLives() > 0) {

            players[i++ % size].turnToPlay(players[j++ % size]);

            player = (players[0].getLives() < players>

                    players[1] :

                    players[0];

        }


        System.out.printf("Congrats Player %d, you won!",player.getId());

    }

}

Main.java


package .tn;


import com.tn.game.Game;


public class Main {


    public static void main(String[] args) {

        Game game = new Game();

        game.start();

    }

}

Your answer

1 Answer

More Java discussions