ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바 - BattleShip Game
    미니 2023. 5. 14. 20:36

     

    자바로 구현한 배틀쉽 게임이다.

     

    게임 룰 

    https://en.wikipedia.org/wiki/Battleship_(game) 

     

    Battleship (game) - Wikipedia

    From Wikipedia, the free encyclopedia Strategy type guessing game for two players A map of one player's ships and the hits against them, from a game in progress. The grey boxes are the ships placed by the player, and the cross marks show the squares that t

    en.wikipedia.org

     

    1. 각 플레이어는 정해진 규칙에 따라 필드에 배를 올려둔다.

    2. 플레이어 한 명씩 돌아가면서, 배가 있을 만한 위치에 좌표를 선택한다.

    3. 상배편의 배를 모두 침몰시키는 쪽이 이긴다.

     

     

    구현

     

    package battleship;
    
    
    import java.util.*;
    
    public class Main {
        public static void main(String[] args) {
            // Write your code here
            //game start()
            BattleGame newgame = new BattleGame();
            newgame.gameStart();
    
        }
    }
    
    public class BattleGame {
    
        final String rowIndex = " ABCDEFGHIJKLMNOPQRSTUWVXYZ";
    
    
        public void gameStart() {
    
            int thisturn = 0;
            int nextturn = 1;
            Player[] Players = new Player[]{new Player(), new Player()};
            //좌표 set
            for (int i = 0; i < Players.length; i++) {
                System.out.println("Player " + (i + 1) + ", place your ships on the game field");
                Players[i].setShips();
                printMessage();
            }
    
            //쏘기 시작
            while (!Players[0].endofgame && !Players[1].endofgame) {
    
                Players[nextturn].printAll(Players[nextturn].flogOfwar);
                System.out.println("---------------------");
                Players[thisturn].printAll();
                System.out.println();
                System.out.println("Player " + ((thisturn + 1) % 2 + 1) + ", it's your turn:");
                Shot(Players[thisturn++], Players[nextturn++]);
    
                thisturn %= Players.length;
                nextturn %= Players.length;
                printMessage();
            }
        }
    
        private void printMessage() {
            Scanner scanner = new Scanner(System.in);
    
            System.out.println("Press Enter and pass the move to another player");
            scanner.nextLine();
            System.out.print("\033[H\033[2J");
            System.out.flush();
        }
    
    
        private void Shot(Player shotted, Player attatcked) {
            Scanner sanner = new Scanner(System.in);
            int[] input;
    
            input = shotted.inputToInt(sanner.nextLine());
            try {
                shotCheck(input[0], input[1], attatcked);
            } catch (TryAgain e) {
                System.out.println(e.getMessage() + " Try again!");
            }
    
        }
    
        private void shotCheck(int y, int x, Player attatcked) throws TryAgain {
            boolean sankShips;
            if (y >= attatcked.battlefield.length || x >= attatcked.battlefield.length)
                throw new TryAgain("Error! You entered the wrong coordinates!");
            else {
                if (attatcked.battlefield[y][x] == 'O' || attatcked.battlefield[y][x] == 'X') {
                    attatcked.battlefield[y][x] = 'X';
                    attatcked.flogOfwar[y][x] = 'X';
                } else {
                    attatcked.battlefield[y][x] = 'M';
                    attatcked.flogOfwar[y][x] = 'M';
                }
            }
    
            sankShips = checkSank(attatcked);
            if (sankShips && attatcked.endofgame) {
                System.out.print("You sank the last ship. You won. Congratulations!");
            } else if (sankShips) {
                System.out.println("You sank a ship! Specify a new target:");
            } else {
                System.out.printf("%s \n", attatcked.battlefield[y][x] == 'X' ? "You hit a ship!" : "You missed.");
            }
    
    
        }
    
        private boolean checkSank(Player p) {
            boolean sank = false;
            int index = 0;
            for (Player.ShipsPoint s : p.sp) {
                sank = false;
                sank:
                for (int y = s.startY; y <= s.endY; y++) {
                    for (int x = s.startX; x <= s.endX; x++) {
                        if (p.flogOfwar[y][x] != 'X') {
                            sank = false;
                            break sank;
                        }
                    }
                    sank = true;
                }
    
                if (sank) {
                    p.sp.remove(index);
                    p.ships--;
                    if (p.ships == 0) p.endofgame = true;
                    break;
                }
                index++;
            }
            return sank;
        }
        private int[] inputToInt(String readLine) {
            StringTokenizer a = new StringTokenizer(readLine, rowIndex, true);
            int[] XYpoint;
            int countSpace = 0;
            for (char ch : readLine.toCharArray()) {
                if (ch == ' ') countSpace++;
            }
            XYpoint = new int[countSpace * 2 + 2];
            int index = 0;
            while (a.hasMoreTokens()) {
                String s = a.nextToken();
                if (" ".equals(s)) continue;
                if (s.charAt(0) >= 'A' && s.charAt(0) <= 'Z')
                    XYpoint[index++] = (int) s.charAt(0) - 'A' + 1;
                else XYpoint[index++] = Integer.parseInt(s);
            }
    
            return XYpoint;
        }
    
    
        public static class TryAgain extends Exception {
            TryAgain(String msg) {
                super(msg);
            }
    
        }
    }
    
    
    
    package battleship;
    
    import java.util.ArrayList;
    import java.util.Scanner;
    import java.util.StringTokenizer;
    
    public class Player {
         int[][] battlefield;
         int[][] flogOfwar;
        final String rowIndex = " ABCDEFGHIJKLMNOPQRSTUWVXYZ";
         boolean endofgame = false;
         int ships = Ships.size;
         ArrayList<ShipsPoint> sp = new ArrayList<>();
    
        Player(){
            battlefield = new int[11][11];
            flogOfwar = new int [11][11];
            fill();
        }
    
        private void showmenu(String a, int size) {
            System.out.println();
            System.out.println("Enter the coordinates of the " + a + " (" + size + " cells):");
    
        }
        public void setShips(){
            int[] input = null;
            boolean flag;
            Scanner sanner = new Scanner(System.in);
            for(Ships s : Ships.values()){
                flag = false;
                printAll();
                showmenu(s.getName(),s.getlen());
                while(!flag){
                    input = inputToInt(sanner.nextLine());
                    try{
                        flag = checkPoint(input,s);
                    }catch (BattleGame.TryAgain e){
                        System.out.println(e.getMessage() + " Try again:");
                    }
                }
                putships(input, s);
                sp.add(new ShipsPoint(s.getName(),input[0],input[1],input[2],input[3]));
            }
            printAll();
    
        }
        private void putships(int[] input, Ships s) {
            if (input[0] == input[2]) {
                int y = input[0];
                int startX = Math.min(input[1], input[3]);
                for (int n = startX; n < startX + s.getlen(); n++) {
                    battlefield[y][n] = 'O';
                }
    
            } else {
                int x = input[1];
                int startY = Math.min(input[0], input[2]);
                for (int n = startY; n < startY + s.getlen(); n++) {
                    battlefield[n][x] = 'O';
                }
            }
        }
        private void fill() {
            //rows and cols
            for (int i = 1; i < battlefield.length; i++) {
                battlefield[0][i] = i;
                battlefield[i][0] = (i + 'A' - 1);
            }
            for (int y = 1; y < battlefield.length; y++) {
                for (int x = 1; x < battlefield[y].length; x++) {
                    battlefield[y][x] = '~';
                }
            }
            int index=0;
            for(int[] x : battlefield){
                System.arraycopy(x,0,flogOfwar[index++],0,x.length);
            }
        }
         class ShipsPoint{
            String name;
            final int startX;
            final int startY;
            final int endX;
            final int endY;
            ShipsPoint(String name,int Y1,int X1,int Y2, int X2){
                this.name = name;
                this.startX = Math.min(X1,X2);
                this.startY = Math.min(Y1,Y2);
                this.endX = Math.max(X1,X2);
                this.endY = Math.max(Y1,Y2);
            }
        }
        public void printAll() {
            printAll(battlefield);
        }
        public void printAll(int[][] field){
            for (int i = 0; i < field.length; i++) {
                for (int j = 0; j < field[i].length; j++) {
                    if (field[i][j] == 0) {
                        System.out.print("  ");
                    } else if (i == 0) {
                        System.out.print(field[i][j] + " ");
                    } else {
                        System.out.print(((char) field[i][j]) + " ");
                    }
                }
                System.out.println();
            }
        }
    
         int[] inputToInt(String readLine) {
            StringTokenizer a = new StringTokenizer(readLine, rowIndex, true);
            int[] XYpoint;
            int countSpace=0;
            for(char ch: readLine.toCharArray()){
                if(ch == ' ') countSpace++;
            }
            XYpoint = new int[countSpace*2 + 2];
            int index = 0;
            while (a.hasMoreTokens()) {
                String s = a.nextToken();
                if (" ".equals(s)) continue;
                if (s.charAt(0) >= 'A' && s.charAt(0) <= 'Z')
                    XYpoint[index++] = (int) s.charAt(0) - 'A' + 1;
                else XYpoint[index++] = Integer.parseInt(s);
            }
    
            return XYpoint;
        }
    
        private boolean checkPoint(int[] input, Ships s) throws BattleGame.TryAgain {
            if (input[0] != input[2] && input[1] != input[3]) {
                throw new BattleGame.TryAgain("Error! Wrong ship location!");
            } else {
                int abs = Math.abs((input[0] + input[1]) - (input[2] + input[3])) + 1;
                if (abs != s.getlen()) {
                    throw new BattleGame.TryAgain("Error! Wrong length of the " + s.getName() + "!");
                } else {
                    if (!checkAround(input, s)) {
                        throw new BattleGame.TryAgain("Error! You placed it too close to another one.");
                    }
                }
    
    
            }
            return true;
        }
    
        private boolean checkAround(int[] input, Ships s) {
            int start;
            int end;
            int x = 0;
            int y = 0;
            int n;
            boolean check = false;
            boolean samerow = input[0] == input[2];
            if (samerow) {
                start = Math.min(input[1], input[3]);
                end = start + s.getlen();
                y = input[0];
            } else {
                start = Math.min(input[0], input[2]);
                end = start + s.getlen();
                x = input[1];
            }
            for (n = start; n < end; n++) {
                if (samerow) {
                    if (battlefield[y][n] == 'O') break;
                    if (n != 10) {
                        if (battlefield[y][n + 1] == 'O') break;
                    }
                    if (y != 10) {
                        if (battlefield[y + 1][n] == 'O') break;
                    }
                    if (battlefield[y - 1][n] == 'O' || battlefield[y][n - 1] == 'O')
                        break;
                } else {
                    if (battlefield[n][x] == 'O') break;
                    if (n != 10) {
                        if (battlefield[n + 1][x] == 'O') break;
                    }
                    if (x != 10) {
                        if (battlefield[n][x + 1] == 'O') break;
                    }
                    if (battlefield[n - 1][x] == 'O' || battlefield[n][x - 1] == 'O')
                        break;
                }
            }
    
            if (n == end) check = true;
    
            return check;
        }
    
    
    }
    
    public enum Ships {
        AIRCRAFT_CARRIER("Aircraft Carrier",5),
        BATTLESHIP("Battleship",4),
        SUBMARINE("Submarine",3),
        CRUISER("Cruiser",3),
        DESTROYER("Destroyer",2);
        private final String name;
        private final int len;
        static final int size  = Ships.values().length;
        //enum size
        public String getName(){
            return this.name;
        }
        public int getlen(){
            return this.len;
        }
        Ships(String name, int len){
            this.name = name;
            this.len = len;
        }
    
    }
    

    '미니' 카테고리의 다른 글

    Naver Maps openAPI (1) -JSON  (0) 2023.06.23
    자바 콘솔 -bulls and cows 게임  (0) 2023.03.10
    자바 콘솔 -커피머신  (0) 2023.03.09
Designed by Tistory.