From c0abb190f6b7f2751882d78c6bc1f2f551a1b286 Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 17:39:30 +0900 Subject: [PATCH 01/29] docs : add functional list --- docs/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/README.md b/docs/README.md index e69de29bb2..33d7c9b435 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,20 @@ +# 기능 목록 + +입출력 +- [ ] 사용자 입력 + - [ ] 숫자 입력 + - [ ] 예외처리 + - [ ] 게임 진행(1 or 2) 입력 + - [ ] 예외처리 +- [ ] 메시지 출력 + - [ ] 시작 메시지 + - [ ] (b, s) -> 볼/스트라이크 출력 + - [ ] 종료 메시지 + +게임 진행 +- [ ] main + - [ ] 게임 시작 + - [ ] 게임 종료, 결과 출력 +- [ ] singleGame + - [ ] init : 난수 생성 + - [ ] singleTurn (xxx) -> 판정 후 결과 리턴 From f449f836216a4fc735a4cfe2567ca6f57770d362 Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:23:50 +0900 Subject: [PATCH 02/29] test : add UserOutput test code --- src/main/java/baseball/inout/UserOutput.java | 19 +++++ .../java/baseball/inout/UserOutputTest.java | 82 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/main/java/baseball/inout/UserOutput.java create mode 100644 src/test/java/baseball/inout/UserOutputTest.java diff --git a/src/main/java/baseball/inout/UserOutput.java b/src/main/java/baseball/inout/UserOutput.java new file mode 100644 index 0000000000..bb6524a44f --- /dev/null +++ b/src/main/java/baseball/inout/UserOutput.java @@ -0,0 +1,19 @@ +package baseball.inout; + +import baseball.game.GameStatus; + +public class UserOutput { + + public void initMessage(){ + + } + + public void statusMessage(GameStatus status){ + + } + + public void endMessage(){ + + } + +} diff --git a/src/test/java/baseball/inout/UserOutputTest.java b/src/test/java/baseball/inout/UserOutputTest.java new file mode 100644 index 0000000000..ff5b6dce56 --- /dev/null +++ b/src/test/java/baseball/inout/UserOutputTest.java @@ -0,0 +1,82 @@ +package baseball.inout; + +import baseball.game.GameStatus; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class UserOutputTest { + private static ByteArrayOutputStream outputMessage; + private static UserOutput output; + + @BeforeEach + void setUpStreams() { + outputMessage = new ByteArrayOutputStream(); // OutputStream 생성 + System.setOut(new PrintStream(outputMessage)); // 생성한 OutputStream 으로 설정 + + output = new UserOutput(); + } + + @AfterEach + void restoresStreams() { + System.setOut(System.out); // 원상복귀 + } + + @Test + void initMessage() { + // when + output.initMessage(); + + // then + assertThat(outputMessage.toString()).isEqualTo("숫자 야구 게임을 시작합니다."); + } + + @Test + @DisplayName("statusMessage 테스트 - 1볼") + @ParameterizedTest + @ValueSource(ints = {0,1,2}) + void statusMessage(int strike) { + // when + output.statusMessage(new GameStatus(1,strike)); + + // then + if (strike == 0) + assertThat(outputMessage.toString()).isEqualTo("1볼"); + else + assertThat(outputMessage.toString()).isEqualTo("1볼 "+strike+"스트라이크"); + } + + @Test + @DisplayName("statusMessage 테스트 - 3스트라이크, 낫싱") + @ParameterizedTest + @ValueSource(ints = {0,3}) + void statusMessage2(int strike) { + // when + output.statusMessage(new GameStatus(0,strike)); + + // then + if (strike == 0) + assertThat(outputMessage.toString()).isEqualTo("낫싱"); + else + assertThat(outputMessage.toString()).isEqualTo("3스트라이크"); + } + + @Test + void endMessage() { + // when + output.endMessage(); + + // then + assertThat(outputMessage.toString()).isEqualTo("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + } + +} \ No newline at end of file From 714d713b1a9f02111a268de98ec9298fa2a98573 Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:24:02 +0900 Subject: [PATCH 03/29] test : add UserInput test code --- src/main/java/baseball/inout/CheckRegex.java | 4 + src/main/java/baseball/inout/UserInput.java | 29 +++++ .../java/baseball/inout/UserInputTest.java | 103 ++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 src/main/java/baseball/inout/CheckRegex.java create mode 100644 src/main/java/baseball/inout/UserInput.java create mode 100644 src/test/java/baseball/inout/UserInputTest.java diff --git a/src/main/java/baseball/inout/CheckRegex.java b/src/main/java/baseball/inout/CheckRegex.java new file mode 100644 index 0000000000..f9b73a6ecd --- /dev/null +++ b/src/main/java/baseball/inout/CheckRegex.java @@ -0,0 +1,4 @@ +package baseball.inout; + +public class CheckRegex { +} diff --git a/src/main/java/baseball/inout/UserInput.java b/src/main/java/baseball/inout/UserInput.java new file mode 100644 index 0000000000..e1d6af3fa4 --- /dev/null +++ b/src/main/java/baseball/inout/UserInput.java @@ -0,0 +1,29 @@ +package baseball.inout; + + +import java.util.List; + +import static camp.nextstep.edu.missionutils.Console.readLine; + +public class UserInput { + + /** + * 숫자 입력 + */ + public List getNum() { + System.out.print("숫자를 입력해주세요 : "); + String input = readLine(); + +// CheckRegex.isPlayball +// Integer.parseInt(input); + return List.of(0,0,0); + } + + /** + * 게임 진행여부 입력 + */ + public boolean isContinue() { + return false; + } + +} diff --git a/src/test/java/baseball/inout/UserInputTest.java b/src/test/java/baseball/inout/UserInputTest.java new file mode 100644 index 0000000000..d23a04ae17 --- /dev/null +++ b/src/test/java/baseball/inout/UserInputTest.java @@ -0,0 +1,103 @@ +package baseball.inout; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class UserInputTest { + private static ByteArrayOutputStream outputMessage; + private static ByteArrayInputStream inputMessage; + private static UserInput userInput; + + @BeforeEach + void setUpStreams() { + outputMessage = new ByteArrayOutputStream(); // OutputStream 생성 + System.setOut(new PrintStream(outputMessage)); // 생성한 OutputStream 으로 설정 + + userInput = new UserInput(); + } + + @AfterEach + void restoresStreams() { + System.setOut(System.out); // 원상복귀 + } + + @Test + @DisplayName("숫자 입력 동작 테스트") + @ParameterizedTest + @ValueSource(strings = {"123", "145", "671"}) + void getNum(String input) { + // given + enterInput(input); + List compare = new ArrayList<>(); + for (int i = 0; i < 3; i++) + compare.add( input.charAt(i) - '0'); + + // when + List list = userInput.getNum(); + + // then + assertThat(list).isEqualTo(compare); + } + + @Test + @DisplayName("숫자 입력 예외 테스트") + @ParameterizedTest + @ValueSource(strings = {"111", "122", "1325", "a11"}) + void getNumErrors(String input) { + // given + enterInput(input); + + // then + assertThatThrownBy( () -> { + userInput.getNum(); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("게임진행 입력 동작 테스트") + @ParameterizedTest + @ValueSource(strings = {"0", "1"}) + void isContinue(String input) { + // given + enterInput(input); + + // when + boolean cmd = userInput.isContinue(); + + // then + assertThat(cmd).isEqualTo( input.equals("1") ); + } + + @Test + @DisplayName("게임진행 입력 예외 테스트") + @ParameterizedTest + @ValueSource(strings = {"111", "2", "0", "a"}) + void isContinueError(String input) { + // given + enterInput(input); + + // then + assertThatThrownBy( () -> { + userInput.isContinue(); + }).isInstanceOf(IllegalArgumentException.class); + } + + void enterInput(String input){ + inputMessage = new ByteArrayInputStream(input.getBytes()); + System.setIn(inputMessage); + } +} \ No newline at end of file From 3ac7ecc18d1e2ee9fad728cec782389b34c6b70f Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:24:13 +0900 Subject: [PATCH 04/29] test : add SingleGame test code --- src/main/java/baseball/game/GameStatus.java | 26 ++++++++++ src/main/java/baseball/game/SingleGame.java | 31 +++++++++++ .../java/baseball/game/SingleGameTest.java | 52 +++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 src/main/java/baseball/game/GameStatus.java create mode 100644 src/main/java/baseball/game/SingleGame.java create mode 100644 src/test/java/baseball/game/SingleGameTest.java diff --git a/src/main/java/baseball/game/GameStatus.java b/src/main/java/baseball/game/GameStatus.java new file mode 100644 index 0000000000..d3b3f0cdb1 --- /dev/null +++ b/src/main/java/baseball/game/GameStatus.java @@ -0,0 +1,26 @@ +package baseball.game; + +import java.util.Objects; + +public class GameStatus { + public int ball; + public int strike; + + public GameStatus(int ball, int strike) { + this.ball = ball; + this.strike = strike; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GameStatus that = (GameStatus) o; + return ball == that.ball && strike == that.strike; + } + + @Override + public int hashCode() { + return Objects.hash(ball, strike); + } +} diff --git a/src/main/java/baseball/game/SingleGame.java b/src/main/java/baseball/game/SingleGame.java new file mode 100644 index 0000000000..10975b1ac1 --- /dev/null +++ b/src/main/java/baseball/game/SingleGame.java @@ -0,0 +1,31 @@ +package baseball.game; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.ArrayList; +import java.util.List; + +public class SingleGame { + List computer = new ArrayList<>(); + + public SingleGame() { + while(computer.size() < 3) { + int randomNumber = Randoms.pickNumberInRange(1, 9); + if (!computer.contains(randomNumber)) + computer.add(randomNumber); + } + } + + public void setComputer (List list) { + computer = list; + } + + + public GameStatus singleTurn(List player){ + + + return new GameStatus(0,0); + } + + +} diff --git a/src/test/java/baseball/game/SingleGameTest.java b/src/test/java/baseball/game/SingleGameTest.java new file mode 100644 index 0000000000..e614d9dbbe --- /dev/null +++ b/src/test/java/baseball/game/SingleGameTest.java @@ -0,0 +1,52 @@ +package baseball.game; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class SingleGameTest { + SingleGame singleGame; + + @BeforeAll + void setSingleGame() { + singleGame = new SingleGame(); + singleGame.setComputer(List.of(1, 2, 3)); + } + + List> inputs = new ArrayList<>(List.of( + List.of(4, 5, 6), // n + List.of(4, 5, 1), // 1b + List.of(1, 5, 6), // 1s + List.of(1, 5, 2), // 1b1s + List.of(1, 2, 3) // 3s + )); + List expects = new ArrayList<>(List.of( + new GameStatus(0, 0), + new GameStatus(1, 0), + new GameStatus(0, 1), + new GameStatus(1, 1), + new GameStatus(0, 3) + )); + + @Test + @DisplayName("singleTurn 동작 테스트") + @ParameterizedTest + @ValueSource(ints = {0, 1, 2, 3, 4}) + void singleTurn(int i) { + // when + GameStatus status = singleGame.singleTurn(inputs.get(i)); + + // then + assertThat(status).isEqualTo(expects.get(i)); + } +} \ No newline at end of file From 292c25cea32347800afaf17f9b8bebfffa334e87 Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:55:16 +0900 Subject: [PATCH 05/29] test : edit UserOutput test code --- .../java/baseball/inout/UserOutputTest.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/test/java/baseball/inout/UserOutputTest.java b/src/test/java/baseball/inout/UserOutputTest.java index ff5b6dce56..8fcd65a538 100644 --- a/src/test/java/baseball/inout/UserOutputTest.java +++ b/src/test/java/baseball/inout/UserOutputTest.java @@ -37,37 +37,37 @@ void initMessage() { output.initMessage(); // then - assertThat(outputMessage.toString()).isEqualTo("숫자 야구 게임을 시작합니다."); + assertThat(outputMessage.toString().trim()).isEqualTo("숫자 야구 게임을 시작합니다."); } - @Test - @DisplayName("statusMessage 테스트 - 1볼") + @ParameterizedTest - @ValueSource(ints = {0,1,2}) + @DisplayName("statusMessage 테스트 - 1볼") + @ValueSource(ints = {0, 1, 2}) void statusMessage(int strike) { // when - output.statusMessage(new GameStatus(1,strike)); + output.statusMessage(new GameStatus(1, strike)); // then if (strike == 0) - assertThat(outputMessage.toString()).isEqualTo("1볼"); + assertThat(outputMessage.toString().trim()).isEqualTo("1볼"); else - assertThat(outputMessage.toString()).isEqualTo("1볼 "+strike+"스트라이크"); + assertThat(outputMessage.toString().trim()).isEqualTo("1볼 " + strike + "스트라이크"); } - @Test - @DisplayName("statusMessage 테스트 - 3스트라이크, 낫싱") + @ParameterizedTest - @ValueSource(ints = {0,3}) + @DisplayName("statusMessage 테스트 - 3스트라이크, 낫싱") + @ValueSource(ints = {0, 3}) void statusMessage2(int strike) { // when - output.statusMessage(new GameStatus(0,strike)); + output.statusMessage(new GameStatus(0, strike)); // then if (strike == 0) - assertThat(outputMessage.toString()).isEqualTo("낫싱"); + assertThat(outputMessage.toString().trim()).isEqualTo("낫싱"); else - assertThat(outputMessage.toString()).isEqualTo("3스트라이크"); + assertThat(outputMessage.toString().trim()).isEqualTo("3스트라이크"); } @Test @@ -76,7 +76,7 @@ void endMessage() { output.endMessage(); // then - assertThat(outputMessage.toString()).isEqualTo("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + assertThat(outputMessage.toString().trim()).isEqualTo("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); } } \ No newline at end of file From e4f003cf7a931cc0bc6ba3ef1031a418466948e2 Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:55:24 +0900 Subject: [PATCH 06/29] test : edit UserInput test code --- src/test/java/baseball/inout/UserInputTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/java/baseball/inout/UserInputTest.java b/src/test/java/baseball/inout/UserInputTest.java index d23a04ae17..ec01987904 100644 --- a/src/test/java/baseball/inout/UserInputTest.java +++ b/src/test/java/baseball/inout/UserInputTest.java @@ -53,9 +53,9 @@ void getNum(String input) { assertThat(list).isEqualTo(compare); } - @Test - @DisplayName("숫자 입력 예외 테스트") + @ParameterizedTest + @DisplayName("숫자 입력 예외 테스트") @ValueSource(strings = {"111", "122", "1325", "a11"}) void getNumErrors(String input) { // given @@ -67,10 +67,10 @@ void getNumErrors(String input) { }).isInstanceOf(IllegalArgumentException.class); } - @Test - @DisplayName("게임진행 입력 동작 테스트") + @ParameterizedTest - @ValueSource(strings = {"0", "1"}) + @DisplayName("게임진행 입력 동작 테스트") + @ValueSource(strings = {"1", "2"}) void isContinue(String input) { // given enterInput(input); @@ -82,10 +82,10 @@ void isContinue(String input) { assertThat(cmd).isEqualTo( input.equals("1") ); } - @Test - @DisplayName("게임진행 입력 예외 테스트") + @ParameterizedTest - @ValueSource(strings = {"111", "2", "0", "a"}) + @DisplayName("게임진행 입력 예외 테스트") + @ValueSource(strings = {"111", "3", "0", "a"}) void isContinueError(String input) { // given enterInput(input); From 6e8eec3377f1a7e1c10e00e16b8d19faabd2bdf4 Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:55:37 +0900 Subject: [PATCH 07/29] test : edit SingleGame test code --- src/test/java/baseball/game/SingleGameTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/baseball/game/SingleGameTest.java b/src/test/java/baseball/game/SingleGameTest.java index e614d9dbbe..34bf6ab246 100644 --- a/src/test/java/baseball/game/SingleGameTest.java +++ b/src/test/java/baseball/game/SingleGameTest.java @@ -38,9 +38,8 @@ void setSingleGame() { new GameStatus(0, 3) )); - @Test - @DisplayName("singleTurn 동작 테스트") @ParameterizedTest + @DisplayName("singleTurn 동작 테스트") @ValueSource(ints = {0, 1, 2, 3, 4}) void singleTurn(int i) { // when From 6b2fc5066057f65accd2a413e565ac74fc6ea56a Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:56:48 +0900 Subject: [PATCH 08/29] feat : implement SingleGame --- src/main/java/baseball/game/GameStatus.java | 4 ++++ src/main/java/baseball/game/SingleGame.java | 11 ++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/baseball/game/GameStatus.java b/src/main/java/baseball/game/GameStatus.java index d3b3f0cdb1..2169e8afd8 100644 --- a/src/main/java/baseball/game/GameStatus.java +++ b/src/main/java/baseball/game/GameStatus.java @@ -23,4 +23,8 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(ball, strike); } + + public boolean isCorrect() { + return (strike == 3 && ball == 0); + } } diff --git a/src/main/java/baseball/game/SingleGame.java b/src/main/java/baseball/game/SingleGame.java index 10975b1ac1..c083f3680b 100644 --- a/src/main/java/baseball/game/SingleGame.java +++ b/src/main/java/baseball/game/SingleGame.java @@ -20,12 +20,13 @@ public void setComputer (List list) { computer = list; } - public GameStatus singleTurn(List player){ + int strike = 0, ball = 0; + for (int i = 0; i < player.size(); i++) { + if (computer.get(i) == player.get(i)) strike ++; + else if (computer.contains(player.get(i))) ball ++; + } - - return new GameStatus(0,0); + return new GameStatus(ball, strike); } - - } From dcc759fcec847e6ec184f3c7d44e0d2888f8a3cd Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:56:54 +0900 Subject: [PATCH 09/29] feat : implement UserInput --- src/main/java/baseball/inout/UserInput.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/baseball/inout/UserInput.java b/src/main/java/baseball/inout/UserInput.java index e1d6af3fa4..120444aa10 100644 --- a/src/main/java/baseball/inout/UserInput.java +++ b/src/main/java/baseball/inout/UserInput.java @@ -1,6 +1,7 @@ package baseball.inout; +import java.util.ArrayList; import java.util.List; import static camp.nextstep.edu.missionutils.Console.readLine; @@ -12,18 +13,26 @@ public class UserInput { */ public List getNum() { System.out.print("숫자를 입력해주세요 : "); - String input = readLine(); + String input = readLine().trim(); // CheckRegex.isPlayball -// Integer.parseInt(input); - return List.of(0,0,0); + + List numbers = new ArrayList<>(); + for (int i = 0; i < 3; i++) + numbers.add(input.charAt(i) - '0'); + + return numbers; } /** * 게임 진행여부 입력 */ public boolean isContinue() { - return false; + System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + String input = readLine().trim(); + // regex + + return input.equals("1"); } } From 483d07344af55b0eda2cd81d9f7a8fefd4fc8efc Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:57:02 +0900 Subject: [PATCH 10/29] feat : implement UserOutput --- src/main/java/baseball/inout/UserOutput.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/baseball/inout/UserOutput.java b/src/main/java/baseball/inout/UserOutput.java index bb6524a44f..2cfd75fe0c 100644 --- a/src/main/java/baseball/inout/UserOutput.java +++ b/src/main/java/baseball/inout/UserOutput.java @@ -4,16 +4,24 @@ public class UserOutput { - public void initMessage(){ - + public void initMessage() { + System.out.println("숫자 야구 게임을 시작합니다."); } - public void statusMessage(GameStatus status){ + public void statusMessage(GameStatus status) { + if (status.ball == 0 && status.strike == 0) + System.out.println("낫싱"); + else if (status.ball == 0) + System.out.println(status.strike + "스트라이크"); + else if (status.strike == 0) + System.out.println(status.ball + "볼"); + else + System.out.println(status.ball + "볼 " + status.strike + "스트라이크"); } - public void endMessage(){ - + public void endMessage() { + System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); } } From 6a580a17a38758fe881b13aa332c4ef4416982a6 Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 19:57:13 +0900 Subject: [PATCH 11/29] feat : implement Application --- src/main/java/baseball/Application.java | 39 ++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index dd95a34214..0c1dfef90a 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -1,7 +1,44 @@ package baseball; +import baseball.game.GameStatus; +import baseball.game.SingleGame; +import baseball.inout.UserInput; +import baseball.inout.UserOutput; + +import java.util.List; + public class Application { + private static UserInput userInput; + private static UserOutput userOutput; + public static void main(String[] args) { - // TODO: 프로그램 구현 + boolean isContinue = true; + + startGame(); + while (isContinue) + isContinue = playSingleGame(); + } + + private static void startGame() { + userInput = new UserInput(); + userOutput = new UserOutput(); + + userOutput.initMessage(); + } + + private static boolean playSingleGame() { + SingleGame singleGame = new SingleGame(); + + boolean isCorrect = false; + + while (!isCorrect) { + List playNum = userInput.getNum(); + GameStatus gameStatus = singleGame.singleTurn(playNum); + userOutput.statusMessage(gameStatus); + isCorrect = gameStatus.isCorrect(); + } + + userOutput.endMessage(); + return userInput.isContinue(); } } From 9a837a4bdf22c752c00346020db6d45b8f8149ae Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 21:46:58 +0900 Subject: [PATCH 12/29] feat : add regex to check user input --- src/main/java/baseball/inout/CheckRegex.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/baseball/inout/CheckRegex.java b/src/main/java/baseball/inout/CheckRegex.java index f9b73a6ecd..9355e724db 100644 --- a/src/main/java/baseball/inout/CheckRegex.java +++ b/src/main/java/baseball/inout/CheckRegex.java @@ -1,4 +1,18 @@ package baseball.inout; public class CheckRegex { + + public static boolean isThreeDigit (String test) { + String pattern = "\\d{3}"; + return test.matches(pattern); + } + public static boolean isBaseball (String test) { + String pattern = "^(?!.*(.).*\\1)\\d{3}$"; + return test.matches(pattern); + } + + public static boolean isCommand (String test) { + String pattern = "[12]"; + return test.matches(pattern); + } } From d6fb92ae1466a5937d2b70082c1901854f5a451f Mon Sep 17 00:00:00 2001 From: raycho Date: Sat, 25 Mar 2023 21:47:47 +0900 Subject: [PATCH 13/29] feat : add code for checking exceptions in UserInput --- src/main/java/baseball/inout/UserInput.java | 7 ++++++- src/test/java/baseball/inout/UserInputTest.java | 3 +-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/baseball/inout/UserInput.java b/src/main/java/baseball/inout/UserInput.java index 120444aa10..c8a41a1068 100644 --- a/src/main/java/baseball/inout/UserInput.java +++ b/src/main/java/baseball/inout/UserInput.java @@ -15,7 +15,10 @@ public List getNum() { System.out.print("숫자를 입력해주세요 : "); String input = readLine().trim(); -// CheckRegex.isPlayball + if (!CheckRegex.isThreeDigit(input)) + throw new IllegalArgumentException("3자리의 숫자를 입력해야 합니다."); + if (!CheckRegex.isBaseball(input)) + throw new IllegalArgumentException("중복이 없는 3자리의 숫자를 입력해야 합니다."); List numbers = new ArrayList<>(); for (int i = 0; i < 3; i++) @@ -31,6 +34,8 @@ public boolean isContinue() { System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); String input = readLine().trim(); // regex + if (!CheckRegex.isCommand(input)) + throw new IllegalArgumentException("1 또는 2를 입력해야 합니다."); return input.equals("1"); } diff --git a/src/test/java/baseball/inout/UserInputTest.java b/src/test/java/baseball/inout/UserInputTest.java index ec01987904..f3ac9ba52f 100644 --- a/src/test/java/baseball/inout/UserInputTest.java +++ b/src/test/java/baseball/inout/UserInputTest.java @@ -35,9 +35,8 @@ void restoresStreams() { System.setOut(System.out); // 원상복귀 } - @Test - @DisplayName("숫자 입력 동작 테스트") @ParameterizedTest + @DisplayName("숫자 입력 동작 테스트") @ValueSource(strings = {"123", "145", "671"}) void getNum(String input) { // given From 756a63331410996343e53be41aa9ec1ca704b554 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:14:37 +0900 Subject: [PATCH 14/29] test : add GameBall test --- .../baseball/game/model/GameBallTest.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/test/java/baseball/game/model/GameBallTest.java diff --git a/src/test/java/baseball/game/model/GameBallTest.java b/src/test/java/baseball/game/model/GameBallTest.java new file mode 100644 index 0000000000..123c4040e6 --- /dev/null +++ b/src/test/java/baseball/game/model/GameBallTest.java @@ -0,0 +1,59 @@ +package baseball.game.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +class GameBallTest { + + @ParameterizedTest + @DisplayName("GameBall 생성 동작 테스트") + @ValueSource(strings = {"123", "145", "671"}) + void createBall(String input) { + // given + + // when & then + assertThatCode( () -> { + GameBall.createBall(input); + }).doesNotThrowAnyException(); + } + + + @ParameterizedTest + @DisplayName("GameBall 생성 예외 테스트") + @ValueSource(strings = {"111", "122", "1325", "a11"}) + void createBallErrors(String input) { + // given + + // when & then + assertThatThrownBy( () -> { + GameBall.createBall(input); + }).isInstanceOf(IllegalArgumentException.class); + } + + @ParameterizedTest + @DisplayName("getStatus 생성 동작 테스트") + @CsvSource(value = {"456:0:0", + "516:1:0", "156:0:1", "231:3:0", "123:0:3"}, delimiter = ':' + ) + void getStatus(String input, int ball, int strike) { + // given + GameBall computer = GameBall.createBall("123"); + GameBall player = GameBall.createBall(input); + + // when + GameStatus gameStatus = computer.getStatus(player); + + // then + assertThat(gameStatus).isEqualTo(new GameStatus(ball, strike)); + } + +} \ No newline at end of file From 951f6b78ecb8f2cc2f2cc4bd67d4a39bd0044802 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:15:03 +0900 Subject: [PATCH 15/29] test : delete UserInputTest.java --- .../java/baseball/inout/UserInputTest.java | 102 ------------------ 1 file changed, 102 deletions(-) delete mode 100644 src/test/java/baseball/inout/UserInputTest.java diff --git a/src/test/java/baseball/inout/UserInputTest.java b/src/test/java/baseball/inout/UserInputTest.java deleted file mode 100644 index f3ac9ba52f..0000000000 --- a/src/test/java/baseball/inout/UserInputTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package baseball.inout; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -class UserInputTest { - private static ByteArrayOutputStream outputMessage; - private static ByteArrayInputStream inputMessage; - private static UserInput userInput; - - @BeforeEach - void setUpStreams() { - outputMessage = new ByteArrayOutputStream(); // OutputStream 생성 - System.setOut(new PrintStream(outputMessage)); // 생성한 OutputStream 으로 설정 - - userInput = new UserInput(); - } - - @AfterEach - void restoresStreams() { - System.setOut(System.out); // 원상복귀 - } - - @ParameterizedTest - @DisplayName("숫자 입력 동작 테스트") - @ValueSource(strings = {"123", "145", "671"}) - void getNum(String input) { - // given - enterInput(input); - List compare = new ArrayList<>(); - for (int i = 0; i < 3; i++) - compare.add( input.charAt(i) - '0'); - - // when - List list = userInput.getNum(); - - // then - assertThat(list).isEqualTo(compare); - } - - - @ParameterizedTest - @DisplayName("숫자 입력 예외 테스트") - @ValueSource(strings = {"111", "122", "1325", "a11"}) - void getNumErrors(String input) { - // given - enterInput(input); - - // then - assertThatThrownBy( () -> { - userInput.getNum(); - }).isInstanceOf(IllegalArgumentException.class); - } - - - @ParameterizedTest - @DisplayName("게임진행 입력 동작 테스트") - @ValueSource(strings = {"1", "2"}) - void isContinue(String input) { - // given - enterInput(input); - - // when - boolean cmd = userInput.isContinue(); - - // then - assertThat(cmd).isEqualTo( input.equals("1") ); - } - - - @ParameterizedTest - @DisplayName("게임진행 입력 예외 테스트") - @ValueSource(strings = {"111", "3", "0", "a"}) - void isContinueError(String input) { - // given - enterInput(input); - - // then - assertThatThrownBy( () -> { - userInput.isContinue(); - }).isInstanceOf(IllegalArgumentException.class); - } - - void enterInput(String input){ - inputMessage = new ByteArrayInputStream(input.getBytes()); - System.setIn(inputMessage); - } -} \ No newline at end of file From 21696076b1c9f4e00ca808bbe745b5772319bd34 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:15:27 +0900 Subject: [PATCH 16/29] chore : edit method name --- src/main/java/baseball/inout/UserOutput.java | 6 +++--- src/test/java/baseball/inout/UserOutputTest.java | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/baseball/inout/UserOutput.java b/src/main/java/baseball/inout/UserOutput.java index 2cfd75fe0c..cf3c37f101 100644 --- a/src/main/java/baseball/inout/UserOutput.java +++ b/src/main/java/baseball/inout/UserOutput.java @@ -1,6 +1,6 @@ package baseball.inout; -import baseball.game.GameStatus; +import baseball.game.model.GameStatus; public class UserOutput { @@ -8,7 +8,7 @@ public void initMessage() { System.out.println("숫자 야구 게임을 시작합니다."); } - public void statusMessage(GameStatus status) { + public void printStatus(GameStatus status) { if (status.ball == 0 && status.strike == 0) System.out.println("낫싱"); else if (status.ball == 0) @@ -20,7 +20,7 @@ else if (status.strike == 0) } - public void endMessage() { + public void printEndMessage() { System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); } diff --git a/src/test/java/baseball/inout/UserOutputTest.java b/src/test/java/baseball/inout/UserOutputTest.java index 8fcd65a538..70da70c73c 100644 --- a/src/test/java/baseball/inout/UserOutputTest.java +++ b/src/test/java/baseball/inout/UserOutputTest.java @@ -1,6 +1,6 @@ package baseball.inout; -import baseball.game.GameStatus; +import baseball.game.model.GameStatus; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -12,7 +12,6 @@ import java.io.PrintStream; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; class UserOutputTest { private static ByteArrayOutputStream outputMessage; @@ -46,7 +45,7 @@ void initMessage() { @ValueSource(ints = {0, 1, 2}) void statusMessage(int strike) { // when - output.statusMessage(new GameStatus(1, strike)); + output.printStatus(new GameStatus(1, strike)); // then if (strike == 0) @@ -61,7 +60,7 @@ void statusMessage(int strike) { @ValueSource(ints = {0, 3}) void statusMessage2(int strike) { // when - output.statusMessage(new GameStatus(0, strike)); + output.printStatus(new GameStatus(0, strike)); // then if (strike == 0) @@ -73,7 +72,7 @@ void statusMessage2(int strike) { @Test void endMessage() { // when - output.endMessage(); + output.printEndMessage(); // then assertThat(outputMessage.toString().trim()).isEqualTo("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); From 3198cf6960cc424dbfc94ff225928b097420c2a6 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:16:07 +0900 Subject: [PATCH 17/29] refactor : edit output type --- src/main/java/baseball/inout/UserInput.java | 39 ++++++++++++--------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/java/baseball/inout/UserInput.java b/src/main/java/baseball/inout/UserInput.java index c8a41a1068..0256177492 100644 --- a/src/main/java/baseball/inout/UserInput.java +++ b/src/main/java/baseball/inout/UserInput.java @@ -1,6 +1,8 @@ package baseball.inout; +import baseball.util.CheckRegex; + import java.util.ArrayList; import java.util.List; @@ -11,33 +13,36 @@ public class UserInput { /** * 숫자 입력 */ - public List getNum() { + public String getNum() { System.out.print("숫자를 입력해주세요 : "); String input = readLine().trim(); - - if (!CheckRegex.isThreeDigit(input)) - throw new IllegalArgumentException("3자리의 숫자를 입력해야 합니다."); - if (!CheckRegex.isBaseball(input)) - throw new IllegalArgumentException("중복이 없는 3자리의 숫자를 입력해야 합니다."); - - List numbers = new ArrayList<>(); - for (int i = 0; i < 3; i++) - numbers.add(input.charAt(i) - '0'); - - return numbers; + return input; + +// if (!CheckRegex.isThreeDigit(input)) +// throw new IllegalArgumentException("3자리의 숫자를 입력해야 합니다."); +// if (!CheckRegex.isBaseball(input)) +// throw new IllegalArgumentException("중복이 없는 3자리의 숫자를 입력해야 합니다."); +// +// List numbers = new ArrayList<>(); +// for (int i = 0; i < 3; i++) +// numbers.add(input.charAt(i) - '0'); +// +// return numbers; } /** * 게임 진행여부 입력 */ - public boolean isContinue() { + public String isContinue() { System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); String input = readLine().trim(); - // regex - if (!CheckRegex.isCommand(input)) - throw new IllegalArgumentException("1 또는 2를 입력해야 합니다."); + return input; - return input.equals("1"); +// // regex +// if (!CheckRegex.isCommand(input)) +// throw new IllegalArgumentException("1 또는 2를 입력해야 합니다."); +// +// return input.equals("1"); } } From fec88027f035fe24396cd74244112fde8450d086 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:44:36 +0900 Subject: [PATCH 18/29] refactor : edit UserInput return type --- src/main/java/baseball/inout/UserInput.java | 22 --------------------- 1 file changed, 22 deletions(-) diff --git a/src/main/java/baseball/inout/UserInput.java b/src/main/java/baseball/inout/UserInput.java index 0256177492..8187328528 100644 --- a/src/main/java/baseball/inout/UserInput.java +++ b/src/main/java/baseball/inout/UserInput.java @@ -1,11 +1,6 @@ package baseball.inout; -import baseball.util.CheckRegex; - -import java.util.ArrayList; -import java.util.List; - import static camp.nextstep.edu.missionutils.Console.readLine; public class UserInput { @@ -17,17 +12,6 @@ public String getNum() { System.out.print("숫자를 입력해주세요 : "); String input = readLine().trim(); return input; - -// if (!CheckRegex.isThreeDigit(input)) -// throw new IllegalArgumentException("3자리의 숫자를 입력해야 합니다."); -// if (!CheckRegex.isBaseball(input)) -// throw new IllegalArgumentException("중복이 없는 3자리의 숫자를 입력해야 합니다."); -// -// List numbers = new ArrayList<>(); -// for (int i = 0; i < 3; i++) -// numbers.add(input.charAt(i) - '0'); -// -// return numbers; } /** @@ -37,12 +21,6 @@ public String isContinue() { System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); String input = readLine().trim(); return input; - -// // regex -// if (!CheckRegex.isCommand(input)) -// throw new IllegalArgumentException("1 또는 2를 입력해야 합니다."); -// -// return input.equals("1"); } } From 93366965962a06937db56198b8560c69fe8433df Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:45:19 +0900 Subject: [PATCH 19/29] refactor : refactor game code --- src/main/java/baseball/game/GameService.java | 42 +++++++++++++++ src/main/java/baseball/game/SingleGame.java | 32 ------------ .../java/baseball/game/SingleGameTest.java | 51 ------------------- 3 files changed, 42 insertions(+), 83 deletions(-) create mode 100644 src/main/java/baseball/game/GameService.java delete mode 100644 src/main/java/baseball/game/SingleGame.java delete mode 100644 src/test/java/baseball/game/SingleGameTest.java diff --git a/src/main/java/baseball/game/GameService.java b/src/main/java/baseball/game/GameService.java new file mode 100644 index 0000000000..0e4382afe7 --- /dev/null +++ b/src/main/java/baseball/game/GameService.java @@ -0,0 +1,42 @@ +package baseball.game; + +import baseball.game.model.GameBall; +import baseball.game.model.GameCommand; +import baseball.game.model.GameStatus; +import baseball.inout.UserInput; +import baseball.inout.UserOutput; +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.ArrayList; +import java.util.List; + +public class GameService { + + private static UserInput userInput; + private static UserOutput userOutput; + + GameBall computer; + + public GameService() { + computer = GameBall.createRandomBall(); + userInput = new UserInput(); + userOutput = new UserOutput(); + } + + public void playSingleGame() { + boolean isContinue = true; + + while (isContinue) { + GameBall playNum = GameBall.createBall(userInput.getNum()); + GameStatus gameStatus = computer.getStatus(playNum); + userOutput.printStatus(gameStatus); + isContinue = gameStatus.isContinue(); + } + userOutput.printEndMessage(); + } + + public GameCommand getCommand() { + return GameCommand.getCommand(userInput.isContinue()); + } + +} diff --git a/src/main/java/baseball/game/SingleGame.java b/src/main/java/baseball/game/SingleGame.java deleted file mode 100644 index c083f3680b..0000000000 --- a/src/main/java/baseball/game/SingleGame.java +++ /dev/null @@ -1,32 +0,0 @@ -package baseball.game; - -import camp.nextstep.edu.missionutils.Randoms; - -import java.util.ArrayList; -import java.util.List; - -public class SingleGame { - List computer = new ArrayList<>(); - - public SingleGame() { - while(computer.size() < 3) { - int randomNumber = Randoms.pickNumberInRange(1, 9); - if (!computer.contains(randomNumber)) - computer.add(randomNumber); - } - } - - public void setComputer (List list) { - computer = list; - } - - public GameStatus singleTurn(List player){ - int strike = 0, ball = 0; - for (int i = 0; i < player.size(); i++) { - if (computer.get(i) == player.get(i)) strike ++; - else if (computer.contains(player.get(i))) ball ++; - } - - return new GameStatus(ball, strike); - } -} diff --git a/src/test/java/baseball/game/SingleGameTest.java b/src/test/java/baseball/game/SingleGameTest.java deleted file mode 100644 index 34bf6ab246..0000000000 --- a/src/test/java/baseball/game/SingleGameTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package baseball.game; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import java.util.ArrayList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -class SingleGameTest { - SingleGame singleGame; - - @BeforeAll - void setSingleGame() { - singleGame = new SingleGame(); - singleGame.setComputer(List.of(1, 2, 3)); - } - - List> inputs = new ArrayList<>(List.of( - List.of(4, 5, 6), // n - List.of(4, 5, 1), // 1b - List.of(1, 5, 6), // 1s - List.of(1, 5, 2), // 1b1s - List.of(1, 2, 3) // 3s - )); - List expects = new ArrayList<>(List.of( - new GameStatus(0, 0), - new GameStatus(1, 0), - new GameStatus(0, 1), - new GameStatus(1, 1), - new GameStatus(0, 3) - )); - - @ParameterizedTest - @DisplayName("singleTurn 동작 테스트") - @ValueSource(ints = {0, 1, 2, 3, 4}) - void singleTurn(int i) { - // when - GameStatus status = singleGame.singleTurn(inputs.get(i)); - - // then - assertThat(status).isEqualTo(expects.get(i)); - } -} \ No newline at end of file From d5d7ade5e7e910be259050f15fa6a64a2957bee0 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:45:55 +0900 Subject: [PATCH 20/29] test : add GameCommand test --- .../baseball/game/model/GameCommandTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/baseball/game/model/GameCommandTest.java diff --git a/src/test/java/baseball/game/model/GameCommandTest.java b/src/test/java/baseball/game/model/GameCommandTest.java new file mode 100644 index 0000000000..e3dfe968dd --- /dev/null +++ b/src/test/java/baseball/game/model/GameCommandTest.java @@ -0,0 +1,52 @@ +package baseball.game.model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class GameCommandTest { + + @Test + void getCommand() { + } + + @Test + void isContinue() { + } + + + + @ParameterizedTest + @DisplayName("게임진행 입력 동작 테스트") + @ValueSource(strings = {"1", "2"}) + void getCommand(String input) { + // given + + // when + GameCommand cmd = GameCommand.getCommand(input); + + // then + if (input.equals("1")) + assertThat(cmd).isEqualTo(GameCommand.CONTINUE); + else + assertThat(cmd).isEqualTo(GameCommand.QUIT); + } + + + @ParameterizedTest + @DisplayName("게임진행 입력 예외 테스트") + @ValueSource(strings = {"111", "3", "0", "a"}) + void getCommandError(String input) { + // given + + // then + assertThatThrownBy( () -> { + GameCommand.getCommand(input); + }).isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file From 44721812b49096908aa2e47c08c99c172d89a61f Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:46:07 +0900 Subject: [PATCH 21/29] feat : add GameCommand --- .../java/baseball/game/model/GameCommand.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/baseball/game/model/GameCommand.java diff --git a/src/main/java/baseball/game/model/GameCommand.java b/src/main/java/baseball/game/model/GameCommand.java new file mode 100644 index 0000000000..3e3805ec47 --- /dev/null +++ b/src/main/java/baseball/game/model/GameCommand.java @@ -0,0 +1,35 @@ +package baseball.game.model; + +import java.util.Arrays; + +public enum GameCommand { + QUIT(2), + CONTINUE(1); + + private final int number; + + GameCommand(int number) { + this.number = number; + } + + public static GameCommand getCommand (String userInput) { + int commandNumber ; + try{ + commandNumber = Integer.parseInt(userInput); + } + catch (NumberFormatException ex){ + throw new IllegalArgumentException("숫자를 입력해야 합니다."); + } + + GameCommand command = Arrays.stream(values()) + .filter(value -> value.number == commandNumber) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("올바른 숫자가 입력되지 않았습니다.")); + + return command; + } + + public boolean isContinue() { + return this == CONTINUE; + } +} From cc19a60eff2b55e4d09b195ee01b012aee1d4ed2 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:46:22 +0900 Subject: [PATCH 22/29] feat : add GameBall --- .../java/baseball/game/model/GameBall.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/main/java/baseball/game/model/GameBall.java diff --git a/src/main/java/baseball/game/model/GameBall.java b/src/main/java/baseball/game/model/GameBall.java new file mode 100644 index 0000000000..5f939e4900 --- /dev/null +++ b/src/main/java/baseball/game/model/GameBall.java @@ -0,0 +1,74 @@ +package baseball.game.model; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.*; + +public class GameBall { + + private final static int BALL_MAX = 9; + private final static int BALL_MIN = 1; + private final static int BALL_NUM = 3; + + private List ballNumbers; + + private GameBall(List ballNumbers) { + this.ballNumbers = ballNumbers; + } + + public static GameBall createBall(String userInput){ + if (isInvalidLength(userInput)) + throw new IllegalArgumentException("3자리의 숫자를 입력해야 합니다."); + if (isInvalidRange(userInput)) + throw new IllegalArgumentException("숫자의 범위가 올바르지 않습니다."); + + List ball = new ArrayList<>(); + for (int i = 0; i < 3; i++) + ball.add(userInput.charAt(i) - '0'); + + if (isDuplicated(ball)) + throw new IllegalArgumentException("중복이 없는 3자리의 숫자를 입력해야 합니다."); + + return new GameBall(ball); + } + + public static GameBall createRandomBall (){ + Set ball = new LinkedHashSet<>(); + + while(ball.size() < BALL_NUM) { + int randomNumber = Randoms.pickNumberInRange(1, 9); + ball.add(randomNumber); + } + + return new GameBall(new ArrayList<>(ball)); + } + + public GameStatus getStatus(GameBall other) { + int strike = 0; + int ball = 0; + + for (int i = 0; i < this.ballNumbers.size(); i++) { + if (other.ballNumbers.get(i).equals(this.ballNumbers.get(i))) strike++; + else if (other.ballNumbers.contains(this.ballNumbers.get(i))) ball++; + } + + return new GameStatus(ball, strike); + } + + private static boolean isInvalidLength(String input) { + return input.length() != BALL_NUM; + } + + private static boolean isDuplicated(List input) { + return input.size() != (new HashSet(input)).size(); + } + + private static boolean isInvalidRange(String input) { + for (int i = 0; i < input.length(); i++) { + int num = input.charAt(i) - '0'; + if (num > BALL_MAX || num < BALL_MIN) return true; + } + return false; + } + +} From 314e127310f1df697fd3b8d4f63e7159a27e9fe4 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:46:47 +0900 Subject: [PATCH 23/29] chore : edit method order of GameStatus --- src/main/java/baseball/game/{ => model}/GameStatus.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) rename src/main/java/baseball/game/{ => model}/GameStatus.java (84%) diff --git a/src/main/java/baseball/game/GameStatus.java b/src/main/java/baseball/game/model/GameStatus.java similarity index 84% rename from src/main/java/baseball/game/GameStatus.java rename to src/main/java/baseball/game/model/GameStatus.java index 2169e8afd8..3e343a3f3c 100644 --- a/src/main/java/baseball/game/GameStatus.java +++ b/src/main/java/baseball/game/model/GameStatus.java @@ -1,4 +1,4 @@ -package baseball.game; +package baseball.game.model; import java.util.Objects; @@ -11,6 +11,10 @@ public GameStatus(int ball, int strike) { this.strike = strike; } + public boolean isContinue() { + return !(strike == 3 && ball == 0); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -24,7 +28,4 @@ public int hashCode() { return Objects.hash(ball, strike); } - public boolean isCorrect() { - return (strike == 3 && ball == 0); - } } From 1b3f09b8dd5208606f6c42cb7f4947fa17fe180c Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:47:09 +0900 Subject: [PATCH 24/29] refactor : refactor main method to GameService --- src/main/java/baseball/Application.java | 40 ++++++------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index 0c1dfef90a..cb5c594f56 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -1,44 +1,22 @@ package baseball; -import baseball.game.GameStatus; -import baseball.game.SingleGame; +import baseball.game.model.GameCommand; +import baseball.game.model.GameStatus; +import baseball.game.GameService; import baseball.inout.UserInput; import baseball.inout.UserOutput; import java.util.List; public class Application { - private static UserInput userInput; - private static UserOutput userOutput; - public static void main(String[] args) { - boolean isContinue = true; - - startGame(); - while (isContinue) - isContinue = playSingleGame(); - } - - private static void startGame() { - userInput = new UserInput(); - userOutput = new UserOutput(); - - userOutput.initMessage(); - } - - private static boolean playSingleGame() { - SingleGame singleGame = new SingleGame(); - - boolean isCorrect = false; + GameCommand command = GameCommand.CONTINUE; - while (!isCorrect) { - List playNum = userInput.getNum(); - GameStatus gameStatus = singleGame.singleTurn(playNum); - userOutput.statusMessage(gameStatus); - isCorrect = gameStatus.isCorrect(); + while (command.isContinue()){ + GameService gameService = new GameService(); + gameService.playSingleGame(); + command = gameService.getCommand(); } - - userOutput.endMessage(); - return userInput.isContinue(); } + } From 7e9f562dc5eb31098ea61fb266589fad22e0104c Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:47:24 +0900 Subject: [PATCH 25/29] feat : delete Regex code --- src/main/java/baseball/inout/CheckRegex.java | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/main/java/baseball/inout/CheckRegex.java diff --git a/src/main/java/baseball/inout/CheckRegex.java b/src/main/java/baseball/inout/CheckRegex.java deleted file mode 100644 index 9355e724db..0000000000 --- a/src/main/java/baseball/inout/CheckRegex.java +++ /dev/null @@ -1,18 +0,0 @@ -package baseball.inout; - -public class CheckRegex { - - public static boolean isThreeDigit (String test) { - String pattern = "\\d{3}"; - return test.matches(pattern); - } - public static boolean isBaseball (String test) { - String pattern = "^(?!.*(.).*\\1)\\d{3}$"; - return test.matches(pattern); - } - - public static boolean isCommand (String test) { - String pattern = "[12]"; - return test.matches(pattern); - } -} From 6472f4a1e99286690a21d291a52b54a20745c7dd Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:52:09 +0900 Subject: [PATCH 26/29] feat : edit UserInput, UserOutput into static method --- src/main/java/baseball/game/GameService.java | 13 ++++--------- src/main/java/baseball/inout/UserInput.java | 7 +++++-- src/main/java/baseball/inout/UserOutput.java | 9 ++++++--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main/java/baseball/game/GameService.java b/src/main/java/baseball/game/GameService.java index 0e4382afe7..bcb0dc3726 100644 --- a/src/main/java/baseball/game/GameService.java +++ b/src/main/java/baseball/game/GameService.java @@ -12,31 +12,26 @@ public class GameService { - private static UserInput userInput; - private static UserOutput userOutput; - GameBall computer; public GameService() { computer = GameBall.createRandomBall(); - userInput = new UserInput(); - userOutput = new UserOutput(); } public void playSingleGame() { boolean isContinue = true; while (isContinue) { - GameBall playNum = GameBall.createBall(userInput.getNum()); + GameBall playNum = GameBall.createBall(UserInput.getNum()); GameStatus gameStatus = computer.getStatus(playNum); - userOutput.printStatus(gameStatus); + UserOutput.printStatus(gameStatus); isContinue = gameStatus.isContinue(); } - userOutput.printEndMessage(); + UserOutput.printEndMessage(); } public GameCommand getCommand() { - return GameCommand.getCommand(userInput.isContinue()); + return GameCommand.getCommand(UserInput.isContinue()); } } diff --git a/src/main/java/baseball/inout/UserInput.java b/src/main/java/baseball/inout/UserInput.java index 8187328528..47205db637 100644 --- a/src/main/java/baseball/inout/UserInput.java +++ b/src/main/java/baseball/inout/UserInput.java @@ -5,10 +5,13 @@ public class UserInput { + private UserInput() { + } + /** * 숫자 입력 */ - public String getNum() { + public static String getNum() { System.out.print("숫자를 입력해주세요 : "); String input = readLine().trim(); return input; @@ -17,7 +20,7 @@ public String getNum() { /** * 게임 진행여부 입력 */ - public String isContinue() { + public static String isContinue() { System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); String input = readLine().trim(); return input; diff --git a/src/main/java/baseball/inout/UserOutput.java b/src/main/java/baseball/inout/UserOutput.java index cf3c37f101..34a54e88c2 100644 --- a/src/main/java/baseball/inout/UserOutput.java +++ b/src/main/java/baseball/inout/UserOutput.java @@ -4,11 +4,14 @@ public class UserOutput { - public void initMessage() { + private UserOutput() { + } + + public static void initMessage() { System.out.println("숫자 야구 게임을 시작합니다."); } - public void printStatus(GameStatus status) { + public static void printStatus(GameStatus status) { if (status.ball == 0 && status.strike == 0) System.out.println("낫싱"); else if (status.ball == 0) @@ -20,7 +23,7 @@ else if (status.strike == 0) } - public void printEndMessage() { + public static void printEndMessage() { System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); } From dc3d36ff32b1bd2fdecdc3d76448f58b8e4c03db Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:56:45 +0900 Subject: [PATCH 27/29] chore : edit appearance --- src/main/java/baseball/game/model/GameCommand.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/baseball/game/model/GameCommand.java b/src/main/java/baseball/game/model/GameCommand.java index 3e3805ec47..06d74b9f50 100644 --- a/src/main/java/baseball/game/model/GameCommand.java +++ b/src/main/java/baseball/game/model/GameCommand.java @@ -12,12 +12,11 @@ public enum GameCommand { this.number = number; } - public static GameCommand getCommand (String userInput) { - int commandNumber ; - try{ + public static GameCommand getCommand(String userInput) { + int commandNumber; + try { commandNumber = Integer.parseInt(userInput); - } - catch (NumberFormatException ex){ + } catch (NumberFormatException ex) { throw new IllegalArgumentException("숫자를 입력해야 합니다."); } @@ -32,4 +31,5 @@ public static GameCommand getCommand (String userInput) { public boolean isContinue() { return this == CONTINUE; } + } From 9d64f967efe9248622f9eb74ebca0821c8618b4c Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:57:01 +0900 Subject: [PATCH 28/29] test : edit UserOutputTest --- src/test/java/baseball/inout/UserOutputTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/test/java/baseball/inout/UserOutputTest.java b/src/test/java/baseball/inout/UserOutputTest.java index 70da70c73c..c79efa9e91 100644 --- a/src/test/java/baseball/inout/UserOutputTest.java +++ b/src/test/java/baseball/inout/UserOutputTest.java @@ -21,8 +21,6 @@ class UserOutputTest { void setUpStreams() { outputMessage = new ByteArrayOutputStream(); // OutputStream 생성 System.setOut(new PrintStream(outputMessage)); // 생성한 OutputStream 으로 설정 - - output = new UserOutput(); } @AfterEach @@ -33,7 +31,7 @@ void restoresStreams() { @Test void initMessage() { // when - output.initMessage(); + UserOutput.initMessage(); // then assertThat(outputMessage.toString().trim()).isEqualTo("숫자 야구 게임을 시작합니다."); @@ -45,7 +43,7 @@ void initMessage() { @ValueSource(ints = {0, 1, 2}) void statusMessage(int strike) { // when - output.printStatus(new GameStatus(1, strike)); + UserOutput.printStatus(new GameStatus(1, strike)); // then if (strike == 0) @@ -60,7 +58,7 @@ void statusMessage(int strike) { @ValueSource(ints = {0, 3}) void statusMessage2(int strike) { // when - output.printStatus(new GameStatus(0, strike)); + UserOutput.printStatus(new GameStatus(0, strike)); // then if (strike == 0) @@ -72,7 +70,7 @@ void statusMessage2(int strike) { @Test void endMessage() { // when - output.printEndMessage(); + UserOutput.printEndMessage(); // then assertThat(outputMessage.toString().trim()).isEqualTo("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); From af4d49d136985e3081f36929031f4a100f6271f2 Mon Sep 17 00:00:00 2001 From: raycho Date: Mon, 27 Mar 2023 20:57:20 +0900 Subject: [PATCH 29/29] chore : edit method --- src/main/java/baseball/inout/UserInput.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/baseball/inout/UserInput.java b/src/main/java/baseball/inout/UserInput.java index 47205db637..16216d48f4 100644 --- a/src/main/java/baseball/inout/UserInput.java +++ b/src/main/java/baseball/inout/UserInput.java @@ -1,7 +1,7 @@ package baseball.inout; -import static camp.nextstep.edu.missionutils.Console.readLine; +import camp.nextstep.edu.missionutils.Console; public class UserInput { @@ -13,7 +13,7 @@ private UserInput() { */ public static String getNum() { System.out.print("숫자를 입력해주세요 : "); - String input = readLine().trim(); + String input = Console.readLine().trim(); return input; } @@ -22,7 +22,7 @@ public static String getNum() { */ public static String isContinue() { System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); - String input = readLine().trim(); + String input = Console.readLine().trim(); return input; }