diff --git a/docs/README.md b/docs/README.md index e69de29bb2..4ffb988867 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,34 @@ +# 기능 목록 + +## 프로그램 구성 +- 컴퓨터 : 1~9 사이의 서로 다른 임의의 수 3개 선택 +- 사용자 : 서로 다른 3개의 숫자 입력 +- 결과 : -스트라이크 / -볼 -스크라이크 / 낫싱 +- 게임이 끝난 후 : 1 - 재시작, 2 - 종료 + +## 예외 경우 +- 3개의 숫자가 아닌 경우 (많거나 적거나 숫자가 아니거나) +- 게임이 끝난 후 1, 2가 아닌 다른 수를 입력한 경우 + +## Controller +- ### settingGame + - isGameRunning 변수를 통해 게임 진행중으로 표시(false가 될때까지 반복) + - 컴퓨터 번호 설정 + - 게임 시작 문구 + - 게임 시작 +- ### startGame + - 3스트라이크가 나올때까지 반복 + - 사용자가 입력한 변수가 검증되었다면, 결과 출력 + - 3스트라이크라면, 재시작 문구를 출력하고 사용자가 입력한 값이 1이면 재시작, 2면 종료 + +## Service +- ### setComputerNumbers + - 중복되지 않는 1~9 사이의 임의의 수 3개 설정 +- ### validateInputNumber + - 사용자가 입력한 값 검증 + - 1 ~ 9 사이의 수 3개가 맞는지 +- ### OutputGameResult + - 사용자가 입력한 수와 컴퓨터의 수(정답)과의 자리를 비교하여 볼과 스트라이크 수 카운트 +- ### isRestartGame + - 사용자가 입력한 값이 1,2가 아니라면 예외처리 + - 사용자가 입력한 값을 1과 비교하여 맞다면 true, 아니라면 false -> isGameRunning 변수로 할당됨 \ No newline at end of file diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index dd95a34214..59cb4e545a 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -1,7 +1,10 @@ package baseball; +import controller.GameController; + public class Application { - public static void main(String[] args) { - // TODO: 프로그램 구현 + public static void main(String[] args) throws IllegalArgumentException{ + GameController gameController = new GameController(); + gameController.settingGame(); } } diff --git a/src/main/java/controller/GameController.java b/src/main/java/controller/GameController.java new file mode 100644 index 0000000000..fb5a67d01f --- /dev/null +++ b/src/main/java/controller/GameController.java @@ -0,0 +1,51 @@ +package controller; + +import camp.nextstep.edu.missionutils.Console; +import domain.GameMessage; +import domain.GameResult; +import service.GameService; + +import java.util.List; + +public class GameController { + + private final GameService gameService; + public GameController() { + this.gameService = new GameService(); + } + + // 게임 세팅 + public void settingGame() { + boolean isGameRunning = true; + do { + // 컴퓨터 번호 설정 + List answerNumbers = gameService.setComputerNumbers(); + // 게임 시작 문구 + System.out.println(GameMessage.GAME_START_MESSAGE.getGameMessage()); + // 게임 시작 + isGameRunning = isGameStarting(isGameRunning, answerNumbers); + } while (isGameRunning); + } + + // 게임 시작 + private boolean isGameStarting(boolean isGameRunning, List answerNumbers) { + while(true) { + // 사용자 번호 입력 (검증) + System.out.print(GameMessage.INPUT_NUMBER_MESSAGE.getGameMessage()); + String inputNumbers = gameService.validateInputNumber(Console.readLine()); + // 결과 도출 + GameResult gameResult = gameService.outputGameResult(inputNumbers, answerNumbers); + GameResult.gameResultMessage(gameResult); + if (gameResult.isGameSuccess()) { + return isGameRestart(isGameRunning); + } + } + } + + private boolean isGameRestart(boolean isGameRunning) { + System.out.println(GameMessage.GAME_SUCCESS_MESSAGE.getGameMessage()); + System.out.println(GameMessage.GAME_RESTART_MESSAGE.getGameMessage()); + isGameRunning = gameService.isRestartGame(Console.readLine()); + return isGameRunning; + } +} diff --git a/src/main/java/domain/GameMessage.java b/src/main/java/domain/GameMessage.java new file mode 100644 index 0000000000..5f6fd1931e --- /dev/null +++ b/src/main/java/domain/GameMessage.java @@ -0,0 +1,20 @@ +package domain; + +public enum GameMessage { + + // enum으로 안내 문구 설정 + GAME_START_MESSAGE("숫자 야구 게임을 시작합니다."), + INPUT_NUMBER_MESSAGE("숫자를 입력해 주세요 : "), + GAME_SUCCESS_MESSAGE("3개의 숫자를 모두 맞히셨습니다!\n게임 종료"), + GAME_RESTART_MESSAGE("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + + private final String getGameMessage; + + GameMessage(String gameMessage) { + getGameMessage = gameMessage; + } + + public String getGameMessage() { + return getGameMessage; + } +} diff --git a/src/main/java/domain/GameResult.java b/src/main/java/domain/GameResult.java new file mode 100644 index 0000000000..f3c0a358fc --- /dev/null +++ b/src/main/java/domain/GameResult.java @@ -0,0 +1,56 @@ +package domain; + +public class GameResult { + // enum으로 게임 결과 도출 + enum GameResultMessage { + GAME_OUT_MESSAGE("낫싱"); + + private final String getGameResult; + + GameResultMessage(String gameResultMessage) { + getGameResult = gameResultMessage; + } + + } + + private int strike; + private int ball; + private static String NOTHING = "낫싱"; + + public GameResult(int strike, int ball) { + this.strike = strike; + this.ball = ball; + } + + public int getStrike() { + return strike; + } + + public int getBall() { + return ball; + } + + public boolean isGameSuccess() { + return strike == 3; + } + + // 게임 결과 + public static String makeGameResult(GameResult gameResult) { + String output = ""; + if (gameResult.getStrike() == 0 && gameResult.getBall() == 0) { + return NOTHING; + } + if (gameResult.getStrike() != 0) { + output = gameResult.getStrike() + "스트라이크"; + } + if (gameResult.getBall() > 0) { + output = gameResult.getBall() + "볼 " + output; + } + return output.trim(); + } + + public static void gameResultMessage(GameResult gameResult) { + System.out.println(makeGameResult(gameResult)); + } + +} diff --git a/src/main/java/service/GameService.java b/src/main/java/service/GameService.java new file mode 100644 index 0000000000..f4e5956a23 --- /dev/null +++ b/src/main/java/service/GameService.java @@ -0,0 +1,62 @@ +package service; + +import camp.nextstep.edu.missionutils.Randoms; +import domain.GameResult; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class GameService { + + // 컴퓨터 번호 설정 + public List setComputerNumbers() { + List computerNumbers = new ArrayList<>(); + while (computerNumbers.size() < 3) { + int randomNumber = Randoms.pickNumberInRange(1, 9); + if (!computerNumbers.contains(randomNumber)) { + computerNumbers.add(randomNumber); + } + } + return computerNumbers; + } + // 사용자 번호 검증 + public String validateInputNumber(String inputNumber) { + inputNumber = inputNumber.trim(); + Set collect = Arrays.asList(inputNumber.split("")).stream().collect(Collectors.toSet()); + boolean matches = inputNumber.matches("[1-9]{3}"); + boolean notValidatedInput = !matches || collect.size() != 3; + if(notValidatedInput) { + throw new IllegalArgumentException(); + } + return inputNumber; + } + + // 결과 도출 + public GameResult outputGameResult(String inputNumber, List computerNumbers) { + int strike = 0, ball = 0; + + List inputNumbers = Arrays.asList(inputNumber.split("")).stream().map(Integer::parseInt).collect(Collectors.toList()); + for(int i = 0; i < 3; i++) { + // if ~ else문 함수로 바꾸기 + if (computerNumbers.get(i).equals(inputNumbers.get(i))) { + strike++; + } + else if (inputNumbers.get(i).equals(computerNumbers.get((i + 1) % 3)) || inputNumbers.get(i).equals(computerNumbers.get((i + 2) % 3))) { + ball++; + } + } + return new GameResult(strike, ball); + } + + // 게임 재시작 + public boolean isRestartGame(String inputNum) { + inputNum = inputNum.trim(); + if(!(inputNum.equals("1") || inputNum.equals("2"))) { + throw new IllegalArgumentException(); + } + return inputNum.equals("1"); + } +} diff --git a/src/test/java/baseball/ApplicationTest.java b/src/test/java/baseball/ApplicationTest.java index 3fa29fa67b..bfdf067eb7 100644 --- a/src/test/java/baseball/ApplicationTest.java +++ b/src/test/java/baseball/ApplicationTest.java @@ -28,6 +28,13 @@ class ApplicationTest extends NsTest { ); } + @Test + void 문자_예외_테스트() { + assertSimpleTest(() -> + assertThatThrownBy(() -> runException("apple")) + .isInstanceOf(IllegalArgumentException.class)); + } + @Override public void runMain() { Application.main(new String[]{});