-
Notifications
You must be signed in to change notification settings - Fork 5
[숫자 야구] 공희상 제출합니다. #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
28799a8
8be4def
7592c7a
7aefda6
f1e64ca
ae729c6
703b929
a2a6689
348a827
92cc2c0
754b5b8
1659cfc
a04f212
d52c1d4
6a2146b
b6e80f2
137c58a
128ef27
5686309
3cae7bd
4fef63b
88c5e12
04bd94e
af8c084
1e34c4b
d122140
985b88e
f9fea8d
2f64bfe
024f59e
3eb1df7
1232aad
ba53a04
1b60c7b
a3cbd69
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,13 @@ | ||
| package baseball; | ||
|
|
||
| import baseball.config.GameConfig; | ||
| import baseball.controller.GameController; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| // TODO: 프로그램 구현 | ||
| GameConfig gameConfig = new GameConfig(); | ||
| GameController gameController = gameConfig.getGameComputer(); | ||
|
|
||
| gameController.start(); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package baseball.common.constant; | ||
|
|
||
| public class Constants { | ||
| public final static int MIN_NUMBER = 1; | ||
| public final static int MAX_NUMBER = 9; | ||
| public final static int NUMBERS_SIZE = 3; | ||
|
|
||
| public final static String WHITE_SPACE = " "; | ||
| public final static String STRIKE = "%d스트라이크"; | ||
| public final static String BALL = "%d볼"; | ||
| public final static String NOTHING = "낫싱"; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package baseball.config; | ||
|
|
||
| import baseball.controller.GameController; | ||
| import baseball.view.InputView; | ||
| import baseball.view.OutputView; | ||
|
|
||
| public class GameConfig { | ||
|
|
||
| private final InputView inputView = new InputView(); | ||
| private final OutputView outputView = new OutputView(); | ||
| private final GameController gameController; | ||
|
|
||
| public GameConfig() { | ||
| this.gameController = new GameController(inputView, outputView); | ||
| } | ||
|
|
||
| public GameController getGameComputer() { | ||
| return gameController; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| package baseball.controller; | ||
|
|
||
| import baseball.model.domain.ComputerNumbers; | ||
| import baseball.model.domain.GameMenu; | ||
| import baseball.model.domain.PlayerNumbers; | ||
| import baseball.model.domain.Result; | ||
| import baseball.view.InputView; | ||
| import baseball.view.OutputView; | ||
|
|
||
| public class GameController { | ||
| private final InputView inputView; | ||
| private final OutputView outputView; | ||
|
|
||
| public GameController(InputView inputView, OutputView outputView) { | ||
| this.inputView = inputView; | ||
| this.outputView = outputView; | ||
| } | ||
|
|
||
| public void start() { | ||
| try { | ||
| boolean isContinue = true; | ||
| outputView.printStartMessage(); | ||
| while (isContinue) { | ||
| play(); | ||
| isContinue = restart(); | ||
|
Comment on lines
+24
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메서드가 아주 보기 좋게 잘려있으니 이 둘을 서비스나 다른 컨트롤러로 분리하기 아주 좋아보입니다. ㅎㅎ.... (츄릅) |
||
| } | ||
| } catch (IllegalArgumentException e) { | ||
| throw new IllegalArgumentException(e.getMessage()); | ||
|
Comment on lines
+27
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어차피 IllegalArgumentException으로 받아서 똑같은 메시지로 다시 던질거면 여기서 try-catch를 왜 사용하신지 궁금해요! |
||
| } | ||
| } | ||
|
|
||
| private void play() { | ||
| boolean isFinish = false; | ||
| ComputerNumbers computerNumbers = init(); | ||
| while (!isFinish) { | ||
| PlayerNumbers playerNumbers = input(); | ||
| isFinish = result(computerNumbers, playerNumbers); | ||
| } | ||
|
Comment on lines
+33
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do while로 처리하면 더 좋을것 같습니다. |
||
| finish(); | ||
| } | ||
|
|
||
| private ComputerNumbers init() { | ||
| return new ComputerNumbers(); | ||
| } | ||
|
|
||
| private PlayerNumbers input() { | ||
| outputView.printNumberPrompt(); | ||
| String input = inputView.getNumber(); | ||
| return new PlayerNumbers(input); | ||
| } | ||
|
|
||
| private boolean result(ComputerNumbers computerNumbers, PlayerNumbers playerNumbers) { | ||
| Result result = computerNumbers.compare(playerNumbers); | ||
| outputView.printResultMessage(result.toString()); | ||
| return result.isCorrect(); | ||
| } | ||
|
|
||
| private boolean restart() { | ||
| outputView.printRestartPrompt(); | ||
| String input = inputView.askRestart(); | ||
| return GameMenu.from(input); | ||
| } | ||
|
|
||
| private void finish() { | ||
| outputView.printFinishMessage(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package baseball.model.domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
|
|
||
| import static baseball.common.constant.Constants.MAX_NUMBER; | ||
| import static baseball.common.constant.Constants.MIN_NUMBER; | ||
| import static baseball.common.constant.Constants.NUMBERS_SIZE; | ||
| import static camp.nextstep.edu.missionutils.Randoms.pickNumberInRange; | ||
|
|
||
| public class ComputerNumbers { | ||
| private final List<Integer> computerNumbers; | ||
|
|
||
| public ComputerNumbers() { | ||
| this.computerNumbers = createRandomNumbers(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 생성자에서 온전히 생성만을 담당하기 위해 |
||
| } | ||
|
|
||
| private List<Integer> createRandomNumbers() { | ||
| Set<Integer> randomNumbers = new HashSet<>(); | ||
| while (randomNumbers.size() < NUMBERS_SIZE) { | ||
| int randomNumber = pickNumberInRange(MIN_NUMBER, MAX_NUMBER); | ||
| randomNumbers.add(randomNumber); | ||
| } | ||
| return new ArrayList<>(randomNumbers); | ||
| } | ||
|
|
||
| public Result compare(PlayerNumbers player) { | ||
| int strikes = 0; | ||
| int balls = 0; | ||
|
|
||
| List<Integer> playerNumbers = player.getPlayerNumbers(); | ||
|
|
||
| for (int i = 0; i < NUMBERS_SIZE; i++) { | ||
| boolean isStrike = computerNumbers.get(i).equals(playerNumbers.get(i)); | ||
| boolean isBall = !isStrike && computerNumbers.contains(playerNumbers.get(i)); | ||
| if (isStrike) { | ||
| strikes++; | ||
| } | ||
| if (isBall) { | ||
| balls++; | ||
| } | ||
| } | ||
|
Comment on lines
+35
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 클래스에 스트라이크, 볼 판정 로직이 있어도 될지 궁금합니다 |
||
| return new Result(strikes, balls); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package baseball.model.domain; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| public enum GameMenu { | ||
| RESTART("1", true), | ||
| QUIT("2", false); | ||
|
Comment on lines
+6
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 재시작을 이넘으로 처리하셨네요 좋은방법 같아 보입니다 |
||
|
|
||
| private final String code; | ||
| private final boolean countinue; | ||
|
|
||
| GameMenu(String code, boolean countinue) { | ||
| this.code = code; | ||
| this.countinue = countinue; | ||
| } | ||
|
|
||
| public static boolean from(String input) { | ||
| return Arrays.stream(GameMenu.values()) | ||
| .filter(menu -> menu.code.equals(input)) | ||
| .findFirst() | ||
| .map(GameMenu::isCountinue) | ||
| .orElseThrow(() -> new IllegalArgumentException("잘못된 메뉴 선택입니다.")); | ||
| } | ||
|
|
||
| private boolean isCountinue() { | ||
| return countinue; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package baseball.model.domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class PlayerNumbers { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PlayerNumber와 ComputerNumeber가 비슷한 기능을 수행하는 부분이 있어서, 추상클래스로 묶으면 검증등의 로직을 빼볼 수 있을 것 같아요! |
||
| private final List<Integer> playerNumbers; | ||
|
|
||
| public PlayerNumbers(String input) { | ||
| this.playerNumbers = parse(input); | ||
| } | ||
|
|
||
| private List<Integer> parse(String input) { | ||
| List<String> items = List.of(input.split("")); | ||
| List<Integer> numbers = new ArrayList<>(); | ||
| for (String item : items) { | ||
| int number = parseNumber(item); | ||
| numbers.add(number); | ||
| } | ||
| validateNumbers(numbers); | ||
| return numbers; | ||
| } | ||
|
|
||
|
Comment on lines
+13
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 파싱 부분은 따로 클래스를 만들어서 빼는게 어떨까요? |
||
| private int parseNumber(String input) { | ||
| try { | ||
| int number = Integer.parseInt(input); | ||
| validateNumber(number); | ||
| return number; | ||
| } catch (NumberFormatException e) { | ||
| throw new IllegalArgumentException("입력값은 숫자여야 합니다."); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외처리도 상수화 하시면 좋을것 같습니다 |
||
| } | ||
| } | ||
|
|
||
| private int validateNumber(int number) { | ||
| if (number < 1 || number > 9) { | ||
| throw new IllegalArgumentException("숫자는 1에서 9까지의 수만 허용됩니다."); | ||
| } | ||
| return number; | ||
| } | ||
|
|
||
| private void validateNumbers(List<Integer> numbers) { | ||
| if (numbers.size() != 3) { | ||
| throw new IllegalArgumentException("숫자 3자리를 입력해야 합니다."); | ||
| } | ||
| int uniqueCount = (int) numbers.stream() | ||
| .distinct() | ||
| .count(); | ||
| if (uniqueCount != 3) { | ||
| throw new IllegalArgumentException("중복된 숫자는 허용되지 않습니다."); | ||
| } | ||
| } | ||
|
|
||
| public List<Integer> getPlayerNumbers() { | ||
| return playerNumbers; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package baseball.model.domain; | ||
|
|
||
| import static baseball.common.constant.Constants.BALL; | ||
| import static baseball.common.constant.Constants.NOTHING; | ||
| import static baseball.common.constant.Constants.STRIKE; | ||
| import static baseball.common.constant.Constants.WHITE_SPACE; | ||
|
|
||
| public class Result { | ||
| private final int strikes; | ||
| private final int balls; | ||
|
|
||
| public Result(int strikes, int balls) { | ||
| this.strikes = strikes; | ||
| this.balls = balls; | ||
| } | ||
|
|
||
| public boolean isCorrect() { | ||
| return strikes == 3; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NUMBER_SIZE 상수를 써도 좋을것 같네요. |
||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| if (strikes == 0 && balls == 0) { | ||
| return NOTHING; | ||
| } | ||
| StringBuilder result = new StringBuilder(); | ||
| if (balls > 0) { | ||
| result.append(BALL.formatted(balls)).append(WHITE_SPACE); | ||
| } | ||
| if (strikes > 0) { | ||
| result.append(STRIKE.formatted(strikes)); | ||
| } | ||
| return result.toString().trim(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package baseball.view; | ||
|
|
||
| import static camp.nextstep.edu.missionutils.Console.readLine; | ||
|
|
||
| public class InputView { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. InputView에서 좀 더 적극적으로 List나 boolean을 제공하지 않고, String만 제공하는지 궁금합니다! 너무 역할이 없는 것 같아요. |
||
|
|
||
| public String getNumber() { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메서드이름에 get이 들어가는걸 지양해야할것 같습니다 |
||
| return readLine(); | ||
| } | ||
|
|
||
| public String askRestart() { | ||
| return readLine(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package baseball.view; | ||
|
|
||
| public class OutputView { | ||
| private final static String ERROR = "[ERROR]%s"; | ||
|
|
||
| public void printStartMessage() { | ||
| System.out.println("숫자 야구 게임을 시작합니다."); | ||
| } | ||
|
|
||
| public void printNumberPrompt() { | ||
| System.out.print("숫자를 입력해주세요 : "); | ||
| } | ||
|
|
||
| public void printResultMessage(String message) { | ||
| System.out.println(message); | ||
| } | ||
|
|
||
| public void printFinishMessage() { | ||
| System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); | ||
| } | ||
|
|
||
| public void printRestartPrompt() { | ||
| System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); | ||
| } | ||
|
|
||
| public void printErrorMessage(String message) { | ||
| System.out.println(ERROR.formatted(message)); | ||
| } | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 상수들은 위 상수들과는 조금 다르게 출력에 초점을 맞추고 있는 상수들이에요. 상수도 분리해서 관리하면 어떨까요?