오늘은 기존에 만든 숫자 야구 게임 기능에 도전 구현 기능을 추가했다.
새로운 기능을 추가하고, 더 좋은 코드 구조를 만들기 위해 고민한 내용을 정리한다.
0~9의 서로 다른 3자리 숫자로 설정 0이 오면 안 됨 092 ❌, 870 ✅, 300 ❌struct RandomNumberGenerator: RandomNumberGeneratable { /** 중복되지 않는 서로 다른 숫자 랜덤 생성 함수 - Returns: 중복되지 않는 랜덤으로 생성한 3개의 숫자를 배열로 반환 */ func randomNumberGenerator() -> [Int] { let randomNumber1 = Int.random(in: 1...9) // 첫번째 자리수는 변경 X var randomNumber2: Int var randomNumber3: Int // 첫번째 수와 동일하지 않을 때 까지 랜덤 숫자 생성 repeat { randomNumber2 = Int.random(in: 0...9) // 1...9 -> 0...9 로 변경 } while randomNumber2 == randomNumber1 // 두번째 수와 세번째 수와 중복되지 않을 때 까지 랜덤 숫자 생성 repeat { randomNumber3 = Int.random(in: 0...9) // 1...9 -> 0...9 로 변경 } while randomNumber3 == randomNumber1 || randomNumber3 == randomNumber2 // 디버깅 //let test = [randomNumber1, randomNumber2, randomNumber3] //print(test) return [randomNumber1, randomNumber2, randomNumber3] } }
환영합니다! 원하시는 번호를 입력해주세요
1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기1, 2, 3이 아닌 값 입력 시 오류 메시지 출력 func mainMenu() { var isQuit: Bool = true // 게임 반복 여부 저장 변수 var gameCount: Int = 0 // 게임 횟수 var logArray: [String] = [] while isQuit { message.menu() // 메인메뉴 선택 안내 메시지 출력 switch readLine() ?? "" { case "1": var tryCount = startGame() // 게임 시작 매소드 실행 gameCount += 1 // 개임 횟수 증가 logArray.append(log.gameLog(gameCount, tryCount)) // 게임 로그 저장 tryCount = 0 // 시도 횟수 초기화 case "2": print("< 게임 기록 보기 >") message.gameLog(logArray) // 로그 출력 case "3": print("Bye!") isQuit = false // 반복문 종료 default: print("올바른 번호를 입력해주세요.") } } } // 예상 출력 결과 -- // 환영합니다! 원하시는 번호를 입력해주세요 // // 1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기
게임 기록 보기(2번)을 선택하면, 지금까지 완료한 게임의 시도 횟수 출력 < 게임 기록 보기 >
1번째 게임 : 시도 횟수 - 14
2번째 게임 : 시도 횟수 - 9
3번째 게임 : 시도 횟수 - 12 아래의
gameLog메소드가 현재 게임 횟수와 시도 횟수를 반환한다.struct Log: LogProtocol { func gameLog(_ gameCount: Int, _ tryCount: Int) -> String { return "\(gameCount)번째 게임 : 시도 횟수 - \(tryCount)" } }
mainMenu메소드에서 아래와 같이 처리한다while isQuit { message.menu() // 메인메뉴 선택 안내 메시지 출력 switch readLine() ?? "" { case "1": var tryCount = startGame() // 게임 시작 매소드 실행 gameCount += 1 // 개임 횟수 증가 // 위에서 설명한 `gameLog` 메소드를 반환값인 게임 로그를 `logArray` 저장 logArray.append(log.gameLog(gameCount, tryCount)) tryCount = 0 // 시도 횟수 초기화 case "2": print("< 게임 기록 보기 >") message.gameLog(logArray) // 로그 출력 case "3": print("Bye!") isQuit = false // 반복문 종료 default: print("올바른 번호를 입력해주세요.") } }
종료하기(3번)을 선택하면 프로그램이 종료됨 반복문을 종료할수있게 3번을 입력하면
isQuit변수의 값이false변하며, 반복문이 끝나 게임이 종료된다.while isQuit { switch readLine() ?? "" { case "3": print("Bye!") isQuit = false // 반복문 종료 } }
tryCount를 지역 변수로 변경tryCount를 BaseballGame 클래스의 클래스 변수로 선언했음. startGame()의 반환값으로 변경하여 해결함.func startGame() -> Int { // tryCount를 반환
message.start()
let gameAnswer = randomNumber.randomNumberGenerator()
var tryCount = 0 // 지역 변수로 변경
while true {
message.input()
tryCount += 1 // 시도 횟수 증가
let userAnswer = userInput.getUserInput()
let gameResult = checkAnswer.check(gameAnswer, userAnswer)
if gameResult.strike == 3 {
message.success()
break
} else if gameResult.strike == 0 && gameResult.ball == 0 {
message.lose()
} else {
message.resultMessage(strike: gameResult.strike, ball: gameResult.ball)
}
print("") // 줄바꿈
}
return tryCount // tryCount를 반환
}
그리고 mainMenu()에서 startGame()의 반환값을 받아서 logArray에 추가하도록 변경함.
switch readLine() ?? "" {
case "1":
let tryCount = startGame() // startGame()에서 반환된 tryCount를 받음
gameCount += 1
logArray.append(log.gameLog1(gameCount, tryCount)) // logArray에 추가
tryCount가 게임 내에서만 사용되므로 지역 변수로 관리하는 것이 더 적절 startGame()을 호출할 때마다 새로운 tryCount를 사용하여 값의 일관성 유지 inout을 이용한 값 변경 방법 (적용 X)tryCount를 inout 매개변수로 사용하면 startGame()에서 직접 값을 변경할 수도 있음 inout 대신 반환값을 활용하는 방식을 선택함func startGame(_ tryCount: inout Int) {
message.start()
let gameAnswer = randomNumber.randomNumberGenerator()
while true {
message.input()
tryCount += 1 // 시도 횟수 증가
let userAnswer = userInput.getUserInput()
let gameResult = checkAnswer.check(gameAnswer, userAnswer)
if gameResult.strike == 3 {
message.success()
break
} else if gameResult.strike == 0 && gameResult.ball == 0 {
message.lose()
} else {
message.resultMessage(strike: gameResult.strike, ball: gameResult.ball)
}
print("")
}
}
📌 이 방식은 사용하지 않음
inout은 값이 변경된다는 것을 명확하게 나타내지만, 함수의 부작용이 커질 수 있음 오늘은 숫자 야구 게임을 개선하면서
inout과 반환값을 활용하는 방식 비교