From d008b104d82da65f236c1dfe7e0a2e3ab7f9ff4c Mon Sep 17 00:00:00 2001 From: OYJ Date: Mon, 20 Nov 2023 23:31:59 +0900 Subject: [PATCH 01/11] =?UTF-8?q?docs:=20=EB=8B=B9=EC=B2=A8=20=EB=A1=9C?= =?UTF-8?q?=EB=98=90=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=EB=8B=B9=EC=B2=A8=20=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=B3=80=EA=B2=BD=20=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f7c43182f..73620a6c9 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,14 @@ 로또 (Data) - [O] 로또 번호의 조합을 가지고 있는다. +당청 로또 +- [] 당첨 번호 일치 개수 반환 +- [] 보너스 넘버 일치 검증 + 로또 머신 (object) - [O] 입력받은 번호로 구성된 로또로 생성한다. - [O] 당첨 번호 생성(with 보너스 번호) -- [O] 당첨 여부 검증 +- [] 당첨 여부 검증 - [O] 수익률 반환 로또 게임 (class) From dffd018aef7c342ece5705a5ac7377a8b9b9f515 Mon Sep 17 00:00:00 2001 From: OYJ Date: Mon, 20 Nov 2023 23:33:05 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=9D=BC=EC=B9=98=20=EA=B0=AF=EC=88=98=20=EB=B0=98?= =?UTF-8?q?=ED=99=98,=20=EB=B3=B4=EB=84=88=EC=8A=A4=20=EB=B2=88=ED=98=B8?= =?UTF-8?q?=20=EC=9D=BC=EC=B9=98=20=EA=B2=80=EC=A6=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- src/main/kotlin/lotto/data/WinningLotto.kt | 10 ++++- .../kotlin/lotto/data/WinningLottoTest.kt | 45 +++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 src/test/kotlin/lotto/data/WinningLottoTest.kt diff --git a/README.md b/README.md index 73620a6c9..a1799d2c3 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,8 @@ - [O] 로또 번호의 조합을 가지고 있는다. 당청 로또 -- [] 당첨 번호 일치 개수 반환 -- [] 보너스 넘버 일치 검증 +- [O] 당첨 번호 일치 개수 반환 +- [O] 보너스 번호 일치 검증 로또 머신 (object) - [O] 입력받은 번호로 구성된 로또로 생성한다. diff --git a/src/main/kotlin/lotto/data/WinningLotto.kt b/src/main/kotlin/lotto/data/WinningLotto.kt index 9eb3c2d2f..d3936b623 100644 --- a/src/main/kotlin/lotto/data/WinningLotto.kt +++ b/src/main/kotlin/lotto/data/WinningLotto.kt @@ -1,3 +1,11 @@ package lotto.data -data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) +data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) { + fun countMatchingNumbers(lotto: Lotto): Int { + return this.lotto.selectNumbers.intersect(lotto.selectNumbers).size + } + + fun hasBonusNumber(lotto: Lotto): Boolean { + return lotto.selectNumbers.contains(bonusNumber) + } +} diff --git a/src/test/kotlin/lotto/data/WinningLottoTest.kt b/src/test/kotlin/lotto/data/WinningLottoTest.kt new file mode 100644 index 000000000..9a12f21de --- /dev/null +++ b/src/test/kotlin/lotto/data/WinningLottoTest.kt @@ -0,0 +1,45 @@ +package lotto.data + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class WinningLottoTest { + + @Test + fun `당첨 번호와 일치하는 번호 수 반환`() { + // given : 당첨로또와 로또를 받는다. + val lotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) + val lotto2 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + + // 당첨번호 [1,2,3,4,5,7] + 보너스 번호 [6] + val wLotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + val winningLotto = WinningLotto(wLotto1, LottoNumber.from(6)) + + // when : 검증 로직을 실행한다. + val actual1 = winningLotto.countMatchingNumbers(lotto1) + val actual2 = winningLotto.countMatchingNumbers(lotto2) + + // then : 일치하는 번호의 개수를 반환한다. + assertThat(actual1).isEqualTo(5) + assertThat(actual2).isEqualTo(6) + } + + @Test + fun `보너스 번호 일치 검증`() { + // given : 당첨로또와 로또를 받는다. + val lotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) + val lotto2 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + + // 당첨번호 [1,2,3,4,5,7] + 보너스 번호 [6] + val wLotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + val winningLotto = WinningLotto(wLotto1, LottoNumber.from(6)) + + // when : 보너스 번호 일치 검증 로직을 호출한다. + val actual1 = winningLotto.hasBonusNumber(lotto1) + val actual2 = winningLotto.hasBonusNumber(lotto2) + + // then : + assertThat(actual1).isTrue() + assertThat(actual2).isFalse() + } +} From 2273de6bdd31ab38bb4ce956604394558ed8164f Mon Sep 17 00:00:00 2001 From: OYJ Date: Mon, 20 Nov 2023 23:38:14 +0900 Subject: [PATCH 03/11] =?UTF-8?q?Refactor:=20=EB=8B=B9=EC=B2=A8=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EA=B2=80=EC=A6=9D=20=EC=97=AD=ED=95=A0=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20(LottoMachine=20->=20LottoRanking),=20Lott?= =?UTF-8?q?oRanking=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/kotlin/lotto/data/LottoRanking.kt | 54 ++++++++++---------- src/main/kotlin/lotto/domain/LottoMachine.kt | 29 ++--------- 3 files changed, 31 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index a1799d2c3..0d246da30 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ 로또 머신 (object) - [O] 입력받은 번호로 구성된 로또로 생성한다. - [O] 당첨 번호 생성(with 보너스 번호) -- [] 당첨 여부 검증 +- [O] 당첨 여부 검증 - [O] 수익률 반환 로또 게임 (class) diff --git a/src/main/kotlin/lotto/data/LottoRanking.kt b/src/main/kotlin/lotto/data/LottoRanking.kt index 92f6bb9bc..33f7351c1 100644 --- a/src/main/kotlin/lotto/data/LottoRanking.kt +++ b/src/main/kotlin/lotto/data/LottoRanking.kt @@ -1,36 +1,34 @@ package lotto.data enum class LottoRanking(val matchingNumberCnt: Int, val price: Int) : Prize { - FirstPlace(6, 2_000_000_000) { - override fun findPrize(winningStatus: Pair): Int { - return winningStatus.first.price * winningStatus.second - } - }, - SecondPlace(5, 30_000_000) { - override fun findPrize(winningStatus: Pair): Int { - return winningStatus.first.price * winningStatus.second - } - }, - ThirdPlace(5, 1_500_000) { - override fun findPrize(winningStatus: Pair): Int { - return winningStatus.first.price * winningStatus.second - } - }, - FourthPlace(4, 50_000) { - override fun findPrize(winningStatus: Pair): Int { - return winningStatus.first.price * winningStatus.second - } - }, - FifthPlace(3, 5_000) { - override fun findPrize(winningStatus: Pair): Int { - return winningStatus.first.price * winningStatus.second + FirstPlace(6, 2_000_000_000), + SecondPlace(5, 30_000_000), + ThirdPlace(5, 1_500_000), + FourthPlace(4, 50_000), + FifthPlace(3, 5_000), + None(0, 0); + + override fun findPrize(winningStatus: Pair): Int { + return winningStatus.first.price * winningStatus.second + } + + companion object { + fun findLottoRanking(matchingNumberCnt: Int, hasBonusNumber: Boolean): LottoRanking { + return if (matchingNumberCnt == SecondPlace.matchingNumberCnt) { + determineRankingWithBonusNumber(hasBonusNumber) + } else { + LottoRanking.values().find { it.matchingNumberCnt == matchingNumberCnt } ?: None + } } - }, - None(0, 0) { - override fun findPrize(winningStatus: Pair): Int { - return winningStatus.first.price * winningStatus.second + + private fun determineRankingWithBonusNumber(isContainBonusNumber: Boolean): LottoRanking { + return if (isContainBonusNumber) { + SecondPlace + } else { + ThirdPlace + } } - }; + } } fun interface Prize { diff --git a/src/main/kotlin/lotto/domain/LottoMachine.kt b/src/main/kotlin/lotto/domain/LottoMachine.kt index d323cd0b1..a66633e25 100644 --- a/src/main/kotlin/lotto/domain/LottoMachine.kt +++ b/src/main/kotlin/lotto/domain/LottoMachine.kt @@ -3,12 +3,6 @@ package lotto.domain import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking -import lotto.data.LottoRanking.FifthPlace -import lotto.data.LottoRanking.FirstPlace -import lotto.data.LottoRanking.FourthPlace -import lotto.data.LottoRanking.None -import lotto.data.LottoRanking.SecondPlace -import lotto.data.LottoRanking.ThirdPlace import lotto.data.WinningLotto object LottoMachine { @@ -24,17 +18,10 @@ object LottoMachine { } fun checkLotto(purchaseLotto: Lotto, winningLotto: WinningLotto): LottoRanking { - val intersectNumber = winningLotto.lotto.selectNumbers.intersect(purchaseLotto.selectNumbers) - - return when (intersectNumber.size) { - FirstPlace.matchingNumberCnt -> FirstPlace - SecondPlace.matchingNumberCnt, ThirdPlace.matchingNumberCnt -> { - checkSecondPlace(purchaseLotto, winningLotto.bonusNumber) - } - FourthPlace.matchingNumberCnt -> FourthPlace - FifthPlace.matchingNumberCnt -> FifthPlace - else -> None - } + val matchingNumberCnt = winningLotto.countMatchingNumbers(purchaseLotto) + val hasBonusNumber = winningLotto.hasBonusNumber(purchaseLotto) + + return LottoRanking.findLottoRanking(matchingNumberCnt, hasBonusNumber) } fun createWinningRate(cash: Int, winningStatus: Map): Float { @@ -43,14 +30,6 @@ object LottoMachine { return totalPrice / cash.toFloat() } - private fun checkSecondPlace(purchaseLotto: Lotto, bonusLottoNumber: LottoNumber): LottoRanking { - return if (purchaseLotto.selectNumbers.contains(bonusLottoNumber)) { - SecondPlace - } else { - ThirdPlace - } - } - private fun createTotalWinningPrice(winningStatus: Map): Int { return winningStatus.toList().sumOf { it.first.findPrize(it) } } From e28951ce68dc12ca8e6d43d601e9763274fe5521 Mon Sep 17 00:00:00 2001 From: OYJ Date: Tue, 21 Nov 2023 00:26:06 +0900 Subject: [PATCH 04/11] =?UTF-8?q?docs:=20=EB=8B=B9=EC=B2=A8=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d246da30..8c5da9788 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,10 @@ 로또 (Data) - [O] 로또 번호의 조합을 가지고 있는다. -당청 로또 +당첨 로또 - [O] 당첨 번호 일치 개수 반환 - [O] 보너스 번호 일치 검증 +- [] 당첨번호 & 보너스 번호 중복 로또 머신 (object) - [O] 입력받은 번호로 구성된 로또로 생성한다. From 8dfcb458f8b081b71257ddb1107a0bc2f87e95ff Mon Sep 17 00:00:00 2001 From: OYJ Date: Tue, 21 Nov 2023 00:26:56 +0900 Subject: [PATCH 05/11] =?UTF-8?q?Feat:=20=EB=8B=B9=EC=B2=A8=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20&=20=EB=B3=B4=EB=84=88=EC=8A=A4=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=A4=91=EB=B3=B5=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/data/WinningLotto.kt | 13 +++++++++++++ src/test/kotlin/lotto/data/WinningLottoTest.kt | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/main/kotlin/lotto/data/WinningLotto.kt b/src/main/kotlin/lotto/data/WinningLotto.kt index d3936b623..4faded4b3 100644 --- a/src/main/kotlin/lotto/data/WinningLotto.kt +++ b/src/main/kotlin/lotto/data/WinningLotto.kt @@ -1,6 +1,11 @@ package lotto.data data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) { + + init { + validateWinningLotto() + } + fun countMatchingNumbers(lotto: Lotto): Int { return this.lotto.selectNumbers.intersect(lotto.selectNumbers).size } @@ -8,4 +13,12 @@ data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) { fun hasBonusNumber(lotto: Lotto): Boolean { return lotto.selectNumbers.contains(bonusNumber) } + + private fun validateWinningLotto() { + validateDuplicationBonusNumber() + } + + private fun validateDuplicationBonusNumber() { + require(!lotto.selectNumbers.contains(bonusNumber)) { "당첨 번호 구성과 보너스 번호가 중복됩니다." } + } } diff --git a/src/test/kotlin/lotto/data/WinningLottoTest.kt b/src/test/kotlin/lotto/data/WinningLottoTest.kt index 9a12f21de..8f9d632ec 100644 --- a/src/test/kotlin/lotto/data/WinningLottoTest.kt +++ b/src/test/kotlin/lotto/data/WinningLottoTest.kt @@ -42,4 +42,17 @@ class WinningLottoTest { assertThat(actual1).isTrue() assertThat(actual2).isFalse() } + + @Test + fun `보너스 번호 중복 검증`() { + // given : 당첨 번호로 구성된 로또와 이와 중복되는 보너스 번호를 받는다. + val lotto = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) + val bonusLottoNumber = LottoNumber.from(6) + + // when : + val actual = runCatching { WinningLotto(lotto, bonusLottoNumber) }.exceptionOrNull() + + // then : + assertThat(actual).isInstanceOf(IllegalArgumentException::class.java) + } } From 9b5f0543b68cd94813474b253e0ec7c0d6ef080f Mon Sep 17 00:00:00 2001 From: OYJ Date: Tue, 21 Nov 2023 01:07:45 +0900 Subject: [PATCH 06/11] =?UTF-8?q?docs:=20=EB=A1=9C=EB=98=90=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20chore:=20test=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99,=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=BB=A8=EB=B2=A4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ src/main/kotlin/lotto/LottoMain.kt | 1 - src/test/kotlin/lotto/{ => data}/LottoNumberTest.kt | 3 +-- src/test/kotlin/lotto/{ => data}/LottoTest.kt | 4 +--- src/test/kotlin/lotto/{ => domain}/LottoMachineTest.kt | 3 +-- 5 files changed, 6 insertions(+), 8 deletions(-) rename src/test/kotlin/lotto/{ => data}/LottoNumberTest.kt (96%) rename src/test/kotlin/lotto/{ => data}/LottoTest.kt (95%) rename src/test/kotlin/lotto/{ => domain}/LottoMachineTest.kt (98%) diff --git a/README.md b/README.md index 8c5da9788..04c5a09f6 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,9 @@ - [O] 보너스 번호 일치 검증 - [] 당첨번호 & 보너스 번호 중복 +로또 계산기 +- [] 수익률 반환 + 로또 머신 (object) - [O] 입력받은 번호로 구성된 로또로 생성한다. - [O] 당첨 번호 생성(with 보너스 번호) diff --git a/src/main/kotlin/lotto/LottoMain.kt b/src/main/kotlin/lotto/LottoMain.kt index cfdcff828..116cc60ab 100644 --- a/src/main/kotlin/lotto/LottoMain.kt +++ b/src/main/kotlin/lotto/LottoMain.kt @@ -1,6 +1,5 @@ package lotto -import lotto.data.LottoNumber import lotto.domain.LottoMachine import lotto.domain.RandomLogic import lotto.service.LottoGame diff --git a/src/test/kotlin/lotto/LottoNumberTest.kt b/src/test/kotlin/lotto/data/LottoNumberTest.kt similarity index 96% rename from src/test/kotlin/lotto/LottoNumberTest.kt rename to src/test/kotlin/lotto/data/LottoNumberTest.kt index dde22d134..0bbdc7595 100644 --- a/src/test/kotlin/lotto/LottoNumberTest.kt +++ b/src/test/kotlin/lotto/data/LottoNumberTest.kt @@ -1,6 +1,5 @@ -package lotto +package lotto.data -import lotto.data.LottoNumber import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/lotto/LottoTest.kt b/src/test/kotlin/lotto/data/LottoTest.kt similarity index 95% rename from src/test/kotlin/lotto/LottoTest.kt rename to src/test/kotlin/lotto/data/LottoTest.kt index c0b77e571..a1ab83dfd 100644 --- a/src/test/kotlin/lotto/LottoTest.kt +++ b/src/test/kotlin/lotto/data/LottoTest.kt @@ -1,7 +1,5 @@ -package lotto +package lotto.data -import lotto.data.Lotto -import lotto.data.LottoNumber import org.assertj.core.api.Assertions import org.junit.jupiter.api.Test diff --git a/src/test/kotlin/lotto/LottoMachineTest.kt b/src/test/kotlin/lotto/domain/LottoMachineTest.kt similarity index 98% rename from src/test/kotlin/lotto/LottoMachineTest.kt rename to src/test/kotlin/lotto/domain/LottoMachineTest.kt index 4899d0fdb..9fb0d43db 100644 --- a/src/test/kotlin/lotto/LottoMachineTest.kt +++ b/src/test/kotlin/lotto/domain/LottoMachineTest.kt @@ -1,10 +1,9 @@ -package lotto +package lotto.domain import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking import lotto.data.WinningLotto -import lotto.domain.LottoMachine import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test From a0698e5fa1b17003fd82376155377c79009a857c Mon Sep 17 00:00:00 2001 From: OYJ Date: Tue, 21 Nov 2023 01:29:58 +0900 Subject: [PATCH 07/11] =?UTF-8?q?Feat:=20=EB=A1=9C=EB=98=90=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=EA=B8=B0=20-=20=EC=88=98=EC=9D=B5=EB=A5=A0=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?Refactor:=20=EB=8B=B9=EC=B2=A8=20=ED=86=B5=EA=B3=84=20=EC=97=AD?= =?UTF-8?q?=ED=95=A0=20=EC=9D=B4=EB=8F=99=20(LottoMachine=20->=20LottoCalc?= =?UTF-8?q?ulator)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../kotlin/lotto/domain/LottoCalculator.kt | 12 ++++++++++ src/main/kotlin/lotto/domain/LottoMachine.kt | 8 +------ .../lotto/domain/LottoCalculatorTest.kt | 22 +++++++++++++++++++ 4 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 src/main/kotlin/lotto/domain/LottoCalculator.kt create mode 100644 src/test/kotlin/lotto/domain/LottoCalculatorTest.kt diff --git a/README.md b/README.md index 04c5a09f6..a2db2c5df 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ - [] 당첨번호 & 보너스 번호 중복 로또 계산기 -- [] 수익률 반환 +- [O] 수익률 반환 로또 머신 (object) - [O] 입력받은 번호로 구성된 로또로 생성한다. diff --git a/src/main/kotlin/lotto/domain/LottoCalculator.kt b/src/main/kotlin/lotto/domain/LottoCalculator.kt new file mode 100644 index 000000000..52a854c9b --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoCalculator.kt @@ -0,0 +1,12 @@ +package lotto.domain + +import lotto.data.LottoRanking + +object LottoCalculator { + + fun calculateWinningRate(cash: Int, winningStatus: Map): Float { + val totalPrice = winningStatus.toList().sumOf { it.first.findPrize(it) } + + return totalPrice / cash.toFloat() + } +} diff --git a/src/main/kotlin/lotto/domain/LottoMachine.kt b/src/main/kotlin/lotto/domain/LottoMachine.kt index a66633e25..7fd4f8337 100644 --- a/src/main/kotlin/lotto/domain/LottoMachine.kt +++ b/src/main/kotlin/lotto/domain/LottoMachine.kt @@ -25,12 +25,6 @@ object LottoMachine { } fun createWinningRate(cash: Int, winningStatus: Map): Float { - val totalPrice = createTotalWinningPrice(winningStatus) - - return totalPrice / cash.toFloat() - } - - private fun createTotalWinningPrice(winningStatus: Map): Int { - return winningStatus.toList().sumOf { it.first.findPrize(it) } + return LottoCalculator.calculateWinningRate(cash, winningStatus) } } diff --git a/src/test/kotlin/lotto/domain/LottoCalculatorTest.kt b/src/test/kotlin/lotto/domain/LottoCalculatorTest.kt new file mode 100644 index 000000000..e743b4ffb --- /dev/null +++ b/src/test/kotlin/lotto/domain/LottoCalculatorTest.kt @@ -0,0 +1,22 @@ +package lotto.domain + +import lotto.data.LottoRanking +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class LottoCalculatorTest { + @Test + fun `로또 수익율 반환 로직`() { + // given : 구매한 로또의 통계와 구매 금액을 받는다. + // 총 당첨금 5천원 + val cash = 100000 + val winningStatus = mutableMapOf() + winningStatus[LottoRanking.FifthPlace] = 1 + + // when : 구매 금액 대비 당첨 금액에 대한 수익률은 요청한다. + val actual: Float = LottoCalculator.calculateWinningRate(cash, winningStatus) + + // then : 수익률이 반환된다. + assertThat(actual).isEqualTo(0.05f) + } +} From 45784539b086f571356f6314c39915d9f468e7a7 Mon Sep 17 00:00:00 2001 From: OYJ Date: Tue, 21 Nov 2023 01:45:06 +0900 Subject: [PATCH 08/11] =?UTF-8?q?Refactor:=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=20=ED=95=A8=EC=88=98=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/main/kotlin/lotto/domain/LottoCalculator.kt | 6 ++++++ src/main/kotlin/lotto/service/LottoGame.kt | 14 +++++++------- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a2db2c5df..6b715089e 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ 로또 계산기 - [O] 수익률 반환 +- [O] 게임 횟수 반환 로또 머신 (object) - [O] 입력받은 번호로 구성된 로또로 생성한다. diff --git a/src/main/kotlin/lotto/domain/LottoCalculator.kt b/src/main/kotlin/lotto/domain/LottoCalculator.kt index 52a854c9b..2215a099f 100644 --- a/src/main/kotlin/lotto/domain/LottoCalculator.kt +++ b/src/main/kotlin/lotto/domain/LottoCalculator.kt @@ -4,9 +4,15 @@ import lotto.data.LottoRanking object LottoCalculator { + private const val GAME_COST = 1000 + fun calculateWinningRate(cash: Int, winningStatus: Map): Float { val totalPrice = winningStatus.toList().sumOf { it.first.findPrize(it) } return totalPrice / cash.toFloat() } + + fun getTimes(cash: Int): Int { + return cash / GAME_COST + } } diff --git a/src/main/kotlin/lotto/service/LottoGame.kt b/src/main/kotlin/lotto/service/LottoGame.kt index 6702b4291..547d5d8d3 100644 --- a/src/main/kotlin/lotto/service/LottoGame.kt +++ b/src/main/kotlin/lotto/service/LottoGame.kt @@ -4,6 +4,7 @@ import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking import lotto.data.WinningLotto +import lotto.domain.LottoCalculator import lotto.domain.LottoMachine import lotto.domain.RandomLogicInterface import lotto.domain.WinningDomain @@ -11,14 +12,17 @@ import lotto.domain.WinningDomain class LottoGame(private val randomLogic: RandomLogicInterface) { fun buyLotto(cash: Int): List { - val lottoList = mutableListOf() - val times = cash / GAME_COST + val times = LottoCalculator.getTimes(cash) + + return createLotto(times) + } + private fun createLotto(times: Int): List { + val lottoList = mutableListOf() repeat(times) { val lottoNumberCombination = LottoNumber.createRandomLottoNumber(randomLogic) lottoList.add(LottoMachine.createSelectLotto(lottoNumberCombination)) } - return lottoList } @@ -26,8 +30,4 @@ class LottoGame(private val randomLogic: RandomLogicInterface) { return WinningDomain.checkWinningResult(winningLotto, purchaseLottoList) } - - companion object { - private const val GAME_COST = 1000 - } } From 787b65d7a7bf8ddf0857c3df7909f84931420bc1 Mon Sep 17 00:00:00 2001 From: OYJ Date: Wed, 22 Nov 2023 02:04:38 +0900 Subject: [PATCH 09/11] =?UTF-8?q?Refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=20=EB=8B=B4=EB=8B=B9=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20(LottoCalculator=20->=20LottoGame)=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=ED=86=B5=EA=B3=84=20=EC=9E=90=EB=A3=8C?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD=20Map=20->=20EnumMap=20?= =?UTF-8?q?=EB=8B=B9=EC=B2=A8=20=EB=B2=88=ED=98=B8=20=EC=9D=BC=EC=B9=98=20?= =?UTF-8?q?=EA=B0=9C=EC=88=98=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Feat: 보너스 번호 중복 검증 로직 추가 --- src/main/kotlin/lotto/data/LottoRanking.kt | 12 ++---------- src/main/kotlin/lotto/data/WinningLotto.kt | 12 ++++++++++-- src/main/kotlin/lotto/domain/LottoCalculator.kt | 9 ++++----- src/main/kotlin/lotto/domain/LottoMachine.kt | 3 ++- src/main/kotlin/lotto/domain/WinningDomain.kt | 5 +++-- src/main/kotlin/lotto/service/LottoGame.kt | 12 ++++++++---- src/test/kotlin/lotto/domain/LottoCalculatorTest.kt | 3 ++- src/test/kotlin/lotto/domain/LottoMachineTest.kt | 12 ++++++------ 8 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/lotto/data/LottoRanking.kt b/src/main/kotlin/lotto/data/LottoRanking.kt index 33f7351c1..d8c483159 100644 --- a/src/main/kotlin/lotto/data/LottoRanking.kt +++ b/src/main/kotlin/lotto/data/LottoRanking.kt @@ -14,18 +14,10 @@ enum class LottoRanking(val matchingNumberCnt: Int, val price: Int) : Prize { companion object { fun findLottoRanking(matchingNumberCnt: Int, hasBonusNumber: Boolean): LottoRanking { - return if (matchingNumberCnt == SecondPlace.matchingNumberCnt) { - determineRankingWithBonusNumber(hasBonusNumber) - } else { - LottoRanking.values().find { it.matchingNumberCnt == matchingNumberCnt } ?: None - } - } - - private fun determineRankingWithBonusNumber(isContainBonusNumber: Boolean): LottoRanking { - return if (isContainBonusNumber) { + return if (matchingNumberCnt == SecondPlace.matchingNumberCnt && hasBonusNumber) { SecondPlace } else { - ThirdPlace + LottoRanking.values().find { it.matchingNumberCnt == matchingNumberCnt } ?: None } } } diff --git a/src/main/kotlin/lotto/data/WinningLotto.kt b/src/main/kotlin/lotto/data/WinningLotto.kt index 4faded4b3..97f8b140e 100644 --- a/src/main/kotlin/lotto/data/WinningLotto.kt +++ b/src/main/kotlin/lotto/data/WinningLotto.kt @@ -7,7 +7,7 @@ data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) { } fun countMatchingNumbers(lotto: Lotto): Int { - return this.lotto.selectNumbers.intersect(lotto.selectNumbers).size + return this.lotto.matching(lotto) } fun hasBonusNumber(lotto: Lotto): Boolean { @@ -19,6 +19,14 @@ data class WinningLotto(val lotto: Lotto, val bonusNumber: LottoNumber) { } private fun validateDuplicationBonusNumber() { - require(!lotto.selectNumbers.contains(bonusNumber)) { "당첨 번호 구성과 보너스 번호가 중복됩니다." } + require(!lotto.selectNumbers.contains(bonusNumber)) { ERR_MSG_DUPLICATION_BONUS_NUMBER } + } + + private fun Lotto.matching(lotto: Lotto): Int { + return this.selectNumbers.intersect(lotto.selectNumbers).size + } + + companion object { + private const val ERR_MSG_DUPLICATION_BONUS_NUMBER = "당첨 번호 구성과 보너스 번호가 중복됩니다." } } diff --git a/src/main/kotlin/lotto/domain/LottoCalculator.kt b/src/main/kotlin/lotto/domain/LottoCalculator.kt index 2215a099f..c9a27354b 100644 --- a/src/main/kotlin/lotto/domain/LottoCalculator.kt +++ b/src/main/kotlin/lotto/domain/LottoCalculator.kt @@ -1,18 +1,17 @@ package lotto.domain import lotto.data.LottoRanking +import java.util.EnumMap object LottoCalculator { - private const val GAME_COST = 1000 - - fun calculateWinningRate(cash: Int, winningStatus: Map): Float { + fun calculateWinningRate(cash: Int, winningStatus: EnumMap): Float { val totalPrice = winningStatus.toList().sumOf { it.first.findPrize(it) } return totalPrice / cash.toFloat() } - fun getTimes(cash: Int): Int { - return cash / GAME_COST + fun getTimes(cash: Int, gameCost: Int): Int { + return cash / gameCost } } diff --git a/src/main/kotlin/lotto/domain/LottoMachine.kt b/src/main/kotlin/lotto/domain/LottoMachine.kt index 7fd4f8337..7edc40728 100644 --- a/src/main/kotlin/lotto/domain/LottoMachine.kt +++ b/src/main/kotlin/lotto/domain/LottoMachine.kt @@ -4,6 +4,7 @@ import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking import lotto.data.WinningLotto +import java.util.EnumMap object LottoMachine { @@ -24,7 +25,7 @@ object LottoMachine { return LottoRanking.findLottoRanking(matchingNumberCnt, hasBonusNumber) } - fun createWinningRate(cash: Int, winningStatus: Map): Float { + fun createWinningRate(cash: Int, winningStatus: EnumMap): Float { return LottoCalculator.calculateWinningRate(cash, winningStatus) } } diff --git a/src/main/kotlin/lotto/domain/WinningDomain.kt b/src/main/kotlin/lotto/domain/WinningDomain.kt index 61d2270c2..08040befd 100644 --- a/src/main/kotlin/lotto/domain/WinningDomain.kt +++ b/src/main/kotlin/lotto/domain/WinningDomain.kt @@ -3,12 +3,13 @@ package lotto.domain import lotto.data.Lotto import lotto.data.LottoRanking import lotto.data.WinningLotto +import java.util.EnumMap object WinningDomain { // 보너스 번호 추가. - fun checkWinningResult(winningLotto: WinningLotto, purchaseLottoList: List): Map { - val winningStatusMap = mutableMapOf() + fun checkWinningResult(winningLotto: WinningLotto, purchaseLottoList: List): EnumMap { + val winningStatusMap: EnumMap = EnumMap(LottoRanking::class.java) purchaseLottoList.forEach { val lottoRanking = LottoMachine.checkLotto(it, winningLotto) diff --git a/src/main/kotlin/lotto/service/LottoGame.kt b/src/main/kotlin/lotto/service/LottoGame.kt index 547d5d8d3..6e3e6a15d 100644 --- a/src/main/kotlin/lotto/service/LottoGame.kt +++ b/src/main/kotlin/lotto/service/LottoGame.kt @@ -8,11 +8,12 @@ import lotto.domain.LottoCalculator import lotto.domain.LottoMachine import lotto.domain.RandomLogicInterface import lotto.domain.WinningDomain +import java.util.EnumMap -class LottoGame(private val randomLogic: RandomLogicInterface) { +class LottoGame(private val randomLogic: RandomLogicInterface, private val gameCost: Int = DEFAULT_COST) { fun buyLotto(cash: Int): List { - val times = LottoCalculator.getTimes(cash) + val times = LottoCalculator.getTimes(cash, gameCost) return createLotto(times) } @@ -26,8 +27,11 @@ class LottoGame(private val randomLogic: RandomLogicInterface) { return lottoList } - fun getWinningStats(winningLotto: WinningLotto, purchaseLottoList: List): Map { - + fun getWinningStats(winningLotto: WinningLotto, purchaseLottoList: List): EnumMap { return WinningDomain.checkWinningResult(winningLotto, purchaseLottoList) } + + companion object { + private const val DEFAULT_COST = 1000 + } } diff --git a/src/test/kotlin/lotto/domain/LottoCalculatorTest.kt b/src/test/kotlin/lotto/domain/LottoCalculatorTest.kt index e743b4ffb..a81f2c2ed 100644 --- a/src/test/kotlin/lotto/domain/LottoCalculatorTest.kt +++ b/src/test/kotlin/lotto/domain/LottoCalculatorTest.kt @@ -3,6 +3,7 @@ package lotto.domain import lotto.data.LottoRanking import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test +import java.util.EnumMap class LottoCalculatorTest { @Test @@ -10,7 +11,7 @@ class LottoCalculatorTest { // given : 구매한 로또의 통계와 구매 금액을 받는다. // 총 당첨금 5천원 val cash = 100000 - val winningStatus = mutableMapOf() + val winningStatus: EnumMap = EnumMap(LottoRanking::class.java) winningStatus[LottoRanking.FifthPlace] = 1 // when : 구매 금액 대비 당첨 금액에 대한 수익률은 요청한다. diff --git a/src/test/kotlin/lotto/domain/LottoMachineTest.kt b/src/test/kotlin/lotto/domain/LottoMachineTest.kt index 9fb0d43db..52821c731 100644 --- a/src/test/kotlin/lotto/domain/LottoMachineTest.kt +++ b/src/test/kotlin/lotto/domain/LottoMachineTest.kt @@ -6,6 +6,7 @@ import lotto.data.LottoRanking import lotto.data.WinningLotto import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test +import java.util.EnumMap class LottoMachineTest { @@ -61,12 +62,11 @@ class LottoMachineTest { fun `구매 금액과 당첨 통계를 받았고, 수익률을 요청한다면, 수익률을 반환한다`() { // given : 구매 금액과 당첨 통계를 받는다. val cash = 6000 - val winningStatus = mutableMapOf( - LottoRanking.ThirdPlace to 2, - LottoRanking.FourthPlace to 1, - LottoRanking.FifthPlace to 2, - LottoRanking.None to 1 - ) + val winningStatus: EnumMap = EnumMap(LottoRanking::class.java) + winningStatus[LottoRanking.ThirdPlace] = 2 + winningStatus[LottoRanking.FourthPlace] = 1 + winningStatus[LottoRanking.FifthPlace] = 2 + winningStatus[LottoRanking.None] = 1 // when : 수익률을 요청한다. val winningRate = LottoMachine.createWinningRate(cash, winningStatus) From 8532e6692b2290743f13832e86cb6827f0a2482a Mon Sep 17 00:00:00 2001 From: OYJ Date: Thu, 23 Nov 2023 01:45:01 +0900 Subject: [PATCH 10/11] =?UTF-8?q?Feat:=20NumberCombination=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor: 로또 번호 조힙 List -> NumberCombination 변경 --- README.md | 2 +- src/main/kotlin/lotto/LottoMain.kt | 3 ++- src/main/kotlin/lotto/data/LottoNumber.kt | 4 +-- .../kotlin/lotto/data/NumberCombination.kt | 3 +++ src/main/kotlin/lotto/domain/LottoMachine.kt | 5 ++-- src/test/kotlin/lotto/LottoGameTest.kt | 17 ++++++------ src/test/kotlin/lotto/data/LottoNumberTest.kt | 12 +++++---- src/test/kotlin/lotto/data/LottoTest.kt | 8 +++--- .../lotto/data/NumberCombinationTest.kt | 3 +++ .../kotlin/lotto/data/WinningLottoTest.kt | 14 +++++----- .../kotlin/lotto/domain/LottoMachineTest.kt | 27 ++++++++++--------- 11 files changed, 55 insertions(+), 43 deletions(-) create mode 100644 src/main/kotlin/lotto/data/NumberCombination.kt create mode 100644 src/test/kotlin/lotto/data/NumberCombinationTest.kt diff --git a/README.md b/README.md index 6b715089e..cc00ff928 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ 당첨 로또 - [O] 당첨 번호 일치 개수 반환 - [O] 보너스 번호 일치 검증 -- [] 당첨번호 & 보너스 번호 중복 +- [O] 당첨번호 & 보너스 번호 중복 로또 계산기 - [O] 수익률 반환 diff --git a/src/main/kotlin/lotto/LottoMain.kt b/src/main/kotlin/lotto/LottoMain.kt index 116cc60ab..c37596302 100644 --- a/src/main/kotlin/lotto/LottoMain.kt +++ b/src/main/kotlin/lotto/LottoMain.kt @@ -1,5 +1,6 @@ package lotto +import lotto.data.NumberCombination import lotto.domain.LottoMachine import lotto.domain.RandomLogic import lotto.service.LottoGame @@ -14,7 +15,7 @@ fun main() { OutputView.showLottoList(purchaseLottoList) - val winningNumberList = InputView.inputWinningNumber() + val winningNumberList = NumberCombination(InputView.inputWinningNumber()) val bonusNumber = InputView.inputBonusNumber() val winningLotto = LottoMachine.createWinningLotto(winningNumberList, bonusNumber) diff --git a/src/main/kotlin/lotto/data/LottoNumber.kt b/src/main/kotlin/lotto/data/LottoNumber.kt index a8f743b6f..7f323f575 100644 --- a/src/main/kotlin/lotto/data/LottoNumber.kt +++ b/src/main/kotlin/lotto/data/LottoNumber.kt @@ -19,8 +19,8 @@ class LottoNumber private constructor(private val number: Int) : Comparable = (MIN_NUMBER..MAX_NUMBER).associateWith(::LottoNumber) - fun createLottoNumbers(numbers: List): Set { - return LinkedHashSet(numbers.map(::from)) + fun createLottoNumbers(numberCombination: NumberCombination): Set { + return LinkedHashSet(numberCombination.numberCombination.map(::from)) } fun createRandomLottoNumber(lottoCreation: RandomLogicInterface): Set { diff --git a/src/main/kotlin/lotto/data/NumberCombination.kt b/src/main/kotlin/lotto/data/NumberCombination.kt new file mode 100644 index 000000000..1f6e783c8 --- /dev/null +++ b/src/main/kotlin/lotto/data/NumberCombination.kt @@ -0,0 +1,3 @@ +package lotto.data + +class NumberCombination(val numberCombination: List) diff --git a/src/main/kotlin/lotto/domain/LottoMachine.kt b/src/main/kotlin/lotto/domain/LottoMachine.kt index 7edc40728..e59731974 100644 --- a/src/main/kotlin/lotto/domain/LottoMachine.kt +++ b/src/main/kotlin/lotto/domain/LottoMachine.kt @@ -3,6 +3,7 @@ package lotto.domain import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking +import lotto.data.NumberCombination import lotto.data.WinningLotto import java.util.EnumMap @@ -12,8 +13,8 @@ object LottoMachine { return Lotto(lottoNumbers) } - fun createWinningLotto(winningNumbers: List, bonusNumber: Int): WinningLotto { - val winningLotto = LottoNumber.createLottoNumbers(winningNumbers) + fun createWinningLotto(winningNumberCombination: NumberCombination, bonusNumber: Int): WinningLotto { + val winningLotto = LottoNumber.createLottoNumbers(winningNumberCombination) val bonusLottoNumber = LottoNumber.from(bonusNumber) return WinningLotto(Lotto(winningLotto), bonusLottoNumber) } diff --git a/src/test/kotlin/lotto/LottoGameTest.kt b/src/test/kotlin/lotto/LottoGameTest.kt index 3bf369b7f..f0f6e1d58 100644 --- a/src/test/kotlin/lotto/LottoGameTest.kt +++ b/src/test/kotlin/lotto/LottoGameTest.kt @@ -3,6 +3,7 @@ package lotto import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking +import lotto.data.NumberCombination import lotto.domain.LottoMachine import lotto.domain.RandomLogic import lotto.service.LottoGame @@ -27,16 +28,16 @@ class LottoGameTest { fun `로또 구매와 당첨 번호를 입력 했다면, 당첨을 확인을 요청할 때, 당첨 통계를 반환한다`() { // given : 로또 구매와 당첨 번호를 입력한다. // 2등 - 2개, 3등 - 1개, 4등 - 1개 - val winningNumberList = listOf(1, 2, 3, 4, 5, 6) + val winningNumberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6)) val bonusNumber = 7 - val winningLotto = LottoMachine.createWinningLotto(winningNumberList, bonusNumber) + val winningLotto = LottoMachine.createWinningLotto(winningNumberCombination, bonusNumber) - val purchaseLottoNumbers1 = LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7)) - val purchaseLottoNumbers2 = LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7)) - val purchaseLottoNumbers3 = LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 7, 8)) - val purchaseLottoNumbers4 = LottoNumber.createLottoNumbers(listOf(1, 2, 3, 7, 8, 9)) - val purchaseLottoNumbers5 = LottoNumber.createLottoNumbers(listOf(1, 2, 6, 7, 8, 9)) - val purchaseLottoNumbers6 = LottoNumber.createLottoNumbers(listOf(11, 12, 13, 14, 15, 16)) + val purchaseLottoNumbers1 = LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 7))) + val purchaseLottoNumbers2 = LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 7))) + val purchaseLottoNumbers3 = LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 7, 8))) + val purchaseLottoNumbers4 = LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 7, 8, 9))) + val purchaseLottoNumbers5 = LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 6, 7, 8, 9))) + val purchaseLottoNumbers6 = LottoNumber.createLottoNumbers(NumberCombination(listOf(11, 12, 13, 14, 15, 16))) val purchaseLotto1 = Lotto((purchaseLottoNumbers1)) val purchaseLotto2 = Lotto((purchaseLottoNumbers2)) diff --git a/src/test/kotlin/lotto/data/LottoNumberTest.kt b/src/test/kotlin/lotto/data/LottoNumberTest.kt index 0bbdc7595..9448fe65f 100644 --- a/src/test/kotlin/lotto/data/LottoNumberTest.kt +++ b/src/test/kotlin/lotto/data/LottoNumberTest.kt @@ -9,11 +9,13 @@ class LottoNumberTest { // given : // when : 번호 조합을 입력 받았을 때 - val selectNumberList = listOf(1, 2, 3, 4, 5, 6) + val numberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6)) // then : 로또 번호 조합을 생성할 수 있다. - val lottoNumbers = LottoNumber.createLottoNumbers(selectNumberList) - val expect = LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6)) + val lottoNumbers = LottoNumber.createLottoNumbers(numberCombination) + + val expectNumberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6)) + val expect = LottoNumber.createLottoNumbers(expectNumberCombination) assertThat(lottoNumbers).isEqualTo(expect) } @@ -21,10 +23,10 @@ class LottoNumberTest { @Test fun `1 ~ 45 범위를 넘어가는 값을 받았다면, 로또를 생성했을 때, 예외를 던진다`() { // given : 범위를 벗어나는 값을 포함하여 번호를 구성한다. - val selectNumberList = listOf(1, 2, 3, 4, 5, 450) + val numberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 450)) // when : 로또번호를 구성한다. - val actual = runCatching { LottoNumber.createLottoNumbers(selectNumberList) }.exceptionOrNull() + val actual = runCatching { LottoNumber.createLottoNumbers(numberCombination) }.exceptionOrNull() // then : 예외를 던진다. assertThat(actual).isInstanceOf(IllegalArgumentException()::class.java) diff --git a/src/test/kotlin/lotto/data/LottoTest.kt b/src/test/kotlin/lotto/data/LottoTest.kt index a1ab83dfd..27831e7cd 100644 --- a/src/test/kotlin/lotto/data/LottoTest.kt +++ b/src/test/kotlin/lotto/data/LottoTest.kt @@ -15,10 +15,10 @@ class LottoTest { @Test fun `6개로 구성되지 않는 번호 구성을 받았다면, 로또를 생성했을 때, 예외를 던진다`() { // given : 6개로 구성되지 않은 번호 구성을 받는다. - val selectNumberList = listOf(1, 2, 3, 4, 5, 6, 7) + val selectNumberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6, 7)) // when : 로또번호를 구성한다. - val actual = runCatching { Lotto(LottoNumber.createLottoNumbers(selectNumberList)) }.exceptionOrNull() + val actual = runCatching { Lotto(LottoNumber.createLottoNumbers(selectNumberCombination)) }.exceptionOrNull() // then : 예외를 던진다. Assertions.assertThat(actual).isInstanceOf(IllegalArgumentException()::class.java) @@ -27,10 +27,10 @@ class LottoTest { @Test fun `중복값을 포함한 6개의 번호 구성을 받았다면, 로또를 생성했을 때, 예외를 던진다`() { // given : 중복값을 포함한 6개의 번호 구성을 받는다. - val selectNumberList = listOf(1, 2, 3, 4, 6, 6) + val selectNumberCombination = NumberCombination(listOf(1, 2, 3, 4, 6, 6)) // when : 로또번호를 구성한다. - val actual = runCatching { Lotto(LottoNumber.createLottoNumbers(selectNumberList)) }.exceptionOrNull() + val actual = runCatching { Lotto(LottoNumber.createLottoNumbers(selectNumberCombination)) }.exceptionOrNull() // then : 예외를 던진다. Assertions.assertThat(actual).isInstanceOf(IllegalArgumentException()::class.java) diff --git a/src/test/kotlin/lotto/data/NumberCombinationTest.kt b/src/test/kotlin/lotto/data/NumberCombinationTest.kt new file mode 100644 index 000000000..637af10c4 --- /dev/null +++ b/src/test/kotlin/lotto/data/NumberCombinationTest.kt @@ -0,0 +1,3 @@ +package lotto.data + +class NumberCombinationTest diff --git a/src/test/kotlin/lotto/data/WinningLottoTest.kt b/src/test/kotlin/lotto/data/WinningLottoTest.kt index 8f9d632ec..a3a231ca5 100644 --- a/src/test/kotlin/lotto/data/WinningLottoTest.kt +++ b/src/test/kotlin/lotto/data/WinningLottoTest.kt @@ -8,11 +8,11 @@ class WinningLottoTest { @Test fun `당첨 번호와 일치하는 번호 수 반환`() { // given : 당첨로또와 로또를 받는다. - val lotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) - val lotto2 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + val lotto1 = Lotto(LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 6)))) + val lotto2 = Lotto(LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 7)))) // 당첨번호 [1,2,3,4,5,7] + 보너스 번호 [6] - val wLotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + val wLotto1 = Lotto(LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 7)))) val winningLotto = WinningLotto(wLotto1, LottoNumber.from(6)) // when : 검증 로직을 실행한다. @@ -27,11 +27,11 @@ class WinningLottoTest { @Test fun `보너스 번호 일치 검증`() { // given : 당첨로또와 로또를 받는다. - val lotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) - val lotto2 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + val lotto1 = Lotto(LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 6)))) + val lotto2 = Lotto(LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 7)))) // 당첨번호 [1,2,3,4,5,7] + 보너스 번호 [6] - val wLotto1 = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 7))) + val wLotto1 = Lotto(LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 7)))) val winningLotto = WinningLotto(wLotto1, LottoNumber.from(6)) // when : 보너스 번호 일치 검증 로직을 호출한다. @@ -46,7 +46,7 @@ class WinningLottoTest { @Test fun `보너스 번호 중복 검증`() { // given : 당첨 번호로 구성된 로또와 이와 중복되는 보너스 번호를 받는다. - val lotto = Lotto(LottoNumber.createLottoNumbers(listOf(1, 2, 3, 4, 5, 6))) + val lotto = Lotto(LottoNumber.createLottoNumbers(NumberCombination(listOf(1, 2, 3, 4, 5, 6)))) val bonusLottoNumber = LottoNumber.from(6) // when : diff --git a/src/test/kotlin/lotto/domain/LottoMachineTest.kt b/src/test/kotlin/lotto/domain/LottoMachineTest.kt index 52821c731..c5f0942a5 100644 --- a/src/test/kotlin/lotto/domain/LottoMachineTest.kt +++ b/src/test/kotlin/lotto/domain/LottoMachineTest.kt @@ -3,6 +3,7 @@ package lotto.domain import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking +import lotto.data.NumberCombination import lotto.data.WinningLotto import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -13,8 +14,8 @@ class LottoMachineTest { @Test fun `번호 리스트를 받았다면, 로또를 생성 요청을 했을 때, 해당 번호로 구성된 로또를 생성한다`() { // given : 번호를 리스트를 받는다. - val numberList = listOf(1, 2, 3, 4, 5, 6) - val lottoNumbers = LottoNumber.createLottoNumbers(numberList) + val numberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6)) + val lottoNumbers = LottoNumber.createLottoNumbers(numberCombination) // when : 로또를 생성한다. val actual = LottoMachine.createSelectLotto(lottoNumbers) @@ -27,12 +28,12 @@ class LottoMachineTest { @Test fun `구매 로또와 당첨 로또를 받았다면, 당첨 확인을 요청했을 때, 당첨 등수를 반환한다`() { // given : 구매 로또 리스트와 추첨된 로또를 받는다. - val winningNumberList = listOf(1, 2, 3, 4, 5, 6) + val numberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6)) val bonusLottoNumber = LottoNumber.from(7) - val winningLotto = WinningLotto(Lotto(LottoNumber.createLottoNumbers(winningNumberList)), bonusLottoNumber) + val winningLotto = WinningLotto(Lotto(LottoNumber.createLottoNumbers(numberCombination)), bonusLottoNumber) - val purchaseNumberList = listOf(1, 2, 3, 4, 5, 8) - val purchaseLotto = Lotto(LottoNumber.createLottoNumbers(purchaseNumberList)) + val purchaseNumberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 8)) + val purchaseLotto = Lotto(LottoNumber.createLottoNumbers(purchaseNumberCombination)) // when : 당첨 여부를 확인을 요청한다. val actual = LottoMachine.checkLotto(purchaseLotto, winningLotto) @@ -44,12 +45,12 @@ class LottoMachineTest { @Test fun ` 2등 당첨 시나리오`() { // given : 보너스 번호를 포함해 일치하는 숫자가 6개인 구성의 로또를 받는다. - val winningNumberList = listOf(1, 2, 3, 4, 5, 6) + val numberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6)) val bonusLottoNumber = LottoNumber.from(7) - val winningLotto = WinningLotto(Lotto(LottoNumber.createLottoNumbers(winningNumberList)), bonusLottoNumber) + val winningLotto = WinningLotto(Lotto(LottoNumber.createLottoNumbers(numberCombination)), bonusLottoNumber) - val purchaseNumberList = listOf(1, 2, 3, 4, 5, 7) - val purchaseLotto = Lotto(LottoNumber.createLottoNumbers(purchaseNumberList)) + val purchaseNumberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 7)) + val purchaseLotto = Lotto(LottoNumber.createLottoNumbers(purchaseNumberCombination)) // when : 당첨 확인을 요청한다 val actual = LottoMachine.checkLotto(purchaseLotto, winningLotto) @@ -78,12 +79,12 @@ class LottoMachineTest { @Test fun `당첨 로또와 보너스 번호를 받고, 당첨 로또 번호 생성을 요청할때, 당첨 로또번호가 반환된다`() { // given : 1등 당첨 번호, 보너스 번호 - val numberList = listOf(1, 2, 3, 4, 5, 6) - val lottoNumber = LottoNumber.createLottoNumbers(numberList) + val numberCombination = NumberCombination(listOf(1, 2, 3, 4, 5, 6)) + val lottoNumber = LottoNumber.createLottoNumbers(numberCombination) val bonusNumber = 8 // when : 당첨 번호 - val actual = LottoMachine.createWinningLotto(numberList, bonusNumber) + val actual = LottoMachine.createWinningLotto(numberCombination, bonusNumber) // then : 당첨 로또 생성. val lotto = LottoMachine.createSelectLotto(lottoNumber) From 6d0bb74ed368cdeb1d4f19350d631a02a6af7449 Mon Sep 17 00:00:00 2001 From: OYJ Date: Thu, 23 Nov 2023 02:55:27 +0900 Subject: [PATCH 11/11] =?UTF-8?q?Feat:=20=EB=A1=9C=EB=98=90=20=EC=88=98?= =?UTF-8?q?=EB=8F=99=20=EA=B5=AC=EB=A7=A4=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor: 구매 금액 반환값 String -> Int변경 --- README.md | 2 +- src/main/kotlin/lotto/LottoMain.kt | 16 +++++--- .../kotlin/lotto/domain/LottoCalculator.kt | 7 ++++ src/main/kotlin/lotto/service/LottoGame.kt | 24 +++++++++--- src/main/kotlin/lotto/view/InputView.kt | 38 +++++++++++++++++-- src/main/kotlin/lotto/view/OutputView.kt | 6 ++- src/test/kotlin/lotto/LottoGameTest.kt | 3 +- 7 files changed, 78 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index cc00ff928..9d9b42131 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,6 @@ inputView (object) - [O] 입력된 금액 포맷 검증 - [O] 숫자 포맷 검증 - [O] 금액 범위는 1,000원 이상 100,000원 이하의 정수 -- [] 지난 당첨 번호 포맷 검증 +- [O] 지난 당첨 번호 포맷 검증 - [O] 콤마(,)를 기준으로 나눈다 - [O] 숫자 포맷 검증 diff --git a/src/main/kotlin/lotto/LottoMain.kt b/src/main/kotlin/lotto/LottoMain.kt index c37596302..7d00e090f 100644 --- a/src/main/kotlin/lotto/LottoMain.kt +++ b/src/main/kotlin/lotto/LottoMain.kt @@ -1,6 +1,5 @@ package lotto -import lotto.data.NumberCombination import lotto.domain.LottoMachine import lotto.domain.RandomLogic import lotto.service.LottoGame @@ -11,16 +10,21 @@ fun main() { val cash = InputView.inputCash() val lottoGame = LottoGame(RandomLogic()) - val purchaseLottoList = lottoGame.buyLotto(cash.toInt()) + val gameTimes = lottoGame.getGameTimes(cash) + val manualGameTimes = InputView.inputManualCnt(gameTimes) - OutputView.showLottoList(purchaseLottoList) + val numberCombinationList = InputView.inputNumberCombination(manualGameTimes) - val winningNumberList = NumberCombination(InputView.inputWinningNumber()) + val purchaseLottoList = lottoGame.buyLotto(gameTimes, numberCombinationList) + + OutputView.showLottoList(purchaseLottoList, manualGameTimes) + + val winningNumberCombination = InputView.inputWinningNumber() val bonusNumber = InputView.inputBonusNumber() - val winningLotto = LottoMachine.createWinningLotto(winningNumberList, bonusNumber) + val winningLotto = LottoMachine.createWinningLotto(winningNumberCombination, bonusNumber) val winningStatus = lottoGame.getWinningStats(winningLotto, purchaseLottoList) - val winningRate = LottoMachine.createWinningRate(cash.toInt(), winningStatus) + val winningRate = LottoMachine.createWinningRate(cash, winningStatus) OutputView.showWinningStatus(winningStatus, winningRate) } diff --git a/src/main/kotlin/lotto/domain/LottoCalculator.kt b/src/main/kotlin/lotto/domain/LottoCalculator.kt index c9a27354b..171812c59 100644 --- a/src/main/kotlin/lotto/domain/LottoCalculator.kt +++ b/src/main/kotlin/lotto/domain/LottoCalculator.kt @@ -5,6 +5,8 @@ import java.util.EnumMap object LottoCalculator { + private const val ERR_MSG_OVER_MANUAL_GAME_TIMES = "수동 게임 횟수가 총 게임 횟수를 초과하였습니다." + fun calculateWinningRate(cash: Int, winningStatus: EnumMap): Float { val totalPrice = winningStatus.toList().sumOf { it.first.findPrize(it) } @@ -14,4 +16,9 @@ object LottoCalculator { fun getTimes(cash: Int, gameCost: Int): Int { return cash / gameCost } + + fun getAutoTimes(totalTimes: Int, manualGameTimes: Int): Int { + require(totalTimes >= manualGameTimes) { ERR_MSG_OVER_MANUAL_GAME_TIMES } + return totalTimes - manualGameTimes + } } diff --git a/src/main/kotlin/lotto/service/LottoGame.kt b/src/main/kotlin/lotto/service/LottoGame.kt index 6e3e6a15d..0b03bec32 100644 --- a/src/main/kotlin/lotto/service/LottoGame.kt +++ b/src/main/kotlin/lotto/service/LottoGame.kt @@ -3,6 +3,7 @@ package lotto.service import lotto.data.Lotto import lotto.data.LottoNumber import lotto.data.LottoRanking +import lotto.data.NumberCombination import lotto.data.WinningLotto import lotto.domain.LottoCalculator import lotto.domain.LottoMachine @@ -12,10 +13,22 @@ import java.util.EnumMap class LottoGame(private val randomLogic: RandomLogicInterface, private val gameCost: Int = DEFAULT_COST) { - fun buyLotto(cash: Int): List { - val times = LottoCalculator.getTimes(cash, gameCost) + fun getGameTimes(cash: Int): Int { + return LottoCalculator.getTimes(cash, gameCost) + } + + fun buyLotto(gameTimes: Int, numberCombinationList: List = emptyList()): List { + val autoTimes = LottoCalculator.getAutoTimes(gameTimes, numberCombinationList.size) + val lottoList = mutableListOf() - return createLotto(times) + lottoList.addAll(numberCombinationList.map { createManualLotto(it) }) + lottoList.addAll(createLotto(autoTimes)) + + return lottoList + } + + fun getWinningStats(winningLotto: WinningLotto, purchaseLottoList: List): EnumMap { + return WinningDomain.checkWinningResult(winningLotto, purchaseLottoList) } private fun createLotto(times: Int): List { @@ -27,8 +40,9 @@ class LottoGame(private val randomLogic: RandomLogicInterface, private val gameC return lottoList } - fun getWinningStats(winningLotto: WinningLotto, purchaseLottoList: List): EnumMap { - return WinningDomain.checkWinningResult(winningLotto, purchaseLottoList) + private fun createManualLotto(numberCombination: NumberCombination): Lotto { + val lottoNumberCombination = LottoNumber.createLottoNumbers(numberCombination) + return LottoMachine.createSelectLotto(lottoNumberCombination) } companion object { diff --git a/src/main/kotlin/lotto/view/InputView.kt b/src/main/kotlin/lotto/view/InputView.kt index b55efb10a..7d866bc03 100644 --- a/src/main/kotlin/lotto/view/InputView.kt +++ b/src/main/kotlin/lotto/view/InputView.kt @@ -1,5 +1,7 @@ package lotto.view +import lotto.data.NumberCombination + object InputView { private const val ERR_MSG_INVALID_NUMERIC_FORMAT = "입력된 값의 포맷이 숫자가 압니다." @@ -7,18 +9,37 @@ object InputView { private const val MIN_GAME_COST = 1000 private const val MAX_GAME_COST = 100000 - fun inputCash(): String { + fun inputCash(): Int { println("구입금액을 입력해 주세요.") val inputData = readln() validateCash(inputData) - return inputData + return inputData.toInt() + } + + fun inputManualCnt(gameTimes: Int): Int { + println("수동으로 구매할 로또 수를 입력해 주세요.") + val inputData = readln() + validateBuyManual(inputData, gameTimes) + return inputData.toInt() } - fun inputWinningNumber(): List { + fun inputNumberCombination(manualGameTimes: Int): List { + val numberCombinationList = mutableListOf() + + println("수동으로 구매할 번호를 입력해 주세요.") + repeat(manualGameTimes) { + val inputData = readln() + numberCombinationList.add(NumberCombination(splitInputData(inputData))) + } + println() + return numberCombinationList.toList() + } + + fun inputWinningNumber(): NumberCombination { println("지난 주 당첨 번호를 입력해 주세요.") val inputData = readln() println() - return splitInputData(inputData) + return NumberCombination(splitInputData(inputData)) } fun inputBonusNumber(): Int { @@ -33,6 +54,15 @@ object InputView { validateNumberRange(inputData.toInt()) } + fun validateBuyManual(inputData: String, gameTimes: Int) { + validateNumericFormat(inputData) + validateManualTimes(inputData.toInt(), gameTimes) + } + + private fun validateManualTimes(inputData: Int, gameTimes: Int) { + require(gameTimes >= inputData) { "수동 게임 횟수가 총 게임 횟수를 초과하였습니다." } + } + fun splitInputData(inputData: String): List { val splitData = inputData.split(",").map { it.trim() } validateWinningNumber(splitData) diff --git a/src/main/kotlin/lotto/view/OutputView.kt b/src/main/kotlin/lotto/view/OutputView.kt index 797678e7a..5d7237f16 100644 --- a/src/main/kotlin/lotto/view/OutputView.kt +++ b/src/main/kotlin/lotto/view/OutputView.kt @@ -2,6 +2,7 @@ package lotto.view import lotto.data.Lotto import lotto.data.LottoRanking +import lotto.domain.LottoCalculator object OutputView { @@ -10,7 +11,10 @@ object OutputView { private const val TXT_LOSS_COMMENT = "기준이 1이기 때문에 결과적으로 손해라는 의미임" private const val DIVIDING_LINE = "---------" - fun showLottoList(lottoList: List) { + fun showLottoList(lottoList: List, manualGameTimes: Int) { + val autoGameTimes = LottoCalculator.getAutoTimes(lottoList.size, manualGameTimes) + + println("수동으로 ${manualGameTimes}장, 자동으로 ${autoGameTimes}장 구매했습니다.") lottoList.forEach { println(it.selectNumbers) } diff --git a/src/test/kotlin/lotto/LottoGameTest.kt b/src/test/kotlin/lotto/LottoGameTest.kt index f0f6e1d58..5535aec4f 100644 --- a/src/test/kotlin/lotto/LottoGameTest.kt +++ b/src/test/kotlin/lotto/LottoGameTest.kt @@ -16,9 +16,10 @@ class LottoGameTest { // given : 금액을 입력 받는다. val cash = 4500 val lottoGame = LottoGame(RandomLogic()) + val gameTimes = lottoGame.getGameTimes(cash) // when : 로또를 구매한다. - val lottoList = lottoGame.buyLotto(cash) + val lottoList = lottoGame.buyLotto(gameTimes) // then : 입력 받은 금액의 최대 수량의 로또를 구매한다. assertThat(lottoList.size).isEqualTo(4)