Java Number Baseball Game TIL_2

coldrice99·2024년 9월 13일
0

📝 Today I Learned (TIL): 게임 진행 횟수와 시도 횟수 관리 및 출력 문제 해결


💡 문제: 게임 진행 횟수와 시도 횟수 관리 및 출력 문제

🐞 문제 상황:

오늘 가장 어려웠던 부분은 게임 진행 횟수게임별 시도 횟수를 관리하고 출력하는 로직을 구현하는 것이었다. 게임이 진행될 때마다 게임 횟수시도 횟수를 기록해야 하는데, 이를 각각 다른 클래스에서 처리하고, 나중에 출력하는 방식이 복잡했다.
BaseballGame 클래스에서 횟수를 저장하고, 이를 BaseballGameDisplay에서 출력하는 메서드를 만들어, 이를 Main 클래스에서 호출하는 과정에서 어려움을 겪었다.
책임 분리기록 출력 로직을 적절하게 배치하는 것이 가장 큰 도전이었다.


🔧 해결 방법:
  1. 게임 횟수와 시도 횟수의 분리:

    • 게임 횟수Main 클래스에서 직접 관리하고, 시도 횟수BaseballGame 클래스의 play() 메서드가 반환하는 방식으로 분리하여 관리하였다.
    • 이를 통해 게임별 시도 횟수를 기록하고, 나중에 이 기록을 BaseballGameDisplay 클래스에서 출력할 수 있도록 하였다.
  2. 책임 분리:

    • 게임 기록 관리Main 클래스에서 관리하고, 출력 로직BaseballGameDisplay 클래스에서 처리하도록 하여 각 클래스의 역할을 명확하게 분리하였다.
    • BaseballGame은 게임 로직을 처리하고, play() 메서드가 시도 횟수를 반환하여 Main에서 기록을 관리하게 하였다.

🔍 코드 구현:
  1. BaseballGame 클래스: 게임이 끝나면 시도 횟수를 반환하도록 play() 메서드를 구현.
public class BaseballGame {
    private Set<Integer> answerSet;
    private BaseballGameDisplay display = new BaseballGameDisplay();

    public int play() {
        Scanner sc = new Scanner(System.in);
        int attempts = 0;  // 시도 횟수 추적

        // 새로운 게임 시작 시 정답 생성
        this.answerSet = generateAnswerSet();
        System.out.println("정답은 " + answerSet);  // 디버깅용 출력

        while (true) {
            System.out.println("숫자 3개를 입력하세요.");
            List<Integer> inputList = new ArrayList<>();
            boolean isValid = false;

            // 입력값 검증 및 시도 횟수 계산
            while (!isValid) {
                try {
                    int input = sc.nextInt();
                    switch (validateInput(input, inputList)) {
                        case "중복":
                            System.out.println("중복된 숫자는 입력할 수 없습니다.");
                            break;
                        case "세자리x":
                            System.out.println("세 자리 숫자만 입력 가능합니다.");
                            break;
                        case "정상":
                            isValid = true;
                            break;
                    }
                } catch (InputMismatchException e) {
                    System.out.println("숫자만 입력 가능합니다.");
                    sc.next();  // 입력 버퍼 초기화
                }
            }

            attempts++;  // 시도 횟수 증가

            // 스트라이크와 볼 계산
            long strikes = countStrikeAndBall(inputList, true);
            long balls = countStrikeAndBall(inputList, false);

            // 힌트 출력
            display.displayHint((int) strikes, (int) balls);

            // 정답을 맞춘 경우 시도 횟수를 반환하고 게임 종료
            if (strikes == 3) {
                System.out.println("정답입니다! 게임이 종료되었습니다.");
                return attempts;  // 시도 횟수 반환
            }
        }
    }
    
    // 정답 생성 메서드 및 기타 로직 생략...
}
  1. Main 클래스: 게임 기록을 관리하고 BaseballGameDisplay를 통해 기록을 출력.
public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        BaseballGame game = new BaseballGame();  // BaseballGame 인스턴스 생성
        BaseballGameDisplay display = new BaseballGameDisplay();  // BaseballGameDisplay 인스턴스 생성
        List<Integer> gameRecords = new ArrayList<>();  // 각 게임의 시도 횟수를 저장할 리스트
        int gameCount = 0;  // 게임 횟수 추적

        System.out.println("환영합니다! 원하시는 번호를 입력해주세요.");
        System.out.println("1. 게임 시작하기 " +
                "2. 게임 기록 보기 " +
                "3. 종료하기");

        while (true) {
            int choice = sc.nextInt();
            switch (choice) {
                case 1:
                    System.out.println("< 게임을 시작합니다 >");
                    int attempts = game.play();  // 게임을 진행하고 시도 횟수를 반환받음
                    gameCount++;  // 게임 횟수 증가
                    gameRecords.add(attempts);  // 게임 기록 저장
                    break;
                case 2:
                    // BaseballGameDisplay 클래스를 사용하여 게임 기록 출력
                    display.displayGameRecords(gameRecords);
                    break;
                case 3:
                    System.out.println("프로그램을 종료합니다.");
                    return;  // 프로그램 종료
                default:
                    System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
            }
        }
    }
}
  1. BaseballGameDisplay 클래스: 기록을 출력하는 메서드 구현.
public class BaseballGameDisplay {

    public void displayGameRecords(List<Integer> gameRecords) {
        if (gameRecords.isEmpty()) {
            System.out.println("아직 진행된 게임이 없습니다.");
        } else {
            for (int i = 0; i < gameRecords.size(); i++) {
                System.out.println((i + 1) + "번째 게임 : 시도 횟수 - " + gameRecords.get(i));
            }
        }
    }

    // 힌트 출력 메서드도 생략...
}

🏁 결과: Lv3 완성

  • 게임 진행 횟수와 시도 횟수를 분리하여 각각 적절하게 관리하고, BaseballGameDisplay 클래스에서 기록을 출력하는 방식으로 문제를 해결하였다.
  • 게임 기록 관리와 출력의 책임을 적절히 나누어 각 클래스의 역할을 명확하게 하였으며, Main에서 손쉽게 게임 기록을 확인할 수 있게 되었다.

✨ 배운 점:

  • 책임 분리를 통해 각 클래스가 명확한 역할을 가지게 하고, 이를 통해 유지보수성과 가독성을 높일 수 있다.
  • 클래스 간 협력을 고려한 설계가 복잡한 로직을 해결하는 데 중요한 역할을 한다.

https://github.com/coldrice99/NumberBaseballGame.git

profile
서두르지 않으나 쉬지 않고

0개의 댓글