SDE3 | Machine Coding round | Kotak Bank | LLD | Data base design
Anonymous User
5264

Below problem statement was given to me and expectation was to come up with a proper working code for it.
BattleShip Game
Design and implement a battleship game to be played between two players until one comes out
as the winner.

Requirements:
● The game will be played in a square area of the sea with NxN grids which will be called
a battlefield. “N” should be taken as input in your code.
● The battlefield will be divided in half between both the players. So in a NxN battlefield,
NxN/2 grids will belong to PlayerA and the other NxN/2 grids will belong to playerB
● The size and location of each ship will be taken as input. Each ship will be assumed to
be of Square shape. Both the players should be assigned equal fleet.
● The location of each ship in the NxN grids has to be taken as input (X, Y). X and Y
should be integers. For eg. if a ship “SH1” is at (2, 2) and has the size of 4, its corners
will be at (0, 0), (0, 4), (4, 0) and (4,4)
● Ships will remain stationary. No two ships should overlap with each other. However they
can touch boundaries with each other.
● Each player will fire one missile towards the enemy field during his turn using the
“random coordinate fire” strategy, which means the missile will hit at a random
coordinate of the opponent’s field. It might hit or miss the opponent ship. In either case
the turn is then transferred to the other player.
○ In case of a hit, the opponent’s ship is destroyed.
○ In case of a miss, nothing happens.
● No two missiles should ever be fired at the same coordinates throughout the course
of the game.
● When all the ships of a particular player has been destroyed, he loses the game.
The following APIs have to be implemented:
Mandatory:
● initGame(N)

This will initialize the game with a battlefield of size NxN. Where the left half of
N/2xN will be assigned to PlayerA and the right half will be assigned to PlayerB
● addShip(id, size, x position PlayerA, y position PlayerA, x position PlayerB, y position
PlayerB)
This will add a ship of given size at the given coordinates in both the player’s
fleet.
● startGame()

This will begin the game, where PlayerA will always take the first turn. The output
of each step should be printed clearly in the console.
For eg.
PlayerA’s turn: Missile fired at (2, 4). “Hit”. PlayerB’s ship with id “SH1”
destroyed.
PlayerB’s turn: Missile fired at (6, 1). “Miss”

Optional
● viewBattleField()

This will display the battlefield as a NxN grid and all the ships along with the grids
occupied by each ship. PlayerA’s ship with id SH1 will be marked as A-SH1, with
id SH2 as A-SH2 and so on. Whereas PlayerB’s ships will be marked as B-SH1,
B-SH2 and so on.
Note: It should mark all the grids occupied by a ship and not just the center
coordinate.

Here is Java code for above problem. And I was asked to come up with schema and data base design as well.

import java.util.*;

class Ship {
    private String name;
    private int size;
    private int x, y;
    private Set<String> coordinates;

    public Ship(String name, int size, int x, int y) {
        this.name = name;
        this.size = size;
        this.x = x;
        this.y = y;
        this.coordinates = new HashSet<>();
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                coordinates.add((x + i) + "," + (y + j));
            }
        }
    }

    public Set<String> getCoordinates() {
        return coordinates;
    }

    public String getName() {
        return name;
    }
}

class Player {
    private String name;
    private List<Ship> ships;

    public Player(String name) {
        this.name = name;
        this.ships = new ArrayList<>();
    }

    public void addShip(Ship ship) {
        ships.add(ship);
    }

    public String getName() {
        return name;
    }

    public List<Ship> getShips() {
        return ships;
    }
}

class BattleShip {
    private int N;
    private char[][] battleField;
    private Player playerA;
    private Player playerB;
    private boolean gameStarted;

    public BattleShip() {
        this.gameStarted = false;
    }

    public void initGame(int N) {
        this.N = N;
        this.battleField = new char[N][N];
        for (char[] row : battleField) {
            Arrays.fill(row, '.');
        }
        int half = N / 2;
        playerA = new Player("Player A");
        playerB = new Player("Player B");
        gameStarted = false;
    }

    public Player getPlayerA() {
        return playerA;
    }

    public Player getPlayerB() {
        return playerB;
    }

    public void addShip(String id, int size, int xa, int ya, int xb, int yb) {
        if (gameStarted) {
            System.out.println("Game already started");
            return;
        }

        Ship shipA = new Ship(id, size, xa, ya);
        Ship shipB = new Ship(id, size, xb, yb);

        playerA.addShip(shipA);
        playerB.addShip(shipB);

        for (String coord : shipA.getCoordinates()) {
            String[] parts = coord.split(",");
            int x = Integer.parseInt(parts[0]);
            int y = Integer.parseInt(parts[1]);
            battleField[x][y] = 'A';
        }

        for (String coord : shipB.getCoordinates()) {
            String[] parts = coord.split(",");
            int x = Integer.parseInt(parts[0]);
            int y = Integer.parseInt(parts[1]);
            battleField[x][y] = 'B';
        }
    }

    public void startGame() {
        if (!gameStarted) {
            gameStarted = true;
            System.out.println("Game started!");
        } else {
            System.out.println("Game already started!");
        }
    }

    public void fireMissile(Player attacker, Player opponent) {
        if (!gameStarted) {
            System.out.println("Game has not started yet.");
            return;
        }

        Random rand = new Random();
        int x = rand.nextInt(N);
        int y = rand.nextInt(N);

        System.out.print(attacker.getName() + " fires missile at (" + x + "," + y + "). ");

        boolean hit = false;
        for (Ship ship : opponent.getShips()) {
            for (String coord : ship.getCoordinates()) {
                String[] parts = coord.split(",");
                int shipX = Integer.parseInt(parts[0]);
                int shipY = Integer.parseInt(parts[1]);
                if (shipX == x && shipY == y) {
                    hit = true;
                    System.out.println("Hit! " + opponent.getName() + "'s ship with id " + ship.getName() + " destroyed.");
                    break;
                }
            }
            if (hit) {
                break;
            }
        }

        if (!hit) {
            System.out.println("Miss!");
        }
    }

    public void viewBattleField() {
        System.out.println("BattleField :");
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                System.out.print(battleField[i][j] + " ");
            }
            System.out.println();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        BattleShip game = new BattleShip();
        game.initGame(10);

        game.addShip("SH1", 2, 1, 1, 4, 4);
        game.addShip("SH2", 3, 3, 3, 7, 7);

        game.startGame();

        Player playerA = game.getPlayerA();
        Player playerB = game.getPlayerB();

        game.fireMissile(playerA, playerB);
        game.fireMissile(playerB, playerA);

        game.viewBattleField();
    }
}
Comments (8)