From 646f57a093668991e37d76d1c5110b01ae15d6e1 Mon Sep 17 00:00:00 2001 From: youngreal Date: Sun, 29 May 2022 18:29:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=202=EC=A3=BC=EC=B0=A8=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=EA=B5=AC=ED=98=84=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Main.java | 20 ++++++ .../exception/DuplicateNumberException.java | 7 ++ .../exception/NotOnlyNumberException.java | 7 ++ src/main/java/util/Answer.java | 27 ++++++++ src/main/java/util/CompareAnswer.java | 57 ++++++++++++++++ src/main/java/util/Constant.java | 18 +++++ src/main/java/util/GameSetting.java | 66 +++++++++++++++++++ src/main/java/util/InputNumber.java | 58 ++++++++++++++++ src/main/java/view/View.java | 39 +++++++++++ 9 files changed, 299 insertions(+) create mode 100644 src/main/java/Main.java create mode 100644 src/main/java/exception/DuplicateNumberException.java create mode 100644 src/main/java/exception/NotOnlyNumberException.java create mode 100644 src/main/java/util/Answer.java create mode 100644 src/main/java/util/CompareAnswer.java create mode 100644 src/main/java/util/Constant.java create mode 100644 src/main/java/util/GameSetting.java create mode 100644 src/main/java/util/InputNumber.java create mode 100644 src/main/java/view/View.java diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 000000000..d4789c33e --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,20 @@ +import util.GameSetting; +import view.View; + +public class Main { + public static void main(String[] args) { + GameSetting gameSetting = new GameSetting(); + do { + gameSetting.startGame(); + gameSetting.correctAnswer(); + if (isNotContinueGame()) { + break; + } + gameSetting.reGame(); + } while(true); + } + + private static boolean isNotContinueGame() { + return !View.isContinue(); + } +} diff --git a/src/main/java/exception/DuplicateNumberException.java b/src/main/java/exception/DuplicateNumberException.java new file mode 100644 index 000000000..bdc755885 --- /dev/null +++ b/src/main/java/exception/DuplicateNumberException.java @@ -0,0 +1,7 @@ +package exception; + +public class DuplicateNumberException extends RuntimeException { + public DuplicateNumberException(String message) { + super(message); + } +} diff --git a/src/main/java/exception/NotOnlyNumberException.java b/src/main/java/exception/NotOnlyNumberException.java new file mode 100644 index 000000000..5c3571ed3 --- /dev/null +++ b/src/main/java/exception/NotOnlyNumberException.java @@ -0,0 +1,7 @@ +package exception; + +public class NotOnlyNumberException extends RuntimeException{ + public NotOnlyNumberException(String message) { + super(message); + } +} diff --git a/src/main/java/util/Answer.java b/src/main/java/util/Answer.java new file mode 100644 index 000000000..543f08f1a --- /dev/null +++ b/src/main/java/util/Answer.java @@ -0,0 +1,27 @@ +package util; + +import java.util.ArrayList; + +import static util.Constant.ANSWER_MAX_SIZE; +import static util.Constant.ANSWER_NUMBER_RANGE; + +/** + * 정답 넘버 중복없는 3자리 생성하는 클래스 + */ +public class Answer{ + private final ArrayList answerNum= new ArrayList<>(); + + public ArrayList generateNumber() { + while (answerNum.size() < ANSWER_MAX_SIZE) { + int element = (int) (Math.random() * ANSWER_NUMBER_RANGE); + if(isNotContainsNumber(element)){ + answerNum.add(element); + } + } + return this.answerNum; + } + + private boolean isNotContainsNumber(int element) { + return !answerNum.contains(element); + } +} diff --git a/src/main/java/util/CompareAnswer.java b/src/main/java/util/CompareAnswer.java new file mode 100644 index 000000000..59393b03d --- /dev/null +++ b/src/main/java/util/CompareAnswer.java @@ -0,0 +1,57 @@ +package util; + +import java.util.ArrayList; + +/** + * 정답숫자와 인풋숫자를 비교하여 점수를 카운팅하는 클래스 + */ +public class CompareAnswer { + private final ArrayList inputNum; + private final ArrayList answerNum; + private int strikeCount=0; + private int ballCount=0; + private int nothing=0; + + public CompareAnswer(ArrayList inputNum, ArrayList answerNum) { + this.inputNum = inputNum; + this.answerNum = answerNum; + } + + public void ballScoreCount() { + for (int i = 0; i < 3; i++) { + ballCounting(i); + } + } + + public void ballCounting(int position) { + if (isStrike(position)) { + this.strikeCount++; + return; + } + if (isBall(position)) { + this.ballCount++; + return; + } + this.nothing++; + } + + private boolean isStrike(int position) { + return this.inputNum.get(position).equals(this.answerNum.get(position)); + } + + private boolean isBall(int position) { + return this.answerNum.contains(this.inputNum.get(position)); + } + + public int getStrikeCount() { + return strikeCount; + } + + public int getBallCount() { + return ballCount; + } + + public int getNothing() { + return nothing; + } +} diff --git a/src/main/java/util/Constant.java b/src/main/java/util/Constant.java new file mode 100644 index 000000000..bebba0878 --- /dev/null +++ b/src/main/java/util/Constant.java @@ -0,0 +1,18 @@ +package util; + +/** + * 상수값들을 보관한 클래스 + */ +public class Constant { + public static final int ANSWER_MAX_SIZE = 3; + public static final int ANSWER_NUMBER_RANGE = 10; + public static final int CHAR_TO_INT = 48; + public static final int INPUT_NUMBER_LENGTH = 3; + public static final int INPUT_NUMBER_MAXVALUE = 9; + public static final int INPUT_NUMBER_MINVALUE = 0; + public static final int STRIKE_BALL_MIN = 0; + public static final int NOTHING = 3; + public static final String GAME_START_MESSAGE = "숫자를 입력해주세요"; + public static final String ALL_NUMBER_CORRECT_MESSAGE = "3개의 숫자를 모두 맞히셨습니다! 게임종료"; + public static final String CONTINUE_GAME_QUESTION = "게임을 새로시작하려면 1, 종료하려면 2를 입력하세요"; +} diff --git a/src/main/java/util/GameSetting.java b/src/main/java/util/GameSetting.java new file mode 100644 index 000000000..ffc1cf470 --- /dev/null +++ b/src/main/java/util/GameSetting.java @@ -0,0 +1,66 @@ +package util; + +import exception.DuplicateNumberException; +import exception.NotOnlyNumberException; +import view.View; + +import java.util.ArrayList; + +/** + * 정답을 맞출때까지 게임을 진행하는 클래스 + */ +public class GameSetting { + public void startGame() { + ArrayList answerNumber = getAnswerNumber(); + View view = new View(); + int strikeCount=0; + + do { + View.printStart(); + // 인풋숫자 받고,검증 + InputNumber inputNumber = new InputNumber(); + if (inputNumberScanAndValidation(inputNumber)) continue; + ArrayList inputNumberArray = getInputNumber(inputNumber); + + // 인풋숫자와 정답을 비교하고, 스코어매기기 + CompareAnswer compareAnswer = new CompareAnswer(inputNumberArray,answerNumber); + compareAnswer.ballScoreCount(); + + // 정답확인하기 + strikeCount = compareAnswer.getStrikeCount(); + view.printResult(compareAnswer); + + }while (strikeCount<3); + } + + private ArrayList getInputNumber(InputNumber inputNumber) { + return inputNumber.getInputNumArray(); + } + + private boolean inputNumberScanAndValidation(InputNumber inputNumber) { + try { + inputNumber.inputNumberValidation(inputNumber.inputNumberScanner()); + } catch (ArrayIndexOutOfBoundsException | NotOnlyNumberException | DuplicateNumberException e) { + System.out.println(e.getMessage()); + return true; + } + return false; + } + + private ArrayList getAnswerNumber() { + Answer answer = new Answer(); + return generateAnswerNumber(answer); + } + + public void correctAnswer() { + View.printEnding(); + } + + private ArrayList generateAnswerNumber(Answer answer) { + return answer.generateNumber(); + } + + public void reGame() { + getAnswerNumber(); + } +} \ No newline at end of file diff --git a/src/main/java/util/InputNumber.java b/src/main/java/util/InputNumber.java new file mode 100644 index 000000000..e1aafc6f3 --- /dev/null +++ b/src/main/java/util/InputNumber.java @@ -0,0 +1,58 @@ +package util; + +import exception.DuplicateNumberException; +import exception.NotOnlyNumberException; + +import java.util.ArrayList; +import java.util.Scanner; + +import static util.Constant.*; + +/** + * 사용자가 입력한 숫자에대해 다루는 클래스 + */ +public class InputNumber { + private final Scanner sc= new Scanner(System.in); + private final ArrayList inputNumArray= new ArrayList<>(); + + public ArrayList getInputNumArray() { + return inputNumArray; + } + + public char[] inputNumberScanner() { + this.inputNumArray.clear(); + String scStr = sc.nextLine(); + return scStr.toCharArray(); + } + + public void inputNumberValidation(char[] scChar) { + ArrayIndexExceptionValidation(scChar); + for (char c : scChar) { + notOnlyExceptionValidation(c); + DuplicateNumberExceptionValidation(c); + this.inputNumArray.add(c - CHAR_TO_INT); + } + } + + private void DuplicateNumberExceptionValidation(char c) { + if (inputNumArray.contains(c - CHAR_TO_INT)) { + throw new DuplicateNumberException("서로다른 숫자만 입력해주세요"); + } + } + + private void notOnlyExceptionValidation(char c) { + if (OutOfRangeNumber(c)) { + throw new NotOnlyNumberException("0~9사이의 숫자만 입력해주세요"); + } + } + + private boolean OutOfRangeNumber(char scChar) { + return scChar - CHAR_TO_INT > INPUT_NUMBER_MAXVALUE || scChar - CHAR_TO_INT < INPUT_NUMBER_MINVALUE; + } + + private void ArrayIndexExceptionValidation(char[] scChar) { + if (scChar.length != INPUT_NUMBER_LENGTH) { + throw new ArrayIndexOutOfBoundsException("세자리 수를 입력해주세요."); + } + } +} diff --git a/src/main/java/view/View.java b/src/main/java/view/View.java new file mode 100644 index 000000000..4e21383cd --- /dev/null +++ b/src/main/java/view/View.java @@ -0,0 +1,39 @@ +package view; + +import util.CompareAnswer; + +import java.util.Scanner; + +import static util.Constant.*; + +/** + * 화면출력용 클래스 + */ +public class View { + public static void printStart() { + System.out.println(GAME_START_MESSAGE); + } + + public void printResult(CompareAnswer answer) { + if (answer.getStrikeCount()>STRIKE_BALL_MIN) { + System.out.printf("%d스트라이크 ",answer.getStrikeCount()); + } + if (answer.getBallCount()>STRIKE_BALL_MIN) { + System.out.printf("%d볼 ",answer.getBallCount()); + } + if (answer.getNothing()== NOTHING) { + System.out.print("낫싱"); + } + System.out.println(""); + } + + public static void printEnding() { + System.out.println(ALL_NUMBER_CORRECT_MESSAGE); + System.out.println(CONTINUE_GAME_QUESTION); + } + + public static boolean isContinue() { + Scanner sc = new Scanner(System.in); + return sc.nextInt() == 1; + } +} From ac3b3426ac04d2bc1475f03fbf26da34316b5d11 Mon Sep 17 00:00:00 2001 From: youngreal Date: Sun, 29 May 2022 18:29:49 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test:=202=EC=A3=BC=EC=B0=A8=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/util/CompareAnswerTest.java | 80 +++++++++++++++++++++++ src/test/java/util/InputNumberTest.java | 47 +++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/test/java/util/CompareAnswerTest.java create mode 100644 src/test/java/util/InputNumberTest.java diff --git a/src/test/java/util/CompareAnswerTest.java b/src/test/java/util/CompareAnswerTest.java new file mode 100644 index 000000000..381c4b02c --- /dev/null +++ b/src/test/java/util/CompareAnswerTest.java @@ -0,0 +1,80 @@ +package util; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.assertj.core.api.Assertions.assertThat; + +class CompareAnswerTest { + ArrayList inputNum= new ArrayList<>(); + ArrayList answerNum= new ArrayList<>(); + + @BeforeEach + void setup() { + answerNum.add(3); + answerNum.add(4); + answerNum.add(6); + } + + @Test + @DisplayName("0스트라이크 1볼") + void ballCountingTest() { + inputNum.add(1); + inputNum.add(2); + inputNum.add(3); + CompareAnswer compareAnswer = new CompareAnswer(inputNum,answerNum); + ballCounting(compareAnswer); + assertThat(compareAnswer.getStrikeCount()).isEqualTo(0); + assertThat(compareAnswer.getBallCount()).isEqualTo(1); + assertThat(compareAnswer.getNothing()).isNotEqualTo(3); + System.out.println(compareAnswer.getNothing()); + } + + @Test + @DisplayName("2스트라이크") + void ballCountingTest2() { + inputNum.add(3); + inputNum.add(5); + inputNum.add(6); + CompareAnswer compareAnswer = new CompareAnswer(inputNum,answerNum); + ballCounting(compareAnswer); + assertThat(compareAnswer.getStrikeCount()).isEqualTo(2); + assertThat(compareAnswer.getBallCount()).isEqualTo(0); + assertThat(compareAnswer.getNothing()).isNotEqualTo(3); + } + + @Test + @DisplayName("낫싱") + void ballCountingTest3() { + inputNum.add(1); + inputNum.add(2); + inputNum.add(5); + CompareAnswer compareAnswer = new CompareAnswer(inputNum,answerNum); + ballCounting(compareAnswer); + assertThat(compareAnswer.getStrikeCount()).isEqualTo(0); + assertThat(compareAnswer.getBallCount()).isEqualTo(0); + assertThat(compareAnswer.getNothing()).isEqualTo(3); + } + + @Test + @DisplayName("3볼") + void ballCountingTest4() { + inputNum.add(6); + inputNum.add(3); + inputNum.add(4); + CompareAnswer compareAnswer = new CompareAnswer(inputNum,answerNum); + ballCounting(compareAnswer); + assertThat(compareAnswer.getStrikeCount()).isEqualTo(0); + assertThat(compareAnswer.getBallCount()).isEqualTo(3); + assertThat(compareAnswer.getNothing()).isNotEqualTo(3); + } + + private void ballCounting(CompareAnswer compareAnswer) { + compareAnswer.ballCounting(0); + compareAnswer.ballCounting(1); + compareAnswer.ballCounting(2); + } +} \ No newline at end of file diff --git a/src/test/java/util/InputNumberTest.java b/src/test/java/util/InputNumberTest.java new file mode 100644 index 000000000..d7c99516a --- /dev/null +++ b/src/test/java/util/InputNumberTest.java @@ -0,0 +1,47 @@ +package util; + +import exception.DuplicateNumberException; +import exception.NotOnlyNumberException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class InputNumberTest { + InputNumber inputNumber = new InputNumber(); + + @ParameterizedTest + @ValueSource(strings = {"!@#", " ", "-13"}) + @DisplayName("0~9사이의 숫자만 입력해야한다: 특수문자, 공백, 음수") + void NotOnlyNumberExceptionTest(String input) { + char[] chars = toCharArray(input); + assertThrows(NotOnlyNumberException.class, () ->{ + inputNumber.inputNumberValidation(chars); + }); + } + + @ParameterizedTest + @ValueSource(strings ={"","0","12","1234"} ) + @DisplayName("세자리 수만 입력해야한다") + void InputThreeNumberTest(String input) { + char[] chars = toCharArray(input); + assertThrows(ArrayIndexOutOfBoundsException.class, () ->{ + inputNumber.inputNumberValidation(chars); + }); + } + + @ParameterizedTest + @ValueSource(strings ={"111","112","009"} ) + @DisplayName("서로 다른 수만 입력해야한다") + void DuplicateNumberExceptionTest(String input) { + char[] chars = toCharArray(input); + assertThrows(DuplicateNumberException.class, () ->{ + inputNumber.inputNumberValidation(chars); + }); + } + + private char[] toCharArray(String input) { + return input.toCharArray(); + } +} \ No newline at end of file