241024 개인과제2 마무리

물고기가자라면어그로·2024년 10월 25일
0

숫자 설정 및 비교 로직

드디어 진척이 생겼다.

원래는 생성되고 입력되는 숫자를 자릿수별로 일일이 다른 속성으로 필드에 저장해서 이를 비교하려고 했었는데 그렇게 하지 않고 중복검사를 하기 위해 숫자를 넣었던 Set을 List 형식으로 형변환하여 for문을 돌려 (i)번째 자리끼리 비교하기로 했다.

  • 입력한 숫자를 세팅하는 메서드
    - String으로 입력받아 charAt()으로 자릿수별로 뜯어 HashSet에 넣음 (중복검사)
    - 이를 ArrayList로 형변환
    public void settingInput(String InputNumbers) throws BadException {
        HashSet<Integer> checkingSet = new LinkedHashSet<Integer>();

        for(int i = 0 ; i<3 ; i++){
            checkingSet.add(Character.getNumericValue(InputNumbers.charAt(i)));
        }

        while (checkingSet.size() != 3) {
            throw new BadException();
        }
        this.inputNumberList = new ArrayList<>(checkingSet);
    }
  • 입력한 숫자와 랜덤숫자를 비교하는 메서드
    - 각 자리의 수를 비교한 결과를 저장할 ArrayList를 생성
    - for문을 돌리며 랜덤숫자를 저장한 gameNumberList가 입력숫자를 contains 하는지 확인 -> 아니라면 각 List의 i번째 숫자를 비교
    public boolean checkNumbers() {
        ArrayList<String> score = new ArrayList<String>();
        for (int i = 0; i < 3; i++) {
            if (!this.gameNumberList.contains(this.inputNumberList.get(i))) {
                score.add("out");
            } else if (this.inputNumberList.get(i) == this.gameNumberList.get(i)) {
                score.add("strike");
            } else {
                score.add("ball");
            }
        }
    }

결과(힌트) 출력

숫자를 입력하고 나서 얼마나 맞췄는지를 알려줄 힌트를 출력하기 위해
끌어다 쓸 메서드를 새로운 클래스에 따로 만들었다.

  • score 리스트output(strike, ball, out 중 하나)를 매개변수로 입력받아 리스트 안의 output의 개수를 세어 출력
    - frequency함수 사용
    - 개수가 1개 이상일 때만 print()로 찍어 한 줄로 나열되게 함
public class PrintScore {

    public static void printScore(ArrayList<String> score, String output) {
        int numberOfOutput = Collections.frequency(score, output);
        if (numberOfOutput > 0) {
            System.out.print(numberOfOutput + output + " ");
        }
    }
}

게임을 진행하며 이런식으로 힌트가 출력이 된다. 🔽

게임 시도횟수 저장하기

요점은 숫자를 입력하고 결과(힌트)를 받는 것을 반복할 때마다 int 필드를 하나 만들어 +=1 해주면 된다. 그리고 이 시도 횟수를 ArrayList에 기록하면 i 번째 내용물을 get할 때마다 i 번째 판의 시도횟수를 가져올 수 있게 된다.

나는 GameNumber 클래스에 tryNumber를 시도횟수로 저장하고 이를 record라는 ArrayList에 저장했다.

 BaseballGame baseballGame = new BaseballGame(difficultyInput);
                boolean gameWin = false;
                while (!gameWin) {                    //게임 한 판(round) 시작
                    try {
                        gameWin = baseballGame.play(); //게임 구동 -> 한 번의 숫자 입력 후 결과출력
                        baseballGame.tryNumber += 1; //시도 횟수 + 1

                    } catch (BadException e) {
                        System.out.println(e.getMessage());
                    }
                }
                record.add(baseballGame.tryNumber);     //방금 한 게임의 시도횟수 저장
                return false;

그리고 처음이나 게임 한 판이 끝나고 뜨는 시작메뉴에서 2. 기록하기를 누르면 이 record를 조회할 수 있게 했다.

System.out.println("<게임 기록 보기>");
                for (int i = 0; i < record.size(); i++) {
                    System.out.println(i + 1 + "번째 게임 : 시도횟수 - " + record.get(i));
                }

난이도 조절하기

과제의 도전기능 중에는 난이도를 조절하는 기능이 있었다.
게임을 시작했을 때 프로그램이 생성할 숫자의 자릿수를 직접 고를 수 있는 것이다.
지금까지는 3개의 숫자를 맞추면 됐지만 이를 4개, 5개의 숫자도 고른다면 가능케 하는 것이다.

사실 이 부분은 그렇게 어려운 것 같지 않았다.
애초에 숫자를 자리별로 하나하나 따로 필드에 저장하지 않고
(원래 하려고 했던 것처럼 int firstNumber, int secondNumber이런 식으로)
크기가 가변적인 ArrayList에 숫자들이 저장되어있기 때문에 숫자를 원하는 만큼 넣어주기만 하면 되기 때문이다.

그래서 int difficulty 라는 필드를 하나 만들어서 처음에 선택한 난이도를 저장하고, 반복문에 들어있는 3들을 전부 이 difficulty 로 대체해주었다.

과제를 마무리하며 . . .

저번 과제는 필수 기능들만 구현했는데 이번에는 모든 도전 기능들을 완벽하진 않더라도 구현하는 데에 성공했다는 것이 기쁘다.
그리고 저번 과제에서는 예외처리 하는 방법을 잘 이해하지 못한 상태에서 진행했기때문에 모든 예외처리를 while문이나 if문으로 처리했는데 이번에는 예외처리도 시도해보았다는 의의를 가진다.

다만 아쉬운 점은 접근제어를 언제 어떤식으로 써야할지 잘 몰라서 전부 public으로 만들어 프로젝트 안의 모든 클래스를 접근용이하게 만들어 사용했다는 점이다. 마찬가지로 인터페이스나 추상메서드의 경우나 함수형 프로그래밍에 대한 이해도도 좀 떨어져서 이를 사용하지 못했음이 아쉽다. 이런 것들을 사용했으면 복잡한 코딩이 좀 더 단순화되고 잘 정리되었을까 싶다.

0개의 댓글