본문 바로가기

𝗔𝗦𝗦𝗜𝗚𝗡𝗠𝗘𝗡𝗧/[내배캠] 3주차 - 야구 게임

[내일배움캠프] Swift 문법 3주차 심화 과제 - 숫자 야구 게임

 

숫자 야구 게임

새로 한 주가 시작되고, 새로운 과제와 강의를 받았다. 솔직히 말하면 처음 3주차 발제 강의를 들었을 때 조금 막막했다. '이걸 어떻게하지, Lv.06까지 다 할 수나 있을까.' 하는 생각이 든 것도 사실이다.

 

아직까지도 Xcode는 나한테 어렵고, 자꾸 Visual Studio Code로 돌아가고 싶은 마음이 굴뚝이다... 사용법이 너무 어렵고 낯설다. 이것저것 매번 만지작 거리고는 있는데 언제나 새롭다. 그런데 이번 과제는 플레이그라운드도 아닌 command line tool을 활용해야 해서 더 어려웠던 것 같다.

 

그런데 걱정했던 것과는 다르게 구글링도 하고 필요한 부분을 찾아 강의도 다시 들어보며 차분히 하나하나 따라가다 보니 어느새 Lv.04까지. 솔직히 필수 구현 기능인 Lv.02까지라도 해볼까 했는데 하다보니 재밌었다. 역시 이 맛에 코딩하지. ⁽⁽◝( ˙ ꒳ ˙ )◜⁾⁾

 

 

 

이번 과제는,

 

 

숫자 야구 게임이라는 주제로 임의로 설정된 총 3개의 숫자를 사용자가 맞히는 게임이다. 사용자는 3개의 숫자를 입력하고, 설정된 숫자와 비교하여 숫자와 위치가 맞으면 스트라이크, 숫자는 맞지만 위치가 틀리면 볼로 판정된다. 사용자가 모든 숫자와 위치를 맞히면 이기는 게임이며, 게임은 최대 10번까지 도전할 수 있다.

 

구현하면서 제일 어려웠던 건 Lv.05번에 게임 기록 보여주기였다. 이제까지 사용자가 진행했던 게임 기록을 배열에 저장하고 사용자가 원할 경우 그 기록을 보여주는 것, 다른 것도 어려웠지만 이 부분이 가장 막막했던 것 같다.

 

이번에도 한참을 고민하다가 튜터님을 찾아갔고 배열에 임의로 기록을 넣어두고 출력하는 건지, 실제 사용자의 게임 기록을 배열에 저장 후 출력해주는 건지에 대해 질문 했다. 역시 당연하게도 후자였고... 그래서 더 막막해졌다. 그래도 다행인 건 튜터님이 임의로 설정하는 숫자처럼 배열을 사용해볼 것을 힌트로 알려주셨고 그 힌트를 기준으로 따라가다 보니 막막했던 문제가 풀렸다. ₍₍ ◝(・ω・)◟ ⁾⁾ 역시 튜터님... 짱.

 

 

 

Code

 

 

게임 시작(정답 생성)

게임 시작하기

private func generateAnswer() {
    var numbers = Set<Int>()

    while numbers.count < 3 {
        var randomNumber = Int.random(in: 0...9)

        if numbers.isEmpty {
            randomNumber = Int.random(in: 1...9)
       }
        numbers.insert(randomNumber)
    }

    answer = Array(numbers)
}

 

- numbers라는 이름의 빈 Set을 선언

   → Set은 중복된 값을 허용하지 않으므로, 컴퓨터가 선택한 숫자들을 중복되지 않도록 보장

 

- while 루프를 사용하여 numbers의 요소 개수가 3보다 작을 때까지 반복

   → 3개의 서로 다른 숫자를 선택하기 위한 조건

 

- 루프 내부에서 0부터 9까지의 임의의 숫자를 생성하여 randomNumber에 저장

   → 첫 번째 숫자를 선택할 때는 1부터 9까지의 범위에서 선택하도록 함

 

- 생성된 randomNumbernumbers에 삽입

   → Set은 중복된 값을 허용하지 않으므로, 이미 있는 숫자는 추가되지 않음

 

- numbers의 요소 개수가 3이 되면

   즉, 3개의 서로 다른 숫자가 선택되었을 때 이를 배열로 변환하여 answer에 저장

 

 

 


 

 

기록 보기

기록 보기

struct GameRecord {
    let gameNumber: Int
    let attemptsCount: Int
}

private var records: [GameRecord] = []

// 생략

private func recordGame(attempts: Int) {
    let record = GameRecord(gameNumber: currentGameNumber, attemptsCount: attempts)
    records.append(record)
}

private func showRecords() {
    if records.isEmpty {
        print("아직 기록이 없습니다.")
    } else {
        print("< 게임 기록 보기 >")
        for record in records {
            print("\(record.gameNumber)번째 게임 : 시도 횟수 - \(record.attemptsCount)")
        }
    }
}

 

- GameRecord 구조체는 게임 번호(gameNumber)와 시도 횟수(attemptsCount)를 저장하는 데 사용

 

- records 배열은 게임 기록을 저장하기 위한 배열

   → 각 요소는 GameRecord 구조체의 인스턴스로 구성

 

- recordGame(attempts:) 함수는 게임의 시도 횟수를 받아서

   새로운 GameRecord 인스턴스를 생성, 이를 records 배열에 추가

 

- showRecords() 함수는 현재까지의 게임 기록을 출력하는 역할

   → records 배열이 비어있으면 "아직 기록이 없습니다." 출력, 비어있지 않으면 각 게임 번호와 시도 횟수 출력

 

 

 


 

 

게임 플레이

private func playGame() {
    var attemptsCount = 0 

    while true {
        attemptsCount += 1
        print("3개의 숫자를 입력하세요. 각 숫자는 띄어쓰기로 구분해주세요.")
        guard let input = readLine() else {
            print("입력이 없습니다.")
            continue
        }
        let numbers = input.split(separator: " ").compactMap { Int($0) }
        guard numbers.count == 3 else {
            print("숫자 3개를 입력해주세요.")
            continue
        }
        guard Set(numbers).count == 3 else {
            print("각각 다른 숫자를 입력해주세요.")
            continue
        }

        var strike = 0
        var ball = 0

        for (index, number) in numbers.enumerated() {
            if number == answer[index] {
                strike += 1
            } else if answer.contains(number) {
                ball += 1
            }
        }

        if strike == 3 {
            recordGame(attempts: attemptsCount)
            print("정답입니다!")
            break 
        } else {
            print("\(strike) 스트라이크, \(ball) 볼입니다.")
            if attemptsCount == 10 {
                recordGame(attempts: attemptsCount)
                print("10번의 시도 동안 정답을 맞추지 못했습니다. 게임 종료.")
                break
            }
        }
    }
    startGame() 
}

 

- attemptsCount 변수를 초기화하고, 사용자가 정답을 맞출 때까지 무한 루프 실행

 

- 각 루프에서는 사용자로부터 세 개의 숫자를 입력받음

   → 입력이 없는 경우 "입력이 없습니다." 출력

 

- 입력받은 숫자는 공백으로 구분되어 있으므로 split(separator: " ")을 사용하여 문자열을 분할

   → 분할한 문자열을 compactMap을 사용하여 문자열을 정수로 변환

   → 사용자가 입력한 숫자와 정답을 비교하여 스트라이크와 볼을 계산

 

- recordGame(attempts:) 함수를 호출하여 게임 기록을 저장하고 "정답입니다!"를 출력한 후 루프 종료

 

- 사용자가 10번의 시도 동안 정답을 맞추지 못하는 경우, 게임 기록을 저장하고

   "10번의 시도 동안 정답을 맞추지 못했습니다. 게임 종료."를 출력한 후 루프 종료

 

 

 


 

 

게임 종료

게임 종료

private func startGame() {
    // 생략

    if let input = readLine(), let choice = Int(input) {
        switch choice {
        // 생략
        case 3:
            print("게임을 종료합니다.")
            records = [] 
            startGame()
        default:
            // 생략
        }
    } else {
        print("숫자를 입력해주세요.")
        startGame() 
    }
}

 

 

 

 

Recent Posts
Visits
Today
Yesterday
Archives
Calendar
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31