내일배움캠프 iOS

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

yjuni22 2024. 11. 6. 23:33

야구게임 이란?

숫자 야구 게임은 두 명이 즐길 수 있는 추리 게임으로, 상대방이 설정한 3자리의 숫자를 맞히는 것이 목표입니다. 각 자리의 숫자와 위치가 모두 맞으면 '스트라이크', 숫자만 맞고 위치가 다르면 '볼'로 판정됩니다. 예를 들어, 상대방의 숫자가 123일 때 132를 추리하면 1스트라이크 2볼이 됩니다. 이러한 힌트를 활용하여 상대방의 숫자를 추리해 나가는 게임입니다.

 

ex)

숫자를 입력하세요

435

1스트라이크 1볼

 

숫자를 입력하세요

357

1스트라이크

 

https://github.com/bryjna07/BaseballGame

 

GitHub - bryjna07/BaseballGame

Contribute to bryjna07/BaseballGame development by creating an account on GitHub.

github.com

Lv 1

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

< Hint >

// main.swift 파일
// 프로젝트 생성시 자동 생성됨

let game = BaseballGame()
game.start() // BaseballGame 인스턴스를 만들고 start 함수를 구현하기


// BaseballGame.swift 파일 생성
class 혹은 struct {
	func start() {
		let answer = makeAnswer() // 정답을 만드는 함수
	}
	
	func makeAnswer() -> Int {
		// 함수 내부를 구현하기
	}
}

 

진행과정

첫 시작

어떻게 시작해야 할지 막막해서 힌트를 보았다.

전혀 막막함이 나아지지 않음.

-> 우선 코드로 시작하기보단 알고리즘 처럼 어떻게 시작하면 좋을지 순서를 써보며 3개의 안을 생각해봄

1안

- 1~9에서 랜덤으로 하나씩 뽑고 삭제하고 뽑고 하면 중복도 막을 수 있지 않을까 ?

 

1. 한자리 수의 배열 만들기  -  하나씩 빼려면 배열에서 빼는 것이 쉬울 것이라고 생각함

      ex)    var Array = [1, 2, 3, 4, 5, 6 ,7 ,8 ,9].  -> 랜덤으로 뽑힌 숫자: 3 ->  [1, 2, 4, 5, 6, 7, 8, 9] ->  ...  -> 3개 뽑기

2. makeAnswer 메서드에서 랜덤숫자뽑기        Array.randomElement() - ?  라는 걸 이용하라고 한다.

3. 하나의 수를 선택 후 선택한 수 배열에서 삭제

4. 반복하여 총 한자리 수 3개를 뽑아냄    ->   빈 배열에 하나씩 넣기   [ i, j, k ]

5. 3자리 수로 만들기 i * 100 + j * 10 + k


2

- 처음부터 빈 배열에 넣는 방법은 어떨까 ?

 

1. 빈배열을 만들고 랜덤값 넣기

    Array: [Int] = []    -> [ i, j, k ]

2.  중복 제거 - ? ( 각각의 요소끼리 비교하는 조건문을 구현하면 되는건가 ?  if  i != j  ( ? ) )

  하나씩 뽑아서 총 3개 배열만들고 3자리수로 변환시키기

  i * 100 + j * 10 + k


3

- 중복제거 구현 대신 중복이 없는 set 으로 만든 후 3자리수로 변환하는건 어떨까 ?

 

 1. 빈 배열로 만들고 집합으로 변경

 Set< >         ->        < i, j, k >   

 2. 집합에서 숫자 뽑아내기

  i * 100 + j * 10 + k


3안까지 생각한 후

3개의 안을 생각했지만 배열, 집합의 메서드가 아직 익숙하지 않아

생각해본 방식의 메서드를 직접 구현하기에 어려움을 느꼈다.

(Lv 2 를 해보면서 3자리 수로 굳이 변환하지 않아도 될 것 같다고 판단.)

-> 서칭을 통해 구현방식을 찾아보며 비슷한 코드를 보고 아래처럼 시도해 보았다.

1안 구현방법

< 알게된 메서드 >

.randomElement()

.firstIndex(of: element)

var array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

if let firstNum = array1.randomElement() {   // 랜덤으로 배열 안에 하나의 요소 뽑기
     // 배열에서 firstNum 값이 존재하는 인덱스 찾기
    if let index = array1.firstIndex(of: firstNum) {
    // 찾은 인덱스를 통해 firstNum 삭제
        array1.remove(at: index)
    }
}

- 이런식으로 뽑은 요소를 삭제하고 다시 뽑고 세번째 숫자 까지 뽑으면 될 것 같다. 


2구현방법

<새롭게 알게된 것>

.contains( ) 을 통한 중복방지

  func makeAnswer() -> Int {
        // 함수 내부를 구현하기 , 서로 다른 임의의 수 3개 생성하기
        var randomNumbers: [Int] = []
        
        while randomNumbers.count < 3 {
            let randomNum = Int.random(in: 1...9)
            
            if !randomNumbers.contains(randomNum) {
                randomNumbers.append(randomNum)
            }
        }
        return randomNumbers[0] * 100 + randomNumbers[1] + randomNumbers[2]
    }

-  중복숫자 해결을 어떻게 할지 어려웠는데

while 루프 안에서 랜덤으로 뽑은 randomNum 을 if 문을 통해

randomNumbers 배열에 들어가 있지 않다면 넣어주는 방법을 사용하면 된다는 것을 알게 되었다.

!randomNumber.contains(randomNum)

그나마 알고있는 배열의 메서드들로 구현되어서 접근하기 쉽게 느껴졌다.  


3구현방법

func getRandomNumbers() -> Int {
    var randomNumbers = Set<Int>()
    while randomNumbers.count < 3 {
        randomNumbers.insert(Int.random(in: 0...9))
    }
    
    let randomNumber = Array(randomNumbers)
    return randomNumber[0] * 100 + randomNumber[1] * 10 + randomNumber[2]
}

- while 조건문을 사용하여 집합 내에 3개의 숫자를 넣기 위해

 .count < 3 을 조건으로 넣으면 갯수는 정수이기 때문에 0, 1, 2 까지 총 3번 루프가 되어 3개의 요소를 집합에 넣을 수 있다.

제일 간단한 방법 같지만 Lv2를 진행하며 집합보다는 배열을 이용하는 것이

숫자비교에 있어서 배열 안의 숫자가 순서를 가지고 있기 때문에 적합하다고 느껴졌다.

 

최종 Lv 1. 구현

Lv 2 에서의 숫자비교를 위해 3자리 수로 변환시키는 것보다는 배열로 구현하는 것이 좋을 것 같다고 생각했다.

 

다음 TIL에 이어서..