diff --git a/docs/README.md b/docs/README.md index e69de29bb2..6d288062fe 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,26 @@ +# 요구사항 +> ### 프로그램 기능 +> - #### 1부터 9까지의 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임 +> 1. 입력한 숫자가 같은 자리에 있을 경우 스트라이크 +> 2. 입력한 숫자가 다른 자리에 있을 경우 볼 +> 3. 입력한 수가 전혀 없을 경우 낫싱 +>- #### 컴퓨터는 1에서 9까지의 서로 다른 임의수 3개를 선택 +> 1. 사용자가 입력하는 값과 컴퓨터가 가지고 있는 값을 비교 +> 2. 3개의 숫자를 모두 맞히면 게임이 종료 되고 다시 시작하거나 완전히 종료할지 결정 가능 + +# 입력 +>- 서로 다른 3자리의 수를 매 판마다 입력 +>- 게임이 끝나고 난 후에 재시작/종료를 구분하는 1과 2 중 하나의 수 + +# 출력 +> - 사용자가 입력한 수에 대한 결과를 볼, 스트라이크 개수로 표시 +> - 하나도 없는 경우 낫싱 + +# 예외처리 +> - 사용자가 잘못된 값을 입력할 경우에 IllegalArgumentException을 발생 + +1부터 9까지 중 랜더함 3개의 숫자를 생성하는 NumberMaker +사용자의 입력을 받는 input +출력을 하는 output +사령관 역할의 컨트롤러 하나 +사용자가 입력한 값을 만들어진 3자리의 숫자와 비교하는 CheckNumber diff --git a/src/main/java/baseball/Answer.java b/src/main/java/baseball/Answer.java new file mode 100644 index 0000000000..3c16aff3ee --- /dev/null +++ b/src/main/java/baseball/Answer.java @@ -0,0 +1,58 @@ +package baseball; +import camp.nextstep.edu.missionutils.Randoms; +import java.util.ArrayList; +import java.util.List; + +public class Answer { + List answer; + List transformedResult; + public Answer(){ + makeAnswer(); + } + + public void makeAnswer() { + answer = new ArrayList<>(); + while (answer.size() < 3) { + int randomNumber = Randoms.pickNumberInRange(1, 9); + if (!answer.contains(randomNumber)) { + answer.add(randomNumber); + } + } + } + + public List getResult(){ + return transformedResult; + } + + private List answerTransforming(List integerResult) { + List result = new ArrayList<>(); + if (integerResult.get(0) == 0 && integerResult.get(1) == 0){ + result.add("낫싱"); + return result; + } + result.add(integerResult.get(0) + "스트라이크"); + result.add(integerResult.get(1) + "볼"); + return result; + } + + public boolean checkAnswer(int[] userNumber) { + transformedResult = new ArrayList<>(); + int strike = 0; + int ball = 0; + for (int i = 0; i < answer.size(); i++){ + for (int j = 0; j < answer.size(); j++){ + if (j == i && answer.get(i).equals(userNumber[j])) { + strike++; + } + else if (answer.get(i).equals(userNumber[j])) ball++; + } + } + List result = new ArrayList<>(); + result.add(strike); + result.add(ball); + transformedResult = answerTransforming(result); + return result.get(0) == 3; + } + + +} diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index dd95a34214..6aad84cd91 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -1,7 +1,12 @@ package baseball; + + public class Application { + public static void main(String[] args) { + Controller controller = new Controller(); // TODO: 프로그램 구현 + controller.startGame(); } } diff --git a/src/main/java/baseball/Controller.java b/src/main/java/baseball/Controller.java new file mode 100644 index 0000000000..d033b1b1f3 --- /dev/null +++ b/src/main/java/baseball/Controller.java @@ -0,0 +1,28 @@ +package baseball; + +public class Controller { + Input input; + Output output; + Answer answer; + public Controller(){ + input = new Input(); + output = new Output(); + answer = new Answer(); + } + public void startGame(){ + output.start(); + while (true){ + output.enterNumber(); + if (answer.checkAnswer(input.getUserInput())) { + output.endGame(); + if (input.isRestart()) { + answer.makeAnswer(); + output.result(answer.getResult()); + continue; + } + else break; + } + output.result(answer.getResult()); + } + } +} diff --git a/src/main/java/baseball/Input.java b/src/main/java/baseball/Input.java new file mode 100644 index 0000000000..f8e18135d3 --- /dev/null +++ b/src/main/java/baseball/Input.java @@ -0,0 +1,59 @@ +package baseball; + +import static camp.nextstep.edu.missionutils.Console.readLine; + +import java.util.HashSet; + +public class Input { + final String ERROR = "[ERROR]"; + public int[] getUserInput() throws IllegalArgumentException{ + String input = readLine(); + validateInput(input); + return transformInput(input); + } + + private void validateInput(String input) throws IllegalArgumentException{ + isThreeNumber(input); + isNumber(input); + isNotDuplicate(input); + } + + public void isNotDuplicate(String input) { + HashSet uniqueValue = new HashSet<>(); + for (int i = 0; i < input.length(); i++) { + uniqueValue.add(String.valueOf(input.charAt(i))); + } + if (uniqueValue.size() != 3) throw new IllegalArgumentException(ERROR + " 중복된 값은 입력이 불가능 합니다."); + } + + public void isNumber(String input) { + if (!input.matches("\\d+")) throw new IllegalArgumentException(ERROR + " 숫자만 입력 가능합니다."); + } + + private void isThreeNumber(String input) { + if (!(input.length() == 3)) throw new IllegalArgumentException(ERROR + " 3개의 숫자를 입력해주세요"); + } + + private int[] transformInput(String input) { + return charArrToIntArr(stringToCharArr(input)); + } + private char[] stringToCharArr(String input){ + char[] transformedInput = new char[input.length()]; + for (int i = 0; i < input.length(); i++){ + transformedInput[i] = input.charAt(i); + } + return transformedInput; + } + private int[] charArrToIntArr(char[] transformedInput){ + int[] userNumber = new int[transformedInput.length]; + for (int i = 0; i < transformedInput.length; i++) { + userNumber[i] = Character.getNumericValue(transformedInput[i]); + } + return userNumber; + } + public boolean isRestart(){ + String confirmation = readLine(); + return Integer.parseInt(confirmation) == 1; + } + +} diff --git a/src/main/java/baseball/Output.java b/src/main/java/baseball/Output.java new file mode 100644 index 0000000000..aa6d4a07e9 --- /dev/null +++ b/src/main/java/baseball/Output.java @@ -0,0 +1,23 @@ +package baseball; + +import java.util.List; + +public class Output { + public void start(){ + System.out.println("숫자 야구 게임을 시작합니다."); + } + + public void enterNumber(){ + System.out.print("숫자를 입력해주세요 : "); + } + + public void result(List result){ + result.forEach(i -> System.out.print(i + " ")); + System.out.println(" "); + } + + public void endGame(){ + System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요"); + } +} diff --git a/src/test/java/baseball/ApplicationTest.java b/src/test/java/baseball/ApplicationTest.java index 3fa29fa67b..c35ad93c3b 100644 --- a/src/test/java/baseball/ApplicationTest.java +++ b/src/test/java/baseball/ApplicationTest.java @@ -14,7 +14,7 @@ class ApplicationTest extends NsTest { assertRandomNumberInRangeTest( () -> { run("246", "135", "1", "597", "589", "2"); - assertThat(output()).contains("낫싱", "3스트라이크", "1볼 1스트라이크", "3스트라이크", "게임 종료"); + assertThat(output()).contains("낫싱", "3스트라이크", "1스트라이크 1볼", "3스트라이크", "게임 종료"); }, 1, 3, 5, 5, 8, 9 ); diff --git a/src/test/java/baseball/InputTest.java b/src/test/java/baseball/InputTest.java new file mode 100644 index 0000000000..d9b0dbc4de --- /dev/null +++ b/src/test/java/baseball/InputTest.java @@ -0,0 +1,33 @@ +package baseball; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class InputTest { + Input input = new Input(); + @Test + void TestisNotDuplicateWhenUserInputIsDuplicate(){ + String duplicateValue = "111"; + assertThrows(IllegalArgumentException.class, () -> { + input.isNotDuplicate(duplicateValue); + }); + } + + @Test + void testIsNotDuplicateWhenUserInputIsNotDuplicate() { + String nonDuplicateValue = "123"; + assertDoesNotThrow(() -> { + input.isNotDuplicate(nonDuplicateValue); + }); + } + + @Test + void testIsNumber(){ + String notNumber = "abc"; + assertThrows(IllegalArgumentException.class, () -> { + input.isNumber(notNumber); + }); + } +}