-
야구게임 만들기 - 2iOS 앱 개발 부트캠프/TIL 2024. 11. 6. 17:31
어제에 이어 숫자야구 게임을 어느정도 완성하였다.
실행시 입력을 받아 게임을 시작하거나, 종료하거나, 게임 기록을 확인 할 수 있고, 게임 시작 시 입력을 정답과 비교해 스트라이크와 볼 판정을 하여 힌트를 제공한다.
코드 전체 내용은 https://github.com/maxminseok/baseballProject 에서 확인할 수 있다.
현재 상태는 메인 파일에 게임 진행을 위한 코드가 작성되어 있고, 각 기능별 클래스들을 따로 분리하였다.
- Checks 폴더 - 정답이나 입력의 값이 형식에 맞는지 확인하기 위한 각종 check 클래스들을 저장
- GameLogic 폴더 - 게임에 진행에 필요한 스트라이크와 볼 판정 클래스, 정답 생성 클래스 저장
- ConvertNumber 폴더 - 정답이나 입력 숫자를 한 글자씩 배열에 저장하는 클래스 저장
트러블 슈팅
발단
처음에 Lv1~3은 어렵지 않게 작성을 하였고, 이후 Lv 4~6 까지 요구사항까지 어느정도 구현한 뒤에 테스트를 진행하는데 다음과 같은 에러가 발생하였다.
게임을 처음 시작할 때, 기록이 없는 상태에서 2를 입력해 기록 보기를 누르면 에러가 발생한 것이다.
gameCount는 1를 입력했 때 게임이 진행되어 정답을 맞췄을 때, 몇 번만에 정답을 맞췄는지 세는 tryCount가 저장되는 배열이다.
인덱스 값을 통해 몇 번째 게임이 몇 번 시도 끝에 정답을 맞췄는지 확인할 수 있도록 한 건데, 기록이 없을 땐 빈 배열이니 반복문의 반복 범위 1...gameCount.count가 에러가 난 것이다.
전개
이를 해결하기 위해 2를 입력했을 때의 분기 if문을 if gameSelect == "2" 에서 if gameSelect =="2" && gameCount.isEmpty로 바꿔 기록이 있을때만 해당 if문이 동작하도록 하였고, else문에서 아직 게임 기록이 없다는 문구와, 1이나 3을 입력하라는 안내 문구를 띄운 뒤 재입력을 받도록 하였다.
코드를 수정을 한 뒤, 다시 테스트를 진행하였다.
기록이 없을 때 2번 입력해 기록 없음을 확인하는 문구와, 1 또는 3을 입력하라는 문구를 띄우게 되었는데, 여기서 1~3이 아닌 다른 값을 입력하면 또다시 기록 없음과 1 또는 3을 입력하라는 문구가 출력 됐다.
2가 입력 됐을 때 기록이 있으면 기록을 띄우고, 그 외에는 else문으로 해당 출력과 새 입력을 받도록 코드를 작성해서 당연하다면 당연한 결과였다.
위기
뿐만 아니라 이 문제는 게임 기록이 있을 때도 마찬가지 였는데, 기록이 있을 때도 2를 입력해 기록을 확인한 뒤 gameSelect의 값을 재입력 받을 때 1~3이 아닌 숫자를 입력하면 기록이 없다는 문구와 1 또는 3을 입력하라는 문구, 즉 위에서 작성한 else문이 동작하였다.
이는 gameSelect가 1~3인지 확인하는 if문이 게임을 진행하는 while문 밖에만 있어, 게임 진행 혹은 기록 확인 후 gameSelect를 재입력 받을 때는 아무 값이나 입력이 가능해진 것이다.
이 문제는 전체적인 코드를 작성할 때 생각할 수 있는 문제였을텐데 에러를 바로잡다 알게 된 것이 조금 아쉽게 느껴졌다.
아무튼 이걸 해결하기 위해 else if문을 추가해 1~3만 입력되도록 하였다.
왼쪽은 기록이 없을 때 잘 작동하는지 확인한 것이고, 오른쪽은 기록이 있을 때도 잘 수정 되었는지 확인한 것이다. 문제 없이 원하는대로 동작하였다.
이 정도 하면 필요한 기능은 전부 구현 했고, 주석이나 print 출력 문구, 그리고 변수명이나 불필요한 변수 정리 같은 디테일한 부분만 바꿔 코드를 가독성 좋게 바꾸는 정도면 되겠다 싶었다.
절정
다시 테스트해보는데, 초반에 해결했어야 할 문제가 다시 발견되었다.
처음에 게임을 시작할 때, 입력이 1~3이 아니면 1~3 사이의 숫자를 입력하라고 안내 문구만 뜨고 바로 종료되어 버렸다.
if문 하나로 1~3인지만 확인하였으니 당연한 결과였다.
이를 해결하기 위해 if문으로 확인하던 gameSelect을 while문으로 바꿔 1~3이 아니면 계속 재입력을 받도록 바꾸었고, else로 묶여있던 게임 진행 while문도 따로 분리하게 되었다.
gameSelect에 저장될 처음 입력을 1~3이 아닌 값으로 입력하면 재입력 받게 바뀌었고, 기록 없을 때 기록 확인 문제도 잘 해결되었다.
이후 유지보수성과 가독성을 위해 클래스를 파일별로 나누었고, 메인에 있던 정답 재생성 코드를 makeAnswer 클래스안에 makeAnswerArray() 메서드를 만들어 통합시켰다.
makeAnswer인데 처음 한번만 생성하고 재생성은 메인에서 하는 건 일관성이 떨어진다고 생각했기 때문이다.
마지막이라고 생각하고 테스트 하던 도중 다른 팀원이, 음수를 입력하면 에러가 난다는 이야기를 하였다. 나는 입력 값을 String으로 반환하는 readLine()의 값을 그대로 받은 뒤 한 글자씩 저장해 3글자인지, 숫자인지 판별하기 때문에 문제 없지 않을까 했다.
-123 같은 세자리 음수는 문제가 없다. ["-", "1", "2", "3"] 으로 저장 돼 3글자가 아닌 걸로 판별나서 걸러졌을테니까.
문제는 -12 같은 두자리 음수였다. ["-", "1", "2"]로 저장되니 3글자가 맞고, "-12"는 Int로 변환도 되니 숫자도 맞다고 판별해서 스트라이크/볼 판정까지 가게 되었다.
생각보다 클래스가 많이 필요하다 했더니 이제 음수를 처리하는 클래스도 만들어야 하는 걸까?
기능 구현은 checkNumber나 CheckThree의 return에 AND 연산자를 이용해 !(input.contains("-"))를 붙이면 클래스를 추가할 필요 없이 음수 처리도 어렵지 않게 구현 가능할 것 같았다.
결말
다른 클래스에 음수 판별 기능을 추가하는 건 결과적으로 클래스 단일 원칙을 깨는 일이라고 생각해서 그냥 새로 클래스를 만들기로 했다.
여러 기능별로 클래스를 나누고, 클래스별로 폴더나 파일까지 나누면서 모듈화 한 것은 클래스 단일 원칙을 지켜 유지보수성과 가독성을 늘리기 위해서였다. 그런데 음수 판별 기능은 숫자인지 확인하는 것도, 0인지 확인하는 것도, 3글자인지 확인하는 것도 아닌 애매한 기능인 것 같았기 때문이다.
checkNegative 클래스를 추가해 마이너스 기호 유무에 따라 true 혹은 false를 반환하게 하였다.
나중에 checkCorrectInput 클래스에서 && 연산자로 묶일 예정이니, 마이너스 기호가 있을 때 false, 없을 떄 true를 반환하도록 하였다.
checkCorrectInput 클래스의 check 메서드도 수정하고 나서 테스트를 진행했다.
음수가 입력되면 재입력을 받도록 잘 수정되었다. 이로써 구현해야 할 기능의 코딩은 거의 마무리 되었다.
마무리
이번 과제를 진행하며 했던 트러블 슈팅을 요약하면 다음과 같다.
- 게임 선택 시 2를 입력했을 때 기록이 없으면 런타임 에러가 발생하는 문제
- 위 에러 수정 후 게임 기록이 없을 때 기록 없음을 보인 뒤, 재입력을 1~3 이외의 값이 입력할 때도 기록 없음이 나오는 문제
- 게임 선택을 하는 gameSelect가 한 번 입력되고 나면 더 입력 받지 않고 종료되는 문제
- 정답을 생성하는 makeAnswer 클래스가 난수만 생성하고, 형식에 맞지않는 정답 생성시 재생성 하는 코드는 메인에 있던 것 makeAnswer 클래스로 통합
- 정답을 중복 없는 두자리 음수(ex. -12, -57..)로 입력하면 입력이 되는 문제 수정
전반적으로 크게 어려운 건 없었는데, 작성하면서 감을 잡은 뒤에 오류가 나면 수정하는 방식으로 진행했더니 완성했다고 생각한 상태에서 생각지 못한 방향으로 동작하는 경우가 조금 있었다.
특히, 이 글에는 작성하지 않았는데, 옳은 입력인지 검증하는 checkCorrectInput에서 여러개의 클래스 반환값들을 AND 혹은 OR 연산자로 묶다보니 많이 헷갈렸었다.
내가 원하는 반환 결과는 어떤 과정을 거쳐야 하는지 글로 한 번 작성한 뒤에, 그 글에 맞게 논리 연산자들을 쓴 뒤에야 원하는 대로 작동하였다.
또, 유지보수성과 가독성을 위해 클래스들을 나눴는데, 기능을 하나하나 다 나누다 보니 오히려 가독성이 떨어진 거 같아서 어디까지 나눠야하고 어디까지 한 클래스 안에 있어야 하는지 조금 어렵게 느껴졌다. 마지막에 추가한 음수 체크 같은 것 때문에 더욱 그러했다.
'iOS 앱 개발 부트캠프 > TIL' 카테고리의 다른 글
가장 많이 받은 선물 -1- (0) 2024.11.09 자연수 뒤집기 알고리즘 (0) 2024.11.07 야구게임 로직 만들기 (5) 2024.11.05 약수의 합 (0) 2024.11.04 짝수와 홀수, 배열의 평균값, 자리수 합치기 (0) 2024.11.03