백엔드 부트캠프[사전캠프]/추가공부

[창의문제풀기] 야구 스트라이크 문제

sintory-04 2025. 1. 25. 02:47

    자바 문제를 풀다보니 갑자기 옛날에 파이썬으로 풀었던 스트라이크 문제를 해볼까? 라는 생각이 들었다.

    자세한 규칙은 챗GPT한테 정해달라했다.


    숫자 야구 규칙

    게임 목표

    상대가 정한 숫자(4자리의 숫자)를 맞히는 것.

    1. 각 숫자는 중복되지 않음.
    2. 각 자리는 0~9 사이의 숫자를 사용할 수 있음.
    3. 스트라이크와 볼의 정의

    - 스트라이크: 숫자와 위치가 모두 맞을 때.
    - 볼: 숫자는 맞지만 위치가 틀릴 때.

    게임 진행

    상대방은 비밀 숫자를 정함 (예: 123).
    플레이어는 숫자를 추측해서 말함 (예: 135).
    상대방은 "스트라이크"와 "볼"의 개수를 알려줌.
    예: 135를 말했을 때, 1 스트라이크(1), 1 볼(3).
    계속 추측하면서 정답을 맞출 때까지 반복.

    정답

    모든 숫자와 위치가 맞으면 (예: 123) "3 스트라이크!"로 게임 종료.

    예시
    - 비밀 숫자: 527
    - 플레이어 추측: 572
    - 판정: 1 스트라이크(5), 2 볼(7, 2)
    - 다음 추측을 통해 점점 좁혀가야 함.


    1. 틀잡기.

    • 랜덤한 4자리 숫자 출력
    • 사용자 입력 확인
    • 볼, 스트라이크 판단
    • 게임 승리 여부

    크게 4가지를 구현해야한다.

    2. 랜덤한 4자리 숫자 출력

        static Set<Integer> randomSet = new HashSet();
        // randomInt
        public void randomInt(){
            Random random = new Random();
            for (int i=0; randomSet.size() < 4; i++){
                randomSet.add(random.nextInt(10));
            }
        }

    - Set 은 순서가 없고 중복이 허용되지 않는 배열이다.

    - 이번 야구 게임은 중복된 값을 정답으로 내지 않을 것 이기 때문에 set 을 이용했다.

    3. 사용자 입력 확인

    - 사용자 입력 확인은 아래의 조건들을 고려했다.

    - 숫자인가? 4자리인가? 0에서 9999 의 범위인가?

        public int checkInput(String users){        
            try {
                if (users.length() == 4){
                    int changeInt = Integer.parseInt(users);
                    if (changeInt >= 0 && changeInt <= 9999) {
                         return 0;}
                    else { 
                        System.out.println("Out of range."); 
                        return 1;}
                }
                else {
                    System.out.println("Out of range.");
                    return 1;}
            }
            catch (NumberFormatException e) {
                System.out.println("Input Error.");
                return 1;}
        }

    4. 볼, 스트라이크 판단

    - 여기에 Strike 가 4가 되면, boolean 값으로 true를 주었다.( 나중에 승리여부를 확인하기 위해서이다.)
    - 정답 리스트에 있는 숫자가 유저 리스트에도 있냐? 라는 생각을 중심으로 코딩했다.
    - 보다 쉽게 숫자에 접근하기 위해서 ArrayList로 바꾸어주었다.
    - ball 은 out과 strike 만 알아도 알수있어서 따로 count 하지 않았다

        // 볼, 스트라이크인지 확인
        public boolean judgeInput(String users, Set<Integer> randomSet){
            // 볼, 스트라이크, 아웃 선언
            int ball = 0; 
            int strike = 0;
            int out = 0;
            ArrayList<Integer> randomList = new ArrayList<>(randomSet); 
            ArrayList<Integer> usersList = new ArrayList<>();
            for (int i=0; i<users.length(); i++ ){
                usersList.add(Character.getNumericValue(users.charAt(i)));
            }
            // string 도 리스트로 바꾸어 주겠습니다.
            // 정답이 유저 리스트에 있냐 없냐 그걸 판단
            for (int i=0; i<4; i++){
                if(usersList.contains(randomList.get(i))) { 
                    if(randomList.get(i) == usersList.get(i)){
                        strike ++;   
                    }}      
                else {
                    out ++;}}
            ball = 4-out-strike;
            System.out.printf("strike: %d | ball: %d | out: %d\n", strike, ball,out);
            if (strike==4){
                return true;}
            else{return false;}
        }

    5. 게임 승리 여부

    - main 함수에서 승리여부를 판단했다.

    - while 문을 통해서 true(승리여부)가 될때까지 순회하도록 구현했다.

    public static void main(String[] args) {
            Main main = new Main();
            // 랜덤한 4글자의 숫자 생성
            main.randomInt();
            System.out.println(randomSet);
            Scanner scanner = new Scanner(System.in);
            while(true){
                System.out.println("*****************************");
                System.out.println("Please enter a 4-digit number.");
                String userInput = scanner.nextLine();
                int check = main.checkInput(userInput);
                if(check==0) {
                    boolean judge = main.judgeInput(userInput,randomSet);
                    if(judge){
                        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                        System.out.printf("You got the correct answer!! \nThe correct answer is: %s\n",userInput);
                        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                        break;}}
                else {continue;}
            }
        }
    }

    - 설날에 사촌집에서 코딩하다 보니, Online Java Compiler를 이용하게 되었다.

    - 한글은 출력되지 않아 sout 부분은 영어로 출력했다.

    6. 전체 코드

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    // The main method must be in a class named "Main".
    class Main {
        static Set<Integer> randomSet = new HashSet();
        // randomInt
        public void randomInt(){
            Random random = new Random();
            for (int i=0; randomSet.size() < 4; i++){
                randomSet.add(random.nextInt(10));
            }
        }
    
        // 사용자 입력 확인
        public int checkInput(String users){        
            try {
                if (users.length() == 4){
                    int changeInt = Integer.parseInt(users);
                    if (changeInt >= 0 && changeInt <= 9999) {
                         return 0;}
                    else { 
                        System.out.println("Out of range."); 
                        return 1;}
                }
                else {
                    System.out.println("Out of range.");
                    return 1;}
            }
            catch (NumberFormatException e) {
                System.out.println("Input Error.");
                return 1;}
        }
    
        // 볼, 스트라이크인지 확인
        public boolean judgeInput(String users, Set<Integer> randomSet){
            // 볼, 스트라이크, 아웃
            int ball = 0;
            int strike = 0;
            int out = 0;
            ArrayList<Integer> randomList = new ArrayList<>(randomSet); 
            ArrayList<Integer> usersList = new ArrayList<>();
            for (int i=0; i<users.length(); i++ ){
                usersList.add(Character.getNumericValue(users.charAt(i)));
            }
            // string 도 리스트로 바꾸어 주겠습니다.
            // 정답이 유저 리스트에 있냐 없냐 그걸 판단
            for (int i=0; i<4; i++){
                if(usersList.contains(randomList.get(i))) { 
                    if(randomList.get(i) == usersList.get(i)){
                        strike ++;   
                    }}      
                else {
                    out ++;}}
            ball = 4-out-strike;
            System.out.printf("strike: %d | ball: %d | out: %d\n", strike, ball,out);
            if (strike==4){
                return true;}
            else{return false;}
        }
        
        public static void main(String[] args) {
            Main main = new Main();
            // 랜덤한 4글자의 숫자 생성
            main.randomInt();
            // System.out.println(randomSet);
            Scanner scanner = new Scanner(System.in);
            while(true){
                System.out.println("*****************************");
                System.out.println("Please enter a 4-digit number.");
                String userInput = scanner.nextLine();
                int check = main.checkInput(userInput);
                if(check==0) {
                    boolean judge = main.judgeInput(userInput,randomSet);
                    if(judge){
                        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                        System.out.printf("You got the correct answer!! \nThe correct answer is: %s\n",userInput);
                        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
                        break;}}
                else {continue;}
            }
        }
    }

    7. 출력 확인

    Note: /tmp/PswGCD3EyM/Main.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
    [1, 2, 6, 9]
    *****************************
    Please enter a 4-digit number.
    1000
    strike: 1 | ball: 0 | out: 3
    *****************************
    Please enter a 4-digit number.
    1200
    strike: 2 | ball: 0 | out: 2
    *****************************
    Please enter a 4-digit number.
    160000
    Out of range.
    *****************************
    Please enter a 4-digit number.
    gksd
    Input Error.
    *****************************
    Please enter a 4-digit number.
    0012
    strike: 0 | ball: 2 | out: 2
    *****************************
    Please enter a 4-digit number.
    1269
    strike: 4 | ball: 0 | out: 0
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    You got the correct answer!! 
    The correct answer is: 1269
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    
    === Code Execution Successful ===

    - 정상 작동 여부 확인을 위해 맨 위에 정답을 출력했다. (코드에서는 주석처리했다.)