과제리뷰

[CH3개인과제] 숫자 야구

hahahabbb 2024. 10. 23. 20:08

1) LV0 - 시간/공간 효율, 가독성 상관 없이 구현하기 (Random 클래스, 정적배열)

 

발단 : 정답을 맞추기 위한 세자리 수를 입력받는 부분 구현

전개 : for문으로 세 자리를 각각 입력받았습니다.

위기 : 한 번에 입력하는 게 효율적인데, 한 번에 입력할 경우 인식되지 않았습니다.

절정 : 그래서 세자리 수인 숫자를 입력받고 각각을 % 연산을 통해 배열에 저장했습니다.

결말 : 한 번에 세자리 수를 입력받아 결과를 출력할 수 있었습니다.

//수정 전
for (int i=0;i<DIGITS;i++){
        record[i] = sc.nextInt();
}

입력 예시

//수정 후
int input = sc.nextInt();
for (int i=DIGITS-1;i>=0;i--){
    record[i] = input%10;
    input /= 10;
}

 

2) LV123 - 기본 게임 구현 (Random 클래스, HashSet 클래스 구현)

 

(1) 한 자리 수를 입력하면 0 두 개가 배열에 들어가서 중복된 값으로 처리되는 부분

발단: 입력 받을 때 세 자리 아닌 수나 중복 값을 입력해도 게임이 진행되었습니다.

전개: 중복 값을 입력받을 경우, input값이 세 자리가 아닐 경우를 예외처리했습니다. 

위기: input의 각 자리의 값을 분리할 때 배열에 input%10 값을 넣는데, 한 자리 수를 입력받는 경우 0이 두 개 들어가게 되었습니다. 그래서 자릿수 문제가 아닌 중복값 문제로 처리되었습니다.

절정: 자릿수 예외처리를 먼저 수행한 후, 중복값은 else if로 진행하도록 구현하였습니다.

결말: 한 자리 수 입력에도 "세 자리 수가 아닙니다."를. 출력합니다.

 

3) LV4 - 도전 기능 추가 구현

 

(1) 메뉴 0 입력(자릿수 설정) 시의 객체 생성과 1 입력 시(자릿수 3으로 시작) 시의 객체 생성을 합침

발단: 난이도 조절을 위해 자릿수 설정 메뉴 추가

전개: 메뉴 0 입력 시 자릿수 설정 후 객체를 생성해서 플레이를 진행. 1 입력 시에는 바로 객체 생성해서 플레이 진행하도록 구현 

위기: 자릿수만 다르고 생성되는 객체의 클래스는 동일하기 때문에 비효율적이라고 생각이 들었습니다.

절정: switch-case문에서 0 입력 시 자릿수만 설정하여 1로 넘어가서 객체 생성하도록 하였습니다. 그리고 자릿수가 3-5 사잇값이 아닐 경우 break하도록 구현했습니다. 1의 경우 자릿수 3으로 설정되어야 하므로 게임 새로 시작할 때마다 digits은 3으로 정의하였습니다.

결말 : 불필요한 코드 없이 제대로 작동하였습니다.

            int digits = 3;    // 기본 자릿수 3으로 고정
            System.out.println("\n환영합니다! 원하시는 번호를 입력해주세요.");
            System.out.println("0. 자릿수 설정 1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기");
            int num = sc.nextInt();
            switch(num){
                case 0:
                    System.out.println("설정하고자 하는 자리수를 입력하세요.");
                    digits = sc.nextInt();
                    if (!(2 < digits && digits < 6)) break; // 3자리 ~ 5자리만 입력 가능
                case 1:
                    BaseballGame game = new BaseballGame(digits);   // 객체 생성
                    trialList.add(game.play());     // 게임 진행
                    break;

 

(2) 3 입력 받을 시 종료

발단: 반복문을 종료할 메뉴 구현.

전개: 메뉴 3을 입력 받을 시 종료되도록 구현

위기: case 3에서 break로 종료할 경우, switch문만 종료되기 때문에 반복문 종료가 어려움.

절정: flag를 통해 flag 값이 false가 되면 반복문 종료되도록 하였습니다.

결말: 메뉴 3 입력 시 "<숫자 야구 게임을 종료합니다 >" 메세지와 함께 정상적으로 종료됨을 확인했습니다.

boolean flag = true;    // 탈출 flag 설정
        while(flag){
        ...
        switch(num){
        ...
            case 3:
                    System.out.println("< 숫자 야구 게임을 종료합니다. >");
                    trialList.clear();  // 종료 시 시도횟수 리스트 내용 삭제
                    flag = false;   // while문 종료
                    break;
		...
            }

 

(3) 유효성 검사

발단: 추가 기능 구현 시 자릿수를 입력받아 진행해야 합니다.

전개: 기존 LV123은 세 자리수 고정이라 각 자리수를 record[0], record[1], record[2]로 두고 비교하였습니다.

위기: 자릿수가 4,5일 경우 해당 부분 오류가 납니다.

절정: 자릿수 검사 시에는 for문을 돌려 0이 있으면 false를 반환하도록 하였고, 중복 검사 시에는 이중 for문을 돌려 검사를 진행했습니다.

결말: 다른 자릿수더라도 검사가 정상 작동됨을 확인했습니다.

/* 수정 전 */
	//자릿수 검사2 - for문에서 input을 3번 돌렸을 때 0 값이 들어갔을 경우 세 자리 미만.
        if (record[0]==0 || record[1] == 0 || record[2] == 0) {
            System.out.println("세 자리 수가 아닙니다. 다시 입력해주세요.");
            return false;
        }
        // 중복된 숫자 검사
        else if (record[0]==record[1] || record[0] == record[2] || record[1] == record[2]) {
            System.out.println("중복된 값을 입력하였습니다. 다시 입력해주세요.");
            return false;
        }
/* 수정 후 */
	//자릿수 검사2 - for문에서 input을 digits번 돌렸을 때 0 값이 들어갔을 경우 자릿수 미만.
        for (int r : record) {
            if (r != 0) continue;
            else {
                System.out.println("자릿수가 일치하지 않습니다. 다시 입력해주세요.");
                return false;
            }
        }
        // 중복된 숫자 검사
        for (int i = 0; i < record.length; i++) {
            for (int j = 0; j < i; j++) {
                if (record[i] == record[j]) {  // 중복 검사
                    System.out.println("중복된 값을 입력하였습니다. 다시 입력해주세요.");
                    return false;
                }
            }
        }