우아한테크코스 1주차 - 숫자 야구

5tr1ker·2023년 11월 3일
0
post-thumbnail

요구 사항

  • 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.
    • 예) 상대방(컴퓨터)의 수가 425일 때
    • 123을 제시한 경우 : 1스트라이크
    • 456을 제시한 경우 : 1볼 1스트라이크
    • 789를 제시한 경우 : 낫싱
  • 위 숫자 야구 게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 서로 다른 3개의 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한 결과를 출력한다.
  • 이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다.
  • 게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

실행 결과

숫자 야구 게임을 시작합니다.
숫자를 입력해주세요 : 123
1볼 1스트라이크
숫자를 입력해주세요 : 145
1볼
숫자를 입력해주세요 : 671
2볼
숫자를 입력해주세요 : 216
1스트라이크
숫자를 입력해주세요 : 713
3스트라이크
3개의 숫자를 모두 맞히셨습니다! 게임 종료
게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.
1
숫자를 입력해주세요 : 123
1볼

접근 방법

- 3자리 랜덤 값 추출

먼저 세 자릿수의 랜덤 값을 추출하기 위해선 서로 다른 수 3개가 필요합니다. 그러기 위해 0~9까지 숫자가 사용됐는지 여부를 확인하기 위한 boolean 배열 을 선언했습니다.
그리고 3번의 순회를 돌면서 사용 여부를 확인하면서 100의 자릿수 10의 자릿수 1의 자릿수를 골랐습니다.
이때 Math.pow(10 , i) 를 이용하여 제곱을 이용해 100 , 10 , 1을 구현했습니다.
이때 0 은 1입니다.

public void createRandomNumber() {
        checkNumber = new boolean[10];
        int number = 0;

        for (int i = 0; i < 3; i++) {
            int randomNumber = pickNumberInRange(1, 9);

            if (checkNumber[randomNumber]) {
                i--;
                continue;
            }

            number += Math.pow(10, 2 - i) * randomNumber;
            checkNumber[randomNumber] = true;
        }

        answer = number;
    }

정답 여부 출력

컴퓨터와 사용자가 선택한 값을 검증하기 위해 위의 boolean 배열 과 각 자릿수를 확인했습니다. 이때 컴퓨터와 사용자의 입력값을 각각 자릿수로 나눠 다음과 같이 확인했습니다.

  • 스트라이크 조건 : 컴퓨터와 사용자의 자릿수에 있는 값 비교
  • 볼 조건 : 스트라이크 조건이 안될 경우 boolean 배열 의 체크 여부를 확인
public boolean isCorrect(int input) {
        int ball = 0;
        int strike = 0;

        int inputDigit_1 = input % 10;
        int answerDigit_1 = answer % 10;
        if (inputDigit_1 == answerDigit_1) {
            strike += 1;
        } else if (checkNumber[inputDigit_1]) {
            ball += 1;
        }

        int inputDigit_10 = input % 100 / 10;
        int answerDigit_10 = answer % 100 / 10;
        if (inputDigit_10 == answerDigit_10) {
            strike += 1;
        } else if (checkNumber[inputDigit_10]) {
            ball += 1;
        }

        int inputDigit_100 = input / 100;
        int answerDigit_100 = answer / 100;
        if (inputDigit_100 == answerDigit_100) {
            strike += 1;
        } else if (checkNumber[inputDigit_100]) {
            ball += 1;
        }

        if (strike == 3) {
            System.out.println("3스트라이크");
            return true;
        }

        if (ball == 0 && strike == 0) {
            System.out.println("낫싱");
        } else if (ball == 0) {
            System.out.println(strike + "스트라이크");
        } else if (strike == 0) {
            System.out.println(ball + "볼");
        } else {
            System.out.printf("%d볼 %d스트라이크\n", ball, strike);
        }
        return false;
    }

회고

다른 사람의 코드를 리뷰하면서 더욱 효율적인 코드를 발견했습니다.
기존에 각 자릿수를 정수형으로 추출하는 것이 아니라 ArrayList 를 활용해서 3개의 요소를 저장합니다. ( 이때 각 100의 자리 , 10의 자리 , 1의 자리에 해당합니다. )

이후 각 인덱스 위치를 참조하여 같을 경우 스트라이크 ( 이때 .get(0) 메서드를 활용합니다. ) , 아닐 경우 contain() 메서드를 이용해 ArrayList 를 활용해 요소가 있다면 볼로 위의 코드보다 직관적이고 빠르게 구현할 수 있다는 것을 알게 되었습니다.

전체 소스 코드

링크 : https://github.com/5tr1ker/woowacourse-1

profile
https://github.com/5tr1ker

0개의 댓글