TIL/Project

TIL 2024-10-21 (숫자 야구 게임 - 1)

myoma 2024. 10. 21. 20:51

1 ) 숫자 야구 게임.

  • 이번 개인 프로젝트는 숫자 야구 게임을 만드는 것인데 위와 같은 조건을 충족해야한다.
  • 한 부분에서 되게 오랜 시간동안 막혀서 많이 진행하진 못했다.

 

public class Baseballgame {

    private static int[] ran_num = new int[3];
    Integer[] arr={1, 2, 3, 4, 5, 6, 7, 8, 9};
    List<Integer> arrlist =Arrays.asList(arr);

    public Baseballgame() {

        Collections.shuffle(arrlist);
        arrlist.toArray(arr);

        for(int i = 0; i < 3; i++) {
            ran_num[i] = arrlist.get(i);
        }
        System.out.println(Arrays.toString(ran_num));
    }
}
  • 맨처음 Math의 Random 클래스를 사용하려고 하였으나, 수정 및 보완에 번거러움이 있으며 코드의 효율문제 발생.
    • 위에 조건을 충족하기에 위해 처음에 3자리의 Integer을 한 번에 받아 ArrayList를 사용하여 한 자릿수 마다 list에 저장하여 조건을 충족하기 위해 코드 작성.
      • 코드가 복잡하고 길어지는 문제 발생 (가독성 문제 발생)
      • 반복문의 사용으로 비효율
        • 해결책 : 1 ~ 9 까지의 배열을 만들고 배열을 shuffle() 로 배열을 섞어 앞에 3자리만 가져오는 방식 채택.

- 위에 전역변수 선언은 뒤에 문제들을 해결하기 위해 작성된 것 입니다.

 

 

 

  • 정답을 맞추기 위한 숫자 입력하기
    • 여기서 생각보다 오랜 시간이 할애되었지만 모르던 개념들을 알아가는 시간을 가질 수 있었다.
public void play() {
        Scanner sc = new Scanner(System.in);
        boolean flag = true;


        while (flag) {
            System.out.println("3자리 숫자를 입력하시오 : ");
             int input = sc.nextInt();
            if (input < 100 || input > 999) {
                System.out.println("3자리를 입력해주세요!");
                continue;
            }
            flag = validateInput(input);
    }
}
  • 여기서는 3개의 입력 숫자를 한 번에 받아야한다. ex) 123, 111, 523....
  • 위에 랜덤 숫자 3개는 각각 하나씩 따로 받았기에 코드도 복잡하지 않고 길지 않았지만, 여기선 조금 길어진다.
  • 일단 숫자를 입력할 때 2자리 숫자면 안되고, 중복되어선 안되고, 자릿수에 0이 있어선 안된다.
    • 자릿 수 0, 중복 숫자, 2자리 숫자 X

 

protected boolean validateInput(int input) {
        //각 자릿수 0이 아니고 중복 숫자 X, 문자 X

        ArrayList<Integer> list = new ArrayList<Integer>();


        while (input > 0) {
            list.add(input % 10);
            input /= 10;
        }

        if (list.get(0) == 0 || list.get(1) == 0 || list.get(2) == 0) {
            System.out.println("0 불가!");
            return true;
        } else if (list.get(0) == list.get(1) || list.get(0) == list.get(2) || list.get(1) == list.get(2)) {
            System.out.println("중복 불가!");
            return true;
        }
    return false;
}
  • 각 자릿 수 마다 조건을 충족하기 위해 자릿 수를 하나씩 뽑는 방법을 채택.
    • ArrayList 를 하나 만들고, 그 리스트에 각 자릿 수를 하나씩 넣어준다.
    • 넣어주는 방법은 나머지 연산을 사용했는데, input이 0보다 작아질 때 까지 실행하는데
    • input % 10 을 하면 맨 뒤에 자릿 수가 나오기에 이런 방식으로 한 자릿 수를 넣어주고 아래에 바로 input /= 10; 을 해주어 넣어준 자릿 수를 날려버린다.
    • ex) 123 % 10 = 3,  123/10= 12 -> 12%10 = 2. 12/10 = 1 -> 1%10 = 1, 1/10 = 0
    • int형으로 나누기에 뒤에 소수점이 날아간다는 걸 생각하면 된다.
  • 여기서 문제가 발생하는데
    • 조건식을 세우는 건 어렵지 않았으나 조건이 충족되었을 때 처음에 play();로 다시 돌아가는 재귀함수 방법을 선택.
      • 문제 발생. input에 기존에 적었던 데이터들까지 모두 한 번에 다 출력된다.
      • ex) 원래는 100을 적으면 "0 불가!" 가 나오고 다시 입력하는데 
      • 마지막에 제대로 된 숫자를 적고 나서 100까지 같이 input에 출력된다.
        • 해결!
        • 같이 출력되는 이유 : 재귀함수 말그래도 다시 자신으로 돌아가는 함수.
        • 100을 적으면 "0불가"를 출력하고 함수 진행을 잠시 멈추고 play()로 다시 돌아감.
        • 여기서 play()로 다시 돌아가서 제대로 된 숫자를 입력하여 메서드를 탈출하면 그 전에 100으로 입력했던 함수가 이어서 다시 함수를 시작한다.
        • 그렇기에 256를 적어도 뒤에 100이 다시 실행됌.
        • return true; 로 바꿔주어 문제 해결.
        • 조건이 충족되면 while문을 멈춰야함으로 return false; 
  • 스트라이크 조건은 어렵지 않게 바로 구현.
  • 프로젝트 뼈대 구성에서 볼과 스트라이크 메서드를 따로 구현하였는데,
  • 볼을 처리할 때 스트라이크와 별개로 떨어져 있기에 간단하게 해결 불가능.
    • 기존에 코드를 짜기 전에 생각한 구성은 이중for문을 사용하여 스트라이크와 볼을 동시에 처리할 생각.
    • 하지만 메서드가 두 개 따로 동작.
    • 메서드 2개를 이어줄 생각.

 

 

'TIL > Project' 카테고리의 다른 글

Trouble Shooting (숫자 야구 게임)  (0) 2024.10.25
TIL 2024-10-22 (숫자 야구 게임 - 2)  (0) 2024.10.22
TIL 2024-10-16 (Calculate Project)  (0) 2024.10.16
[KPT 회고록] (mini project)  (0) 2024.10.08
TIL 2024-10-02(미니 프로젝트 1.)  (1) 2024.10.02