Xcode command line tool을 이용해 야구게임을 만들어 보았다. 숫자를 예측해서 맞추는 게임이다 보니 사용자 입력을 readLine()로 받아와서 게임을 진행하도록 했다.
기능적으로는 잘 동작하지만 리팩토링해야할 부분이 많다.
func makeRandomNumbers() -> [Int] {
var randomNumbers = Set<Int>()
while randomNumbers.count < 3 {
randomNumbers.insert(Int.random(in: 1...9))
}
return Array(randomNumbers)
}
func makeRandomNumberWithZero() -> [Int] {
var randomNumbers = Set<Int>()
while randomNumbers.count < 2 {
randomNumbers.insert(Int.random(in: 0...9))
}
var resultNumbers = Array(randomNumbers)
while resultNumbers.count < 3 {
let firstNum = Int.random(in: 1...9)
if !(resultNumbers.contains(firstNum)) {
resultNumbers.insert(firstNum, at: 0)
}
}
return resultNumbers
}
0이 가능 첫번째 숫자는 0이 되면 안된다는 조건에 맞추어서도 만들어 보았다. Set으로 겹치지 않게 해준다.0을 제외한 숫자를 랜덤으로 넣어주는 로직이다.Int가 첫번째 숫자가 0이면 자동으로 무시하는 점을 이용하면 더 효율적인 코드가 나올 것 같아서 시도해 보고 싶다.
func cleanNumbers(with input:String) -> [Int]? {
let cleanedNumbers = input.split(separator: "").compactMap { Int($0) }
if cleanedNumbers.count > 3 || Set(cleanedNumbers).count != 3 {
return nil
} else {
return cleanedNumbers
}
}
compactMap이 자동으로 숫자로 변환되지 않으면 반환하지 않아서 숫자만 받는다는 조건에 너무 잘 맞았다.nil을 반환하도록 했다.String 사이에 우연찮게 숫자 세 개가 들어간다면 올바른 입력으로 처리된다. 더 고민해보아야 할 것 같다.func startGame() {
var isGameOn = true
while isGameOn {
print("✏️ 숫자를 입력하세요:", terminator: "")
guard let userInput = readLine(),
let cleanedNumbers = cleanNumbers(with: userInput) else {
print("❌ 잘못된 입력입니다. 겹치지 않는 세자리 숫자를 입력해주세요!")
continue
}
gameCount += 1
let (strikeCount, ballCount) = getGameResults(of: cleanedNumbers)
if strikeCount == 3 {
isGameOn = false
gameOrder += 1
print("🎉🎉🎉🎉🎉🎉\n🎉정답입니다!🎉\n🎉🎉🎉🎉🎉🎉")
gameRecord[gameOrder] = gameCount
} else {
print("\(strikeCount)스트라이크 \(ballCount)볼")
}
}
computerNumbers = makeRandomNumberWithZero()
gameCount = 0
}
while문을 활용했다.Print문 안의 String들은 enum으로 분리해서 rawValue를 불러오는게 나아 보인다.func showRecord() {
if gameRecord.count == 0 {
return
} else {
for num in 1...gameOrder {
print("\(num)번째 게임 : \(gameRecord[num]!) 번 시도")
}
}
}
Dict에 담아주고 순회하면서 보여주도록 만들었다.Dict안에 값이 없을 경우도 다룰 수 있도록 수정했다.