diff --git a/README.md b/README.md index 8d7e8aee..11e05b90 100644 --- a/README.md +++ b/README.md @@ -1 +1,31 @@ -# java-baseball-precourse \ No newline at end of file +# java-baseball-precourse +* Utilty Class + * 난수 생성 함수 + * digit 범위의 3가지 난수를 중복되지 않을 때까지 뽑음. + * 난수 생성 시에는 Math.random() 사용 + * 3자리 난수를 int[]로 반환 + * 입력 받는 함수 + * Scanner()를 사용해서 사용자 입력을 String으로 받고 반환. + * 입력값 유효성 검사 함수 1 + * 파라미터로 String을 받음 + * 길이가 3이 아닌 경우 throw + * 입력이 digit의 조합이 아닌 경우 throw + * 입력 digit이 중복되는 경우 throw + * 입력을 int[]로 반환 + * strike 판정 함수 + * 각 자릿수를 비교해서 strike 개수를 int로 반환 + * ball 판정 함수 + * 다른 자릿수를 비교하여 ball 개수를 int로 반환 + * 난수도, 입력값도 중복이 없다고 가정했으므로 로직은 유효 + * 출력문 반환 함수 + * 파라미터로 strike 개수와 ball 개수를 받아 모두 0이면 "낫싱" 반환 + * ball 개수가 0이 아니면 (ball 개수) + "볼 "을 저장, 0이라면 빈 문자열을 저장 + * strike 개수가 0이 아니면 위에서 저장된 문자열에 (strike 개수) + "스트라이크"를 붙여서 반환, 0이라면 위에서 저장한 문자열만 반환 + * 종료 후 출력 함수 + * 파라미터로 strike 개수를 받아 3이 아니면 빈 문자열 반환 + * 3이라면 안내문 출력 및 입력 받는 함수를 호출하여 입력 받기 + * 입력값 유효성 검사 함수 2 + * 파라미터로 String과 strike 개수를 받음 + * strike 개수가 3이 아니면 true 반환 + * "1"인 경우 true 반환 + * "2"인 경우 false 반환 diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 00000000..981f0b47 --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,51 @@ +public class Application { + + public static void main(String[] args) { + boolean continueFlag = true; + boolean makeFlag = true; + int[] randomNumbers = Utility.makeRandomNumbers(); + int[] userNumbers; + + while (continueFlag) { + if (makeFlag) { + makeFlag = false; + randomNumbers = Utility.makeRandomNumbers(); + } + + System.out.print("숫자를 입력해 주세요 : "); + String userString = Utility.getUserString(); + + try { + Utility.checkStringLength(userString); + Utility.checkStringDistinct(userString); + Utility.checkStringDigit(userString); + } catch (IllegalArgumentException e) { + System.out.print("올바르지 않은 입력입니다. "); + break; + } + + userNumbers = Utility.stringToIntArray(userString); + + int strike = Utility.strikeCount(randomNumbers, userNumbers); + int ball = Utility.ballCount(randomNumbers, userNumbers); + + System.out.println(Utility.getStrikeBall(strike, ball)); + + Utility.printEndMessage(strike); + + if (strike == 3) { + userString = Utility.getUserString(); + makeFlag = true; + } + + try { + continueFlag = Utility.checkKeepGoing(userString, strike); + } catch (IllegalArgumentException e) { + System.out.print("올바르지 않은 입력입니다. "); + break; + } + } + + System.out.println("애플리케이션을 종료합니다."); + } +} diff --git a/src/main/java/Utility.java b/src/main/java/Utility.java new file mode 100644 index 00000000..7fe55eee --- /dev/null +++ b/src/main/java/Utility.java @@ -0,0 +1,133 @@ +import java.util.HashSet; +import java.util.Scanner; + +public class Utility { + + private Utility() { + } + + public static int[] makeRandomNumbers() { + boolean[] flags = new boolean[10]; + int[] randomNumbers = new int[3]; + int count = 0; + + while (count < 3) { + int temp = (int) (Math.random() * 9) + 1; + if (flags[temp]) { + continue; + } else { + randomNumbers[count] = temp; + flags[temp] = true; + count += 1; + } + } + + return randomNumbers; + } + + public static String getUserString() { + Scanner sc = new Scanner(System.in); + String userString = sc.nextLine(); + + return userString; + } + + public static void checkStringLength(String userString) { + if (userString.length() != 3) { + throw new IllegalArgumentException(); + } + } + + public static void checkStringDistinct(String userString) { + HashSet tempSet = new HashSet<>(); + + for (int i = 0; i < userString.length(); i++) { + tempSet.add(userString.charAt(i)); + } + + if (tempSet.size() != userString.length()) { + throw new IllegalArgumentException(); + } + } + + public static void checkStringDigit(String userString) { + for (int i = 0; i < userString.length(); i++) { + int temp = (int) userString.charAt(i) - (int) '0'; + if (temp < 1 || temp > 9) { + throw new IllegalArgumentException(); + } + } + } + + public static int[] stringToIntArray(String userString) { + int[] userNumbers = new int[3]; + + for (int i = 0; i < 3; i++) { + int temp = (int) userString.charAt(i) - (int) '0'; + userNumbers[i] = temp; + } + + return userNumbers; + } + + public static int strikeCount(int[] randomNumbers, int[] userNumbers) { + int strike = 0; + + for (int i = 0; i < 3; i++) { + if (randomNumbers[i] == userNumbers[i]) { + strike += 1; + } + } + + return strike; + } + + public static int ballCount(int[] randomNumbers, int[] userNumbers) { + int ball = 0; + + if (userNumbers[0] == randomNumbers[1] || userNumbers[0] == randomNumbers[2]) { + ball += 1; + } + if (userNumbers[1] == randomNumbers[0] || userNumbers[1] == randomNumbers[2]) { + ball += 1; + } + if (userNumbers[2] == randomNumbers[0] || userNumbers[2] == randomNumbers[1]) { + ball += 1; + } + + return ball; + } + + public static String getStrikeBall(int strike, int ball) { + if (strike == 0 && ball == 0) { + return "낫싱"; + } else if (ball == 0) { + return strike + "스트라이크"; + } else if (strike == 0) { + return ball + "볼"; + } else { + return ball + "볼 " + strike + "스트라이크"; + } + } + + public static void printEndMessage(int strike) { + if (strike == 3) { + System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료"); + System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + } + } + + public static boolean checkKeepGoing(String userString, int strike) { + if (strike != 3) { + return true; + } else { + if (userString.equals("1")) { + return true; + } else if (userString.equals("2")) { + return false; + } else { + throw new IllegalArgumentException(); + } + } + } +} diff --git a/src/test/java/UtilityTest.java b/src/test/java/UtilityTest.java new file mode 100644 index 00000000..d0549b00 --- /dev/null +++ b/src/test/java/UtilityTest.java @@ -0,0 +1,124 @@ +import java.util.HashSet; +import org.junit.jupiter.api.Test; +import org.assertj.core.api.Assertions; + +class UtilityTest { + + @Test + void testMakeRandomNumbers() { + // 난수를 체크하므로 충분히 많은 테스트를 반복 + for (int i = 0; i < 1000; i++) { + int[] randomNumbers = Utility.makeRandomNumbers(); + + Assertions.assertThat(randomNumbers).hasSize(3); + + HashSet tempSet = new HashSet<>(); + for (int randomNumber : randomNumbers) { + tempSet.add(randomNumber); + } + Assertions.assertThat(randomNumbers).hasSize(tempSet.size()); + + for (int j = 0; j < 3; j++) { + Assertions.assertThat(randomNumbers[j]).isBetween(1, 9); + } + } + } + + @Test + void testCheckStringLength() { + Assertions.assertThatCode(() -> Utility.checkStringLength("123")) + .doesNotThrowAnyException(); + Assertions.assertThatCode(() -> Utility.checkStringLength("abc")) + .doesNotThrowAnyException(); + Assertions.assertThatCode(() -> Utility.checkStringLength("000")) + .doesNotThrowAnyException(); + Assertions.assertThatThrownBy(() -> Utility.checkStringLength("")) + .isInstanceOf(IllegalArgumentException.class); + Assertions.assertThatThrownBy(() -> Utility.checkStringLength("11111")) + .isInstanceOf(IllegalArgumentException.class); + Assertions.assertThatThrownBy(() -> Utility.checkStringLength("zbcda")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testCheckStringDistinct() { + Assertions.assertThatCode(() -> Utility.checkStringDistinct("123")) + .doesNotThrowAnyException(); + Assertions.assertThatCode(() -> Utility.checkStringDistinct("123456789")) + .doesNotThrowAnyException(); + Assertions.assertThatCode(() -> Utility.checkStringDistinct("abc")) + .doesNotThrowAnyException(); + Assertions.assertThatThrownBy(() -> Utility.checkStringDistinct("111")) + .isInstanceOf(IllegalArgumentException.class); + Assertions.assertThatThrownBy(() -> Utility.checkStringDistinct("12345678910")) + .isInstanceOf(IllegalArgumentException.class); + Assertions.assertThatThrownBy(() -> Utility.checkStringDistinct("aa")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testCheckStringDigit() { + Assertions.assertThatCode(() -> Utility.checkStringDigit("123")).doesNotThrowAnyException(); + Assertions.assertThatCode(() -> Utility.checkStringDigit("12345678911112")) + .doesNotThrowAnyException(); + Assertions.assertThatCode(() -> Utility.checkStringDigit("")).doesNotThrowAnyException(); + Assertions.assertThatThrownBy(() -> Utility.checkStringDigit("1k3")) + .isInstanceOf(IllegalArgumentException.class); + Assertions.assertThatThrownBy(() -> Utility.checkStringDigit("abc")) + .isInstanceOf(IllegalArgumentException.class); + Assertions.assertThatThrownBy(() -> Utility.checkStringDigit("1111111110")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void testStringToIntArray() { + int[] temp1 = {1, 2, 3}; + Assertions.assertThat(Utility.stringToIntArray("123")).isEqualTo(temp1); + int[] temp2 = {5, 4, 3}; + Assertions.assertThat(Utility.stringToIntArray("543")).isEqualTo(temp2); + int[] temp3 = {2, 4, 6}; + Assertions.assertThat(Utility.stringToIntArray("246")).isEqualTo(temp3); + } + + @Test + void testStrikeCount() { + int[] randomNumbers = {1, 2, 3}; + int[] userNumbers = {1, 2, 3}; + Assertions.assertThat(Utility.strikeCount(randomNumbers, userNumbers)).isEqualTo(3); + int[] userNumbers2 = {1, 4, 3}; + Assertions.assertThat(Utility.strikeCount(randomNumbers, userNumbers2)).isEqualTo(2); + int[] userNumbers3 = {1, 4, 5}; + Assertions.assertThat(Utility.strikeCount(randomNumbers, userNumbers3)).isEqualTo(1); + int[] userNumbers4 = {2, 4, 5}; + Assertions.assertThat(Utility.strikeCount(randomNumbers, userNumbers4)).isEqualTo(0); + } + + @Test + void testBallCount() { + int[] randomNumbers = {1, 2, 3}; + int[] userNumbers = {2, 3, 1}; + Assertions.assertThat(Utility.ballCount(randomNumbers, userNumbers)).isEqualTo(3); + int[] userNumbers2 = {1, 3, 2}; + Assertions.assertThat(Utility.ballCount(randomNumbers, userNumbers2)).isEqualTo(2); + int[] userNumbers3 = {5, 6, 1}; + Assertions.assertThat(Utility.ballCount(randomNumbers, userNumbers3)).isEqualTo(1); + int[] userNumbers4 = {1, 2, 3}; + Assertions.assertThat(Utility.ballCount(randomNumbers, userNumbers4)).isEqualTo(0); + } + + @Test + void testGetStrikeBall() { + Assertions.assertThat(Utility.getStrikeBall(3, 0)).isEqualTo("3스트라이크"); + Assertions.assertThat(Utility.getStrikeBall(1, 1)).isEqualTo("1볼 1스트라이크"); + Assertions.assertThat(Utility.getStrikeBall(0, 2)).isEqualTo("2볼"); + Assertions.assertThat(Utility.getStrikeBall(0, 0)).isEqualTo("낫싱"); + } + + @Test + void testCheckKeepGoing() { + Assertions.assertThat(Utility.checkKeepGoing("1", 3)).isTrue(); + Assertions.assertThat(Utility.checkKeepGoing("234", 2)).isTrue(); + Assertions.assertThat(Utility.checkKeepGoing("2", 3)).isFalse(); + Assertions.assertThatThrownBy(() -> Utility.checkKeepGoing("3", 3)).isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file