From 529a49fc9e63ce134dac2b037616968c507002f7 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Sun, 5 May 2024 18:09:43 +0900 Subject: [PATCH 01/29] =?UTF-8?q?README=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=9E=91=EC=84=B1?= 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..054a80a1 100644 --- a/README.md +++ b/README.md @@ -1 +1,17 @@ -# java-baseball-precourse \ No newline at end of file +# java-baseball-precourse + +구현할 기능 목록 +1. 정답 (서로 다른 숫자 3개로 이루어진 3자리수) 생성 +2. 사용자로부터 3자리수 입력받기 + + 다음과 같은 경우 IllegalArgumentException 발생 -> 애플리케이션 종료 + 1. 정수 외의 입력 + 2. 3자리 수 이외의 입력 + +3. 정답과 사용자입력을 비교하여 결과 계산 (낫싱, 1볼1스트라이크 등) +4. 3의 결과 출력 +5. 정답(3스트라이크)인 경우 게임 종료 +6. 사용자 선택 (1/ 2) 입력 받기 + 1. 1을 입력 받은 경우 다음 게임 시작 (반복) + 2. 2를 입력받은 경우 애플리케이션 종료 + \ No newline at end of file From 9f84baae8b4a6a0fafbcb26945834664644f5dcd Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Sun, 5 May 2024 23:06:07 +0900 Subject: [PATCH 02/29] =?UTF-8?q?=EC=A0=95=EB=8B=B5=20(=EC=84=9C=EB=A1=9C?= =?UTF-8?q?=20=EB=8B=A4=EB=A5=B8=20=EC=88=AB=EC=9E=90=203=EA=B0=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=A3=A8=EC=96=B4=EC=A7=84=203=EC=9E=90?= =?UTF-8?q?=EB=A6=AC=EC=88=98)=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/RandomAnswerGenerator.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/java/game/RandomAnswerGenerator.java diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java new file mode 100644 index 00000000..36fd2c3a --- /dev/null +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -0,0 +1,27 @@ +package game; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class RandomAnswerGenerator { + private static int nDigit = 3; + private List digits = null; + + public RandomAnswerGenerator() { + digits = new ArrayList<>(9); + for (int i = 1; i < 10; i++) { + digits.add(i); + } + } + + public String getAnswerAsString() { + String answer = ""; + for (int i = 0; i < nDigit; i ++) { + Collections.shuffle(digits); + int d = digits.remove(digits.size() - 1); + answer += String.valueOf(d); + } + return answer; + } +} From 702d1f3ce783d8c6cc58c1101bfc6154e97f34f8 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 00:08:31 +0900 Subject: [PATCH 03/29] feat : receive user input Add feature to receive user input in the application Add user input validation functionality to the application --- src/main/java/app/Application.java | 14 ++++++++ src/main/java/game/Game.java | 35 +++++++++++++++++++ src/main/java/game/GameParameters.java | 8 +++++ src/main/java/game/RandomAnswerGenerator.java | 4 +-- src/main/java/utils/UserInputChecker.java | 29 +++++++++++++++ 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/main/java/app/Application.java create mode 100644 src/main/java/game/Game.java create mode 100644 src/main/java/game/GameParameters.java create mode 100644 src/main/java/utils/UserInputChecker.java diff --git a/src/main/java/app/Application.java b/src/main/java/app/Application.java new file mode 100644 index 00000000..c1374d6e --- /dev/null +++ b/src/main/java/app/Application.java @@ -0,0 +1,14 @@ +package app; + +import game.Game; + +public class Application { + public static void main(String[] args) { + Game game = new Game(); + try { + game.run(); + } catch (IllegalArgumentException e) { + System.out.println("IllegalArgumentException"); + } + } +} diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java new file mode 100644 index 00000000..0a9b3c4c --- /dev/null +++ b/src/main/java/game/Game.java @@ -0,0 +1,35 @@ +package game; + +import utils.UserInputChecker; +import view.View; + +public class Game { + + private static UserInputChecker userInputChecker = null; + private RandomAnswerGenerator randomAnswerGenerator = null; + + private String answer = null; + + public Game() { + userInputChecker = new UserInputChecker(); + randomAnswerGenerator = new RandomAnswerGenerator(); + answer = randomAnswerGenerator.getAnswerAsString(); + System.out.println(answer); + } + + public int run() { + while(true) { + String userGuess; + boolean correct = false; + userGuess = View.getUserGuess(); + try { + UserInputChecker.isValidGuess(userGuess); + } catch (IllegalArgumentException e) { + throw e; + } + + } + } + + +} diff --git a/src/main/java/game/GameParameters.java b/src/main/java/game/GameParameters.java new file mode 100644 index 00000000..2969a5dc --- /dev/null +++ b/src/main/java/game/GameParameters.java @@ -0,0 +1,8 @@ +package game; + +public class GameParameters { + public static final int nDigit = 3; + + private GameParameters() { + } +} diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java index 36fd2c3a..3bbd1d02 100644 --- a/src/main/java/game/RandomAnswerGenerator.java +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -5,7 +5,7 @@ import java.util.List; public class RandomAnswerGenerator { - private static int nDigit = 3; + private List digits = null; public RandomAnswerGenerator() { @@ -17,7 +17,7 @@ public RandomAnswerGenerator() { public String getAnswerAsString() { String answer = ""; - for (int i = 0; i < nDigit; i ++) { + for (int i = 0; i < GameParameters.nDigit; i ++) { Collections.shuffle(digits); int d = digits.remove(digits.size() - 1); answer += String.valueOf(d); diff --git a/src/main/java/utils/UserInputChecker.java b/src/main/java/utils/UserInputChecker.java new file mode 100644 index 00000000..64f6072d --- /dev/null +++ b/src/main/java/utils/UserInputChecker.java @@ -0,0 +1,29 @@ +package utils; + +import game.GameParameters; + +public class UserInputChecker { + public UserInputChecker () { + + } + + public static void isValidGuess(String userGuess) throws IllegalArgumentException { + if (userGuess.length() != GameParameters.nDigit) { + // return false; + throw new IllegalArgumentException("자릿수를 확인하세요 input = " + userGuess); + } + + for (int i = 0; i < GameParameters.nDigit; i++) { + if (!Character.isDigit(userGuess.charAt(i))) { + // return false; + throw new IllegalArgumentException("정수만 입력해주세요 input = " + userGuess); + } + } + + //return true; + } + + public static boolean isValidChoice(int userChoice) { + return (userChoice == 1 || userChoice == 2); + } +} From 5848cef74a0c5f379017ea07f1ffdcf3722b9950 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 00:28:17 +0900 Subject: [PATCH 04/29] feat : evaluate user guess Add feature to compare user guess with correct answer --- src/main/java/game/Game.java | 24 +++++++++++++++++++----- src/main/java/view/View.java | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/main/java/view/View.java diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 0a9b3c4c..a2c6511f 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -17,17 +17,31 @@ public Game() { System.out.println(answer); } - public int run() { - while(true) { - String userGuess; - boolean correct = false; + private int[] evaluate(String userGuess) { + int [] ballAndStrike = new int[2]; + + for (int i = 0; i < GameParameters.nDigit; i++) { + int idx = answer.indexOf(userGuess.charAt(i)); + if (idx == i) { + ballAndStrike[1]++; + } else if (idx != -1) { + ballAndStrike[0]++; + } + } + return ballAndStrike; + } + + public void run() { + String userGuess; + boolean correct = false; + while (true) { userGuess = View.getUserGuess(); try { UserInputChecker.isValidGuess(userGuess); } catch (IllegalArgumentException e) { throw e; } - + int[] ballAndStrike = evaluate(userGuess); } } diff --git a/src/main/java/view/View.java b/src/main/java/view/View.java new file mode 100644 index 00000000..36fe4712 --- /dev/null +++ b/src/main/java/view/View.java @@ -0,0 +1,32 @@ +package view; + +import java.util.Scanner; + +public class View { + private static final Scanner scanner = new Scanner(System.in); + + private View() { + + } + + public static String getUserGuess() { + String strUserInput; + System.out.print("숫자를 입력하세요 : "); + strUserInput = scanner.nextLine(); + return strUserInput; + } + + public static void printResult(int nBall, int nStrike) { + if (nBall == 0 && nStrike == 0) { + System.out.println("낫싱"); + } else { + if (nBall > 0) { + System.out.print(nBall + "볼"); + } + if (nStrike > 0) { + System.out.print(nStrike + "스트라이크"); + } + System.out.println(); + } + } +} From 26d874bb99cf6474f2fbdb1f3273471d5b9b65c3 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 00:46:24 +0900 Subject: [PATCH 05/29] feat : show evaluation result - Add feature show the evaluation result --- src/main/java/game/Game.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index a2c6511f..490ed350 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -42,6 +42,7 @@ public void run() { throw e; } int[] ballAndStrike = evaluate(userGuess); + View.printResult(ballAndStrike[0], ballAndStrike[1]); } } From 8d90dae730e9d9c164b21a36af83772bb7979582 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 00:48:44 +0900 Subject: [PATCH 06/29] refactor : refactor View - refactor View.printResult --- src/main/java/view/View.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/view/View.java b/src/main/java/view/View.java index 36fe4712..98de636f 100644 --- a/src/main/java/view/View.java +++ b/src/main/java/view/View.java @@ -19,14 +19,14 @@ public static String getUserGuess() { public static void printResult(int nBall, int nStrike) { if (nBall == 0 && nStrike == 0) { System.out.println("낫싱"); - } else { - if (nBall > 0) { - System.out.print(nBall + "볼"); - } - if (nStrike > 0) { - System.out.print(nStrike + "스트라이크"); - } - System.out.println(); + return; } + if (nBall > 0) { + System.out.print(nBall + "볼"); + } + if (nStrike > 0) { + System.out.print(nStrike + "스트라이크"); + } + System.out.println(); } } From fdc95458aa41945c09b7d4f00df485555eb42094 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 00:56:52 +0900 Subject: [PATCH 07/29] style : apply google java style guide --- src/main/java/app/Application.java | 1 + src/main/java/game/Game.java | 2 +- src/main/java/game/RandomAnswerGenerator.java | 2 +- src/main/java/utils/UserInputChecker.java | 3 ++- src/main/java/view/View.java | 2 ++ 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/app/Application.java b/src/main/java/app/Application.java index c1374d6e..8fdf9bba 100644 --- a/src/main/java/app/Application.java +++ b/src/main/java/app/Application.java @@ -3,6 +3,7 @@ import game.Game; public class Application { + public static void main(String[] args) { Game game = new Game(); try { diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 490ed350..63768489 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -18,7 +18,7 @@ public Game() { } private int[] evaluate(String userGuess) { - int [] ballAndStrike = new int[2]; + int[] ballAndStrike = new int[2]; for (int i = 0; i < GameParameters.nDigit; i++) { int idx = answer.indexOf(userGuess.charAt(i)); diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java index 3bbd1d02..d98f8e46 100644 --- a/src/main/java/game/RandomAnswerGenerator.java +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -17,7 +17,7 @@ public RandomAnswerGenerator() { public String getAnswerAsString() { String answer = ""; - for (int i = 0; i < GameParameters.nDigit; i ++) { + for (int i = 0; i < GameParameters.nDigit; i++) { Collections.shuffle(digits); int d = digits.remove(digits.size() - 1); answer += String.valueOf(d); diff --git a/src/main/java/utils/UserInputChecker.java b/src/main/java/utils/UserInputChecker.java index 64f6072d..2c3a2807 100644 --- a/src/main/java/utils/UserInputChecker.java +++ b/src/main/java/utils/UserInputChecker.java @@ -3,7 +3,8 @@ import game.GameParameters; public class UserInputChecker { - public UserInputChecker () { + + public UserInputChecker() { } diff --git a/src/main/java/view/View.java b/src/main/java/view/View.java index 98de636f..ce4350fb 100644 --- a/src/main/java/view/View.java +++ b/src/main/java/view/View.java @@ -1,8 +1,10 @@ package view; +import java.io.PrintStream; import java.util.Scanner; public class View { + private static final Scanner scanner = new Scanner(System.in); private View() { From 93d79a99cdc8edd1e6c44de0347e826f3628377a Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 02:08:27 +0900 Subject: [PATCH 08/29] =?UTF-8?q?feat=20:=20=EA=B2=8C=EC=9E=84=20=EC=A2=85?= =?UTF-8?q?=EB=A3=8C,=20=EC=9E=AC=EB=8F=84=EC=A0=84=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=20=EB=B0=9B=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/View.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/view/View.java b/src/main/java/view/View.java index ce4350fb..7650efc2 100644 --- a/src/main/java/view/View.java +++ b/src/main/java/view/View.java @@ -31,4 +31,13 @@ public static void printResult(int nBall, int nStrike) { } System.out.println(); } + + public static void printCorrectAndGameOver() { + System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + } + + public static String getUserChoiceForNextGame() { + return scanner.nextLine(); + } } From 3a7c789c99284f12aa85fec3786a747a73ebad07 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 02:10:59 +0900 Subject: [PATCH 09/29] =?UTF-8?q?feat=20:=20=EA=B2=8C=EC=9E=84=20=EC=A2=85?= =?UTF-8?q?=EB=A3=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 정답 맞춘 경우 게임 종료 - 유저 입력 받아서 앱 종료 또는 재시작 --- src/main/java/game/Game.java | 31 +++++++++++++++++++------- src/main/java/game/GameParameters.java | 2 ++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 63768489..0775453c 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -1,5 +1,6 @@ package game; +import java.util.Objects; import utils.UserInputChecker; import view.View; @@ -17,6 +18,10 @@ public Game() { System.out.println(answer); } + private boolean isCorrect(int nStrike) { + return nStrike == GameParameters.nDigit; + } + private int[] evaluate(String userGuess) { int[] ballAndStrike = new int[2]; @@ -31,18 +36,28 @@ private int[] evaluate(String userGuess) { return ballAndStrike; } + private boolean doNextGame() { + View.printCorrectAndGameOver(); + String userChoice = View.getUserChoiceForNextGame(); + UserInputChecker.isValidChoice(userChoice); + + return Objects.equals(userChoice, GameParameters.nextGame); + } + public void run() { String userGuess; - boolean correct = false; - while (true) { + boolean continueGame = true; + while (continueGame) { userGuess = View.getUserGuess(); - try { - UserInputChecker.isValidGuess(userGuess); - } catch (IllegalArgumentException e) { - throw e; - } + UserInputChecker.isValidGuess(userGuess); int[] ballAndStrike = evaluate(userGuess); - View.printResult(ballAndStrike[0], ballAndStrike[1]); + int nBall = ballAndStrike[0]; + int nStrike = ballAndStrike[1]; + View.printResult(nBall, nStrike); + + if (isCorrect(nStrike)) { + continueGame = doNextGame(); + } } } diff --git a/src/main/java/game/GameParameters.java b/src/main/java/game/GameParameters.java index 2969a5dc..113c7dac 100644 --- a/src/main/java/game/GameParameters.java +++ b/src/main/java/game/GameParameters.java @@ -2,6 +2,8 @@ public class GameParameters { public static final int nDigit = 3; + public static final String nextGame = "1"; + public static final String quitGame = "2"; private GameParameters() { } From 5ba1b99568ce727f24dc198696a94a86839e8cff Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 02:14:00 +0900 Subject: [PATCH 10/29] =?UTF-8?q?fix=20:=20String=20=EB=B9=84=EA=B5=90=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=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/utils/UserInputChecker.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/utils/UserInputChecker.java b/src/main/java/utils/UserInputChecker.java index 2c3a2807..de58a47d 100644 --- a/src/main/java/utils/UserInputChecker.java +++ b/src/main/java/utils/UserInputChecker.java @@ -1,6 +1,8 @@ package utils; +import game.Game; import game.GameParameters; +import java.util.Objects; public class UserInputChecker { @@ -24,7 +26,13 @@ public static void isValidGuess(String userGuess) throws IllegalArgumentExceptio //return true; } - public static boolean isValidChoice(int userChoice) { - return (userChoice == 1 || userChoice == 2); + public static void isValidChoice(String userChoice) { + if (Objects.equals(userChoice, GameParameters.nextGame)) { + return; + } + if (Objects.equals(userChoice, GameParameters.quitGame)) { + return; + } + throw new IllegalArgumentException(); } } From 3b547481082b1643e98af4a33df29db13eb961ed Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 02:15:45 +0900 Subject: [PATCH 11/29] =?UTF-8?q?chore=20:=20main=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=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/app/Application.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/app/Application.java b/src/main/java/app/Application.java index 8fdf9bba..34e333a7 100644 --- a/src/main/java/app/Application.java +++ b/src/main/java/app/Application.java @@ -9,7 +9,7 @@ public static void main(String[] args) { try { game.run(); } catch (IllegalArgumentException e) { - System.out.println("IllegalArgumentException"); + System.out.println(e); } } } From 6865d77621a8ab1b591fcd86510beeea41e66aae Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 02:33:00 +0900 Subject: [PATCH 12/29] =?UTF-8?q?fix=20:=20=EC=A0=95=EB=8B=B5=EC=9D=B4=20?= =?UTF-8?q?=EB=B0=94=EB=80=8C=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=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/game/Game.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 0775453c..1ed0dc74 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -7,15 +7,15 @@ public class Game { private static UserInputChecker userInputChecker = null; - private RandomAnswerGenerator randomAnswerGenerator = null; private String answer = null; public Game() { userInputChecker = new UserInputChecker(); - randomAnswerGenerator = new RandomAnswerGenerator(); - answer = randomAnswerGenerator.getAnswerAsString(); - System.out.println(answer); + } + + private void setAnswer() { + answer = (new RandomAnswerGenerator()).getAnswerAsString(); } private boolean isCorrect(int nStrike) { @@ -48,6 +48,7 @@ public void run() { String userGuess; boolean continueGame = true; while (continueGame) { + setAnswer(); userGuess = View.getUserGuess(); UserInputChecker.isValidGuess(userGuess); int[] ballAndStrike = evaluate(userGuess); From fc15b3472d97f6f293c1234626285551a8b43988 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 02:41:00 +0900 Subject: [PATCH 13/29] =?UTF-8?q?refactor=20:=20UserInputChecker=20?= =?UTF-8?q?=EC=8B=B1=EA=B8=80=ED=86=A4=EC=9C=BC=EB=A1=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/Game.java | 7 ++++--- src/main/java/utils/UserInputChecker.java | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 1ed0dc74..e9e050ff 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -11,7 +11,7 @@ public class Game { private String answer = null; public Game() { - userInputChecker = new UserInputChecker(); + userInputChecker = UserInputChecker.getUserInputChecker(); } private void setAnswer() { @@ -39,7 +39,7 @@ private int[] evaluate(String userGuess) { private boolean doNextGame() { View.printCorrectAndGameOver(); String userChoice = View.getUserChoiceForNextGame(); - UserInputChecker.isValidChoice(userChoice); + userInputChecker.isValidChoice(userChoice); return Objects.equals(userChoice, GameParameters.nextGame); } @@ -49,8 +49,9 @@ public void run() { boolean continueGame = true; while (continueGame) { setAnswer(); + System.out.println(answer); userGuess = View.getUserGuess(); - UserInputChecker.isValidGuess(userGuess); + userInputChecker.isValidGuess(userGuess); int[] ballAndStrike = evaluate(userGuess); int nBall = ballAndStrike[0]; int nStrike = ballAndStrike[1]; diff --git a/src/main/java/utils/UserInputChecker.java b/src/main/java/utils/UserInputChecker.java index de58a47d..10b16e5c 100644 --- a/src/main/java/utils/UserInputChecker.java +++ b/src/main/java/utils/UserInputChecker.java @@ -6,11 +6,20 @@ public class UserInputChecker { - public UserInputChecker() { + private static UserInputChecker userInputChecker = null; + private UserInputChecker() { + + } + + public static UserInputChecker getUserInputChecker() { + if (userInputChecker == null) { + userInputChecker = new UserInputChecker(); + } + return userInputChecker; } - public static void isValidGuess(String userGuess) throws IllegalArgumentException { + public void isValidGuess(String userGuess) throws IllegalArgumentException { if (userGuess.length() != GameParameters.nDigit) { // return false; throw new IllegalArgumentException("자릿수를 확인하세요 input = " + userGuess); @@ -26,7 +35,7 @@ public static void isValidGuess(String userGuess) throws IllegalArgumentExceptio //return true; } - public static void isValidChoice(String userChoice) { + public void isValidChoice(String userChoice) { if (Objects.equals(userChoice, GameParameters.nextGame)) { return; } From 174016951cf6c09992f4bbe04481e04e3e7bdce6 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 02:58:42 +0900 Subject: [PATCH 14/29] =?UTF-8?q?refactor=20:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=ED=95=9C=20=ED=8C=90=EA=B3=BC=20=EA=B2=8C=EC=9E=84=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4(series=20of=20games)=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/Game.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index e9e050ff..ba066386 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -44,12 +44,9 @@ private boolean doNextGame() { return Objects.equals(userChoice, GameParameters.nextGame); } - public void run() { + private void runSingleGame() { String userGuess; - boolean continueGame = true; - while (continueGame) { - setAnswer(); - System.out.println(answer); + while (true) { userGuess = View.getUserGuess(); userInputChecker.isValidGuess(userGuess); int[] ballAndStrike = evaluate(userGuess); @@ -58,10 +55,18 @@ public void run() { View.printResult(nBall, nStrike); if (isCorrect(nStrike)) { - continueGame = doNextGame(); + break; } } } - + public void run() { + boolean continueGame = true; + while (continueGame) { + setAnswer(); + System.out.println(answer); + runSingleGame(); + continueGame = doNextGame(); + } + } } From 1fb92b67ac4e97e99bde037d672bcda032991693 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 03:54:43 +0900 Subject: [PATCH 15/29] =?UTF-8?q?fix=20:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=97=90=20=EC=9E=85=EB=A0=A5=EC=97=90=200=EC=9D=B4=20?= =?UTF-8?q?=ED=8F=AC=ED=95=A8=EB=90=9C=20=EA=B2=BD=EC=9A=B0=20=20IllegalAr?= =?UTF-8?q?gumentException?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/utils/UserInputChecker.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/utils/UserInputChecker.java b/src/main/java/utils/UserInputChecker.java index 10b16e5c..eed4435d 100644 --- a/src/main/java/utils/UserInputChecker.java +++ b/src/main/java/utils/UserInputChecker.java @@ -21,18 +21,15 @@ public static UserInputChecker getUserInputChecker() { public void isValidGuess(String userGuess) throws IllegalArgumentException { if (userGuess.length() != GameParameters.nDigit) { - // return false; - throw new IllegalArgumentException("자릿수를 확인하세요 input = " + userGuess); + throw new IllegalArgumentException(); } - + char ch; for (int i = 0; i < GameParameters.nDigit; i++) { - if (!Character.isDigit(userGuess.charAt(i))) { - // return false; - throw new IllegalArgumentException("정수만 입력해주세요 input = " + userGuess); + ch = userGuess.charAt(i); + if (!Character.isDigit(ch) || ch == '0') { + throw new IllegalArgumentException(); } } - - //return true; } public void isValidChoice(String userChoice) { From 54e04838badcd968aa069719a4940e78bca8753f Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 03:59:31 +0900 Subject: [PATCH 16/29] =?UTF-8?q?fix=20:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=97=90=20=EC=9E=85=EB=A0=A5=EC=97=90=200=EC=9D=B4=20?= =?UTF-8?q?=ED=8F=AC=ED=95=A8=EB=90=9C=20=EA=B2=BD=EC=9A=B0=20=20IllegalAr?= =?UTF-8?q?gumentException?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 054a80a1..9b95a6b5 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ 다음과 같은 경우 IllegalArgumentException 발생 -> 애플리케이션 종료 1. 정수 외의 입력 2. 3자리 수 이외의 입력 + 3. 사용자의 입력에 0이 포함된 경우 3. 정답과 사용자입력을 비교하여 결과 계산 (낫싱, 1볼1스트라이크 등) 4. 3의 결과 출력 From eb52d90089215f8282662668a13448a251dd86fc Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 04:02:33 +0900 Subject: [PATCH 17/29] =?UTF-8?q?fix=20:=20=EC=A0=95=EB=8B=B5=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/Game.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index ba066386..6f7b3237 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -64,7 +64,6 @@ public void run() { boolean continueGame = true; while (continueGame) { setAnswer(); - System.out.println(answer); runSingleGame(); continueGame = doNextGame(); } From ce9163776aaf72877e5902a8e6a888fd79f0a9d9 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 04:30:33 +0900 Subject: [PATCH 18/29] =?UTF-8?q?docs=20:=20javadoc=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/Game.java | 26 +++++++++++++++++++ src/main/java/game/RandomAnswerGenerator.java | 10 ++++--- src/main/java/utils/UserInputChecker.java | 14 +++++++++- src/main/java/view/View.java | 16 ++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 6f7b3237..c8cbab91 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -14,14 +14,27 @@ public Game() { userInputChecker = UserInputChecker.getUserInputChecker(); } + /** + * 상대방(컴퓨터)가 예상한 숫자(정답)을 설정한다. + */ private void setAnswer() { answer = (new RandomAnswerGenerator()).getAnswerAsString(); } + /** + * 유저가 정답을 맞혔는지 판단한다 + * @param nStrike 스트라이크의 수 + * @return 정답을 맞힌 경우 true, 아니면 false + */ private boolean isCorrect(int nStrike) { return nStrike == GameParameters.nDigit; } + /** + * 유저의 응답을 정답과 비교하여 볼과 스트라이크의 수를 센다 + * @param userGuess 유저의 응답 + * @return [0]에는 볼, [1]에는 스트라이크의 수를 담은 배열 + */ private int[] evaluate(String userGuess) { int[] ballAndStrike = new int[2]; @@ -36,6 +49,10 @@ private int[] evaluate(String userGuess) { return ballAndStrike; } + /** + * 다음 판을 진행할 지, 게임을 종료할 지 결정한다 + * @return 다음 판을 진행하는 경우 true, 종료하는 경우 false + */ private boolean doNextGame() { View.printCorrectAndGameOver(); String userChoice = View.getUserChoiceForNextGame(); @@ -44,6 +61,10 @@ private boolean doNextGame() { return Objects.equals(userChoice, GameParameters.nextGame); } + /** + * 한 판의 숫자야구 게임을 실행한다 + * 유저가 정답을 맞출 때까지 응답을 입력받고 결과를 출력한다 + */ private void runSingleGame() { String userGuess; while (true) { @@ -60,6 +81,11 @@ private void runSingleGame() { } } + /** + * 여러 번의 게임을 반복적으로 실행한다 + * 매 게임이 시작될 때마다 정답을 세팅한다. + * 매 게임이 끝날 때마다 다음 게임을 시작하거나, 완전히 종료한다 + */ public void run() { boolean continueGame = true; while (continueGame) { diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java index d98f8e46..3f29d1fa 100644 --- a/src/main/java/game/RandomAnswerGenerator.java +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -15,13 +15,17 @@ public RandomAnswerGenerator() { } } + /** + * 1~9까지 다른 숫자 3개로 이루어진정답을 생성한다. + * @return 랜덤으로 생성된 정답 + */ public String getAnswerAsString() { - String answer = ""; + StringBuilder answer = new StringBuilder(); for (int i = 0; i < GameParameters.nDigit; i++) { Collections.shuffle(digits); int d = digits.remove(digits.size() - 1); - answer += String.valueOf(d); + answer.append(String.valueOf(d)); } - return answer; + return answer.toString(); } } diff --git a/src/main/java/utils/UserInputChecker.java b/src/main/java/utils/UserInputChecker.java index eed4435d..6222556e 100644 --- a/src/main/java/utils/UserInputChecker.java +++ b/src/main/java/utils/UserInputChecker.java @@ -19,6 +19,12 @@ public static UserInputChecker getUserInputChecker() { return userInputChecker; } + /** + * 유저가 제출한 숫자의 유효성을 검증한다. + * + * @param userGuess 유저가 제출한 숫자 + * @throws IllegalArgumentException 유저의 응답이 0이나 숫자가 아닌 문자를 포함하는 경우 또는 자릿수가 틀린 경우 + */ public void isValidGuess(String userGuess) throws IllegalArgumentException { if (userGuess.length() != GameParameters.nDigit) { throw new IllegalArgumentException(); @@ -32,7 +38,13 @@ public void isValidGuess(String userGuess) throws IllegalArgumentException { } } - public void isValidChoice(String userChoice) { + /** + * 유저가 입력한 선택(새게임 또는 종료)을 검증한다. + * + * @param userChoice 유저가 입력한 선택 + * @throws IllegalArgumentException 유저가 옵션에 없는 선택을 한 경우 + */ + public void isValidChoice(String userChoice) throws IllegalArgumentException { if (Objects.equals(userChoice, GameParameters.nextGame)) { return; } diff --git a/src/main/java/view/View.java b/src/main/java/view/View.java index 7650efc2..19b38fe7 100644 --- a/src/main/java/view/View.java +++ b/src/main/java/view/View.java @@ -11,6 +11,10 @@ private View() { } + /** + * 유저에게 응답을 입력받는 프롬프트를 출력한다 + * @return 유저가 입력한 응답 + */ public static String getUserGuess() { String strUserInput; System.out.print("숫자를 입력하세요 : "); @@ -18,6 +22,11 @@ public static String getUserGuess() { return strUserInput; } + /** + * 볼과 스트라이크의 개수를 출력한다 + * @param nBall 볼의 개수 + * @param nStrike 스트라이크의 개수 + */ public static void printResult(int nBall, int nStrike) { if (nBall == 0 && nStrike == 0) { System.out.println("낫싱"); @@ -32,11 +41,18 @@ public static void printResult(int nBall, int nStrike) { System.out.println(); } + /** + * 유저가 정답을 맞혔을 때 출력 + */ public static void printCorrectAndGameOver() { System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); } + /** + * 게임 종료 시 유저의 선택을 입력받는다 (새게임 또는 게임종료) + * @return 유저의 선택 + */ public static String getUserChoiceForNextGame() { return scanner.nextLine(); } From 85eb47cdd84d8d5e6706384944e02d3ce915c995 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 04:45:08 +0900 Subject: [PATCH 19/29] =?UTF-8?q?refactor=20:=20nBall=EA=B3=BC=20nStrike?= =?UTF-8?q?=EB=A5=BC=20=EC=9D=B8=EC=8A=A4=ED=84=B4=EC=8A=A4=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - evaluate의 리턴타입을 void로 변경 - isCorrect의 파라미터 제거 --- src/main/java/game/Game.java | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index c8cbab91..624c28da 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -9,9 +9,12 @@ public class Game { private static UserInputChecker userInputChecker = null; private String answer = null; - + private int nBall; + private int nStrike; public Game() { userInputChecker = UserInputChecker.getUserInputChecker(); + nBall = 0; + nStrike = 0; } /** @@ -23,30 +26,28 @@ private void setAnswer() { /** * 유저가 정답을 맞혔는지 판단한다 - * @param nStrike 스트라이크의 수 * @return 정답을 맞힌 경우 true, 아니면 false */ - private boolean isCorrect(int nStrike) { + private boolean isCorrect() { return nStrike == GameParameters.nDigit; } /** - * 유저의 응답을 정답과 비교하여 볼과 스트라이크의 수를 센다 + * 유저의 응답을 정답과 비교하여 볼과 스트라이크의 수를 세고 + * nBall과 nStrike를 업데이트한다. * @param userGuess 유저의 응답 - * @return [0]에는 볼, [1]에는 스트라이크의 수를 담은 배열 */ - private int[] evaluate(String userGuess) { - int[] ballAndStrike = new int[2]; - + private void evaluate(String userGuess) { + nBall = 0; + nStrike = 0; for (int i = 0; i < GameParameters.nDigit; i++) { int idx = answer.indexOf(userGuess.charAt(i)); if (idx == i) { - ballAndStrike[1]++; + nStrike++; } else if (idx != -1) { - ballAndStrike[0]++; + nBall++; } } - return ballAndStrike; } /** @@ -70,12 +71,10 @@ private void runSingleGame() { while (true) { userGuess = View.getUserGuess(); userInputChecker.isValidGuess(userGuess); - int[] ballAndStrike = evaluate(userGuess); - int nBall = ballAndStrike[0]; - int nStrike = ballAndStrike[1]; + evaluate(userGuess); View.printResult(nBall, nStrike); - if (isCorrect(nStrike)) { + if (isCorrect()) { break; } } From f323a8070eba13d35cfc3f5354d707d1fe608ffc Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 04:45:27 +0900 Subject: [PATCH 20/29] =?UTF-8?q?chore=20:=20=EC=B4=88=EA=B8=B0=ED=99=94?= =?UTF-8?q?=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/RandomAnswerGenerator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java index 3f29d1fa..22441e8e 100644 --- a/src/main/java/game/RandomAnswerGenerator.java +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -6,7 +6,7 @@ public class RandomAnswerGenerator { - private List digits = null; + private List digits; public RandomAnswerGenerator() { digits = new ArrayList<>(9); @@ -20,11 +20,11 @@ public RandomAnswerGenerator() { * @return 랜덤으로 생성된 정답 */ public String getAnswerAsString() { - StringBuilder answer = new StringBuilder(); + String answer = ""; for (int i = 0; i < GameParameters.nDigit; i++) { Collections.shuffle(digits); int d = digits.remove(digits.size() - 1); - answer.append(String.valueOf(d)); + answer += d; } return answer.toString(); } From ddb091598a3185c2d6aed2f8cb5782a634b12383 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 04:46:05 +0900 Subject: [PATCH 21/29] =?UTF-8?q?chore=20:=20import=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/utils/UserInputChecker.java | 1 - src/main/java/view/View.java | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/utils/UserInputChecker.java b/src/main/java/utils/UserInputChecker.java index 6222556e..96b83569 100644 --- a/src/main/java/utils/UserInputChecker.java +++ b/src/main/java/utils/UserInputChecker.java @@ -1,6 +1,5 @@ package utils; -import game.Game; import game.GameParameters; import java.util.Objects; diff --git a/src/main/java/view/View.java b/src/main/java/view/View.java index 19b38fe7..169408f7 100644 --- a/src/main/java/view/View.java +++ b/src/main/java/view/View.java @@ -1,6 +1,5 @@ package view; -import java.io.PrintStream; import java.util.Scanner; public class View { @@ -13,6 +12,7 @@ private View() { /** * 유저에게 응답을 입력받는 프롬프트를 출력한다 + * * @return 유저가 입력한 응답 */ public static String getUserGuess() { @@ -24,7 +24,8 @@ public static String getUserGuess() { /** * 볼과 스트라이크의 개수를 출력한다 - * @param nBall 볼의 개수 + * + * @param nBall 볼의 개수 * @param nStrike 스트라이크의 개수 */ public static void printResult(int nBall, int nStrike) { @@ -51,6 +52,7 @@ public static void printCorrectAndGameOver() { /** * 게임 종료 시 유저의 선택을 입력받는다 (새게임 또는 게임종료) + * * @return 유저의 선택 */ public static String getUserChoiceForNextGame() { From 822cf0438a3cc2bcc3799e1ae3e770f2a2156a5b Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 04:49:30 +0900 Subject: [PATCH 22/29] style : formatting --- src/main/java/game/Game.java | 15 ++++++++------- src/main/java/game/RandomAnswerGenerator.java | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 624c28da..4a7df54c 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -11,6 +11,7 @@ public class Game { private String answer = null; private int nBall; private int nStrike; + public Game() { userInputChecker = UserInputChecker.getUserInputChecker(); nBall = 0; @@ -26,6 +27,7 @@ private void setAnswer() { /** * 유저가 정답을 맞혔는지 판단한다 + * * @return 정답을 맞힌 경우 true, 아니면 false */ private boolean isCorrect() { @@ -33,8 +35,8 @@ private boolean isCorrect() { } /** - * 유저의 응답을 정답과 비교하여 볼과 스트라이크의 수를 세고 - * nBall과 nStrike를 업데이트한다. + * 유저의 응답을 정답과 비교하여 볼과 스트라이크의 수를 세고 nBall과 nStrike를 업데이트한다. + * * @param userGuess 유저의 응답 */ private void evaluate(String userGuess) { @@ -52,6 +54,7 @@ private void evaluate(String userGuess) { /** * 다음 판을 진행할 지, 게임을 종료할 지 결정한다 + * * @return 다음 판을 진행하는 경우 true, 종료하는 경우 false */ private boolean doNextGame() { @@ -63,8 +66,7 @@ private boolean doNextGame() { } /** - * 한 판의 숫자야구 게임을 실행한다 - * 유저가 정답을 맞출 때까지 응답을 입력받고 결과를 출력한다 + * 한 판의 숫자야구 게임을 실행한다 유저가 정답을 맞출 때까지 응답을 입력받고 결과를 출력한다 */ private void runSingleGame() { String userGuess; @@ -81,14 +83,13 @@ private void runSingleGame() { } /** - * 여러 번의 게임을 반복적으로 실행한다 - * 매 게임이 시작될 때마다 정답을 세팅한다. - * 매 게임이 끝날 때마다 다음 게임을 시작하거나, 완전히 종료한다 + * 여러 번의 게임을 반복적으로 실행한다 매 게임이 시작될 때마다 정답을 세팅한다. 매 게임이 끝날 때마다 다음 게임을 시작하거나, 완전히 종료한다 */ public void run() { boolean continueGame = true; while (continueGame) { setAnswer(); + System.out.println(answer); runSingleGame(); continueGame = doNextGame(); } diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java index 22441e8e..599f5258 100644 --- a/src/main/java/game/RandomAnswerGenerator.java +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -17,6 +17,7 @@ public RandomAnswerGenerator() { /** * 1~9까지 다른 숫자 3개로 이루어진정답을 생성한다. + * * @return 랜덤으로 생성된 정답 */ public String getAnswerAsString() { From db0a3a5fcde8e690d23c23767743c50236419258 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 06:48:52 +0900 Subject: [PATCH 23/29] =?UTF-8?q?test=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/game/RandomAnswerGeneratorTest.java | 18 ++++++ src/test/java/utils/UserInputCheckerTest.java | 57 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/test/java/game/RandomAnswerGeneratorTest.java create mode 100644 src/test/java/utils/UserInputCheckerTest.java diff --git a/src/test/java/game/RandomAnswerGeneratorTest.java b/src/test/java/game/RandomAnswerGeneratorTest.java new file mode 100644 index 00000000..6f75b062 --- /dev/null +++ b/src/test/java/game/RandomAnswerGeneratorTest.java @@ -0,0 +1,18 @@ +package game; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class RandomAnswerGeneratorTest { + + RandomAnswerGenerator gen = new RandomAnswerGenerator(); + @DisplayName("랜덤 정답 생성 테스트") + @Test + public void testRandomAnswerGenerator() { + assertEquals(GameParameters.nDigit, gen.getAnswerAsString().length(), + "생성된 정답의 길이가 GameParameters.nDigit과 다름"); + } + +} diff --git a/src/test/java/utils/UserInputCheckerTest.java b/src/test/java/utils/UserInputCheckerTest.java new file mode 100644 index 00000000..8a586140 --- /dev/null +++ b/src/test/java/utils/UserInputCheckerTest.java @@ -0,0 +1,57 @@ +package utils; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class UserInputCheckerTest { + + UserInputChecker userInputChecker = UserInputChecker.getUserInputChecker(); + + @DisplayName("유저 응답 exception Throw 테스트") + @Test + public void throwExceptionWhenGetWrongInput() { + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidGuess("12?"); + }); + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidGuess("012"); + }); + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidGuess("1234"); + }); + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidGuess("12"); + }); + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidGuess(""); + }); + } + + @DisplayName("게임종료 후 유저 선택 exception Throw 테스트") + @Test + public void throwExceptionWhenGetWrongChoice() { + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidChoice("0"); + }); + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidChoice("3"); + }); + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidChoice("12"); + }); + assertThrows(IllegalArgumentException.class, + () -> { + userInputChecker.isValidChoice("1-"); + }); + } +} From 388c95437f00b0d36b1be438e1424ab67fe13820 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 07:39:21 +0900 Subject: [PATCH 24/29] style : formatting --- src/test/java/utils/UserInputCheckerTest.java | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/test/java/utils/UserInputCheckerTest.java b/src/test/java/utils/UserInputCheckerTest.java index 8a586140..7b3d0e8c 100644 --- a/src/test/java/utils/UserInputCheckerTest.java +++ b/src/test/java/utils/UserInputCheckerTest.java @@ -13,45 +13,27 @@ public class UserInputCheckerTest { @Test public void throwExceptionWhenGetWrongInput() { assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidGuess("12?"); - }); + () -> userInputChecker.isValidGuess("12?")); assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidGuess("012"); - }); + () -> userInputChecker.isValidGuess("012")); assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidGuess("1234"); - }); + () -> userInputChecker.isValidGuess("1234")); assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidGuess("12"); - }); + () -> userInputChecker.isValidGuess("12")); assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidGuess(""); - }); + () -> userInputChecker.isValidGuess("")); } @DisplayName("게임종료 후 유저 선택 exception Throw 테스트") @Test public void throwExceptionWhenGetWrongChoice() { assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidChoice("0"); - }); + () -> userInputChecker.isValidChoice("0")); assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidChoice("3"); - }); + () -> userInputChecker.isValidChoice("3")); assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidChoice("12"); - }); + () -> userInputChecker.isValidChoice("12")); assertThrows(IllegalArgumentException.class, - () -> { - userInputChecker.isValidChoice("1-"); - }); + () -> userInputChecker.isValidChoice("1-")); } } From 66c4fcf8dc8afabcbaf2a1ba90010ae6f1949e39 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 07:40:09 +0900 Subject: [PATCH 25/29] =?UTF-8?q?fix=20:=20=EC=A0=95=EB=8B=B5=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/game/Game.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 4a7df54c..09423f32 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -89,7 +89,6 @@ public void run() { boolean continueGame = true; while (continueGame) { setAnswer(); - System.out.println(answer); runSingleGame(); continueGame = doNextGame(); } From 564008d5986151f3385149ad3f78b7bc55b5572d Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 09:17:07 +0900 Subject: [PATCH 26/29] =?UTF-8?q?refactor=20:=20evaluator=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - evaluate() - isCorrect() --- src/main/java/game/Evaluator.java | 56 +++++++++++++++++++ src/main/java/game/Game.java | 45 +++------------ src/main/java/game/RandomAnswerGenerator.java | 4 +- 3 files changed, 66 insertions(+), 39 deletions(-) create mode 100644 src/main/java/game/Evaluator.java diff --git a/src/main/java/game/Evaluator.java b/src/main/java/game/Evaluator.java new file mode 100644 index 00000000..3949e0c1 --- /dev/null +++ b/src/main/java/game/Evaluator.java @@ -0,0 +1,56 @@ +package game; + +public class Evaluator { + + private String answer; + private int nBall; + private int nStrike; + + public Evaluator() { + nBall = 0; + nStrike = 0; + } + + public String getAnswer() { + return answer; + } + + public void setAnswer(String answer) { + this.answer = answer; + } + + public int getNBall() { + return nBall; + } + + public int getNStrike() { + return nStrike; + } + + /** + * 유저가 정답을 맞혔는지 판단한다 + * + * @return 정답을 맞힌 경우 true, 아니면 false + */ + public boolean isCorrect() { + return nStrike == GameParameters.nDigit; + } + + /** + * 유저의 응답을 정답과 비교하여 볼과 스트라이크의 수를 세고 nBall과 nStrike를 업데이트한다. + * + * @param userGuess 유저의 응답 + */ + public void evaluate(String userGuess) { + nBall = 0; + nStrike = 0; + for (int i = 0; i < GameParameters.nDigit; i++) { + int idx = answer.indexOf(userGuess.charAt(i)); + if (idx == i) { + nStrike++; + } else if (idx != -1) { + nBall++; + } + } + } +} diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index 09423f32..a9e6a05a 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -7,49 +7,19 @@ public class Game { private static UserInputChecker userInputChecker = null; - - private String answer = null; - private int nBall; - private int nStrike; + private Evaluator evaluator; public Game() { userInputChecker = UserInputChecker.getUserInputChecker(); - nBall = 0; - nStrike = 0; + evaluator = new Evaluator(); } /** * 상대방(컴퓨터)가 예상한 숫자(정답)을 설정한다. */ private void setAnswer() { - answer = (new RandomAnswerGenerator()).getAnswerAsString(); - } - - /** - * 유저가 정답을 맞혔는지 판단한다 - * - * @return 정답을 맞힌 경우 true, 아니면 false - */ - private boolean isCorrect() { - return nStrike == GameParameters.nDigit; - } - - /** - * 유저의 응답을 정답과 비교하여 볼과 스트라이크의 수를 세고 nBall과 nStrike를 업데이트한다. - * - * @param userGuess 유저의 응답 - */ - private void evaluate(String userGuess) { - nBall = 0; - nStrike = 0; - for (int i = 0; i < GameParameters.nDigit; i++) { - int idx = answer.indexOf(userGuess.charAt(i)); - if (idx == i) { - nStrike++; - } else if (idx != -1) { - nBall++; - } - } + String answer = (new RandomAnswerGenerator()).getAnswerAsString(); + evaluator.setAnswer(answer); } /** @@ -73,10 +43,10 @@ private void runSingleGame() { while (true) { userGuess = View.getUserGuess(); userInputChecker.isValidGuess(userGuess); - evaluate(userGuess); - View.printResult(nBall, nStrike); + evaluator.evaluate(userGuess); + View.printResult(evaluator.getNBall(), evaluator.getNStrike()); - if (isCorrect()) { + if (evaluator.isCorrect()) { break; } } @@ -89,6 +59,7 @@ public void run() { boolean continueGame = true; while (continueGame) { setAnswer(); + System.out.println(evaluator.getAnswer()); runSingleGame(); continueGame = doNextGame(); } diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java index 599f5258..0b54949f 100644 --- a/src/main/java/game/RandomAnswerGenerator.java +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -16,7 +16,7 @@ public RandomAnswerGenerator() { } /** - * 1~9까지 다른 숫자 3개로 이루어진정답을 생성한다. + * 1~9까지 다른 숫자 3개로 이루어진 정답을 생성한다. * * @return 랜덤으로 생성된 정답 */ @@ -27,6 +27,6 @@ public String getAnswerAsString() { int d = digits.remove(digits.size() - 1); answer += d; } - return answer.toString(); + return answer; } } From 894b3fece0b0eee16980ba413d9bc68928adba7a Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 10:21:44 +0900 Subject: [PATCH 27/29] =?UTF-8?q?test=20:=20evaluator=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - evaluate() - isCorrect() --- src/test/java/game/EvaluatorTest.java | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/test/java/game/EvaluatorTest.java diff --git a/src/test/java/game/EvaluatorTest.java b/src/test/java/game/EvaluatorTest.java new file mode 100644 index 00000000..d0775113 --- /dev/null +++ b/src/test/java/game/EvaluatorTest.java @@ -0,0 +1,40 @@ +package game; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class EvaluatorTest { + + static Evaluator evaluator; + + @BeforeAll + static void initAll() { + evaluator = new Evaluator(); + AnswerGenerator answerGenerator = new TestAnswerGenerator("123"); + evaluator.setAnswer(answerGenerator); + } + + @DisplayName("evaluate / isCorrect 테스트") + @Test + public void evaluateTest() { + Assertions.assertArrayEquals(new int[]{0, 0}, evaluator.evaluate("456")); + Assertions.assertArrayEquals(new int[]{0, 1}, evaluator.evaluate("178")); + Assertions.assertArrayEquals(new int[]{0, 2}, evaluator.evaluate("923")); + Assertions.assertArrayEquals(new int[]{0, 3}, evaluator.evaluate("123")); + Assertions.assertArrayEquals(new int[]{1, 0}, evaluator.evaluate("289")); + Assertions.assertArrayEquals(new int[]{1, 1}, evaluator.evaluate("283")); + Assertions.assertArrayEquals(new int[]{2, 1}, evaluator.evaluate("213")); + Assertions.assertArrayEquals(new int[]{3, 0}, evaluator.evaluate("231")); + } + + @DisplayName("isCorrect 테스트") + @Test + public void isCorrectTest() { + evaluator.evaluate("123"); + Assertions.assertEquals(3, evaluator.getNStrike()); + Assertions.assertEquals(0, evaluator.getNBall()); + } +} From 8866ee632c15446409ac3323dd412a221e1fda48 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 10:24:27 +0900 Subject: [PATCH 28/29] =?UTF-8?q?refactor=20:=20AnswerGenerator=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RandomAnswerGenerator와 TestAnswerGenerator에서 구현 --- src/main/java/game/AnswerGenerator.java | 7 +++++++ src/main/java/game/RandomAnswerGenerator.java | 2 +- src/main/java/game/TestAnswerGenerator.java | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/main/java/game/AnswerGenerator.java create mode 100644 src/main/java/game/TestAnswerGenerator.java diff --git a/src/main/java/game/AnswerGenerator.java b/src/main/java/game/AnswerGenerator.java new file mode 100644 index 00000000..bb6f3ce5 --- /dev/null +++ b/src/main/java/game/AnswerGenerator.java @@ -0,0 +1,7 @@ +package game; + +public interface AnswerGenerator { + + String getAnswerAsString(); + +} diff --git a/src/main/java/game/RandomAnswerGenerator.java b/src/main/java/game/RandomAnswerGenerator.java index 0b54949f..540c72b2 100644 --- a/src/main/java/game/RandomAnswerGenerator.java +++ b/src/main/java/game/RandomAnswerGenerator.java @@ -4,7 +4,7 @@ import java.util.Collections; import java.util.List; -public class RandomAnswerGenerator { +public class RandomAnswerGenerator implements AnswerGenerator { private List digits; diff --git a/src/main/java/game/TestAnswerGenerator.java b/src/main/java/game/TestAnswerGenerator.java new file mode 100644 index 00000000..2a8da78c --- /dev/null +++ b/src/main/java/game/TestAnswerGenerator.java @@ -0,0 +1,15 @@ +package game; + +public class TestAnswerGenerator implements AnswerGenerator { + + private final String answer; + + public TestAnswerGenerator(String predefinedAnswer) { + answer = predefinedAnswer; + } + + @Override + public String getAnswerAsString() { + return answer; + } +} From ec2fb0a6419a2b7fc1767c120fec7c749509e5e6 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 6 May 2024 10:25:42 +0900 Subject: [PATCH 29/29] style : formatting --- src/main/java/game/Evaluator.java | 13 ++++++++++--- src/main/java/game/Game.java | 10 +--------- src/main/java/game/GameParameters.java | 1 + src/test/java/game/RandomAnswerGeneratorTest.java | 7 ++++++- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/game/Evaluator.java b/src/main/java/game/Evaluator.java index 3949e0c1..e1063bbc 100644 --- a/src/main/java/game/Evaluator.java +++ b/src/main/java/game/Evaluator.java @@ -15,8 +15,11 @@ public String getAnswer() { return answer; } - public void setAnswer(String answer) { - this.answer = answer; + /** + * 상대방(컴퓨터)가 예상한 숫자(정답)을 설정한다. + */ + public void setAnswer(AnswerGenerator answerGenerator) { + answer = answerGenerator.getAnswerAsString(); } public int getNBall() { @@ -41,9 +44,10 @@ public boolean isCorrect() { * * @param userGuess 유저의 응답 */ - public void evaluate(String userGuess) { + public int[] evaluate(String userGuess) { nBall = 0; nStrike = 0; + int[] ballAndStrike = new int[2]; for (int i = 0; i < GameParameters.nDigit; i++) { int idx = answer.indexOf(userGuess.charAt(i)); if (idx == i) { @@ -52,5 +56,8 @@ public void evaluate(String userGuess) { nBall++; } } + ballAndStrike[0] = nBall; + ballAndStrike[1] = nStrike; + return ballAndStrike; } } diff --git a/src/main/java/game/Game.java b/src/main/java/game/Game.java index a9e6a05a..ef0e7ab2 100644 --- a/src/main/java/game/Game.java +++ b/src/main/java/game/Game.java @@ -14,13 +14,6 @@ public Game() { evaluator = new Evaluator(); } - /** - * 상대방(컴퓨터)가 예상한 숫자(정답)을 설정한다. - */ - private void setAnswer() { - String answer = (new RandomAnswerGenerator()).getAnswerAsString(); - evaluator.setAnswer(answer); - } /** * 다음 판을 진행할 지, 게임을 종료할 지 결정한다 @@ -58,8 +51,7 @@ private void runSingleGame() { public void run() { boolean continueGame = true; while (continueGame) { - setAnswer(); - System.out.println(evaluator.getAnswer()); + evaluator.setAnswer(new RandomAnswerGenerator()); runSingleGame(); continueGame = doNextGame(); } diff --git a/src/main/java/game/GameParameters.java b/src/main/java/game/GameParameters.java index 113c7dac..f188b9eb 100644 --- a/src/main/java/game/GameParameters.java +++ b/src/main/java/game/GameParameters.java @@ -1,6 +1,7 @@ package game; public class GameParameters { + public static final int nDigit = 3; public static final String nextGame = "1"; public static final String quitGame = "2"; diff --git a/src/test/java/game/RandomAnswerGeneratorTest.java b/src/test/java/game/RandomAnswerGeneratorTest.java index 6f75b062..244c071e 100644 --- a/src/test/java/game/RandomAnswerGeneratorTest.java +++ b/src/test/java/game/RandomAnswerGeneratorTest.java @@ -1,6 +1,7 @@ package game; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -8,11 +9,15 @@ public class RandomAnswerGeneratorTest { RandomAnswerGenerator gen = new RandomAnswerGenerator(); + @DisplayName("랜덤 정답 생성 테스트") @Test public void testRandomAnswerGenerator() { - assertEquals(GameParameters.nDigit, gen.getAnswerAsString().length(), + String answer = gen.getAnswerAsString(); + assertEquals(GameParameters.nDigit, answer.length(), "생성된 정답의 길이가 GameParameters.nDigit과 다름"); + assertNotEquals(answer.charAt(0), answer.charAt(1)); + assertNotEquals(answer.charAt(1), answer.charAt(2)); } }