내일배움캠프 iOS

iOS) TIL #14 야구게임 만들기 - Lv2

yjuni22 2024. 11. 7. 22:23

Lv 1 (TIL#13 참고)

https://yjuni22.tistory.com/34

 

iOS) TIL #13 야구게임 만들기 - 1

야구게임 이란?숫자 야구 게임은 두 명이 즐길 수 있는 추리 게임으로, 상대방이 설정한 3자리의 숫자를 맞히는 것이 목표입니다. 각 자리의 숫자와 위치가 모두 맞으면 '스트라이크', 숫자만 맞

yjuni22.tistory.com

 

Lv 1 에서 1~9의 숫자 중 중복되지 않는 랜덤 3개를 뽑는 함수를 구현했다.


Lv 2

정답을 맞추기 위해 3자리수를 입력하고 힌트를 받습니다

    • 힌트는 야구용어인 스트라이크입니다.
    • 같은 자리에 같은 숫자가 있는 경우 스트라이크, 다른 자리에 숫자가 있는 경우 입니다
    • ex) 정답 : 456 인 경우
      • 435를 입력한 경우 → 1스트라이크 1볼
      • 357를 입력한 경우 → 1스트라이크
      • 678를 입력한 경우 → 1볼
      • 123를 입력한 경우 → Nothing
    • 만약 올바르지 않은 입력값에 대해서는 오류 문구를 보여주세요
  • 3자리 숫자가 정답과 같은 경우 게임이 종료됩니다

진행과정

Lv1 에서 랜덤으로 3개의 숫자를 뽑음

유저가 입력하는 3자리 숫자에 대한 코드가 필요함.

1. 입력을 받고

2. 정답이랑 비교해준다. -> 비교한 스트라이크, 볼을 알려준다 -> 3스트라이크가 되면 정답

 

Lv1 도 막막했지만 Lv2도 여전히 막막해서 튜터님들의 도움을 받았다.

필요한 진행과정에 대한 피드백을 받아 다시 생각해 보았다.

 

입력값 처리에 대한 것을 구현하기 전에

입력값 3자리 수와 정답을 비교하려면

입력값을 배열형태로 바꿔주는 것이 비교하기가 더 수월할 것 같다고 생각했다.

 

Lv 1 에서 생각했던 배열을 3자리수로 변환하는 것의 반대개념 으로 하면 될 것 같다.

 // 입력받은 숫자에서 각 자릿수 추출
    func getDigits(of number: Int) -> [Int] {
        return [number / 100, (number / 10) % 10, number % 10]
    }

 

그 후 스트라이크, 볼 계산을 해주는 함수가 필요하다.

 func compare(_ answer: [Int], with userInput: [Int]) -> (strikes: Int, balls: Int) {
        var strikes = 0
        var balls = 0
        // 정답과 사용자가 입력한 값을 비교하는 과정
        for (index, element) in userInput.enumerated() {
            if element == answer[index] {
                strikes += 1
            } else if answer.contains(element) {
                balls += 1
            }
        }
        return (strikes, balls)
    }

두 개의 배열을 비교하는 반복문을 이용한 함수 생성

( 구현은 했으나 아직 이해하려면 더 공부가 필요함..)

 

추가적인 두 메서드를 클래스에 생성해주고 나서 1번부터 처리할 수 있게 되었다.

 

1

입력을 받는다.

( while 반복문 안에서 - 정답을 맞출 때 까지 반복해야 하기 때문에 )

1 - 1

입력값에 대한 옵셔널 바인딩 처리

readLine() 이 옵셔널 타입이기 때문

// 1. 유저에게 입력값을 받음
            guard let input = readLine(), let userNumber = Int(input) else {
                         print("잘못된 입력입니다. 숫자를 입력해주세요.")
                         continue
                     }

 

1 -2

3자리 수 이외의 예외처리를 해주어야 한다.

중복된 수, 0 포함 시 , 숫자가 아닐 시, 3자리 수자 아닐 시

 let newNumbers = getDigits(of: userNumber)
        if newNumbers.count != 3 || newNumbers.contains(0) || Set(newNumbers).count != newNumbers.count {
        print("유효하지 않은 입력입니다. 1부터 9까지의 중복되지 않는 세 자리 숫자를 입력해주세요.")
        continue
}

추가한 getDigits 메서드를 통해 입력값을 배열형태로 바꿔주고 유효하지 않은 입력에 대한 처리를 해주었다.

 

2

정답이랑 비교하기

( 마찬가지로 while 문 안에서 )

compare 메서드를 이용하여 스트라이크, 볼 을 readLine에 나올 수 있게 구현했다.

// 3. 정답과 유저의 입력값을 비교하여 스트라이크/볼을 출력하기
    let (strikes, balls) = compare(answer, with: newNumbers)
    print("\(strikes) 스트라이크, \(balls) 볼")
        
// 만약 정답이라면 break 호출하여 반복문 탈출
    if strikes == 3 {
    print("정답입니다! 축하합니다!")
    break

최종구현

이렇게 하여 드디어 start 메서드까지 마무리 하고 실행을 할 수 있게 되었다.

 

실행화면


실행중 버그발견 ..

 

00123 을 입력했더니 정상작동된다..

코드 상 입력값이 세 자리 숫자인지 판별하는 부분의 위치가 잘못되어 있었다.

과제 힌트의 내용을 따라가려 하다 보니 순서를 잘못 두었던 것 같다.

주석 2번이 아닌 1번으로 이동 후 수정.

 

정상화 완료..