diff --git a/README.md b/README.md index fcf3f057..9daa73aa 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,26 @@ ## 과제 제출 과정 * [과제 제출 방법](https://github.com/next-step/nextstep-docs/tree/master/ent-precourse) + +## 구현 기능 목록 +* 입력을 위한 안내 메세지 출력 +* 실제 n자리 숫자 입력받는 기능 +* 입력받은 값이 정수가 맞는지 검증 +* 입력받은 값이 n자리 정수가 될때까지 반복해서 입력받는 기능 +* 입력받은 문자열을 정수 배열로 변환 +* 입력받은 정수 배열에 0이 포함되었는지 검증 +* 입력받은 정수 배열에 중복된 값이 포함되었는지 검증 +* 입력받은 정수와 정답의 비교 결과를 출력 +* 비교 결과 문자열에 스트라이크 개수를 추가 +* 비교 결과 문자열에 볼 개수를 추가 +* 비교 결과에 스트라이크와 볼 모두가 없는 경우의 문자열 추가 +* 정답을 맞춘 경우 게임을 계속할지 여부의 입력을 위한 메세지 출력 및 입력받는 기능 +* 입력받은 종료 옵션이 1 또는 2인지 검증 +* 야구 게임 실행 기능 +* 야구 게임 중 정수를 입력받고 비교하는 부분에 해당하는 기능 +* 1~9 사이의 중복되지 않는 수로 이루어진 n자리 숫자 생성 +* 정답을 콘솔에 출력하는 기능 +* 입력받은 정수와 정답의 비교 +* 입력받은 정수와 정답간의 볼 개수 계산 +* 입력받은 정수와 정답간의 스트라이크 개수 계산 +* 입력받은 정수의 특정 순번의 숫자의 스트라이크 여부 판단 기능 \ No newline at end of file diff --git a/src/main/java/Baseball.java b/src/main/java/Baseball.java new file mode 100644 index 00000000..45c31487 --- /dev/null +++ b/src/main/java/Baseball.java @@ -0,0 +1,246 @@ +import java.util.Scanner; +import java.util.Arrays; +import java.util.Random; +import java.lang.String; + +public class Baseball { + int length; + + Baseball(int ans_length) { + length = ans_length; + } + // print input message + void print_input_msg() { + System.out.print("숫자를 입력해주세요 : "); + } + + // scan input integer + int[] scan_input_num() { + Scanner sc = new Scanner(System.in); + + return verify_input_num(sc.nextLine()); + } + + // verify input integer + int[] verify_input_num(String input_line) { + Scanner sc = new Scanner(System.in); + int[] input_arr = isNumeric(input_line) ? str_to_arr(input_line) : new int[0]; + + while (input_arr.length != length || zero_contain(input_arr) || isDuplicate(input_arr)) { + System.out.printf("1~9사이의 중복되지 않은 숫자로 이루어진 %d자리 정수를 입력해주세요%n", length); + print_input_msg(); + + String tmp = sc.nextLine(); + input_arr = isNumeric(tmp) ? str_to_arr(tmp) : new int[0]; + } + + return input_arr; + } + + // check whether input is integer + boolean isNumeric(String input) { return input != null && input.matches("[1-9]+"); } + + // string to int array + int[] str_to_arr(String input) { + int[] input_arr = new int[input.length()]; + + for (int i = 0; i < input.length(); i++) { + input_arr[i] = input.charAt(i) - '0'; + } + + return input_arr; + } + + // return whether input integer contains zero + boolean zero_contain(int[] input_arr) { + int result = 1; + + for (int i : input_arr) { + result *= i; + } + + return result == 0; + } + + // verify input number duplication + boolean isDuplicate(int[] input_arr) { + for (int i = 0; i < length - 1; i++) { + for (int j = i + 1; j < length; j++) { + if (input_arr[i] == input_arr[j]) { + return true; + } + } + } + + return false; + } + + // print result of compare & return end or not + boolean compare_result(int[] result) { + if (result[0] == length) { + return true; + } + + System.out.println(result_msg(ball_msg(result[1], strike_msg(result[0])))); + + return false; + } + + // add number of strikes to result message + String strike_msg(int strike_num) { + String msg = ""; + + if (strike_num != 0) { + msg += String.format("%d스트라이크 ", strike_num); + } + + return msg; + } + + // add number of balls to result message + String ball_msg(int ball_num, String msg) { + if (ball_num != 0) { + msg += String.format("%d볼", ball_num); + } + + return msg; + } + + // add 'nothing' message if there is no strike and ball + String result_msg(String msg) { + if (msg.length() == 0) { + msg += "낫싱"; + } + + return msg.trim(); + } + + // print end message of game & return end type + int end() { + Scanner sc = new Scanner(System.in); + + System.out.printf("%d개의 숫자를 모두 맞히셨습니다! 게임 종료%n", length); + System.out.println("게임을 새로 시작하시려면 1, 종료하려면 2를 입력하세요."); + + return verify_end_type(sc.nextLine()); + } + + // verify end input + int verify_end_type(String end_input) { + Scanner sc = new Scanner(System.in); + int end_type = isNumeric(end_input) ? Integer.parseInt(end_input) : 0; + + while (end_type != 1 && end_type != 2) { + System.out.println("게임을 새로 시작하시려면 1, 종료하려면 2를 입력하세요."); + + String tmp = sc.nextLine(); + end_type = isNumeric(tmp) ? Integer.parseInt(tmp) : 0; + } + + return end_type; + } + + // baseball game + void bsb_game() { + int end_type = 1; + + while (end_type == 1) { + Computer comp = new Computer(length); + + main_game(comp); + + end_type = end(); + } + } + + // main game part + void main_game(Computer comp) { + boolean is_end = false; + + while (!is_end) { + int[] result = new int[2]; + + print_input_msg(); + comp.compare(scan_input_num(), result); + + is_end = compare_result(result); + } + } + + // main function + public static void main(String[] args) { + Baseball bsb = new Baseball(3); + + bsb.bsb_game(); + } +} + +class Computer { + int length; + int[] answer; + Random random = new Random(System.nanoTime()); + + Computer(int ans_length) { + length = ans_length; + answer = new int[length]; + + for (int i = 0; i < length; i++) { + answer[i] = random.nextInt(9) + 1; + + for (int j = 0; j < i; j++) { + if (answer[i] == answer[j]) { + i--; + break; + } + } + } + } + + // print answer + void print_answer() { + System.out.println(Arrays.toString(answer)); + } + + // set answer + void set_answer(int[] new_ans) { + for (int i = 0; i < length; i++) { + answer[i] = new_ans[i]; + } + } + + // compare input with answer + void compare(int[] input_arr, int[] result) { + + result[0] = count_strike(input_arr); + result[1] = count_ball(input_arr); + } + + // return ball count + int count_ball(int[] input_arr) { + int ball_cnt = 0; + + for (int i = 0; i < length; i++) { + for (int j = 0; j < length; j++) { + ball_cnt += i != j && input_arr[i] == answer[j] ? 1 : 0; + } + } + + return ball_cnt; + } + + // return strike count + int count_strike(int[] input_arr) { + int strike_cnt = 0; + + for (int i = 0; i < length; i++) { + strike_cnt += isStrike(input_arr[i], i); + } + + return strike_cnt; + } + + // return whether strike + int isStrike(int input_elem, int order_num) { + return answer[order_num] == input_elem ? 1 : 0; + } +} diff --git a/src/test/java/BaseballTest.java b/src/test/java/BaseballTest.java new file mode 100644 index 00000000..5fe60a0d --- /dev/null +++ b/src/test/java/BaseballTest.java @@ -0,0 +1,98 @@ +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class BaseballTest { + + @AfterEach + void tearDown() { + } + + @Test + void isNumeric() { + String true_test = "123"; + String false_test = "12a"; + Baseball bsb = new Baseball(3); + + assertTrue(bsb.isNumeric(true_test)); + assertFalse(bsb.isNumeric(false_test)); + } + + @Test + void str_to_arr() { + String test = "123"; + int[] answer = {1, 2, 3}; + Baseball bsb = new Baseball(3); + + assertArrayEquals(bsb.str_to_arr(test), answer); + } + + @Test + void zero_contain() { + int[] true_test = {1, 0, 2}; + int[] false_test = {5, 6, 7}; + Baseball bsb = new Baseball(3); + + assertTrue(bsb.zero_contain(true_test)); + assertFalse(bsb.zero_contain(false_test)); + } + + @Test + void isDuplicate() { + int[] true_test = {1, 3, 1}; + int[] false_test = {5, 6, 7}; + Baseball bsb = new Baseball(3); + + assertTrue(bsb.isDuplicate(true_test)); + assertFalse(bsb.isDuplicate(false_test)); + } + + @Test + void strike_msg() { + int test_1 = 5; + int test_2 = 0; + String answer_1 = "5스트라이크 "; + String answer_2 = ""; + Baseball bsb = new Baseball(3); + + assertEquals(bsb.strike_msg(test_1), answer_1); + assertEquals(bsb.strike_msg(test_2), answer_2); + } + + @Test + void ball_msg() { + int test_1 = 3; + int test_2 = 0; + String test_str_1 = "5스트라이크 "; + String test_str_2 = ""; + String answer_1 = "5스트라이크 3볼"; + String answer_2 = "5스트라이크 "; + String answer_3 = "3볼"; + String answer_4 = ""; + Baseball bsb = new Baseball(3); + + assertEquals(bsb.ball_msg(test_1, test_str_1), answer_1); + assertEquals(bsb.ball_msg(test_2, test_str_1), answer_2); + assertEquals(bsb.ball_msg(test_1, test_str_2), answer_3); + assertEquals(bsb.ball_msg(test_2, test_str_2), answer_4); + } + + @Test + void result_msg() { + String test_1 = ""; + String test_2 = "5스트라이크 "; + String test_3 = "3볼"; + String test_4 = "5스트라이크 3볼"; + String answer_1 = "낫싱"; + String answer_2 = "5스트라이크"; + String answer_3 = "3볼"; + String answer_4 = "5스트라이크 3볼"; + Baseball bsb = new Baseball(3); + + assertEquals(bsb.result_msg(test_1), answer_1); + assertEquals(bsb.result_msg(test_2), answer_2); + assertEquals(bsb.result_msg(test_3), answer_3); + assertEquals(bsb.result_msg(test_4), answer_4); + } +} \ No newline at end of file diff --git a/src/test/java/ComputerTest.java b/src/test/java/ComputerTest.java new file mode 100644 index 00000000..502d5421 --- /dev/null +++ b/src/test/java/ComputerTest.java @@ -0,0 +1,61 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ComputerTest { + + @Test + void count_ball() { + int[] bsb_answer = {4, 9, 6}; + int[] test_1 = {1, 2, 3}; + int[] test_2 = {1, 2, 4}; + int[] test_3 = {9, 2, 4}; + int[] test_4 = {9, 6, 4}; + int answer_1 = 0; + int answer_2 = 1; + int answer_3 = 2; + int answer_4 = 3; + Computer cmp = new Computer(3); + cmp.set_answer(bsb_answer); + + assertEquals(cmp.count_ball(test_1), answer_1); + assertEquals(cmp.count_ball(test_2), answer_2); + assertEquals(cmp.count_ball(test_3), answer_3); + assertEquals(cmp.count_ball(test_4), answer_4); + } + + @Test + void count_strike() { + int[] bsb_answer = {4, 9, 6}; + int[] test_1 = {1, 2, 3}; + int[] test_2 = {4, 2, 3}; + int[] test_3 = {4, 2, 6}; + int[] test_4 = {4, 9, 6}; + int answer_1 = 0; + int answer_2 = 1; + int answer_3 = 2; + int answer_4 = 3; + Computer cmp = new Computer(3); + cmp.set_answer(bsb_answer); + + assertEquals(cmp.count_strike(test_1), answer_1); + assertEquals(cmp.count_strike(test_2), answer_2); + assertEquals(cmp.count_strike(test_3), answer_3); + assertEquals(cmp.count_strike(test_4), answer_4); + } + + @Test + void isStrike() { + int[] bsb_answer = {4, 9, 6}; + int order_num = 0; + int test_1 = 5; + int test_2 = 4; + int answer_1 = 0; + int answer_2 = 1; + Computer cmp = new Computer(3); + cmp.set_answer(bsb_answer); + + assertEquals(cmp.isStrike(test_1, order_num), answer_1); + assertEquals(cmp.isStrike(test_2, order_num), answer_2); + } +} \ No newline at end of file