diff --git a/README.md b/README.md index 025aece..5a2a69e 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,30 @@ -# 숫자 야구 게임 과제 (Week 2) -숫자 야구 게임은 1에서 9까지의 서로 다른 3개의 숫자를 맞추는 게임입니다.
-각 레벨마다 기능이 확장되며, 팀원들이 협업하여 매주 주어진 과제를 해결해 나갑니다. +# ⚾️ 숫자 야구 게임 -# 📝 협업 규칙 +--- +### 🏟️ 개요 +숫자 야구 게임은 랜덤으로 생성된 서로 다른 숫자를 맞추는 게임입니다.
+각 레벨마다 확장된 기능 업데이트가 요구되었습니다. -### 풀 리퀘스트 작성 규칙 -**1** 형식: `[레벨] 작업 내용 - 팀원 이름` - - 예시: `[Lv_1] 야구 로직 구현 - 김상민`
-**2** 작업 세부 사항: 해당 레벨에서 구현한 주요 기능을 요약하여 추가 설명으로 작성합니다. +|개발 기간|인원|개발 언어|개발 환경| +|------|--|------|------| +|24.11.05 - 07|1인|Swift|OS: macOS 15.0.1, IDE: Xcode 16.1| -### 레포지토리 설정 및 브랜치 관리 -**1** **Fork로 가져오기**: 각 팀원은 레포지토리를 Fork하여 자신의 개인 레포지토리로 가져옵니다.
-**2** **브랜치 생성**: Fork한 개인 레포지토리에서 각자의 이름을 딴 브랜치를 생성합니다.
-**3** **Pull Request**: 과제를 마친 후, 각자의 브랜치로 Pull Request를 생성하여 코드 리뷰를 요청합니다. 모든 팀원이 Pull Request에 코멘트를 달고 피드백을 제공합니다.
-**4** **수정 및 Merge**: 피드백을 반영하여 수정하고, 팀원들의 동의를 얻은 후 merge를 진행합니다.
+--- -이 과정을 통해 서로의 코드에 대해 이해를 높이고, “왜 이렇게 작성했는지”에 대한 질문과 답변을 주고받으며 과제를 진행합니다. -# 📂 코드 파일 구조 -* main.swift: 게임의 메인 진입점으로, 레벨을 선택하고 시작할 수 있도록 구성되어 있습니다. startGame() 함수가 게임의 시작을 담당합니다. -* Lv_1.swift ~ Lv_6.swift: 각 레벨별 요구사항에 맞게 구현된 파일입니다. 각 파일에는 해당 레벨의 기능을 구현하는 함수가 포함되어 있습니다. +### 📂 코드 파일 구조 +* main.swift: 인스턴스들이 생성되고 호출되는 곳입니다. +* BaseballGame : 게임이 진행되는 곳입니다. +* Model : 게임 진행을 위해 필요한 데이터 클래스 혹은 구조체 등이 모여 있는 곳입니다. +* PrintManager : 게임 메시지 출력을 도와주는 구조체입니다. +* RecordManager : 게임 기록을 도와주는 구조체입니다. -⠀📜 구현 가이드 +--- -### main.swift -Command Line Tool 프로젝트에서는 하나의 `main.swift` 파일에서만 프로그램을 시작할 수 있습니다. 따라서 각 레벨별 기능을 별도의 파일로 구현한 후, `main.swift` 파일에서 해당 레벨의 함수를 호출하여 실행하도록 구성합니다. +### 💬 PR +* [게임 시작 구현](https://github.com/SpartaCoding-iOS5/Week2-BaseballGame/pull/7) +* [게임 구현 마무리](https://github.com/SpartaCoding-iOS5/Week2-BaseballGame/pull/21) + +--- -```swift -import Foundation - -func startGame() { - print("레벨을 선택하세요 (1, 2, 3, 4, 5, 6):") - - if let input = readLine(), let level = Int(input) { - switch level { - case 1: - levelOne() - case 2: - levelTwo() - case 3: - levelThree() - case 4: - levelFour() - case 5: - levelFive() - case 6: - levelSix() - default: - print("유효하지 않은 레벨입니다. 1~6까지를 선택해주세요.") - } - } else { - print("잘못된 입력입니다.") - } -} - -// 게임 시작 -startGame() -``` -* startGame() 함수에서 게임의 레벨을 선택하여 시작할 수 있도록 구성합니다. -* 사용자가 입력한 레벨 번호에 따라 해당 레벨의 함수를 호출하여 게임을 진행합니다. - - -### 각 레벨 파일 (Lv_1.swift ~ Lv_6.swift) - 구현 파일 - -**Lv_1.swift** - -```swift -import Foundation - -func levelOne() { - // 1. 정답을 생성하는 로직을 추가합니다. - // 2. 유저가 정답을 맞출 때까지 반복해서 입력을 받습니다. - // 3. 입력값이 유효한지 검사하고 힌트를 제공하는 기능을 구현합니다. -} -``` - -각 레벨별로 구현하시면 됩니다. +### 🐞 트러블 슈팅 +* [문자열 enum 내 상수값으로 저장하기](https://chhue96.tistory.com/124) diff --git a/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/project.pbxproj b/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/project.pbxproj index b5ea2cd..0695a57 100644 --- a/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/project.pbxproj +++ b/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/project.pbxproj @@ -249,6 +249,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + MACOSX_DEPLOYMENT_TARGET = 15.0; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; @@ -258,6 +259,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + MACOSX_DEPLOYMENT_TARGET = 15.0; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; diff --git a/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/xcuserdata/chaehyunpark.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/xcuserdata/chaehyunpark.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..f5837ed --- /dev/null +++ b/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/xcuserdata/chaehyunpark.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/xcuserdata/chaehyunpark.xcuserdatad/xcschemes/xcschememanagement.plist b/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/xcuserdata/chaehyunpark.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..dfbd5af --- /dev/null +++ b/Week2-BaseballGame/Week2-BaseballGame.xcodeproj/xcuserdata/chaehyunpark.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Week2-BaseballGame.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/Week2-BaseballGame/Week2-BaseballGame/BaseballGame.swift b/Week2-BaseballGame/Week2-BaseballGame/BaseballGame.swift new file mode 100644 index 0000000..2f5347f --- /dev/null +++ b/Week2-BaseballGame/Week2-BaseballGame/BaseballGame.swift @@ -0,0 +1,186 @@ +// +// baseballGame.swift +// Week2-BaseballGame +// +// Created by CHYUN on 11/5/24. +// + + +class BaseballGame { + + // 기록 매니저 + private var recordManager: RecordManager + private var printManager: PrintManager + init(recordManager: RecordManager, printManager: PrintManager) { + self.recordManager = recordManager + self.printManager = printManager + } + + + // 게임 상태 + private var gameStatus: GameStatus = .on { + willSet(newStatus) { + switch newStatus { + case .on : printManager.printGuideance(guide: Guidance.welcome) + case .off : printManager.printGuideance(guide: Guidance.gameEnd) + } + } + } + + // 게임 시작 + func startGame() { + + gameStatus = .on + commandLoop : while true { + let command = readLine()!.replacingOccurrences(of: " ", with: "") + + switch command { + case "1": + playGame() + break commandLoop + case "2": + recordManager.showRecord() + printManager.printGuideance(guide: Guidance.inputAgain) + + case "3": + gameStatus = .off + break commandLoop + default : + printManager.printError(error: InputError.invalidInputError) + printManager.printGuideance(guide: Guidance.inputAgain) + } + } + } + + + func playGame() { + + let answer = newGame() // 랜덤 값 받아오기 + var score = Score() + var tryCount = 0 + + + while gameStatus == .on { + + // 플레이어에게 값 받기 + let playerInput = getPlayerInput() + + do { + // 예외 없을 경우 + let playerInputAsArray = try checkError(input: playerInput) + + score = calculateScore(playerInput: playerInputAsArray, answer: answer) + + if score.strikeCount == GameConfig.numberOfAnswer { + printManager.printGuideance(guide: Guidance.hit) + recordManager.recordSet(tries: tryCount + 1) + startGame() + } else if score.outCount == GameConfig.numberOfAnswer { + printManager.printGuideance(guide: Guidance.out) + } else { + print("\(score.strikeCount) \(Guidance.strike) \(score.ballCount) \(Guidance.ball)") + } + + score = Score() + tryCount += 1 + + // 예외 경우 + } catch InputError.inputCountError { + printManager.printError(error: InputError.inputCountError) + + } catch InputError.invalidInputError { + printManager.printError(error: InputError.invalidInputError) + + } catch InputError.zeroInputError { + printManager.printError(error: InputError.zeroInputError) + + } catch InputError.duplicateValueError { + printManager.printError(error: InputError.duplicateValueError) + } catch { + printManager.printError(error: InputError.unknownError) + } + } + + } + + + private func calculateScore(playerInput: [Int], answer: [Int]) -> Score { + var score = Score() + for (index, number) in playerInput.enumerated() { + if answer [index] == number { + score.strikeCount += 1 + } else if answer.contains(number) { + score.ballCount += 1 + } else { + score.outCount += 1 + } + } + return score + } + + + // 랜덤 값 추출 + private func newGame() -> [Int] { + var answer: [Int] = [] + var questionBoxes = "" + var range = GameConfig.rangeOfAnswerWithoutZero + + while answer.count < GameConfig.numberOfAnswer { + + let randomNumber = Int.random(in: range) + if !answer.contains(randomNumber) { + answer.append(randomNumber) + range = GameConfig.rangeOfAnswerWithZero // 랜덤 범위 - 0을 포함한 범위로 변경 + questionBoxes.append("[ ? ] ") + } + } + + printManager.printGuideance(guide: Guidance.gameStart) + print(questionBoxes) + + print(answer) //test + return answer + } + + // 입력 값 받아와서 필요한 처리 후 리턴 + private func getPlayerInput() -> String { + printManager.printGuideance(guide: Guidance.requireInput) + return readLine()?.trimmingCharacters(in: .whitespaces) ?? "" + } + + + // 예외 상황 체크 + private func checkError(input: String) throws -> [Int] { + + // 한 자씩 파악하기 위해 배열로 쪼개기 + let inputAsStringArray = input.split(separator: "") + + // 1. 입력 값 개수가 요구치와 다른지 체크 + guard inputAsStringArray.count == GameConfig.numberOfAnswer else { + throw InputError.inputCountError + } + + // String 배열 -> Int 배열 + let inputAsIntArray = inputAsStringArray.map({ Int($0) }) + + // 2. String값 Int로 바꿀경우 nil, 숫자 아닌 값 입력되었는지 체크 + guard !inputAsIntArray.contains(nil) else { + throw InputError.invalidInputError + } + + // 3. 0이 첫 자리에 입력되었는지 체크 + guard inputAsIntArray.first != 0 else { + throw InputError.zeroInputError + } + + // 4. 중복 값 입력되었는지 체크 + guard Set(inputAsIntArray).count == inputAsIntArray.count else { + throw InputError.duplicateValueError + } + + // 모든 예외 상황이 아닐 경우 값비 교를 위한 배열 리턴, 위에서 nil 체크 완료 + return inputAsIntArray.map({ $0! }) + + } + +} diff --git "a/Week2-BaseballGame/Week2-BaseballGame/Lv_1(\355\225\204\354\210\230\352\265\254\355\230\204).swift" "b/Week2-BaseballGame/Week2-BaseballGame/Lv_1(\355\225\204\354\210\230\352\265\254\355\230\204).swift" deleted file mode 100644 index afd8aba..0000000 --- "a/Week2-BaseballGame/Week2-BaseballGame/Lv_1(\355\225\204\354\210\230\352\265\254\355\230\204).swift" +++ /dev/null @@ -1,9 +0,0 @@ -// Lv 1 (11/04 까지) -// 1에서 9까지의 서로 다른 임의의 수 3개를 정하고 맞추는 게임입니다 -// 정답은 랜덤으로 만듭니다.(1에서 9까지의 서로 다른 임의의 수 3자리) - -import Foundation - -func levelOne() { - -} diff --git "a/Week2-BaseballGame/Week2-BaseballGame/Lv_2(\355\225\204\354\210\230\352\265\254\355\230\204).swift" "b/Week2-BaseballGame/Week2-BaseballGame/Lv_2(\355\225\204\354\210\230\352\265\254\355\230\204).swift" deleted file mode 100644 index 6930839..0000000 --- "a/Week2-BaseballGame/Week2-BaseballGame/Lv_2(\355\225\204\354\210\230\352\265\254\355\230\204).swift" +++ /dev/null @@ -1,21 +0,0 @@ -// Lv 2 (11/06 까지) - -/* -- 정답을 맞추기 위해 3자리수를 입력하고 힌트를 받습니다 - - 힌트는 야구용어인 **볼**과 **스트라이크**입니다. - - 같은 자리에 같은 숫자가 있는 경우 **스트라이크**, 다른 자리에 숫자가 있는 경우 **볼**입니다 - - ex) 정답 : 456 인 경우 - - 435를 입력한 경우 → 1스트라이크 1볼 - - 357를 입력한 경우 → 1스트라이크 - - 678를 입력한 경우 → 1볼 - - 123를 입력한 경우 → Nothing - - 만약 올바르지 않은 입력값에 대해서는 오류 문구를 보여주세요 -- 3자리 숫자가 정답과 같은 경우 게임이 종료됩니다 -- 실행 예시(정답 : 456)13123213 -*/ - -import Foundation - -func levelTwo() { - -} diff --git "a/Week2-BaseballGame/Week2-BaseballGame/Lv_3(\353\217\204\354\240\204\352\265\254\355\230\204).swift" "b/Week2-BaseballGame/Week2-BaseballGame/Lv_3(\353\217\204\354\240\204\352\265\254\355\230\204).swift" deleted file mode 100644 index d5df17e..0000000 --- "a/Week2-BaseballGame/Week2-BaseballGame/Lv_3(\353\217\204\354\240\204\352\265\254\355\230\204).swift" +++ /dev/null @@ -1,15 +0,0 @@ -// Lv 3 (11/06 까지) - -/* - - 정답이 되는 숫자를 0에서 9까지의 서로 다른 3자리의 숫자로 바꿔주세요 - - 맨 앞자리에 0이 오는 것은 불가능합니다 - - 092 → 불가능 - - 870 → 가능 - - 300 → 불가능 - */ - -import Foundation - -func levelThree() { - -} diff --git "a/Week2-BaseballGame/Week2-BaseballGame/Lv_4(\353\217\204\354\240\204\352\265\254\355\230\204).swift" "b/Week2-BaseballGame/Week2-BaseballGame/Lv_4(\353\217\204\354\240\204\352\265\254\355\230\204).swift" deleted file mode 100644 index f529e37..0000000 --- "a/Week2-BaseballGame/Week2-BaseballGame/Lv_4(\353\217\204\354\240\204\352\265\254\355\230\204).swift" +++ /dev/null @@ -1,24 +0,0 @@ -// Lv 4 (11/07 까지) - -/* - 프로그램을 시작할 때 안내문구를 보여주세요 - // 예시 - 환영합니다! 원하시는 번호를 입력해주세요 - 1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기 - ​ - 1번 게임 시작하기의 경우 “필수 구현 기능” 의 예시처럼 게임이 진행됩니다 - 정답을 맞혀 게임이 종료된 경우 위 안내문구를 다시 보여주세요 - // 예시 - 환영합니다! 원하시는 번호를 입력해주세요 - 1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기 - 1 // 1번 게임 시작하기 입력 - - < 게임을 시작합니다 > - 숫자를 입력하세요 - */ - -import Foundation - -func levelFour() { - -} diff --git "a/Week2-BaseballGame/Week2-BaseballGame/Lv_5(\353\217\204\354\240\204\352\265\254\355\230\204).swift" "b/Week2-BaseballGame/Week2-BaseballGame/Lv_5(\353\217\204\354\240\204\352\265\254\355\230\204).swift" deleted file mode 100644 index f9e0d17..0000000 --- "a/Week2-BaseballGame/Week2-BaseballGame/Lv_5(\353\217\204\354\240\204\352\265\254\355\230\204).swift" +++ /dev/null @@ -1,20 +0,0 @@ -// Lv 5 (11/07 까지) - -/* - 2번 게임 기록 보기의 경우 완료한 게임들에 대해 시도 횟수를 보여줍니다 - // 예시 - 환영합니다! 원하시는 번호를 입력해주세요 - 1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기 - 2 // 2번 게임 기록 보기 입력 - - < 게임 기록 보기 > - 1번째 게임 : 시도 횟수 - 14 - 2번째 게임 : 시도 횟수 - 9 - 3번째 게임 : 시도 횟수 - 12 -*/ - -import Foundation - -func levelFive() { - -} diff --git "a/Week2-BaseballGame/Week2-BaseballGame/Lv_6(\353\217\204\354\240\204\352\265\254\355\230\204).swift" "b/Week2-BaseballGame/Week2-BaseballGame/Lv_6(\353\217\204\354\240\204\352\265\254\355\230\204).swift" deleted file mode 100644 index 848f2d1..0000000 --- "a/Week2-BaseballGame/Week2-BaseballGame/Lv_6(\353\217\204\354\240\204\352\265\254\355\230\204).swift" +++ /dev/null @@ -1,26 +0,0 @@ -// Lv 6 (11/07 까지) - -/* - 3번 종료하기의 경우 프로그램이 종료됩니다 - 이전의 게임 기록들도 초기화됩니다 - // 예시 - 환영합니다! 원하시는 번호를 입력해주세요 - 1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기 - 3 // 3번 종료하기 입력 - - < 숫자 야구 게임을 종료합니다 > - ​ - 1, 2, 3 이외의 입력값에 대해서는 오류 메시지를 보여주세요 - // 예시 - 환영합니다! 원하시는 번호를 입력해주세요 - 1. 게임 시작하기 2. 게임 기록 보기 3. 종료하기 - 4 - - 올바른 숫자를 입력해주세요! -*/ - -import Foundation - -func levelSix() { - -} diff --git a/Week2-BaseballGame/Week2-BaseballGame/Model.swift b/Week2-BaseballGame/Week2-BaseballGame/Model.swift new file mode 100644 index 0000000..9d03bfc --- /dev/null +++ b/Week2-BaseballGame/Week2-BaseballGame/Model.swift @@ -0,0 +1,56 @@ +// +// Model.swift +// Week2-BaseballGame +// +// Created by CHYUN on 11/6/24. +// + +enum GameStatus: Int { + case on = 1, + off = 0 +} + +enum GameConfig { + static let numberOfAnswer = 3 + static let rangeOfAnswerWithZero = 0...9 + static let rangeOfAnswerWithoutZero = 1...9 +} + + +enum Guidance { + case welcome, + gameStart, gameEnd, + requireInput, inputAgain, + noRecord, + strike, ball, out, hit +} + +/** 값 비교 전 체크 필요 + * [ 해결 가능 - 제일 먼저 체크 ] + * 1. 공백 문자 삽입 여부 + * -------------> 공백 제외 후 비교 + * + * [ 입력 개수 파악 ] + * 2. 입력 값 개수가 numberOfAnswer보다 부족 (입력 값 없을 경우 포함) + * + * [ 올바르지 않은입력 값 파악 ] + * 3. Int 값 외 + * 4. 0 입력 + * 5. 중복 숫자 입력 + * -------------> 다시 입력 받기 + **/ + +enum InputError: Error { + case inputCountError, + invalidInputError, + zeroInputError, + duplicateValueError, + unknownError +} + + +struct Score { + var strikeCount = 0 + var ballCount = 0 + var outCount = 0 +} diff --git a/Week2-BaseballGame/Week2-BaseballGame/PrintManager.swift b/Week2-BaseballGame/Week2-BaseballGame/PrintManager.swift new file mode 100644 index 0000000..f6fa799 --- /dev/null +++ b/Week2-BaseballGame/Week2-BaseballGame/PrintManager.swift @@ -0,0 +1,62 @@ +// +// PrintManager.swift +// Week2-BaseballGame +// +// Created by CHYUN on 11/7/24. +// + +protocol PrintMessage { + func printError(error: InputError) + func printGuideance(guide: Guidance) +} + +struct PrintManager: PrintMessage { + + func printError(error: InputError) { + + let message = switch error { + case InputError.inputCountError: + "The number of inputs is insufficient." + case InputError.invalidInputError: + "Invalid input." + case InputError.zeroInputError: + "The first position cannot contain a zero." + case InputError.duplicateValueError: + "There are duplicate values." + case InputError.unknownError: + "There are unknown errors." + } + + print(message) + } + + func printGuideance(guide: Guidance) { + + let message = switch guide { + case Guidance.welcome : + "Welcome! Please enter the number to execute. \n 1. Game Start 2. Record 3. Exit" + case Guidance.gameStart : + "*** Game Start ***" + case Guidance.gameEnd : + "***Game End***" + case Guidance.requireInput : + "Please enter the numbers for each question mark in order, then press Enter." + case Guidance.inputAgain : + "Input the number to execute again." + case Guidance.noRecord : + "No Record" + case Guidance.strike : + "Stike" + case Guidance.ball : + "Ball" + case Guidance.hit : + "Congratulation! HIT!!" + case Guidance.out : + "OUT!" + } + print(message) + } + +} + + diff --git a/Week2-BaseballGame/Week2-BaseballGame/RecordManager.swift b/Week2-BaseballGame/Week2-BaseballGame/RecordManager.swift new file mode 100644 index 0000000..1a0c37e --- /dev/null +++ b/Week2-BaseballGame/Week2-BaseballGame/RecordManager.swift @@ -0,0 +1,29 @@ +// +// RecordManager.swift +// Week2-BaseballGame +// +// Created by CHYUN on 11/6/24. +// + +struct RecordManager { + + private var record: [(round: Int, tries: Int)] = [] + + mutating func recordSet(tries: Int) { + record.append((record.count + 1, tries)) + } + + func showRecord() { + + guard !record.isEmpty else { + print(Guidance.noRecord) + return + } + + let recordString = record.map { round, tries in + "\(round) Round : Try - \(tries)" + }.joined(separator: "\n") + + print(recordString) + } +} diff --git a/Week2-BaseballGame/Week2-BaseballGame/main.swift b/Week2-BaseballGame/Week2-BaseballGame/main.swift index 36bba57..e236d88 100644 --- a/Week2-BaseballGame/Week2-BaseballGame/main.swift +++ b/Week2-BaseballGame/Week2-BaseballGame/main.swift @@ -1,29 +1,7 @@ import Foundation -func startGame() { - print("레벨을 선택하세요 (1, 2, 4, 5, 6):") - - if let input = readLine(), let level = Int(input) { - switch level { - case 1: - levelOne() - case 2: - levelTwo() - case 3: - levelThree() - case 4: - levelFour() - case 5: - levelFive() - case 6: - levelSix() - default: - print("유효하지 않은 레벨입니다. 1~6까지를 선택해주세요.") - } - } else { - print("잘못된 입력입니다.") - } -} +let recordManager = RecordManager() +let printManager = PrintManager() +let baseballGame = BaseballGame(recordManager: recordManager, printManager: printManager) +baseballGame.startGame() -// 게임 시작 -startGame()