[Project] 숫자 야구 게임 ①

JJOOEE__·2024년 6월 13일
2

Today I Learned....

목록 보기
7/19
post-thumbnail

🍎 숫자 야구 게임 만들기

🍏 야구 게임 이해하고 로직구성하기

코드를 구성하고 프로그램 생성 전 제일 먼저 해야할 일은?
목표를 설정하고 컴퓨터적 사고를 통해 로직을 구성하기!!

⬜ 내가 작성한 로직

1. 게임 시작 / 새게임 시작

  • 이전게임 유지 후 시작
    • 게임 종료 후 중도포기했던 게임 시작 (이전 기록 유지)
  • 새게임 시작
    • 정답 숫자 랜덤 생성 0~9 中 서로 다른 3자리 숫자를 생성합니다.
      • BUT 첫자리는 0 이면 안됨!
    • 사용자로부터 3자리 숫자 입력값 받음
    • 받은 입력값에 대한 힌트 출력
    • 힌트는 볼 / 스트라이크 / 아웃
    • 힌트를 바탕으로 3자리 숫자 입력값 받음
    • 정답을 맞출 때까지 이 과정을 반복
    • 정답을 맞추면 게임이 종료
    • 사용자는 게임 기록을 확인 / 새 게임을 시작

2. 게임 기록 보기:

  • 이전 게임들의 기록을 확인
  • 각 게임의 번호, 시도 횟수, 정답 숫자 정보를 포함

3. 게임 종료:

  • 게임 중 중도포기 가능 > 초기화 / 저장
  • 정답을 맞추면 자동 종료

🍏 Lv. 1

  • Lv1

    • 1에서 9까지의 서로 다른 임의의 수 3개를 정하고 맞추는 게임입니다
    • 정답은 랜덤으로 만듭니다.(1에서 9까지의 서로 다른 임의의 수 3자리)
  • BaseballGame class 생성

    • 함수 startgame() : makeAnswer()
      • 함수 makeAnswer() : 서로 다른 3자리 정수 출력해야 함
        • while 반복문 사용 : 조건 .count < 3 3자리 될때까지만 반복
        • n번째 자리 숫자가 numbers에 포함되지 않을 경우에 포함한다

< BaseballGame 코드 >

class BaseballGame{
    func startgame() {
        let answer = makeAnswer() // 정답을 만드는 함수
    }
    // 함수 내부를 구현하기
    func makeAnswer() -> [Int] {
        var numbers = [Int]()
        while numbers.count < 3 {
            let randomNum = Int.random(in: 0...9)
            if !numbers.contains(randomNum) {
                numbers.append(randomNum)
            }
        }
        return numbers
    }
}

⬜ 코드 작성하며 공부한 내용

🌈 while 반복문 조건 설정

  • while 뒤의 "조건"은 Bool 타입,
    즉 true 혹은 false이고, true일때 중괄호 내부 코드 실행
     while <"조건": Bool> {
       // 내부코드
    }

🍏 Lv2

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

< BaseballGame 코드 >

import Foundation

let game = BaseballGame()
game.startgame()

func isValidNumber(userNum: Int) -> Bool {

    // 세 자리 수인지 확인
    if userNum < 100 || userNum > 999 {
        print("세 자리 수를 입력해주세요.")
        return false
    }
    // 중복된 숫자가 있는지 확인,
    // 숫자 > 문자열 > 문자의 집합 count를 통해 요소 숫자가 3인지 확인하여 중복숫자 검사
    let userNumStr = String(userNum)
    let numSet = Set(userNumStr)
    if numSet.count != 3 {
        print("특정 숫자가 두 번 사용되었습니다. 다시 입력해주세요.")
        return false
    }
    return true
}

⬜ 코드 작성하며 공부한 내용

🌈 isValidNumber 함수를 생성하여 if 조건문에 활용

  • 코드를 재사용하고 중복을 피할 수 있게 해줍니다. 예를 들어, 숫자를 입력하는 다른 부분에서도 이 함수를 호출하여 동일한 유효성 검사를 수행할 수 있습니다.
  • 가독성 향상: isValidNumber 함수를 사용하면 코드의 가독성이 향상됩니다. 사용자가 세 자리 수이고 중복된 숫자가 없는지를 확인하는 논리를 함수 이름만으로 파악할 수 있습니다. 이는 코드를 이해하기 쉽게 만들어줍니다.

🌈 숫자 > 문자열 > 집합 변환

  • 숫자 > 문자 : String() 이니셜라이저를 사용
  • 문자 > 집합 Set() 이니셜라이저를 사용
  • 숫자를 집합으로 변환하기 위해선 문자열로 변환후 가능!

🌈 배열 중복숫자 검사

  1. 반복문을 사용하여 중복 여부 확인하기
  • 이중 반복문을 사용하여 배열을 순회하면서 중복된 요소가 있는지 확인
func hasDuplicates(_ array: [Int]) -> Bool {
    for i in 0..<array.count {
        for j in (i+1)..<array.count {
            if array[i] == array[j] {
                return true // 중복된 요소가 있으면 true 반환
            }
        }
    }
    return false // 중복된 요소가 없으면 false 반환
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10]
let result = hasDuplicates(numbers)
print(result) // 출력: true
  1. set(집합)를 활용하여 중복 제거 후 비교
  • 세트로 변환한 후에 배열과 세트의 요소 수를 비교하여 중복 여부를 확인
    • 중복된 요소가 있다면 배열과 세트의 count 수가 달라짐
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10]
let set = Set(numbers)
let hasDuplicates = numbers.count != set.count
print(hasDuplicates) // 출력: true

< BaseballGame 코드 >

class BaseballGame {
    func startgame() {
        let answerNum = makeAnswerNum() // 정답을 만드는 함수

        //게임 반복을 위한 while 문
        while true {

            // 사용자에게 입력값을 받음
            print("< 게임을 시작합니다 > 숫자를 입력하세요: ", terminator: "")

            if let input = readLine(), let userNum = Int(input) {
                if isValidNumber(userNum: userNum) {
                    // 힌트출력 : 같은숫자 같은자리 스트라이크, 같은숫자 다른자리 볼, 다른숫자 다른자리 아웃

⬜ 코드 작성하며 공부한 내용

< BaseballGame 코드 >

                  // randomNum & userNum > 배열로 변환하여  각 자리 별 비교
                  // if, else if, else 조건문 사용하여 각각 선언
                  let userNumArray = Array(String(userNum))
                  let answerNum = Array(answerNum)
                  var ball = 0
                  var strike = 0
                
                	 for (index, digit) in userNumArray.enumerated() {
                      if String(answerNum[index]) == String(digit) {
                          strike += 1
                      } else if answerNum.contains(Int(String(digit)) ?? -1) {
                          ball += 1
                      }
                  }

⬜ 코드 작성하며 공부한 내용

< BaseballGame 코드 >

                  if strike == 3 {
                      print(" 정답입니다. 처음으로 돌아갑니다 ")
                      break // 게임이 종료되면 반복문 탈출
                      } 
                      if strike == 0 && ball == 0 {
                      print(" OUT( NOTHING ) ")
                      } else {

                      var output = ""
                      if strike > 0 {
                          output += "strike: \(strike)"
                      }
                      if ball > 0 {
                          output += (output.isEmpty ? "" : ", ") + "ball: \(ball)"
                      }
                      print("(\(output))", terminator: "")
                  }
              }
          }
      }
  }

⬜ 코드 작성하며 공부한 내용


< BaseballGame 코드 >

  // 정답을 만드는 함수
  func makeAnswerNum() -> [Int] {
      var numbers = [Int]()
      while numbers.count < 3 {
          let randomNum = Int.random(in: 0...9)
          if !numbers.contains(randomNum) {
              numbers.append(randomNum)
          }
      }
      return numbers
  }
}
profile
개발이 어려운 나를 위한... 개발노트

2개의 댓글

comment-user-thumbnail
2024년 6월 14일

오아 체계적이에요!! 로직 그림그리는 툴은 뭔가요?

1개의 답글