-
자바 - BattleShip Game미니 2023. 5. 14. 20:36
자바로 구현한 배틀쉽 게임이다.
게임 룰
https://en.wikipedia.org/wiki/Battleship_(game)
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 (2) - Geocoding ,Static Map API (0) 2023.06.23 Naver Maps openAPI (1) -JSON (0) 2023.06.23 자바 콘솔 -bulls and cows 게임 (0) 2023.03.10 자바 콘솔 -커피머신 (0) 2023.03.09