Drawer

Projects of the course:

Project 1:
Projects of the course: - image 1 - student projectProject 2: 

import java.util.Arrays;
import java.util.List;

public class Board {

    private final int boardSize;
    private final char[][] board;

    private final List<Character> letters = Arrays.asList(
        'A', 'B', 'C', 'D', 'E',
        'F', 'G', 'H', 'I', 'J'
    );

    private final Player player;

    public Board(int boardSize, Player player) {
        this.boardSize = boardSize;
        this.board = new char[boardSize][boardSize];
        this.player = player;

        createGameBoard();
        placeShips();
    }

    private void createGameBoard() {
        for (char[] row : board) {
            Arrays.fill(row, ' ');
        }
    }

    private void placeShips() {
        for (Ship ship : player.getShips()) {
            for (Coord coord : ship.getCoordinates()) {
                int x = coord.getX();
                int y = coord.getY();

                board[x][y] =
                    String.valueOf(ship.getSize()).charAt(0);
            }
        }
    }

    public int getLetterIndex(char letter) {
        return letters.indexOf(letter);
    }

    public String attemptHit(int x, int y) {
        Coord coord = new Coord(x, y);

        for (Ship ship : player.getShips()) {
            boolean[] hitData = ship.didHit(coord);

            boolean didHit = hitData[0];
            boolean sank = hitData[1];

            if (didHit) {
                board[x][y] = 'X';

                return sank
                    ? "You sank their battleship!"
                    : "Hit!";
            }
        }

        board[x][y] = 'O';
        return "Miss!";
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder("   ");
        String delimiter = " | ";

        for (int a = 0; a < boardSize; a++) {
            result.append(letters.get(a));

            if (a < boardSize - 1) {
                result.append(delimiter);
            }
        }

        result.append("\n");

        for (int x = 0; x < boardSize; x++) {
            result.append(x).append("  ");

            for (int y = 0; y < boardSize; y++) {
                result.append(board[x][y]);

                if (y < boardSize - 1) {
                    result.append(delimiter);
                }
            }

            result.append("\n");
        }

        return result.toString();
    }
}

==================================================

import java.util.Scanner;

public class BattleShip {

    public static void main(String[] args) {
        int boardSize = 10;

        Player player = new Player(boardSize);
        Board board = new Board(boardSize, player);

        runGameLoop(board);
    }

    private static void runGameLoop(Board board) {
        Scanner scanner = new Scanner(System.in);
        String lastAction = null;

        while (true) {
            System.out.println(board);

            if (lastAction != null) {
                System.out.println(lastAction);
            }

            String coord;

            do {
                System.out.println(
                    "Enter a coordinate, for example A0, " +
                    "or quit to stop playing:"
                );

                coord = scanner.next().toUpperCase();

                if (coord.equalsIgnoreCase("quit")) {
                    scanner.close();
                    return;
                }

            } while (!isValidCoord(coord, board));

            char[] array = coord.toCharArray();

            int column = board.getLetterIndex(array[0]);
            int row = array[1] - '0';

            lastAction = board.attemptHit(row, column);
        }
    }

    private static boolean isValidCoord(
        String coord,
        Board board
    ) {
        if (coord.length() != 2) {
            return false;
        }

        char[] array = coord.toCharArray();

        if (board.getLetterIndex(array[0]) == -1) {
            return false;
        }

        return array[1] >= '0' && array[1] <= '9';
    }
}

========================================================

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class Player {

    private final List<Ship> ships = new ArrayList<>();

    public Player(int boardSize) {
        placeShips(boardSize);
    }

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

    private int random(int boardSize, int boatSize) {
        return ThreadLocalRandom.current()
            .nextInt(boardSize - boatSize + 1);
    }

    private List<Coord> getAllCoordinates(
        Coord start,
        Coord end
    ) {
        List<Coord> coordinates = new ArrayList<>();

        if (start.getX() == end.getX()) {
            int min = Math.min(
                start.getY(),
                end.getY()
            );

            int max = Math.max(
                start.getY(),
                end.getY()
            );

            for (int y = min; y < max; y++) {
                coordinates.add(
                    new Coord(start.getX(), y)
                );
            }

        } else {
            int min = Math.min(
                start.getX(),
                end.getX()
            );

            int max = Math.max(
                start.getX(),
                end.getX()
            );

            for (int x = min; x < max; x++) {
                coordinates.add(
                    new Coord(x, start.getY())
                );
            }
        }

        return coordinates;
    }

    private boolean isInUse(Coord coord) {
        for (Ship ship : ships) {
            if (ship.inUse(coord)) {
                return true;
            }
        }

        return false;
    }

    private void placeShips(int boardSize) {
        for (int size : Ship.getSizes()) {
            List<Coord> coordinates;

            main:
            while (true) {
                boolean vertical =
                    ThreadLocalRandom.current().nextBoolean();

                int startX;

                if (vertical) {
                    startX = ThreadLocalRandom.current()
                        .nextInt(boardSize);
                } else {
                    startX = random(boardSize, size);
                }

                int startY;

                if (vertical) {
                    startY = random(boardSize, size);
                } else {
                    startY = ThreadLocalRandom.current()
                        .nextInt(boardSize);
                }

                Coord start = new Coord(startX, startY);

                int endX = vertical
                    ? startX
                    : startX + size;

                int endY = vertical
                    ? startY + size
                    : startY;

                Coord end = new Coord(endX, endY);

                coordinates =
                    getAllCoordinates(start, end);

                for (Coord coord : coordinates) {
                    if (isInUse(coord)) {
                        continue main;
                    }
                }

                break;
            }

            ships.add(new Ship(coordinates));
        }
    }
}

============================================

import java.util.List;

public class Ship {

    private final List<Coord> coordinates;

    public static int[] getSizes() {
        return new int[] {5, 4, 3, 3, 2};
    }

    public Ship(List<Coord> coordinates) {
        this.coordinates = coordinates;
    }

    public List<Coord> getCoordinates() {
        return coordinates;
    }

    public int getSize() {
        return coordinates.size();
    }

    public int getIndex(Coord coord) {
        for (int a = 0; a < coordinates.size(); a++) {
            Coord target = coordinates.get(a);

            if (coord.getX() == target.getX()
                    && coord.getY() == target.getY()) {
                return a;
            }
        }

        return -1;
    }

    public boolean inUse(Coord coord) {
        return getIndex(coord) != -1;
    }

    public boolean[] didHit(Coord coord) {
        int index = getIndex(coord);

        if (index == -1) {
            return new boolean[] {false, false};
        }

        coordinates.get(index).setHit(true);

        boolean sank = true;

        for (Coord c : coordinates) {
            if (!c.isHit()) {
                sank = false;
                break;
            }
        }

        return new boolean[] {true, sank};
    }
}


====================================================

public class Coord {

    private final int x;
    private final int y;
    private boolean hit;

    public Coord(int x, int y) {
        this.x = x;
        this.y = y;
        this.hit = false;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public boolean isHit() {
        return hit;
    }

    public void setHit(boolean hit) {
        this.hit = hit;
    }
}