From c14fbe82e518c4a2f1f8c60b267aa1262fee6d97 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 12:03:16 +0900 Subject: [PATCH 01/26] Feat: Add gamestart --- src/main/kotlin/baseball/Application.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 148d75cc3..e4228ff06 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -1,5 +1,5 @@ package baseball fun main() { - TODO("프로그램 구현") + println("숫자 야구 게임을 시작합니다.") } From c35705d1fc385d0364e83fa596f11f373e2fc9cc Mon Sep 17 00:00:00 2001 From: kang-moonsun <85236336+kang-moonsun@users.noreply.github.com> Date: Wed, 25 Oct 2023 12:16:41 +0900 Subject: [PATCH 02/26] docs: update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docs: 기능 목록 추가 --- README.md | 157 ++++++------------------------------------------------ 1 file changed, 15 insertions(+), 142 deletions(-) diff --git a/README.md b/README.md index 4f55778fe..908e2b803 100644 --- a/README.md +++ b/README.md @@ -1,144 +1,17 @@ # 미션 - 숫자 야구 -## 🔍 진행 방식 - -- 미션은 **기능 요구 사항, 프로그래밍 요구 사항, 과제 진행 요구 사항** 세 가지로 구성되어 있다. -- 세 개의 요구 사항을 만족하기 위해 노력한다. 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다. -- 기능 요구 사항에 기재되지 않은 내용은 스스로 판단하여 구현한다. - -## 📮 미션 제출 방법 - -- 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다. - - GitHub을 활용한 제출 방법은 [프리코스 과제 제출](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 문서를 참고해 - 제출한다. -- GitHub에 미션을 제출한 후 [우아한테크코스 지원](https://apply.techcourse.co.kr) 사이트에 접속하여 프리코스 과제를 제출한다. - - 자세한 방법은 [제출 가이드](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse#제출-가이드) 참고 - - **Pull Request만 보내고 지원 플랫폼에서 과제를 제출하지 않으면 최종 제출하지 않은 것으로 처리되니 주의한다.** - -## 🚨 과제 제출 전 체크 리스트 - 0점 방지 - -- 기능 구현을 모두 정상적으로 했더라도 **요구 사항에 명시된 출력값 형식을 지키지 않을 경우 0점으로 처리**한다. -- 기능 구현을 완료한 뒤 아래 가이드에 따라 테스트를 실행했을 때 모든 테스트가 성공하는지 확인한다. -- **테스트가 실패할 경우 0점으로 처리**되므로, 반드시 확인 후 제출한다. - -### 테스트 실행 가이드 - -- 터미널에서 Mac 또는 Linux 사용자의 경우 `./gradlew clean test` 명령을 실행하고, - Windows 사용자의 경우 `gradlew.bat clean test` 또는 `./gradlew.bat clean test` 명령을 실행할 때 모든 테스트가 아래와 같이 통과하는지 확인한다. - -``` -BUILD SUCCESSFUL in 0s -``` - ---- - -## 🚀 기능 요구 사항 - -기본적으로 1부터 9까지 서로 다른 수로 이루어진 3자리의 수를 맞추는 게임이다. - -- 같은 수가 같은 자리에 있으면 스트라이크, 다른 자리에 있으면 볼, 같은 수가 전혀 없으면 낫싱이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다. - - 예) 상대방(컴퓨터)의 수가 425일 때 - - 123을 제시한 경우 : 1스트라이크 - - 456을 제시한 경우 : 1볼 1스트라이크 - - 789를 제시한 경우 : 낫싱 -- 위 숫자 야구 게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 서로 다른 3개의 숫자를 입력하고, 컴퓨터는 입력한 - 숫자에 대한 - 결과를 출력한다. -- 이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료된다. -- 게임을 종료한 후 게임을 다시 시작하거나 완전히 종료할 수 있다. -- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`을 발생시킨 후 애플리케이션은 종료되어야 한다. - -### 입출력 요구 사항 - -#### 입력 - -- 서로 다른 3자리의 수 -- 게임이 끝난 경우 재시작/종료를 구분하는 1과 2 중 하나의 수 - -#### 출력 - -- 입력한 수에 대한 결과를 볼, 스트라이크 개수로 표시 - -``` -1볼 1스트라이크 -``` - -- 하나도 없는 경우 - -``` -낫싱 -``` - -- 3개의 숫자를 모두 맞힐 경우 - -``` -3스트라이크 -3개의 숫자를 모두 맞히셨습니다! 게임 종료 -``` - -- 게임 시작 문구 출력 - -``` -숫자 야구 게임을 시작합니다. -``` - -#### 실행 결과 예시 - -``` -숫자 야구 게임을 시작합니다. -숫자를 입력해주세요 : 123 -1볼 1스트라이크 -숫자를 입력해주세요 : 145 -1볼 -숫자를 입력해주세요 : 671 -2볼 -숫자를 입력해주세요 : 216 -1스트라이크 -숫자를 입력해주세요 : 713 -3스트라이크 -3개의 숫자를 모두 맞히셨습니다! 게임 종료 -게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요. -1 -숫자를 입력해주세요 : 123 -1볼 -... -``` - ---- - -## 🎯 프로그래밍 요구 사항 - -- Kotlin 1.9.0에서 실행 가능해야 한다. **Kotlin 1.9.0에서 정상적으로 동작하지 않을 경우 0점 처리한다.** -- **Java 코드가 아닌 Kotlin 코드로만 구현해야 한다.** -- 프로그램 실행의 시작점은 `Application`의 `main()`이다. -- `build.gradle(.kts)`을 변경할 수 없고, 외부 라이브러리를 사용하지 않는다. -- [Kotlin 코드 컨벤션](https://github.com/woowacourse/woowacourse-docs/tree/main/styleguide/kotlin) 가이드를 준수하며 프로그래밍한다. -- 프로그램 종료 시 `System.exit()`를 호출하지 않는다. -- 프로그램 구현이 완료되면 `ApplicationTest`의 모든 테스트가 성공해야 한다. **테스트가 실패할 경우 0점 처리한다.** -- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 이름을 수정하거나 이동하지 않는다. - -### 라이브러리 - -- `camp.nextstep.edu.missionutils`에서 제공하는 `Randoms` 및 `Console` API를 사용하여 구현해야 한다. - - Random 값 추출은 `camp.nextstep.edu.missionutils.Randoms`의 `pickNumberInRange()`를 활용한다. - - 사용자가 입력하는 값은 `camp.nextstep.edu.missionutils.Console`의 `readLine()`을 활용한다. - -#### 사용 예시 - -```kotlin -val computer = mutableListOf() -while (computer.size() < 3) { - val randomNumber = Randoms.pickNumberInRange(1, 9) - if (!computer.contains(randomNumber)) { - computer.add(randomNumber) - } -} -``` - ---- - -## ✏️ 과제 진행 요구 사항 - -- 미션은 [kotlin-baseball](https://github.com/woowacourse-precourse/kotlin-baseball-6) 저장소를 Fork & Clone해 시작한다. -- **기능을 구현하기 전 `docs/README.md`에 구현할 기능 목록을 정리**해 추가한다. -- 과제 진행 및 제출 방법은 [프리코스 과제 제출](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) 문서를 참고한다. +## ✨ 기능 목록 +- 게임 시작 안내 출력 +- 입력 + - 컴퓨터 정답 설정 (서로 다른 3개의 숫자) + - 사용자 입력 (서로 다른 3개의 숫자 입력) + - 잘못된 값을 입력한 경우 예외 처리 (애플리케이션 종료) +- 입력에 대한 결과 처리 + - 오답 + - 정답 (게임 종료) +- 출력 + - 결과를 볼, 스트라이크 개수로 표시 + - 하나도 없는 경우 표시 + - 정답 표시 +- loop 설정 +- 게임 종료 후 분기 (재시작 or 종료) From b7177a0950fb0ee249de7518423ab5a159795d1a Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 14:45:38 +0900 Subject: [PATCH 03/26] Feat: Add setComputerNums --- src/main/kotlin/baseball/Application.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index e4228ff06..6b86d8be5 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -1,5 +1,19 @@ package baseball +import camp.nextstep.edu.missionutils.Randoms + fun main() { println("숫자 야구 게임을 시작합니다.") + val computer = mutableListOf() + setComputerNums(computer) + } + +private fun setComputerNums(computer: MutableList) { + while (computer.size < 3) { + val randomNumber = Randoms.pickNumberInRange(1, 9) + if (!computer.contains(randomNumber)) { + computer.add(randomNumber) + } + } +} \ No newline at end of file From a68b49e01a0460070a17509e0b65ef070f14c08c Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 15:53:07 +0900 Subject: [PATCH 04/26] Feat: Add inputUserNums --- src/main/kotlin/baseball/Application.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 6b86d8be5..be0a6b909 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -1,12 +1,17 @@ package baseball +import camp.nextstep.edu.missionutils.Console import camp.nextstep.edu.missionutils.Randoms fun main() { println("숫자 야구 게임을 시작합니다.") val computer = mutableListOf() + val user = mutableListOf() + setComputerNums(computer) + val input = Console.readLine() + input.forEach { user.add(it.digitToInt()) } } private fun setComputerNums(computer: MutableList) { From a837f19054c73d13a5caf66186c2112f3ac5026f Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 16:09:52 +0900 Subject: [PATCH 05/26] Feat: Add compareNums --- src/main/kotlin/baseball/Application.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index be0a6b909..918383916 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -8,10 +8,20 @@ fun main() { val computer = mutableListOf() val user = mutableListOf() + var strike = 0 + var ball = 0 + setComputerNums(computer) val input = Console.readLine() input.forEach { user.add(it.digitToInt()) } + + computer.forEachIndexed { i, value -> + repeat(3) { j -> + if(i == j) { if(value == user[i]) strike++ } + else { if(value == user[j]) ball++ } + } + } } private fun setComputerNums(computer: MutableList) { From a57f98bf2b512442b8f053c7817f4f466bb0ae22 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 16:17:06 +0900 Subject: [PATCH 06/26] Feat: Add output result messages --- src/main/kotlin/baseball/Application.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 918383916..396571fd9 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -22,6 +22,14 @@ fun main() { else { if(value == user[j]) ball++ } } } + + if (strike == 3) { + println("${strike}스트라이크") + println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") + else if (ball != 0) println("${ball}볼") + else if (strike != 0) println("${strike}스트라이크") + else print("낫싱") } private fun setComputerNums(computer: MutableList) { From ffbb2286579d1da6859bb8fad8c0dbc1b781f3a5 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 16:18:17 +0900 Subject: [PATCH 07/26] Feat: Add loop feature --- src/main/kotlin/baseball/Application.kt | 37 ++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 396571fd9..f356496f9 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -12,24 +12,29 @@ fun main() { var ball = 0 setComputerNums(computer) - - val input = Console.readLine() - input.forEach { user.add(it.digitToInt()) } - - computer.forEachIndexed { i, value -> - repeat(3) { j -> - if(i == j) { if(value == user[i]) strike++ } - else { if(value == user[j]) ball++ } + while (true) { + val input = Console.readLine() + input.forEach { user.add(it.digitToInt()) } + + computer.forEachIndexed { i, value -> + repeat(3) { j -> + if (i == j) { + if (value == user[i]) strike++ + } else { + if (value == user[j]) ball++ + } + } } - } - if (strike == 3) { - println("${strike}스트라이크") - println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") - } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") - else if (ball != 0) println("${ball}볼") - else if (strike != 0) println("${strike}스트라이크") - else print("낫싱") + if (strike == 3) { + println("${strike}스트라이크") + println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + break + } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") + else if (ball != 0) println("${ball}볼") + else if (strike != 0) println("${strike}스트라이크") + else print("낫싱") + } } private fun setComputerNums(computer: MutableList) { From 30187fee181e8dfad97e85a2d604c74f9bf7d41f Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 16:34:03 +0900 Subject: [PATCH 08/26] Fix: compareNums --- src/main/kotlin/baseball/Application.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index f356496f9..8aef39259 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -8,21 +8,21 @@ fun main() { val computer = mutableListOf() val user = mutableListOf() - var strike = 0 - var ball = 0 - setComputerNums(computer) while (true) { + print("숫자를 입력해주세요 : ") + + var strike = 0 + var ball = 0 + + user.clear() val input = Console.readLine() input.forEach { user.add(it.digitToInt()) } computer.forEachIndexed { i, value -> repeat(3) { j -> - if (i == j) { - if (value == user[i]) strike++ - } else { - if (value == user[j]) ball++ - } + if (i == j) { if (value == user[i]) strike++ } + else { if (value == user[j]) ball++ } } } From 7be463599f372b9b7d02de4b9fdf92948f8f144f Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 23:05:53 +0900 Subject: [PATCH 09/26] Feat: restart game --- src/main/kotlin/baseball/Application.kt | 60 ++++++++++++++----------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 8aef39259..6b43f2b04 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -8,33 +8,39 @@ fun main() { val computer = mutableListOf() val user = mutableListOf() - setComputerNums(computer) - while (true) { - print("숫자를 입력해주세요 : ") - - var strike = 0 - var ball = 0 - - user.clear() - val input = Console.readLine() - input.forEach { user.add(it.digitToInt()) } - - computer.forEachIndexed { i, value -> - repeat(3) { j -> - if (i == j) { if (value == user[i]) strike++ } - else { if (value == user[j]) ball++ } + do { + computer.clear() + setComputerNums(computer) + while (true) { + print("숫자를 입력해주세요 : ") + + var strike = 0 + var ball = 0 + + user.clear() + val input = Console.readLine() + input.forEach { user.add(it.digitToInt()) } + + computer.forEachIndexed { i, value -> + repeat(3) { j -> + if (i == j) { + if (value == user[i]) strike++ + } else { + if (value == user[j]) ball++ + } + } } - } - if (strike == 3) { - println("${strike}스트라이크") - println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") - break - } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") - else if (ball != 0) println("${ball}볼") - else if (strike != 0) println("${strike}스트라이크") - else print("낫싱") - } + if (strike == 3) { + println("${strike}스트라이크") + println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + break + } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") + else if (ball != 0) println("${ball}볼") + else if (strike != 0) println("${strike}스트라이크") + else print("낫싱") + } + } while (ending(Console.readLine().toInt())) } private fun setComputerNums(computer: MutableList) { @@ -44,4 +50,8 @@ private fun setComputerNums(computer: MutableList) { computer.add(randomNumber) } } +} + +private fun ending(num: Int): Boolean { + return num == 1 } \ No newline at end of file From 5bf1b6d32286a2feaa1a3d084687e704105e4a36 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 23:09:11 +0900 Subject: [PATCH 10/26] Feat: apply exception with validate input number --- src/main/kotlin/baseball/Application.kt | 7 ++++++- src/main/kotlin/baseball/StringExtensions.kt | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/baseball/StringExtensions.kt diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 6b43f2b04..0ab1c124d 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -8,7 +8,7 @@ fun main() { val computer = mutableListOf() val user = mutableListOf() - do { + loop@do { computer.clear() setComputerNums(computer) while (true) { @@ -19,6 +19,11 @@ fun main() { user.clear() val input = Console.readLine() + try { + input.isValidateInputNumber() + } catch (e: IllegalArgumentException) { + break@loop + } input.forEach { user.add(it.digitToInt()) } computer.forEachIndexed { i, value -> diff --git a/src/main/kotlin/baseball/StringExtensions.kt b/src/main/kotlin/baseball/StringExtensions.kt new file mode 100644 index 000000000..9b63efe44 --- /dev/null +++ b/src/main/kotlin/baseball/StringExtensions.kt @@ -0,0 +1,17 @@ +fun String?.getNotEmptyInt(): Int { + val input = this?.trim() + if (input.isNullOrEmpty()) { + throw IllegalArgumentException("input String is null or empty") + } + if (input.toIntOrNull() == null) { + throw IllegalArgumentException("input String cannot be parsed Int") + } + return input.toInt() +} + +fun String?.isValidateInputNumber() { + val num = this.getNotEmptyInt() + if (num < 123 || num > 987) { + throw IllegalArgumentException("input number is unavailable") + } +} \ No newline at end of file From 6e8b9dcf2233337b299379f768bb3987f1042079 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 23:12:26 +0900 Subject: [PATCH 11/26] Feat: apply exception with restart number --- src/main/kotlin/baseball/Application.kt | 10 +++++++--- src/main/kotlin/baseball/StringExtensions.kt | 8 ++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 0ab1c124d..34e1a9ee2 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -45,7 +45,7 @@ fun main() { else if (strike != 0) println("${strike}스트라이크") else print("낫싱") } - } while (ending(Console.readLine().toInt())) + } while(restartOrNot(Console.readLine())) } private fun setComputerNums(computer: MutableList) { @@ -57,6 +57,10 @@ private fun setComputerNums(computer: MutableList) { } } -private fun ending(num: Int): Boolean { - return num == 1 +private fun restartOrNot(input: String?): Boolean { + return try { + input.getValidateRestartNumber() == 1 + } catch(e: IllegalArgumentException) { + false + } } \ No newline at end of file diff --git a/src/main/kotlin/baseball/StringExtensions.kt b/src/main/kotlin/baseball/StringExtensions.kt index 9b63efe44..eb02777a8 100644 --- a/src/main/kotlin/baseball/StringExtensions.kt +++ b/src/main/kotlin/baseball/StringExtensions.kt @@ -14,4 +14,12 @@ fun String?.isValidateInputNumber() { if (num < 123 || num > 987) { throw IllegalArgumentException("input number is unavailable") } +} + +fun String?.getValidateRestartNumber(): Int { + val num = this.getNotEmptyInt() + if (num != 1 && num != 2) { + throw IllegalArgumentException("restart number is unavailable") + } + return num } \ No newline at end of file From ba807039249f896408076b6a01341e498ab99c67 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Wed, 25 Oct 2023 23:41:37 +0900 Subject: [PATCH 12/26] fix: edit exception functions --- src/main/kotlin/baseball/Application.kt | 35 ++++++++++++++++++-- src/main/kotlin/baseball/StringExtensions.kt | 25 -------------- 2 files changed, 32 insertions(+), 28 deletions(-) delete mode 100644 src/main/kotlin/baseball/StringExtensions.kt diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 34e1a9ee2..e5ec51b17 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -20,7 +20,7 @@ fun main() { user.clear() val input = Console.readLine() try { - input.isValidateInputNumber() + isValidateInputNumber(input) } catch (e: IllegalArgumentException) { break@loop } @@ -43,7 +43,7 @@ fun main() { } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") else if (ball != 0) println("${ball}볼") else if (strike != 0) println("${strike}스트라이크") - else print("낫싱") + else println("낫싱") } } while(restartOrNot(Console.readLine())) } @@ -59,8 +59,37 @@ private fun setComputerNums(computer: MutableList) { private fun restartOrNot(input: String?): Boolean { return try { - input.getValidateRestartNumber() == 1 + getValidateRestartNumber(input) == 1 } catch(e: IllegalArgumentException) { false } +} + +fun getNotEmptyInt(string: String?): Int { + val input = string?.trim() + if (input.isNullOrEmpty()) { + throw IllegalArgumentException("input String is null or empty") + } + if (input.toIntOrNull() == null) { + throw IllegalArgumentException("input String cannot be parsed Int") + } + return input.toInt() +} + +fun isValidateInputNumber(string: String?) { + val num = getNotEmptyInt(string) + if (num < 123 || num > 987) { + throw IllegalArgumentException("input number is unavailable") + } + if (num.toString().contains('0')) { + throw IllegalArgumentException("input number is unavailable") + } +} + +fun getValidateRestartNumber(string: String?): Int { + val num = getNotEmptyInt(string) + if (num != 1 && num != 2) { + throw IllegalArgumentException("restart number is unavailable") + } + return num } \ No newline at end of file diff --git a/src/main/kotlin/baseball/StringExtensions.kt b/src/main/kotlin/baseball/StringExtensions.kt deleted file mode 100644 index eb02777a8..000000000 --- a/src/main/kotlin/baseball/StringExtensions.kt +++ /dev/null @@ -1,25 +0,0 @@ -fun String?.getNotEmptyInt(): Int { - val input = this?.trim() - if (input.isNullOrEmpty()) { - throw IllegalArgumentException("input String is null or empty") - } - if (input.toIntOrNull() == null) { - throw IllegalArgumentException("input String cannot be parsed Int") - } - return input.toInt() -} - -fun String?.isValidateInputNumber() { - val num = this.getNotEmptyInt() - if (num < 123 || num > 987) { - throw IllegalArgumentException("input number is unavailable") - } -} - -fun String?.getValidateRestartNumber(): Int { - val num = this.getNotEmptyInt() - if (num != 1 && num != 2) { - throw IllegalArgumentException("restart number is unavailable") - } - return num -} \ No newline at end of file From 8b9fe3533db290404785556e6f55599da7f6b619 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Thu, 26 Oct 2023 03:25:10 +0900 Subject: [PATCH 13/26] Fix: edit exception --- src/main/kotlin/baseball/Application.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index e5ec51b17..1b59dc30d 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -19,13 +19,19 @@ fun main() { user.clear() val input = Console.readLine() - try { - isValidateInputNumber(input) - } catch (e: IllegalArgumentException) { - break@loop - } + + isValidateInputNumber(input) + input.forEach { user.add(it.digitToInt()) } + for(i in 1..9) { + var result = 0 + user.forEachIndexed { _, value -> + if(value == i) result++ + } + if(result > 1) throw IllegalArgumentException("zz") + } + computer.forEachIndexed { i, value -> repeat(3) { j -> if (i == j) { @@ -73,6 +79,7 @@ fun getNotEmptyInt(string: String?): Int { if (input.toIntOrNull() == null) { throw IllegalArgumentException("input String cannot be parsed Int") } + if(input.length > 3 ) throw IllegalArgumentException("input String cannot be parsed Int") return input.toInt() } From 03c70df3ed0e44d13db7cc238a3b3f616b888603 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Fri, 27 Oct 2023 22:48:22 +0900 Subject: [PATCH 14/26] fix: remove try-catch --- src/main/kotlin/baseball/Application.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index 1b59dc30d..cb08373f1 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -24,13 +24,13 @@ fun main() { input.forEach { user.add(it.digitToInt()) } - for(i in 1..9) { - var result = 0 - user.forEachIndexed { _, value -> - if(value == i) result++ - } - if(result > 1) throw IllegalArgumentException("zz") + for(i in 1..9) { + var result = 0 + user.forEachIndexed { _, value -> + if(value == i) result++ } + if(result > 1) throw IllegalArgumentException("zz") + } computer.forEachIndexed { i, value -> repeat(3) { j -> From 72908bb5148314797b7b0308b28e1129e89808a3 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 16:42:58 +0900 Subject: [PATCH 15/26] refactor: seperate GameManager class --- src/main/kotlin/baseball/Application.kt | 100 +--------------------- src/main/kotlin/baseball/GameManager.kt | 105 ++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 98 deletions(-) create mode 100644 src/main/kotlin/baseball/GameManager.kt diff --git a/src/main/kotlin/baseball/Application.kt b/src/main/kotlin/baseball/Application.kt index cb08373f1..68b742643 100644 --- a/src/main/kotlin/baseball/Application.kt +++ b/src/main/kotlin/baseball/Application.kt @@ -1,102 +1,6 @@ package baseball -import camp.nextstep.edu.missionutils.Console -import camp.nextstep.edu.missionutils.Randoms - fun main() { - println("숫자 야구 게임을 시작합니다.") - val computer = mutableListOf() - val user = mutableListOf() - - loop@do { - computer.clear() - setComputerNums(computer) - while (true) { - print("숫자를 입력해주세요 : ") - - var strike = 0 - var ball = 0 - - user.clear() - val input = Console.readLine() - - isValidateInputNumber(input) - - input.forEach { user.add(it.digitToInt()) } - - for(i in 1..9) { - var result = 0 - user.forEachIndexed { _, value -> - if(value == i) result++ - } - if(result > 1) throw IllegalArgumentException("zz") - } - - computer.forEachIndexed { i, value -> - repeat(3) { j -> - if (i == j) { - if (value == user[i]) strike++ - } else { - if (value == user[j]) ball++ - } - } - } - - if (strike == 3) { - println("${strike}스트라이크") - println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") - break - } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") - else if (ball != 0) println("${ball}볼") - else if (strike != 0) println("${strike}스트라이크") - else println("낫싱") - } - } while(restartOrNot(Console.readLine())) -} - -private fun setComputerNums(computer: MutableList) { - while (computer.size < 3) { - val randomNumber = Randoms.pickNumberInRange(1, 9) - if (!computer.contains(randomNumber)) { - computer.add(randomNumber) - } - } -} - -private fun restartOrNot(input: String?): Boolean { - return try { - getValidateRestartNumber(input) == 1 - } catch(e: IllegalArgumentException) { - false - } -} - -fun getNotEmptyInt(string: String?): Int { - val input = string?.trim() - if (input.isNullOrEmpty()) { - throw IllegalArgumentException("input String is null or empty") - } - if (input.toIntOrNull() == null) { - throw IllegalArgumentException("input String cannot be parsed Int") - } - if(input.length > 3 ) throw IllegalArgumentException("input String cannot be parsed Int") - return input.toInt() -} - -fun isValidateInputNumber(string: String?) { - val num = getNotEmptyInt(string) - if (num < 123 || num > 987) { - throw IllegalArgumentException("input number is unavailable") - } - if (num.toString().contains('0')) { - throw IllegalArgumentException("input number is unavailable") - } -} - -fun getValidateRestartNumber(string: String?): Int { - val num = getNotEmptyInt(string) - if (num != 1 && num != 2) { - throw IllegalArgumentException("restart number is unavailable") - } - return num + val gameManager = GameManager() + gameManager.execute() } \ No newline at end of file diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt new file mode 100644 index 000000000..d8d59d489 --- /dev/null +++ b/src/main/kotlin/baseball/GameManager.kt @@ -0,0 +1,105 @@ +package baseball + +import camp.nextstep.edu.missionutils.Console +import camp.nextstep.edu.missionutils.Randoms + +class GameManager { + + fun execute() { + println("숫자 야구 게임을 시작합니다.") + val computer = mutableListOf() + val user = mutableListOf() + + loop@do { + computer.clear() + setComputerNums(computer) + while (true) { + print("숫자를 입력해주세요 : ") + + var strike = 0 + var ball = 0 + + user.clear() + val input = Console.readLine() + + isValidateInputNumber(input) + + input.forEach { user.add(it.digitToInt()) } + + for(i in 1..9) { + var result = 0 + user.forEachIndexed { _, value -> + if(value == i) result++ + } + if(result > 1) throw IllegalArgumentException("zz") + } + + computer.forEachIndexed { i, value -> + repeat(3) { j -> + if (i == j) { + if (value == user[i]) strike++ + } else { + if (value == user[j]) ball++ + } + } + } + + if (strike == 3) { + println("${strike}스트라이크") + println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + break + } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") + else if (ball != 0) println("${ball}볼") + else if (strike != 0) println("${strike}스트라이크") + else println("낫싱") + } + } while(restartOrNot(Console.readLine())) + } + + private fun setComputerNums(computer: MutableList) { + while (computer.size < 3) { + val randomNumber = Randoms.pickNumberInRange(1, 9) + if (!computer.contains(randomNumber)) { + computer.add(randomNumber) + } + } + } + + private fun restartOrNot(input: String?): Boolean { + return try { + getValidateRestartNumber(input) == 1 + } catch(e: IllegalArgumentException) { + false + } + } + + fun getNotEmptyInt(string: String?): Int { + val input = string?.trim() + if (input.isNullOrEmpty()) { + throw IllegalArgumentException("input String is null or empty") + } + if (input.toIntOrNull() == null) { + throw IllegalArgumentException("input String cannot be parsed Int") + } + if(input.length > 3 ) throw IllegalArgumentException("input String cannot be parsed Int") + return input.toInt() + } + + fun isValidateInputNumber(string: String?) { + val num = getNotEmptyInt(string) + if (num < 123 || num > 987) { + throw IllegalArgumentException("input number is unavailable") + } + if (num.toString().contains('0')) { + throw IllegalArgumentException("input number is unavailable") + } + } + + fun getValidateRestartNumber(string: String?): Int { + val num = getNotEmptyInt(string) + if (num != 1 && num != 2) { + throw IllegalArgumentException("restart number is unavailable") + } + return num + } +} \ No newline at end of file From 578617496474e6fa984cd74ac9c912bac75a8f98 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 16:51:47 +0900 Subject: [PATCH 16/26] =?UTF-8?q?refactor:=20=EC=9C=A0=ED=9A=A8=EC=84=B1?= =?UTF-8?q?=20=EA=B2=80=EC=82=AC=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/GameManager.kt | 44 ++++-------------------- src/main/kotlin/baseball/InputManager.kt | 34 ++++++++++++++++++ 2 files changed, 40 insertions(+), 38 deletions(-) create mode 100644 src/main/kotlin/baseball/InputManager.kt diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index d8d59d489..4d0ce3742 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -22,7 +22,7 @@ class GameManager { user.clear() val input = Console.readLine() - isValidateInputNumber(input) + isValidateInputString(input) input.forEach { user.add(it.digitToInt()) } @@ -53,7 +53,7 @@ class GameManager { else if (strike != 0) println("${strike}스트라이크") else println("낫싱") } - } while(restartOrNot(Console.readLine())) + } while(restartOrNot()) } private fun setComputerNums(computer: MutableList) { @@ -65,41 +65,9 @@ class GameManager { } } - private fun restartOrNot(input: String?): Boolean { - return try { - getValidateRestartNumber(input) == 1 - } catch(e: IllegalArgumentException) { - false - } - } - - fun getNotEmptyInt(string: String?): Int { - val input = string?.trim() - if (input.isNullOrEmpty()) { - throw IllegalArgumentException("input String is null or empty") - } - if (input.toIntOrNull() == null) { - throw IllegalArgumentException("input String cannot be parsed Int") - } - if(input.length > 3 ) throw IllegalArgumentException("input String cannot be parsed Int") - return input.toInt() - } - - fun isValidateInputNumber(string: String?) { - val num = getNotEmptyInt(string) - if (num < 123 || num > 987) { - throw IllegalArgumentException("input number is unavailable") - } - if (num.toString().contains('0')) { - throw IllegalArgumentException("input number is unavailable") - } - } - - fun getValidateRestartNumber(string: String?): Int { - val num = getNotEmptyInt(string) - if (num != 1 && num != 2) { - throw IllegalArgumentException("restart number is unavailable") - } - return num + private fun restartOrNot(): Boolean { + val input = Console.readLine() + isValidateFinishNumber(input) + return true } } \ No newline at end of file diff --git a/src/main/kotlin/baseball/InputManager.kt b/src/main/kotlin/baseball/InputManager.kt new file mode 100644 index 000000000..5e8fcaec9 --- /dev/null +++ b/src/main/kotlin/baseball/InputManager.kt @@ -0,0 +1,34 @@ +package baseball + +fun isValidateInputString(input: String) { + // 빈 문자열 확인 + if (input.isBlank()) throw IllegalArgumentException("input string is empty") + // 3자리 수 길이 확인 + if (input.length != 3) throw IllegalArgumentException("input string's length is not suitable") + // 0 포함 확인 + if (input.contains('0')) throw IllegalArgumentException("input string should not contains '0'") + // 숫자 변환 가능 여부 + if (input.toIntOrNull() == null) throw IllegalArgumentException("input string is not parseable") + // 중복값 확인 + if (isDuplicated(input)) throw IllegalArgumentException("number is duplicated in input string") +} + +fun isDuplicated(input: String): Boolean { + input.forEachIndexed { index, num -> + var count = 0 + for (j in index..input.lastIndex) { + if (num == input[j]) { + count++ + } + } + if (count > 1) return true + } + return false +} + +fun isValidateFinishNumber(input: String) { + // 빈 문자열 확인 + if (input.isBlank()) throw IllegalArgumentException("input string is empty") + // 1 또는 2 외의 값 확인 + if (input != "1" && input != "2") throw IllegalArgumentException("input string is not available value") +} \ No newline at end of file From 58e31f60ba89a10c741a0fb1355c3613a345342b Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 16:55:37 +0900 Subject: [PATCH 17/26] =?UTF-8?q?refactor:=20Computer=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/Computer.kt | 16 ++++++++++++++++ src/main/kotlin/baseball/GameManager.kt | 14 ++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 src/main/kotlin/baseball/Computer.kt diff --git a/src/main/kotlin/baseball/Computer.kt b/src/main/kotlin/baseball/Computer.kt new file mode 100644 index 000000000..8bec2bde1 --- /dev/null +++ b/src/main/kotlin/baseball/Computer.kt @@ -0,0 +1,16 @@ +package baseball + +import camp.nextstep.edu.missionutils.Randoms + +class Computer { + fun getNumberList(): MutableList { + val mutableList = mutableListOf() + while (mutableList.size < 3) { + val element = Randoms.pickNumberInRange(1, 9) + if (!mutableList.contains(element)) { + mutableList.add(element) + } + } + return mutableList + } +} \ No newline at end of file diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index 4d0ce3742..e8f0b63bc 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -4,6 +4,7 @@ import camp.nextstep.edu.missionutils.Console import camp.nextstep.edu.missionutils.Randoms class GameManager { + private val computerNumberList = mutableListOf() fun execute() { println("숫자 야구 게임을 시작합니다.") @@ -12,7 +13,7 @@ class GameManager { loop@do { computer.clear() - setComputerNums(computer) + initComputer() while (true) { print("숫자를 입력해주세요 : ") @@ -56,13 +57,10 @@ class GameManager { } while(restartOrNot()) } - private fun setComputerNums(computer: MutableList) { - while (computer.size < 3) { - val randomNumber = Randoms.pickNumberInRange(1, 9) - if (!computer.contains(randomNumber)) { - computer.add(randomNumber) - } - } + private fun initComputer() { + val computer = Computer() + if (computerNumberList.isNotEmpty()) computerNumberList.clear() + computerNumberList.addAll(computer.getNumberList()) } private fun restartOrNot(): Boolean { From 32a9ed71465c0d6e369f384796c97e3983f3da32 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 16:59:20 +0900 Subject: [PATCH 18/26] =?UTF-8?q?refactor:=20User=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/GameManager.kt | 27 +++++++++---------------- src/main/kotlin/baseball/User.kt | 13 ++++++++++++ 2 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 src/main/kotlin/baseball/User.kt diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index e8f0b63bc..5cae4fc93 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -5,35 +5,22 @@ import camp.nextstep.edu.missionutils.Randoms class GameManager { private val computerNumberList = mutableListOf() + private val userNumberList = mutableListOf() fun execute() { println("숫자 야구 게임을 시작합니다.") - val computer = mutableListOf() - val user = mutableListOf() loop@do { - computer.clear() initComputer() + + initUser() while (true) { print("숫자를 입력해주세요 : ") var strike = 0 var ball = 0 - user.clear() - val input = Console.readLine() - - isValidateInputString(input) - - input.forEach { user.add(it.digitToInt()) } - - for(i in 1..9) { - var result = 0 - user.forEachIndexed { _, value -> - if(value == i) result++ - } - if(result > 1) throw IllegalArgumentException("zz") - } + initUser() computer.forEachIndexed { i, value -> repeat(3) { j -> @@ -63,6 +50,12 @@ class GameManager { computerNumberList.addAll(computer.getNumberList()) } + private fun initUser() { + val user = User() + if (userNumberList.isNotEmpty()) userNumberList.clear() + userNumberList.addAll(user.getNumberList()) + } + private fun restartOrNot(): Boolean { val input = Console.readLine() isValidateFinishNumber(input) diff --git a/src/main/kotlin/baseball/User.kt b/src/main/kotlin/baseball/User.kt new file mode 100644 index 000000000..f3062ece1 --- /dev/null +++ b/src/main/kotlin/baseball/User.kt @@ -0,0 +1,13 @@ +package baseball + +import camp.nextstep.edu.missionutils.Console + +class User { + fun getNumberList(): MutableList { + val mutableList = mutableListOf() + val input = Console.readLine() + isValidateInputString(input) + input.forEach { mutableList.add(it.digitToInt()) } + return mutableList + } +} \ No newline at end of file From b5add558a11ec80f9123b288adc0884f52973740 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 17:03:04 +0900 Subject: [PATCH 19/26] =?UTF-8?q?refactor:=20Referee(=EC=B1=84=EC=A0=90=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5)=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/GameManager.kt | 31 +++++++----------------- src/main/kotlin/baseball/Referee.kt | 32 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 src/main/kotlin/baseball/Referee.kt diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index 5cae4fc93..a10a52f3c 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -6,6 +6,7 @@ import camp.nextstep.edu.missionutils.Randoms class GameManager { private val computerNumberList = mutableListOf() private val userNumberList = mutableListOf() + private var result = true fun execute() { println("숫자 야구 게임을 시작합니다.") @@ -14,32 +15,11 @@ class GameManager { initComputer() initUser() - while (true) { + while (result) { print("숫자를 입력해주세요 : ") - var strike = 0 - var ball = 0 - initUser() - - computer.forEachIndexed { i, value -> - repeat(3) { j -> - if (i == j) { - if (value == user[i]) strike++ - } else { - if (value == user[j]) ball++ - } - } - } - - if (strike == 3) { - println("${strike}스트라이크") - println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") - break - } else if (strike != 0 && ball != 0) println("${ball}볼 ${strike}스트라이크") - else if (ball != 0) println("${ball}볼") - else if (strike != 0) println("${strike}스트라이크") - else println("낫싱") + getResult() } } while(restartOrNot()) } @@ -56,6 +36,11 @@ class GameManager { userNumberList.addAll(user.getNumberList()) } + private fun getResult() { + val referee = Referee() + result = !(referee.getResult(computerNumberList, userNumberList)) + } + private fun restartOrNot(): Boolean { val input = Console.readLine() isValidateFinishNumber(input) diff --git a/src/main/kotlin/baseball/Referee.kt b/src/main/kotlin/baseball/Referee.kt new file mode 100644 index 000000000..a21a5df11 --- /dev/null +++ b/src/main/kotlin/baseball/Referee.kt @@ -0,0 +1,32 @@ +package baseball + +class Referee { + private var strike = 0 + private var ball = 0 + + fun getResult(computerNums: MutableList, userNums: MutableList): Boolean { + strike = 0 + ball = 0 + + computerNums.forEachIndexed { i, computerNum -> + userNums.forEachIndexed { j, userNum -> + if (computerNum == userNum) { + if (i == j) strike++ + else ball++ + } + } + } + + return if (strike == 3) { + println("${strike}스트라이크") + println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + true + } else { + if (strike > 0 && ball > 0) println("${ball}볼 ${strike}스트라이크") + else if (strike == 0 && ball > 0) println("${ball}볼") + else if (strike > 0 && ball == 0) println("${strike}스트라이크") + else println("낫싱") + false + } + } +} \ No newline at end of file From 749ba84812f26e66191b5512775ed6e083ae9191 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 17:07:01 +0900 Subject: [PATCH 20/26] =?UTF-8?q?refactor:=20=EC=9E=AC=EC=8B=A4=ED=96=89?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/GameManager.kt | 24 ++++++++++++++++++------ src/main/kotlin/baseball/User.kt | 6 ++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index a10a52f3c..c507df328 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -6,12 +6,13 @@ import camp.nextstep.edu.missionutils.Randoms class GameManager { private val computerNumberList = mutableListOf() private val userNumberList = mutableListOf() + private var state = true private var result = true fun execute() { println("숫자 야구 게임을 시작합니다.") - loop@do { + while(state) { initComputer() initUser() @@ -21,7 +22,8 @@ class GameManager { initUser() getResult() } - } while(restartOrNot()) + finish() + } } private fun initComputer() { @@ -41,9 +43,19 @@ class GameManager { result = !(referee.getResult(computerNumberList, userNumberList)) } - private fun restartOrNot(): Boolean { - val input = Console.readLine() - isValidateFinishNumber(input) - return true + private fun finish() { + val user = User() + val finishNumber = user.getFinishNumber() + if (finishNumber == 1) restart() + else exit() + } + + private fun restart() { + result = true + state = true + } + + private fun exit() { + state = false } } \ No newline at end of file diff --git a/src/main/kotlin/baseball/User.kt b/src/main/kotlin/baseball/User.kt index f3062ece1..1423f9e9d 100644 --- a/src/main/kotlin/baseball/User.kt +++ b/src/main/kotlin/baseball/User.kt @@ -10,4 +10,10 @@ class User { input.forEach { mutableList.add(it.digitToInt()) } return mutableList } + + fun getFinishNumber(): Int { + val input = Console.readLine() + isValidateFinishNumber(input) + return input.toInt() + } } \ No newline at end of file From 330aa106d709bed8205795840ce8b7dab50989cc Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 17:10:47 +0900 Subject: [PATCH 21/26] =?UTF-8?q?style:=20const=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/GameManager.kt | 13 +++++-------- src/main/kotlin/baseball/constants.kt | 5 +++++ 2 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 src/main/kotlin/baseball/constants.kt diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index c507df328..c0cc8bcff 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -1,13 +1,10 @@ package baseball -import camp.nextstep.edu.missionutils.Console -import camp.nextstep.edu.missionutils.Randoms - class GameManager { private val computerNumberList = mutableListOf() private val userNumberList = mutableListOf() - private var state = true - private var result = true + private var state = INIT + private var result = INIT fun execute() { println("숫자 야구 게임을 시작합니다.") @@ -51,11 +48,11 @@ class GameManager { } private fun restart() { - result = true - state = true + state = RESTART + result = INIT } private fun exit() { - state = false + state = EXIT } } \ No newline at end of file diff --git a/src/main/kotlin/baseball/constants.kt b/src/main/kotlin/baseball/constants.kt new file mode 100644 index 000000000..e1b2b04f5 --- /dev/null +++ b/src/main/kotlin/baseball/constants.kt @@ -0,0 +1,5 @@ +package baseball + +const val INIT = true +const val RESTART = true +const val EXIT = false \ No newline at end of file From 0ab9c53ab438aa88a6a9849da04a78ebef625245 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 17:14:08 +0900 Subject: [PATCH 22/26] =?UTF-8?q?refactor:=20print=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/GameManager.kt | 16 +++++++++++++++- src/main/kotlin/baseball/Referee.kt | 20 ++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index c0cc8bcff..1ef1579f1 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -7,7 +7,7 @@ class GameManager { private var result = INIT fun execute() { - println("숫자 야구 게임을 시작합니다.") + showExecuteMessage() while(state) { initComputer() @@ -32,6 +32,7 @@ class GameManager { private fun initUser() { val user = User() if (userNumberList.isNotEmpty()) userNumberList.clear() + showInputMessage() userNumberList.addAll(user.getNumberList()) } @@ -42,6 +43,7 @@ class GameManager { private fun finish() { val user = User() + showFinishMessage() val finishNumber = user.getFinishNumber() if (finishNumber == 1) restart() else exit() @@ -55,4 +57,16 @@ class GameManager { private fun exit() { state = EXIT } + + private fun showExecuteMessage() { + println("숫자 야구를 시작합니다.") + } + + private fun showInputMessage() { + print("숫자를 입력해주세요 : ") + } + + private fun showFinishMessage() { + println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.") + } } \ No newline at end of file diff --git a/src/main/kotlin/baseball/Referee.kt b/src/main/kotlin/baseball/Referee.kt index a21a5df11..4c3d43b82 100644 --- a/src/main/kotlin/baseball/Referee.kt +++ b/src/main/kotlin/baseball/Referee.kt @@ -18,15 +18,23 @@ class Referee { } return if (strike == 3) { - println("${strike}스트라이크") - println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + showCorrectMessage() true } else { - if (strike > 0 && ball > 0) println("${ball}볼 ${strike}스트라이크") - else if (strike == 0 && ball > 0) println("${ball}볼") - else if (strike > 0 && ball == 0) println("${strike}스트라이크") - else println("낫싱") + showHintMessage() false } } + + private fun showCorrectMessage() { + println("${strike}스트라이크") + println("3개의 숫자를 모두 맞히셨습니다! 게임 종료") + } + + private fun showHintMessage() { + if (strike > 0 && ball > 0) println("${ball}볼 ${strike}스트라이크") + else if (strike == 0 && ball > 0) println("${ball}볼") + else if (strike > 0 && ball == 0) println("${strike}스트라이크") + else println("낫싱") + } } \ No newline at end of file From 584354d85556ac90a9f3f389e0b8e5cb8de32143 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 17:20:21 +0900 Subject: [PATCH 23/26] =?UTF-8?q?refactor:=20while=EB=AC=B8(=EC=9E=85?= =?UTF-8?q?=EB=A0=A5,=20=EC=B1=84=EC=A0=90)=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/GameManager.kt | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index 1ef1579f1..4e7cd130f 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -8,18 +8,17 @@ class GameManager { fun execute() { showExecuteMessage() + while (state) { + playGame() + finish() + } + } - while(state) { - initComputer() - + private fun playGame() { + initComputer() + while (result) { initUser() - while (result) { - print("숫자를 입력해주세요 : ") - - initUser() - getResult() - } - finish() + getResult() } } @@ -50,8 +49,8 @@ class GameManager { } private fun restart() { - state = RESTART result = INIT + state = RESTART } private fun exit() { From 024128b5a187eb84c30cf7e85c4bfd77f7ddb5e9 Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 17:50:59 +0900 Subject: [PATCH 24/26] =?UTF-8?q?rename:=20InputManager=20=EB=82=B4=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/InputManager.kt | 4 ++-- src/main/kotlin/baseball/User.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/baseball/InputManager.kt b/src/main/kotlin/baseball/InputManager.kt index 5e8fcaec9..7cc63cbe7 100644 --- a/src/main/kotlin/baseball/InputManager.kt +++ b/src/main/kotlin/baseball/InputManager.kt @@ -1,6 +1,6 @@ package baseball -fun isValidateInputString(input: String) { +fun isValidateInputStringForGame(input: String) { // 빈 문자열 확인 if (input.isBlank()) throw IllegalArgumentException("input string is empty") // 3자리 수 길이 확인 @@ -26,7 +26,7 @@ fun isDuplicated(input: String): Boolean { return false } -fun isValidateFinishNumber(input: String) { +fun isValidateInputStringForFinish(input: String) { // 빈 문자열 확인 if (input.isBlank()) throw IllegalArgumentException("input string is empty") // 1 또는 2 외의 값 확인 diff --git a/src/main/kotlin/baseball/User.kt b/src/main/kotlin/baseball/User.kt index 1423f9e9d..f685e058c 100644 --- a/src/main/kotlin/baseball/User.kt +++ b/src/main/kotlin/baseball/User.kt @@ -6,14 +6,14 @@ class User { fun getNumberList(): MutableList { val mutableList = mutableListOf() val input = Console.readLine() - isValidateInputString(input) + isValidateInputStringForGame(input) input.forEach { mutableList.add(it.digitToInt()) } return mutableList } fun getFinishNumber(): Int { val input = Console.readLine() - isValidateFinishNumber(input) + isValidateInputStringForFinish(input) return input.toInt() } } \ No newline at end of file From 7d902bab3840359e2cdf26faf769a7039cd3956d Mon Sep 17 00:00:00 2001 From: kang-moonsun Date: Mon, 30 Oct 2023 18:03:44 +0900 Subject: [PATCH 25/26] =?UTF-8?q?comment:=20class=20=EB=B0=8F=20method=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/baseball/Computer.kt | 1 + src/main/kotlin/baseball/GameManager.kt | 7 +++++++ src/main/kotlin/baseball/InputManager.kt | 3 +++ src/main/kotlin/baseball/Referee.kt | 2 ++ src/main/kotlin/baseball/User.kt | 2 ++ src/main/kotlin/baseball/constants.kt | 1 + 6 files changed, 16 insertions(+) diff --git a/src/main/kotlin/baseball/Computer.kt b/src/main/kotlin/baseball/Computer.kt index 8bec2bde1..cb641433f 100644 --- a/src/main/kotlin/baseball/Computer.kt +++ b/src/main/kotlin/baseball/Computer.kt @@ -3,6 +3,7 @@ package baseball import camp.nextstep.edu.missionutils.Randoms class Computer { + // 컴퓨터 숫자 랜덤 초기화(중복 제외) - GameManager class의 initComputer()에서 호출 fun getNumberList(): MutableList { val mutableList = mutableListOf() while (mutableList.size < 3) { diff --git a/src/main/kotlin/baseball/GameManager.kt b/src/main/kotlin/baseball/GameManager.kt index 4e7cd130f..16f3a3321 100644 --- a/src/main/kotlin/baseball/GameManager.kt +++ b/src/main/kotlin/baseball/GameManager.kt @@ -6,6 +6,7 @@ class GameManager { private var state = INIT private var result = INIT + // 프로그램 실행 fun execute() { showExecuteMessage() while (state) { @@ -22,12 +23,14 @@ class GameManager { } } + // 컴퓨터 숫자 초기화 private fun initComputer() { val computer = Computer() if (computerNumberList.isNotEmpty()) computerNumberList.clear() computerNumberList.addAll(computer.getNumberList()) } + // 유저 숫자 입력 private fun initUser() { val user = User() if (userNumberList.isNotEmpty()) userNumberList.clear() @@ -35,11 +38,13 @@ class GameManager { userNumberList.addAll(user.getNumberList()) } + // 채점 기능 - playGame() while문 탈출 기여 private fun getResult() { val referee = Referee() result = !(referee.getResult(computerNumberList, userNumberList)) } + // 재실행 분기문 - execute() while문 탈출 기여 private fun finish() { val user = User() showFinishMessage() @@ -48,11 +53,13 @@ class GameManager { else exit() } + // 게임 재실행 - const 변수 초기화 private fun restart() { result = INIT state = RESTART } + // 게임 종료 - false private fun exit() { state = EXIT } diff --git a/src/main/kotlin/baseball/InputManager.kt b/src/main/kotlin/baseball/InputManager.kt index 7cc63cbe7..a3db5e5c1 100644 --- a/src/main/kotlin/baseball/InputManager.kt +++ b/src/main/kotlin/baseball/InputManager.kt @@ -1,5 +1,6 @@ package baseball +// 유효성 검사(사용자 숫자) fun isValidateInputStringForGame(input: String) { // 빈 문자열 확인 if (input.isBlank()) throw IllegalArgumentException("input string is empty") @@ -13,6 +14,7 @@ fun isValidateInputStringForGame(input: String) { if (isDuplicated(input)) throw IllegalArgumentException("number is duplicated in input string") } +// 중복 검사(사용자 숫자) fun isDuplicated(input: String): Boolean { input.forEachIndexed { index, num -> var count = 0 @@ -26,6 +28,7 @@ fun isDuplicated(input: String): Boolean { return false } +// 유효성 검사(재실행 숫자) fun isValidateInputStringForFinish(input: String) { // 빈 문자열 확인 if (input.isBlank()) throw IllegalArgumentException("input string is empty") diff --git a/src/main/kotlin/baseball/Referee.kt b/src/main/kotlin/baseball/Referee.kt index 4c3d43b82..68b9d1fea 100644 --- a/src/main/kotlin/baseball/Referee.kt +++ b/src/main/kotlin/baseball/Referee.kt @@ -1,9 +1,11 @@ package baseball +// 채점 기능 클래스 class Referee { private var strike = 0 private var ball = 0 + // 채점 기능 fun getResult(computerNums: MutableList, userNums: MutableList): Boolean { strike = 0 ball = 0 diff --git a/src/main/kotlin/baseball/User.kt b/src/main/kotlin/baseball/User.kt index f685e058c..13264758a 100644 --- a/src/main/kotlin/baseball/User.kt +++ b/src/main/kotlin/baseball/User.kt @@ -3,6 +3,7 @@ package baseball import camp.nextstep.edu.missionutils.Console class User { + // 사용자 숫자 입력 - GameManager class의 initUser()에서 호출 fun getNumberList(): MutableList { val mutableList = mutableListOf() val input = Console.readLine() @@ -11,6 +12,7 @@ class User { return mutableList } + // 재실행 숫자 입력 - GameManager class의 finish()에서 호출 fun getFinishNumber(): Int { val input = Console.readLine() isValidateInputStringForFinish(input) diff --git a/src/main/kotlin/baseball/constants.kt b/src/main/kotlin/baseball/constants.kt index e1b2b04f5..3098cd5a0 100644 --- a/src/main/kotlin/baseball/constants.kt +++ b/src/main/kotlin/baseball/constants.kt @@ -1,5 +1,6 @@ package baseball +// GameManager class 내 execute() while문과 playGame() while문의 상수 사용 const val INIT = true const val RESTART = true const val EXIT = false \ No newline at end of file From e0dbd30d5287e8689ebbb6e3179d007a93ede019 Mon Sep 17 00:00:00 2001 From: Moonsun Kang <85236336+kio1214@users.noreply.github.com> Date: Mon, 30 Oct 2023 18:29:29 +0900 Subject: [PATCH 26/26] docs: update README.md --- README.md | 64 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 908e2b803..0ee9cb2fd 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,53 @@ # 미션 - 숫자 야구 +## 📚 프로젝트 목표 +- 주어진 요구 사항을 만족시키는 코드를 작성한다. +- 확장 및 유지 보수의 편의성을 고려하여 리팩토링이 가능한 코드를 작성한다. +- 가독성을 고려한 코드를 작성한다. +- 협업을 가정하여 커밋 및 코드 컨벤션을 지킨다. + ## ✨ 기능 목록 -- 게임 시작 안내 출력 -- 입력 - - 컴퓨터 정답 설정 (서로 다른 3개의 숫자) - - 사용자 입력 (서로 다른 3개의 숫자 입력) - - 잘못된 값을 입력한 경우 예외 처리 (애플리케이션 종료) -- 입력에 대한 결과 처리 - - 오답 - - 정답 (게임 종료) -- 출력 - - 결과를 볼, 스트라이크 개수로 표시 - - 하나도 없는 경우 표시 - - 정답 표시 -- loop 설정 -- 게임 종료 후 분기 (재시작 or 종료) +- 컴퓨터의 3자리 수 +- 사용자의 입력 +- 옳지 않은 입력에 대한 예외 처리 +- 채점 +- 힌트 +- 정답시 게임 종료 +- 메세지 출력 + +## 🎨 설계 +숫자 야구 게임 설계 + +### 역할에 따라 클래스 분리 +- GameManager: 게임의 전체 화면 관리 +- InputManager: 사용자 Input 관리 +- Computer Class: 컴퓨터 객체 +- User Class: 사용자 객체 +- Referee Class: 판정 관리 + +### 입력 관리 +- 컴퓨터 숫자 + - mutableList 타입 + - Randoms.pickNumberInRange() 사용 + - getNumberList()로 반환 +- 사용자 숫자 + - mutableList 타입 + - Console.readLine() 사용 + - validateUserNums() - 유효성 검사 + - getNumberList()로 반환 +- 재실행 숫자 + - Int + - validateFinishNums() - 유효성 검사 + - getFinishNumber()로 반환 + +### 예외 처리 +- IllegalArgumentException 발생 +- 사용자 숫자 입력 + - 공백 검사 + - 중복 검사 + - 0 미포함 + - 3자리 + - Int 변환 가능 +- 재실행 숫자 입력 + - 공백 검사 + - 1 혹은 2 외의 값인지