본문 바로가기

iOS 앱 개발자 프로젝트/개인 프로젝트

[Project] 숫자 야구 게임 만들기 (Lv3)

전체 프로젝트 중,

레벨 3 도전 .. 


 

class BaseballGame {
  
  /**
   1에서 9까지의 서로 다른 임의의 수 3개를 정하고 맞추는 게임입니다
   정답은 랜덤으로 만듭니다.(1에서 9까지의 서로 다른 임의의 수 3자리)
   */
  func start() {
    
    var tryCountPerGame: [Int] = []
    
    while true {
      showGreetingMessage()
      
      let option = readLine() ?? ""
      
      switch option {
      case "1":
        let tryCount = playOneGame()
        tryCountPerGame.append(tryCount)
      case "2":
        showGameLog(tryCountPerGame)
      case "3":
        print("< 숫자 야구 게임을 종료합니다 >")
        exit(0)
        break
      default:
        print("올바른 숫자를 입력해주세요!")
        print()
      }
    }
  }
  
  func makeAnswer() -> [Int] {
    
    let arr = (0...9).map { $0 }
    
    let shuffledArray = arr.shuffled()
    
    if shuffledArray[0] == 0 {
      return [Int](shuffledArray[1...3])
    } else {
      return [Int](shuffledArray[0...2])
    }
  }
  
  func validateInput(_ input: [Int]) -> Bool {
    input.count == 3
  }
  
  func showGreetingMessage() {
    
    let greetingMessage = """
    환영합니다! 원하시는 번호를 입력해주세요
    1. 게임 시작하기  2. 게임 기록 보기  3. 종료하기
    """
    
    print(greetingMessage)
  }
  
  // 반환값: 이번 게임의 시도 횟수
  func playOneGame() -> Int {
    
    var tryCount = 0
    
    let answer = makeAnswer()
    print("정답:", answer)
    
    print("< 게임을 시작합니다 >")
    
    while true {
      
      print("숫자를 입력하세요")
      let input = readLine() ?? ""
      tryCount += 1
      
      // "123ㄱ"
      // ["1", "2", "3", "ㄱ"]
      // [1, 2, 3]
      let numberArray = input.map { String($0) }.compactMap { Int($0) }
      
      let isValidate = validateInput(numberArray)
      
      guard isValidate else {
        print("올바르지 않은 입력 값입니다.")
        print()
        continue
      }
      
      var strike = 0
      var ball = 0
      
      // 사용자가 입력한 숫자 순회
      for (index, number) in numberArray.enumerated() {
        
        // 스트라이크
        if number == answer[index] {
          strike += 1
          continue
        }
        
        // 볼인지 판단
        if answer.contains(number) {
          ball += 1
          continue
        }
      }
      
      if strike == 0 && ball == 0 {
        print("Nothing")
      } else if strike == 3 {
        print("정답입니다!")
        print()
        return tryCount
      } else {
        print("\(strike)스트라이크", terminator: " ")
        print("\(ball)볼")
      }
      
      print()
    }
    
  }
  
  func showGameLog(_ tryCountPerGame: [Int]) {
    print("< 게임 기록 보기 >")
    for (index, tryCount) in tryCountPerGame.enumerated() {
      print("\(index+1)번째 게임 : 시도 횟수 - \(tryCount)")
    }
    print()
  }
}

 

 

struct BaseballGame {
    func start() {
        let answer = makeAnswer() // 정답을 만드는 함수 호출

        while true {
            print("세 자리 숫자를 입력하세요:", terminator: " ") // 유저에게 입력값을 받는 안내 메시지 출력

            guard let input = readLine() else { // 입력값이 nil인 경우 반복문 처음으로 돌아가기
                continue
            }

            guard let number = Int(input) else { // 정수로 변환되지 않는 경우 반복문 처음으로 돌아가기
                print("유효하지 않은 입력입니다.")
                continue
            }

            guard input.count == 3 else { // 세 자리가 아닌 경우 반복문 처음으로 돌아가기
                print("세 자리 숫자를 입력하세요.")
                continue
            }

            let digits = String(number).compactMap { Int(String($0)) } // 입력값을 각 자리 숫자로 분리하여 배열로 저장

            guard digits.count == 3, Set(digits).count == 3 else { // 숫자가 세 개가 아니거나, 중복된 숫자가 있는 경우 반복문 처음으로 돌아가기
                print("올바르지 않은 입력값입니다.")
                continue
            }

            var strike = 0
            var ball = 0

            for (index, digit) in digits.enumerated() { // 입력값과 정답을 비교하여 스트라이크와 볼 계산
                if digit == answer[index] {
                    strike += 1
                } else if answer.contains(digit) {
                    ball += 1
                }
            }

            if strike == 3 { // 정답일 경우 게임 종료
                print("정답입니다!")
                break
            } else {
                print("\(strike)스트라이크 \(ball)볼") // 스트라이크와 볼 출력
            }
        }
    }

    private func makeAnswer() -> [Int] {
        var digits = [Int]()

        while digits.count < 3 {
            let digit = Int.random(in: 1...9) // 1부터 9까지의 난수 생성
            if !digits.contains(digit) { // 중복된 숫자가 없을 때만 추가
                digits.append(digit)
            }
        }

        return digits
    }
}

let game = BaseballGame()
game.start()