Swift로 야구 게임 만들기 (1)

버질·2024년 11월 4일

오늘은 숫자 야구 게임을 Swift로 구현했다. 이 게임은 세 자리의 중복 없는 숫자를 맞추는 방식으로 진행되며, 사용자가 입력한 숫자와 정답을 비교하여 스트라이크와 볼을 판별해 힌트를 제공하는 구조로 되어 있다.

코드 설명

게임 시작 함수 (start())

start() 함수는 게임의 핵심 로직을 포함하고 있으며, 사용자 입력을 받아 정답을 맞추기까지 반복하는 구조이다.
makeAnswer() 함수를 호출하여 중복이 없는 세 자리 숫자의 정답을 생성한다.
게임 루프는 while true로 무한 루프를 설정하고, 사용자가 올바른 입력을 할 때까지 반복된다.

func start() {
    let answer = makeAnswer() // 정답을 만드는 함수
    print("< 게임을 시작합니다! >")
    
    while true {
        print("세 자리 숫자를 입력하세요:")
        
        if let input = readLine() {
            let guess = Array(input).compactMap { $0.wholeNumberValue }
            
            // 유효성 검사: 세 자리 숫자인지, 중복이 없는지, 0이 포함되지 않는지 확인
            if guess.count != 3 || Set(guess).count != 3 || guess.contains(0) {
                print("올바르지 않은 입력값입니다")
                continue
            }
            
            // 정답과 비교 후 힌트 제공
            let (strikes, balls) = compareGuess(answer, guess)
            if strikes == 3 {
                print("정답입니다!")
                break
            } else {
                print("\(strikes)스트라이크 \(balls)볼")
            }
        } else {
            print("올바르지 않은 입력값입니다")
        }
    }
}

정답 생성 함수 (makeAnswer())

makeAnswer() 함수는 1부터 9까지의 숫자를 무작위로 섞고, 그 중 첫 세 개의 숫자를 정답으로 설정한다.
numbers.shuffle()을 사용하여 배열을 무작위로 섞고 prefix(3)로 세 개의 숫자를 선택했다.

func makeAnswer() -> [Int] {
    var numbers = Array(1...9)
    numbers.shuffle()
    return Array(numbers.prefix(3))
}

입력값과 정답 비교 함수 (compareGuess())

compareGuess() 함수는 사용자의 입력값(guess)과 정답(answer)을 비교해 스트라이크와 볼의 개수를 반환한다.
스트라이크는 위치와 숫자가 모두 일치할 때 증가하며, 볼은 숫자는 맞지만 위치가 다를 때 증가한다.

func compareGuess(_ answer: [Int], _ guess: [Int]) -> (Int, Int) {
    var strikes = 0
    var balls = 0
    
    for i in 0..<3 {
        if answer[i] == guess[i] {
            strikes += 1
        } else if answer.contains(guess[i]) {
            balls += 1
        }
    }
    return (strikes, balls)
}

main.swift 파일

main.swift 파일은 Swift 프로젝트가 시작될 때 자동 생성되는 파일로, BaseballGame 클래스의 인스턴스를 생성하고 start() 메서드를 호출해 게임을 시작한다.

let game = BaseballGame()
game.start() // BaseballGame 인스턴스를 만들고 start 함수를 실행

느낀 점

입력값 검증의 중요성: 게임이 올바르게 작동하도록 사용자 입력의 유효성을 검증하는 것이 중요하다는 것을 다시금 실감했다. 예를 들어, 세 자리 숫자가 아닌 경우, 중복된 숫자, 혹은 0이 포함된 입력값은 허용되지 않도록 조건문을 작성했다.
스트라이크와 볼의 판별: 두 배열을 비교하면서 스트라이크와 볼을 판별하는 로직은 위치와 값의 일치를 따지는 과정이 중요했다. Swift의 배열과 반복문을 사용하여 손쉽게 구현할 수 있었다.
무작위 숫자 생성: Array(1...9).shuffle()을 사용해 무작위로 정답을 생성하는 방법이 매우 효율적이었다. 이를 통해 prefix()를 사용해 원하는 개수만큼의 숫자를 선택할 수 있었다.

어려웠던 점

입력 검증 로직: 사용자의 입력이 세 자리 숫자인지, 중복된 숫자가 있는지, 0이 포함되어 있는지를 확인하는 조건식을 작성하는 데 시간이 걸렸다. 특히, 배열 변환과 유효성 검증을 간결하게 표현하는 방법을 고민했다.
반복문 로직: while true 무한 루프를 사용해 게임을 지속하다 보니, 게임 종료 조건과 올바른 입력 처리를 확실하게 분기 처리하는 부분에 신경을 써야 했다.

배운 점

이번 프로젝트를 통해 Swift에서의 입력값 처리, 배열 변환, 무작위 숫자 생성에 대해 이해를 깊게 할 수 있었다. 특히, 클래스를 설계하고 여러 함수를 활용하여 코드의 가독성과 유지보수성을 높이는 연습이 되었다. 앞으로도 다양한 게임 알고리즘을 구현하며 문제 해결 능력을 더욱 키우고 싶다.

profile
iOS Developer · SwiftUI & UIKit '가끔 되고 가끔 안 되는' 문제를 뿌리부터 잡습니다.

1개의 댓글

comment-user-thumbnail
2024년 11월 4일

오와 makeAnswer 구현하신 거 인상 깊게 보고 갑니다. 셔플 하고 3개 딱 잘라버릴 때 너무 통쾌해요! 저는 중복 검사 거쳤어야 했는데.. 멋있는 거 배워갑니다😊

답글 달기