1. 과제 설명
2. 규칙
3. 코드 작성
4. 트러블슈팅
5. 번외
야구 게임 로직을 구현하는 것이었다.
필수 구현 기능
Lv.1: 3자리 랜덤 숫자 생성(1에서 9까지의 서로 다른 임의의 수 3자리)
Lv.2: 사용자가 3자리 수를 입력하고 힌트 받기 (n Strike, n Ball)
Lv.3: 3자리 랜덤 숫자 생성(1에서 9까지의 서로 다른 임의의 수 3자리, 맨 앞 0 불가능)
Lv.4: 프로그램을 시 안내문구 생성 (1. 게임 시작, 2. 게임 기록 , 3. 종료)
Lv.5: 게임 기록 보여주기
Lv.6: 프로그램 종료하기
*모든 예외 처리 필수!
게임에 들어가면 게임 모드(A), 기록 보기(B), 종료하기(C) 3가지 모드를 선택할 수있다.
0~9까지의 3자리수 랜덤 숫자가 정답으로 생성되며, 사용자도 3자리 수를 입력한다.
단, 숫자는 중복 불가, 맨 앞에 0이 오는 것이 불가 하다. (정답, 사용자 입력 모두 해당)
같은 자리, 같은 수 -> Strike
다른 자리, 같은 수 -> Ball
다 맞을 경우(3 Strike) -> 정답!
다 틀릴 경우 (0 Strike, 0 Ball) -> Nothing
맨 앞에 0, 중복 숫자, 문자 입력할 경우 -> Error 문구 출력
*정답일 때까지 반복(정답 일 경우, 종료 후 모드 선택으로 돌아감)
이전 게임들에 대한 시도 횟수를 보여준다.
프로그램이 종료(C)되면 기록도 전체 리셋 된다.
ex) n번째 게임: 시도 횟수 - N
기록 출력 후, 모드 선택으로 돌아감
이전 기록 초기화 및 게임 종료가 진행된다.
import Foundation
// BaseballGame 클래스의 인스턴스를 생성하여 게임 시작
let game = BaseballGame()
game.start()
import Foundation
class BaseballGame {
var input : [Int] = [] //사용자가 입력할 숫자 3자리를 담는 배열
var randomNums : [Int] = [] // 정답 숫자 3자리를 담는 배열
var record = 0 // 각 게임 회차마다 횟수를 담을 배열
let recordManager = RecordManager() // RecordManager의 인스턴스 생성
func start() {
while true {
print("환영합니다! 원하는 번호를 입력해주세요.")
print("1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기")
let insertNum = readLine()
switch insertNum {
case "1":
gameMode() // 게임 실행
recordManager.add(record: record) // 게임이 끝난 후, 총 시도 횟수를 add함수로 전달
case "2":
recordManager.showRecords() // 게임 진행 상황 호출
case "3":
print("< 숫자 야구 게임을 종료합니다. >")
return // 게임 종료 후 함수 종료
default:
print("올바르지 않은 입력입니다. 1, 2, 3 중에서 선택해주세요.")
}
}
}
switch 구문을 통해 게임 모드를 선택할 수있도록 한다.
//정답 생성 함수
func makeAnswer() {
var numArr = [0,1,2,3,4,5,6,7,8,9] // 정답 숫자를 만들 때 쓰이는 배열
randomNums = [] //초기화
for i in 0...2 {
if i == 0 { // 1번째 정답 숫자 생성
// 0을 제외한 숫자에서 선택하도록 설정
let nonZeroNumbers = numArr.filter { $0 != 0 }
if let num = nonZeroNumbers.randomElement() {
randomNums.append(num)
numArr.remove(at: numArr.firstIndex(of: num)!)
}
} else { // 2,3 번째 정답 숫자 생성
if let num = numArr.randomElement() {
randomNums.append(num)
numArr.remove(at: numArr.firstIndex(of: num)!)
}
}
}
}
정답 생성 함수를 통해 조건에 맞는 정답을 만든다.
func gameMode() {
makeAnswer()
record = 0
while true {
var strike = 0
var ball = 0
record = record + 1 // 시도 횟수 증가
print("숫자를 입력하세요.")
// 숫자 입력 및 유효성 검사
if let line = readLine() {
// 입력된 문자열을 숫자 배열로 변환
input = line.split(separator: "").compactMap { Int($0) }
// 조건: 세 자리 숫자, 첫 번째 숫자가 0이 아닌지, 중복 숫자가 없는지 확인
guard input.count == 3, input[0] != 0, Set(input).count == 3 else {
print("올바르지 않은 입력 값 입니다.")
continue
}
}
for i in 0..<input.count {
//스트라이크 계산
if input[i] == randomNums[i] {
strike += 1
}
//볼 계산
if randomNums.contains(input[i]) {
ball += 1
}
}
ball -= strike // 볼 카운트에서 스트라이크 값 제외
//결과값 출력
if strike == 3 {
print("정답입니다!")
return
} else if strike == 0 && ball > 0 {
print("\(ball) Ball")
} else if strike != 0 && ball == 0 {
print("\(strike) Strike")
} else if strike != 0 && ball != 0 {
print("\(strike) Strike \(ball) Ball")
} else if strike == 0 && ball == 0 {
print("Nothing")
}
}
}
}
게임모드 함수에서는 게임이 실행된다.
가장 애매하다고 느꼈던 부분은 정답 출력 부분... ㅠㅠ if문이 너무 많았는데, 이거 외에는 어떤식으로 구현해야할지 감이 잘안왔다.
그리고 힌트 출력 부분을 분리 할까 말까... 엄청 고민하다 결국 안했다,,
import Foundation
class RecordManager {
var records: [Int] = [] // 게임 기록을 저장할 배열
// 게임 기록 추가
func add(record: Int) {
records.append(record) //시도 횟수 게임 기록 배열에 추가
}
// 저장된 게임 기록 출력
func showRecords() {
if records.isEmpty { //배열이 비었을 경우
print("저장된 게임 기록이 없습니다.")
} else {
print("게임 기록:")
for (index, record) in records.enumerated() {
print("게임 \(index + 1): \(record)회") //index의 숫자보다 +1회하면 게임을 한 횟수가 됨!
}
}
}
}
진행한 게임 기록 데이터를 관리하는 코드!
크게 어렵지 않았다.
억까의 시작,,
위에 작성한 코드와 같이.. 코드를 작성하고 프로그램을 실행했는뎁 , ,
아래 사진과 같이 띠용 . . . . 계속 실행 버튼 누르는데도 아무 반응이 없음.. 문구가 출력되는 것도 없고....
눈 질끈.. 근데 진짜로 이런 일은 나한테만 매번 일어남......... 진짜 진짜로... (대학때부터.....)

원인을 알 수 없었다.
다른 swift 파일도 다 확인해보고.. 그랬는데..
그래서 결국 새로운 프로젝트를 생성해서 거기서 실행시켜봤는데? 거기선되는 것이다!!??
내 생각에 빌드 폴더를 리셋한 것이 크게 작용한 거 같다..
Xcode야 이유라도 알려주라
- iOS에서 Stack을 사용하는 경우
화면 전환에서 Stack 사용하는 경우가 있습니다.
UINavigationController는 뷰 컨트롤러들을 스택 구조로 관리하여 화면 이동을 처리합니다.
새로운 화면을 push하면 스택에 쌓이고, pop하여 이전 화면으로 돌아갑니다.
- Optional을 사용하는 이유
Optional을 통해 nil 여부를 체크하고 안전하게 값 관리를 할 수 있습니다.