From 0a559bb77523d718a3153b5f85e07e54bb246e14 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 21:40:16 +0900 Subject: [PATCH 01/12] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=ED=95=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d7e8aee..4c3efd6c 100644 --- a/README.md +++ b/README.md @@ -1 +1,17 @@ -# java-baseball-precourse \ No newline at end of file +# java-baseball-precourse + +## 1. View +1. 정답 추측: "숫자를 입력해주세요" 문구 출력 후 사용자 입력 받는 기능 +2. 힌트: 입력받은 결과를 처리하여 힌트를 출력하는 기능 +3. 게임 클리어: 클리어 문구 출력 후 다시하기 여부를 입력받는 기능 + +## 2. Validator +1. 추측 검증: 추측 정보를 검증하는 기능 +2. 다시하기 검증: 다시 시작 정보를 검증하는 기능 + +## 3. GameService +1. 무작위 정답 숫자를 생성하는 새 게임 기능 +2. 입력과 정답을 비교하여 결과를 반환하는 기능 + +## 4. Game +1. 실행: 위 기능들을 사용하여 게임의 전체적인 흐름을 관리하고 게임을 진행하는 기능 \ No newline at end of file From e9fab5efc663c99b0f9104e7a650d8800ee54691 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 22:21:27 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20View=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/View.java | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/View.java diff --git a/src/main/java/View.java b/src/main/java/View.java new file mode 100644 index 00000000..570370b5 --- /dev/null +++ b/src/main/java/View.java @@ -0,0 +1,40 @@ +import java.util.Scanner; + +public class View { + + private View() {} + + public static int guessView() { + System.out.print("숫자를 입력해 주세요 : "); + Scanner sc = new Scanner(System.in); + int num = sc.nextInt(); + sc.close(); + return num; + } + + public static void hintView(ResultDto resultDto) { + int strike = resultDto.getStrike(); + int ball = resultDto.getBall(); + + if (strike == 0 && ball == 0) { + System.out.println("낫싱"); + } else if (strike == 0) { + System.out.println(ball + "볼"); + } else if (ball == 0) { + System.out.println(strike + "스트라이크"); + } else { + System.out.println(ball + "볼 " + strike + "스트라이크"); + } + } + + public static int successView() { + System.out.println("3스트라이크"); + System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + Scanner sc = new Scanner(System.in); + int num = sc.nextInt(); + sc.close(); + return num; + } + +} From 0830b4b12275273f0fcaf001dde117ae7d545dc5 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 22:22:45 +0900 Subject: [PATCH 03/12] =?UTF-8?q?test:=20View=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ViewTest.java | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/test/java/ViewTest.java diff --git a/src/test/java/ViewTest.java b/src/test/java/ViewTest.java new file mode 100644 index 00000000..4494b556 --- /dev/null +++ b/src/test/java/ViewTest.java @@ -0,0 +1,75 @@ +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ViewTest { + + OutputStream out; + + @BeforeEach + void beforeEach() { + out = new ByteArrayOutputStream(); + System.setOut(new PrintStream(out)); + } + + @Test + void guessView() { + InputStream in = new ByteArrayInputStream("123".getBytes()); + System.setIn(in); + + int num1 = View.guessView(); + + Assertions.assertThat(num1).isEqualTo(123); + } + + @Test + void hintViewNothing() { + ResultDto resultDto = new ResultDto(0, 0); + + View.hintView(resultDto); + + Assertions.assertThat(out.toString().trim()).isEqualTo("낫싱"); + } + + @Test + void hintViewStrike() { + ResultDto resultDto = new ResultDto(2, 0); + + View.hintView(resultDto); + + Assertions.assertThat(out.toString().trim()).isEqualTo("2스트라이크"); + } + + @Test + void hintViewBall() { + ResultDto resultDto = new ResultDto(0, 3); + + View.hintView(resultDto); + + Assertions.assertThat(out.toString().trim()).isEqualTo("3볼"); + } + + @Test + void hintViewBoth() { + ResultDto resultDto = new ResultDto(1, 1); + + View.hintView(resultDto); + + Assertions.assertThat(out.toString().trim()).isEqualTo("1볼 1스트라이크"); + } + + @Test + void successView() { + InputStream in = new ByteArrayInputStream("1".getBytes()); + System.setIn(in); + + int num1 = View.guessView(); + + Assertions.assertThat(num1).isEqualTo(1); + } +} \ No newline at end of file From 13abdee6f4ebb0a54cdd72942d71d4ada362d493 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 22:45:11 +0900 Subject: [PATCH 04/12] =?UTF-8?q?feat:=20Validator=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ResultDto.java | 19 +++++++++++++++++++ src/main/java/Validator.java | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/main/java/ResultDto.java create mode 100644 src/main/java/Validator.java diff --git a/src/main/java/ResultDto.java b/src/main/java/ResultDto.java new file mode 100644 index 00000000..058de924 --- /dev/null +++ b/src/main/java/ResultDto.java @@ -0,0 +1,19 @@ +public class ResultDto { + + private final int strike; + private final int ball; + + public ResultDto(int strike, int ball) { + this.strike = strike; + this.ball = ball; + } + + + public int getStrike() { + return strike; + } + + public int getBall() { + return ball; + } +} diff --git a/src/main/java/Validator.java b/src/main/java/Validator.java new file mode 100644 index 00000000..81980cca --- /dev/null +++ b/src/main/java/Validator.java @@ -0,0 +1,18 @@ +public class Validator { + + private Validator() {} + + public static void validateGuess(int num) { + if (num <= 100 || num >= 1000) { + throw new IllegalArgumentException("3자리 숫자를 입력해야 합니다."); + } else if (num/100 == (num%100)/10 || num/100 == num%10 || (num%100)/10 == num%10) { + throw new IllegalArgumentException("서로 다른 세 숫자를 입력해야 합니다."); + } + } + + public static void validateReGame(int num) { + if (num != 1 && num != 2) { + throw new IllegalArgumentException("1 또는 2를 입력해야 합니다."); + } + } +} From a286c5027dd96a37abc7e78801574ea6e2f38678 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 22:45:47 +0900 Subject: [PATCH 05/12] =?UTF-8?q?test:=20Validator=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ValidatorTest.java | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/java/ValidatorTest.java diff --git a/src/test/java/ValidatorTest.java b/src/test/java/ValidatorTest.java new file mode 100644 index 00000000..5e951faf --- /dev/null +++ b/src/test/java/ValidatorTest.java @@ -0,0 +1,39 @@ +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class ValidatorTest { + + @Test + void validateGuessSuccess() { + int guess = 123; + Assertions.assertThatCode(() -> Validator.validateGuess(guess)).doesNotThrowAnyException(); + } + + @Test + void validateGuessTwoDigit() { + int guess = 13; + Assertions.assertThatThrownBy(() -> Validator.validateGuess(guess)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void validateGuessSameDigit() { + int guess = 112; + Assertions.assertThatThrownBy(() -> Validator.validateGuess(guess)) + .isInstanceOf(IllegalArgumentException.class); + } + + + @Test + void validateReGameSucess() { + int num = 1; + Assertions.assertThatCode(() -> Validator.validateReGame(num)).doesNotThrowAnyException(); + } + + @Test + void validateReGameFail() { + int num = 3; + Assertions.assertThatThrownBy(() -> Validator.validateReGame(num)) + .isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file From df5f4f197a2bfdbf63d6e2596484eb9913cb1cb0 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 23:05:06 +0900 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20GameService=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/GameService.java | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/GameService.java diff --git a/src/main/java/GameService.java b/src/main/java/GameService.java new file mode 100644 index 00000000..5a422b62 --- /dev/null +++ b/src/main/java/GameService.java @@ -0,0 +1,40 @@ +import java.util.Random; + +public class GameService { + + private GameService() { + } + + public static int getNewAnswer() { + Random rand = new Random(); + int num1 = rand.nextInt(9) + 1; + int num2 = rand.nextInt(9) + 1; + while (num1 == num2) { + num2 = rand.nextInt(9) + 1; + } + int num3 = rand.nextInt(9) + 1; + while (num3 == num1 || num3 == num2) { + num3 = rand.nextInt(9) + 1; + } + + return num1 * 100 + num2 * 10 + num3; + } + + public static ResultDto getResult(int answer, int guess) { + int strike = 0; + int ball = 0; + int[] answerArr = {answer / 100, (answer % 100) / 10, answer % 10}; + int[] guessArr = {guess / 100, (guess % 100) / 10, guess % 10}; + + for (int i = 0; i < 3; i++) { + if (answerArr[i] == guessArr[i]) { + strike++; + } else if (guessArr[i] == answerArr[(i + 1) % 3] || guessArr[i] == answerArr[(i + 2) + % 3]) { + ball++; + } + } + + return new ResultDto(strike, ball); + } +} From f97e350093ac3067509fab5776659ea1cf1e3a9d Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 23:05:22 +0900 Subject: [PATCH 07/12] =?UTF-8?q?test:=20GameService=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/GameServiceTest.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/test/java/GameServiceTest.java diff --git a/src/test/java/GameServiceTest.java b/src/test/java/GameServiceTest.java new file mode 100644 index 00000000..6bea4371 --- /dev/null +++ b/src/test/java/GameServiceTest.java @@ -0,0 +1,22 @@ +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class GameServiceTest { + + @Test + void getNewAnswer() { + int answer = GameService.getNewAnswer(); + Assertions.assertThatCode(() -> Validator.validateGuess(answer)).doesNotThrowAnyException(); + } + + @Test + void getResult() { + int answer = 123; + int guess = 135; + + ResultDto resultDto = GameService.getResult(answer, guess); + + Assertions.assertThat(resultDto.getBall()).isEqualTo(1); + Assertions.assertThat(resultDto.getStrike()).isEqualTo(1); + } +} \ No newline at end of file From 67599199af9575227a28771cc700107c9bb2a882 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 23:19:55 +0900 Subject: [PATCH 08/12] =?UTF-8?q?fix:=20=EA=B2=8C=EC=9E=84=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20view=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/View.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/View.java b/src/main/java/View.java index 570370b5..5a191031 100644 --- a/src/main/java/View.java +++ b/src/main/java/View.java @@ -28,7 +28,6 @@ public static void hintView(ResultDto resultDto) { } public static int successView() { - System.out.println("3스트라이크"); System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); Scanner sc = new Scanner(System.in); From 6c1fc5c79dfcc6063ba0f56d4c5aff1944bcdcb2 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 23:35:13 +0900 Subject: [PATCH 09/12] =?UTF-8?q?fix:=20Validator=20=EC=B6=94=EC=B8=A1?= =?UTF-8?q?=EA=B0=92=20=EA=B2=80=EC=A6=9D=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Validator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/Validator.java b/src/main/java/Validator.java index 81980cca..0f9eefc5 100644 --- a/src/main/java/Validator.java +++ b/src/main/java/Validator.java @@ -7,6 +7,8 @@ public static void validateGuess(int num) { throw new IllegalArgumentException("3자리 숫자를 입력해야 합니다."); } else if (num/100 == (num%100)/10 || num/100 == num%10 || (num%100)/10 == num%10) { throw new IllegalArgumentException("서로 다른 세 숫자를 입력해야 합니다."); + } else if ((num%100)/10 == 0 || num%10 == 0) { + throw new IllegalArgumentException("1부터 9까지의 숫자만 입력해야 합니다."); } } From 167c156dda87c95f084f11c9b16b396a4b414a47 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 23:35:38 +0900 Subject: [PATCH 10/12] =?UTF-8?q?feat:=20Game=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Application.java | 6 +++++ src/main/java/Game.java | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/Application.java create mode 100644 src/main/java/Game.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 00000000..bc9cae67 --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,6 @@ +public class Application { + + public static void main(String[] args) { + Game.start(); + } +} diff --git a/src/main/java/Game.java b/src/main/java/Game.java new file mode 100644 index 00000000..3b63940e --- /dev/null +++ b/src/main/java/Game.java @@ -0,0 +1,40 @@ +import java.util.InputMismatchException; + +public class Game { + + public static void start() { + Game game = new Game(); + boolean flag = true; + + while (flag) { + flag = game.play(); + } + + } + + int answer; + + public boolean play() { + answer = GameService.getNewAnswer(); + int guess = 0; + + while (answer != guess) { + try { + guess = View.guessView(); + } catch (InputMismatchException e) { + throw new InputMismatchException(); + } + + Validator.validateGuess(guess); + ResultDto resultDto = GameService.getResult(answer, guess); + + View.hintView(resultDto); + } + + int input = View.successView(); + Validator.validateReGame(input); + + return input == 1; + } + +} From 7fa4bd70078ed42a9cc46f61466cf2e01e39dd98 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Sun, 5 May 2024 23:43:58 +0900 Subject: [PATCH 11/12] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 공백 기준으로 여러 숫자를 입력하는 경우를 거르기 위해 nextInt가 아닌 nextLine으로 입력 받도록 변경 --- src/main/java/Game.java | 13 +++++++++++-- src/main/java/View.java | 10 ++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/java/Game.java b/src/main/java/Game.java index 3b63940e..bf74c05f 100644 --- a/src/main/java/Game.java +++ b/src/main/java/Game.java @@ -22,7 +22,9 @@ public boolean play() { try { guess = View.guessView(); } catch (InputMismatchException e) { - throw new InputMismatchException(); + throw new IllegalArgumentException("숫자를 입력해야합니다."); + } catch (Exception e) { + throw new IllegalArgumentException(); } Validator.validateGuess(guess); @@ -31,7 +33,14 @@ public boolean play() { View.hintView(resultDto); } - int input = View.successView(); + int input; + try { + input = View.successView(); + } catch (InputMismatchException e) { + throw new IllegalArgumentException("숫자를 입력해야 합니다."); + } catch (Exception e) { + throw new IllegalArgumentException(); + } Validator.validateReGame(input); return input == 1; diff --git a/src/main/java/View.java b/src/main/java/View.java index 5a191031..abe001ee 100644 --- a/src/main/java/View.java +++ b/src/main/java/View.java @@ -2,13 +2,13 @@ public class View { + private static Scanner sc = new Scanner(System.in); + private View() {} public static int guessView() { System.out.print("숫자를 입력해 주세요 : "); - Scanner sc = new Scanner(System.in); - int num = sc.nextInt(); - sc.close(); + int num = Integer.parseInt(sc.nextLine()); return num; } @@ -30,9 +30,7 @@ public static void hintView(ResultDto resultDto) { public static int successView() { System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); - Scanner sc = new Scanner(System.in); - int num = sc.nextInt(); - sc.close(); + int num = Integer.parseInt(sc.nextLine()); return num; } From 620621ff526119ace13c2134be224b16b793fa60 Mon Sep 17 00:00:00 2001 From: Yeonwoo JI <95765163+speciling@users.noreply.github.com> Date: Mon, 6 May 2024 12:58:09 +0900 Subject: [PATCH 12/12] =?UTF-8?q?fix:=20=EC=9E=85=EB=A0=A5=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=9A=A9=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/View.java | 6 ++++++ src/test/java/ViewTest.java | 9 +++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/View.java b/src/main/java/View.java index abe001ee..a9aed36b 100644 --- a/src/main/java/View.java +++ b/src/main/java/View.java @@ -1,3 +1,4 @@ +import java.io.InputStream; import java.util.Scanner; public class View { @@ -34,4 +35,9 @@ public static int successView() { return num; } + public static void resetScanner(InputStream inputStream) { + sc.close(); + sc = new Scanner(inputStream); + } + } diff --git a/src/test/java/ViewTest.java b/src/test/java/ViewTest.java index 4494b556..6cf3e0c3 100644 --- a/src/test/java/ViewTest.java +++ b/src/test/java/ViewTest.java @@ -4,6 +4,7 @@ import java.io.OutputStream; import java.io.PrintStream; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -19,8 +20,8 @@ void beforeEach() { @Test void guessView() { - InputStream in = new ByteArrayInputStream("123".getBytes()); - System.setIn(in); + InputStream in = new ByteArrayInputStream("123\n".getBytes()); + View.resetScanner(in); int num1 = View.guessView(); @@ -65,8 +66,8 @@ void hintViewBoth() { @Test void successView() { - InputStream in = new ByteArrayInputStream("1".getBytes()); - System.setIn(in); + InputStream in = new ByteArrayInputStream("1\n".getBytes()); + View.resetScanner(in); int num1 = View.guessView();