From 356d7390247ecde6f4eafe26365a663a2c50cabd Mon Sep 17 00:00:00 2001 From: dean Date: Sat, 2 Dec 2023 14:41:18 +0900 Subject: [PATCH 1/7] =?UTF-8?q?LottoNumber=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/Main.kt | 8 ++------ src/main/kotlin/lotto/domain/Lotto.kt | 13 +++++++------ src/main/kotlin/lotto/domain/LottoNumber.kt | 14 ++++++++++++++ src/main/kotlin/lotto/domain/WinningLotto.kt | 6 +----- src/test/kotlin/lotto/domain/LottoGeneratorTest.kt | 2 +- src/test/kotlin/lotto/domain/LottoTest.kt | 4 ++-- 6 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 src/main/kotlin/lotto/domain/LottoNumber.kt diff --git a/src/main/kotlin/lotto/Main.kt b/src/main/kotlin/lotto/Main.kt index 4feee2fa54..c3ef6cf1c0 100644 --- a/src/main/kotlin/lotto/Main.kt +++ b/src/main/kotlin/lotto/Main.kt @@ -1,10 +1,6 @@ package lotto -import lotto.domain.DefaultLottoGenerateStrategy -import lotto.domain.Lotto -import lotto.domain.LottoGenerator -import lotto.domain.LottoStore -import lotto.domain.WinningLotto +import lotto.domain.* import lotto.ui.InputView import lotto.ui.ResultView @@ -16,7 +12,7 @@ fun main() { val boughtLottos = store.buyLottos(money) ResultView.showBoughtLottos(boughtLottos) - val winningLotto = WinningLotto(Lotto(InputView.inputWinningNumbers()), InputView.inputBonusNumber()) + val winningLotto = WinningLotto(Lotto(InputView.inputWinningNumbers()), LottoNumber(InputView.inputBonusNumber())) val checkedLottos = boughtLottos.matchAll(winningLotto) val returnRate = checkedLottos.totalReward() / money.toDouble() diff --git a/src/main/kotlin/lotto/domain/Lotto.kt b/src/main/kotlin/lotto/domain/Lotto.kt index 9a77dbc8a9..395763ee1f 100644 --- a/src/main/kotlin/lotto/domain/Lotto.kt +++ b/src/main/kotlin/lotto/domain/Lotto.kt @@ -1,9 +1,11 @@ package lotto.domain class Lotto( - val numbers: List, + val numbers: List, val winning: LottoWinning = LottoWinning.Miss, ) { + constructor(numbers: List) : this(numbers.map { LottoNumber(it) }) + init { require(numbers.size == NUMBERS_COUNT) { "로또 번호는 항상 ${NUMBERS_COUNT}개 여야 합니다." @@ -11,9 +13,6 @@ class Lotto( require(numbers.distinct().size == NUMBERS_COUNT) { "로또 번호는 중복이 없어야 합니다." } - require(numbers.all { it in MIN_NUMBER..MAX_NUMBER }) { - "로또 번호는 항상 ${MIN_NUMBER}에서 ${MAX_NUMBER}사이 값이어야 합니다." - } require(numbers.isSortedNumber()) { "로또 번호는 항상 정렬되어야 합니다." } @@ -29,8 +28,10 @@ class Lotto( ) } - private fun List.isSortedNumber(): Boolean { - return zipWithNext { a, b -> a <= b }.all { it } + private fun List.isSortedNumber(): Boolean { + return map { it.value } + .zipWithNext { a, b -> a <= b } + .all { it } } companion object { diff --git a/src/main/kotlin/lotto/domain/LottoNumber.kt b/src/main/kotlin/lotto/domain/LottoNumber.kt new file mode 100644 index 0000000000..7f58f411d0 --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoNumber.kt @@ -0,0 +1,14 @@ +package lotto.domain + +@JvmInline +value class LottoNumber(val value: Int) : Comparable { + init { + require(value in Lotto.MIN_NUMBER..Lotto.MAX_NUMBER) { + "로또 번호는 항상 ${Lotto.MIN_NUMBER}에서 ${Lotto.MAX_NUMBER}사이 값이어야 합니다." + } + } + + override fun compareTo(other: LottoNumber): Int { + return value.compareTo(other.value) + } +} diff --git a/src/main/kotlin/lotto/domain/WinningLotto.kt b/src/main/kotlin/lotto/domain/WinningLotto.kt index 7770c1f405..85a9743e3c 100644 --- a/src/main/kotlin/lotto/domain/WinningLotto.kt +++ b/src/main/kotlin/lotto/domain/WinningLotto.kt @@ -2,15 +2,11 @@ package lotto.domain data class WinningLotto( val lotto: Lotto, - val bonusNumber: Int, + val bonusNumber: LottoNumber, ) { init { require(!lotto.numbers.contains(bonusNumber)) { "보너스 번호는 로또 번호에 포함되면 안됩니다." } - - require(bonusNumber in Lotto.MIN_NUMBER..Lotto.MAX_NUMBER) { - "보너스 번호는 항상 ${Lotto.MIN_NUMBER}에서 ${Lotto.MAX_NUMBER}사이 값이어야 합니다." - } } } diff --git a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt index 4b4f68c3c9..5450f5c1c9 100644 --- a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt +++ b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt @@ -13,6 +13,6 @@ class LottoGeneratorTest { val generator = LottoGenerator(lottoGenerateStrategy) val lotto = generator.publish() - assertThat(lotto.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) + assertThat(lotto.numbers.map { it.value }).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) } } diff --git a/src/test/kotlin/lotto/domain/LottoTest.kt b/src/test/kotlin/lotto/domain/LottoTest.kt index 4ccca6fcd3..68f16f6aa7 100644 --- a/src/test/kotlin/lotto/domain/LottoTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTest.kt @@ -15,7 +15,7 @@ class LottoTest { val lotto = Lotto(numbers) - assertThat(lotto.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) + assertThat(lotto.numbers.map { it.value }).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) } @Test @@ -75,7 +75,7 @@ class LottoTest { @ParameterizedTest @MethodSource("provideLotto") fun `당첨 번호가 포함되어있으면 Winning 값을 변경해준다`(lotto: Lotto, expectedWinning: LottoWinning) { - val winningLotto = WinningLotto(Lotto(listOf(1, 2, 3, 4, 5, 6)), 7) + val winningLotto = WinningLotto(Lotto(listOf(1, 2, 3, 4, 5, 6)), LottoNumber(7)) val checkedLotto = lotto.match(winningLotto) val actualWinning = checkedLotto.winning From 538f0318759751221ecc15e168f5ecc54f66d005 Mon Sep 17 00:00:00 2001 From: dean Date: Sat, 2 Dec 2023 19:40:26 +0900 Subject: [PATCH 2/7] =?UTF-8?q?Lotto=EC=97=90=EC=84=9C=20Winning=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/Main.kt | 16 ++++++++---- .../domain/DefaultLottoGenerateStrategy.kt | 2 +- src/main/kotlin/lotto/domain/Lotto.kt | 14 +++++----- src/main/kotlin/lotto/domain/LottoMatcher.kt | 7 +++++ src/main/kotlin/lotto/domain/Lottos.kt | 10 +++---- src/main/kotlin/lotto/domain/MatchedLotto.kt | 6 +++++ src/main/kotlin/lotto/domain/MatchedLottos.kt | 8 ++++++ src/main/kotlin/lotto/ui/ResultView.kt | 3 ++- .../kotlin/lotto/domain/LottoGeneratorTest.kt | 2 +- .../kotlin/lotto/domain/LottoStoreTest.kt | 2 +- src/test/kotlin/lotto/domain/LottoTest.kt | 26 +++++++++---------- 11 files changed, 59 insertions(+), 37 deletions(-) create mode 100644 src/main/kotlin/lotto/domain/LottoMatcher.kt create mode 100644 src/main/kotlin/lotto/domain/MatchedLotto.kt create mode 100644 src/main/kotlin/lotto/domain/MatchedLottos.kt diff --git a/src/main/kotlin/lotto/Main.kt b/src/main/kotlin/lotto/Main.kt index c3ef6cf1c0..a3fb80e9dd 100644 --- a/src/main/kotlin/lotto/Main.kt +++ b/src/main/kotlin/lotto/Main.kt @@ -1,6 +1,12 @@ package lotto -import lotto.domain.* +import lotto.domain.DefaultLottoGenerateStrategy +import lotto.domain.Lotto +import lotto.domain.LottoGenerator +import lotto.domain.LottoMatcher +import lotto.domain.LottoNumber +import lotto.domain.LottoStore +import lotto.domain.WinningLotto import lotto.ui.InputView import lotto.ui.ResultView @@ -12,10 +18,10 @@ fun main() { val boughtLottos = store.buyLottos(money) ResultView.showBoughtLottos(boughtLottos) - val winningLotto = WinningLotto(Lotto(InputView.inputWinningNumbers()), LottoNumber(InputView.inputBonusNumber())) + val winningLotto = WinningLotto(Lotto.of(InputView.inputWinningNumbers()), LottoNumber(InputView.inputBonusNumber())) + val matchedLotto = LottoMatcher.matchAll(boughtLottos, winningLotto) - val checkedLottos = boughtLottos.matchAll(winningLotto) - val returnRate = checkedLottos.totalReward() / money.toDouble() + val returnRate = matchedLotto.totalReward() / money.toDouble() - ResultView.showResult(checkedLottos, returnRate) + ResultView.showResult(matchedLotto, returnRate) } diff --git a/src/main/kotlin/lotto/domain/DefaultLottoGenerateStrategy.kt b/src/main/kotlin/lotto/domain/DefaultLottoGenerateStrategy.kt index e61637a5ab..e06ac5e4fd 100644 --- a/src/main/kotlin/lotto/domain/DefaultLottoGenerateStrategy.kt +++ b/src/main/kotlin/lotto/domain/DefaultLottoGenerateStrategy.kt @@ -7,6 +7,6 @@ class DefaultLottoGenerateStrategy : LottoGenerateStrategy { .subList(0, Lotto.NUMBERS_COUNT) .sorted() - return Lotto(numbers) + return Lotto.of(numbers) } } diff --git a/src/main/kotlin/lotto/domain/Lotto.kt b/src/main/kotlin/lotto/domain/Lotto.kt index 395763ee1f..8098cf8b56 100644 --- a/src/main/kotlin/lotto/domain/Lotto.kt +++ b/src/main/kotlin/lotto/domain/Lotto.kt @@ -2,10 +2,7 @@ package lotto.domain class Lotto( val numbers: List, - val winning: LottoWinning = LottoWinning.Miss, ) { - constructor(numbers: List) : this(numbers.map { LottoNumber(it) }) - init { require(numbers.size == NUMBERS_COUNT) { "로또 번호는 항상 ${NUMBERS_COUNT}개 여야 합니다." @@ -18,14 +15,11 @@ class Lotto( } } - fun match(winningLotto: WinningLotto): Lotto { + fun match(winningLotto: WinningLotto): MatchedLotto { val correctCount = winningLotto.lotto.numbers.count { numbers.contains(it) } val matchBonus = numbers.contains(winningLotto.bonusNumber) - return Lotto( - numbers = numbers, - winning = LottoWinning.of(correctCount, matchBonus) - ) + return MatchedLotto(this, LottoWinning.of(correctCount, matchBonus)) } private fun List.isSortedNumber(): Boolean { @@ -38,5 +32,9 @@ class Lotto( const val NUMBERS_COUNT = 6 const val MIN_NUMBER = 1 const val MAX_NUMBER = 45 + + fun of(numbers: List): Lotto { + return Lotto(numbers.map { LottoNumber(it) }) + } } } diff --git a/src/main/kotlin/lotto/domain/LottoMatcher.kt b/src/main/kotlin/lotto/domain/LottoMatcher.kt new file mode 100644 index 0000000000..810175a31f --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoMatcher.kt @@ -0,0 +1,7 @@ +package lotto.domain + +object LottoMatcher { + fun matchAll(lottos: Lottos, winningLotto: WinningLotto): MatchedLottos { + return lottos.matchAll(winningLotto) + } +} diff --git a/src/main/kotlin/lotto/domain/Lottos.kt b/src/main/kotlin/lotto/domain/Lottos.kt index a0faa9f34c..b16d44454a 100644 --- a/src/main/kotlin/lotto/domain/Lottos.kt +++ b/src/main/kotlin/lotto/domain/Lottos.kt @@ -2,13 +2,9 @@ package lotto.domain @JvmInline value class Lottos(val value: List) { - fun matchAll(winningLotto: WinningLotto): Lottos { - val lottos = value.map { it.match(winningLotto) } + fun matchAll(winningLotto: WinningLotto): MatchedLottos { + val matchedLottos = value.map { it.match(winningLotto) } - return Lottos(lottos) - } - - fun totalReward(): Int { - return value.sumOf { it.winning.reward } + return MatchedLottos(matchedLottos) } } diff --git a/src/main/kotlin/lotto/domain/MatchedLotto.kt b/src/main/kotlin/lotto/domain/MatchedLotto.kt new file mode 100644 index 0000000000..ffa07b1f6e --- /dev/null +++ b/src/main/kotlin/lotto/domain/MatchedLotto.kt @@ -0,0 +1,6 @@ +package lotto.domain + +class MatchedLotto( + val lotto: Lotto, + val winning: LottoWinning, +) diff --git a/src/main/kotlin/lotto/domain/MatchedLottos.kt b/src/main/kotlin/lotto/domain/MatchedLottos.kt new file mode 100644 index 0000000000..890bf18492 --- /dev/null +++ b/src/main/kotlin/lotto/domain/MatchedLottos.kt @@ -0,0 +1,8 @@ +package lotto.domain + +@JvmInline +value class MatchedLottos(val value: List) { + fun totalReward(): Int { + return value.sumOf { it.winning.reward } + } +} diff --git a/src/main/kotlin/lotto/ui/ResultView.kt b/src/main/kotlin/lotto/ui/ResultView.kt index 5a3904e77c..a2c1909ae6 100644 --- a/src/main/kotlin/lotto/ui/ResultView.kt +++ b/src/main/kotlin/lotto/ui/ResultView.kt @@ -2,6 +2,7 @@ package lotto.ui import lotto.domain.LottoWinning import lotto.domain.Lottos +import lotto.domain.MatchedLottos import java.text.DecimalFormat object ResultView { @@ -12,7 +13,7 @@ object ResultView { } } - fun showResult(lottos: Lottos, returnRate: Double) { + fun showResult(lottos: MatchedLottos, returnRate: Double) { val winningLottos = lottos.value .groupBy { it.winning } diff --git a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt index 5450f5c1c9..2a59afbe3c 100644 --- a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt +++ b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt @@ -7,7 +7,7 @@ class LottoGeneratorTest { @Test fun `특정 규칙으로 로또를 발행할 수 있다`() { val lottoGenerateStrategy = LottoGenerateStrategy { - Lotto(listOf(1, 2, 3, 4, 5, 6)) + Lotto.of(listOf(1, 2, 3, 4, 5, 6)) } val generator = LottoGenerator(lottoGenerateStrategy) diff --git a/src/test/kotlin/lotto/domain/LottoStoreTest.kt b/src/test/kotlin/lotto/domain/LottoStoreTest.kt index 9b84a686ce..2a7ff78093 100644 --- a/src/test/kotlin/lotto/domain/LottoStoreTest.kt +++ b/src/test/kotlin/lotto/domain/LottoStoreTest.kt @@ -16,7 +16,7 @@ class LottoStoreTest { ] ) fun `로또는 1000원당 한 장을 살 수 있다`(money: Int, lottoCount: Int) { - val lottoGenerateStrategy = LottoGenerateStrategy { Lotto(listOf(1, 2, 3, 4, 5, 6)) } + val lottoGenerateStrategy = LottoGenerateStrategy { Lotto.of(listOf(1, 2, 3, 4, 5, 6)) } val lottoGenerator = LottoGenerator(lottoGenerateStrategy) val lottoStore = LottoStore(lottoGenerator) diff --git a/src/test/kotlin/lotto/domain/LottoTest.kt b/src/test/kotlin/lotto/domain/LottoTest.kt index 68f16f6aa7..11ec63e4df 100644 --- a/src/test/kotlin/lotto/domain/LottoTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTest.kt @@ -13,7 +13,7 @@ class LottoTest { fun `로또는 중복 없는 6개의 숫자로 만들 수 있다`() { val numbers = listOf(1, 2, 3, 4, 5, 6) - val lotto = Lotto(numbers) + val lotto = Lotto.of(numbers) assertThat(lotto.numbers.map { it.value }).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) } @@ -23,7 +23,7 @@ class LottoTest { val numbers = listOf(1) assertThrows { - Lotto(numbers) + Lotto.of(numbers) } } @@ -32,7 +32,7 @@ class LottoTest { val numbers = listOf(1, 1, 1, 1, 1, 1) assertThrows { - Lotto(numbers) + Lotto.of(numbers) } } @@ -41,7 +41,7 @@ class LottoTest { val numbers = listOf(1, 1, 1, 1, 1, 7) assertThrows { - Lotto(numbers) + Lotto.of(numbers) } } @@ -50,7 +50,7 @@ class LottoTest { val numbers = listOf(0, 1, 1, 1, 1, 1) assertThrows { - Lotto(numbers) + Lotto.of(numbers) } } @@ -59,7 +59,7 @@ class LottoTest { val numbers = listOf(46, 1, 1, 1, 1, 1) assertThrows { - Lotto(numbers) + Lotto.of(numbers) } } @@ -68,14 +68,14 @@ class LottoTest { val numbers = listOf(6, 5, 4, 3, 2, 1) assertThrows { - Lotto(numbers) + Lotto.of(numbers) } } @ParameterizedTest @MethodSource("provideLotto") fun `당첨 번호가 포함되어있으면 Winning 값을 변경해준다`(lotto: Lotto, expectedWinning: LottoWinning) { - val winningLotto = WinningLotto(Lotto(listOf(1, 2, 3, 4, 5, 6)), LottoNumber(7)) + val winningLotto = WinningLotto(Lotto.of(listOf(1, 2, 3, 4, 5, 6)), LottoNumber(7)) val checkedLotto = lotto.match(winningLotto) val actualWinning = checkedLotto.winning @@ -87,11 +87,11 @@ class LottoTest { @JvmStatic private fun provideLotto(): Stream { return Stream.of( - Arguments.of(Lotto(listOf(1, 2, 3, 10, 11, 12)), LottoWinning.Fifth), - Arguments.of(Lotto(listOf(1, 2, 3, 4, 11, 12)), LottoWinning.Fourth), - Arguments.of(Lotto(listOf(1, 2, 3, 4, 5, 12)), LottoWinning.Third), - Arguments.of(Lotto(listOf(1, 2, 3, 4, 5, 7)), LottoWinning.Second), - Arguments.of(Lotto(listOf(1, 2, 3, 4, 5, 6)), LottoWinning.First), + Arguments.of(Lotto.of(listOf(1, 2, 3, 10, 11, 12)), LottoWinning.Fifth), + Arguments.of(Lotto.of(listOf(1, 2, 3, 4, 11, 12)), LottoWinning.Fourth), + Arguments.of(Lotto.of(listOf(1, 2, 3, 4, 5, 12)), LottoWinning.Third), + Arguments.of(Lotto.of(listOf(1, 2, 3, 4, 5, 7)), LottoWinning.Second), + Arguments.of(Lotto.of(listOf(1, 2, 3, 4, 5, 6)), LottoWinning.First), ) } } From c47648893aaef707b1730061172a5fc6144dcac3 Mon Sep 17 00:00:00 2001 From: dean Date: Sat, 2 Dec 2023 19:59:26 +0900 Subject: [PATCH 3/7] =?UTF-8?q?LottoNumbers=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/domain/Lotto.kt | 18 +++++------- src/main/kotlin/lotto/domain/LottoNumbers.kt | 28 +++++++++++++++++++ .../DefaultLottoGenerateStrategyTest.kt | 5 ++-- .../kotlin/lotto/domain/LottoGeneratorTest.kt | 2 +- src/test/kotlin/lotto/domain/LottoTest.kt | 2 +- 5 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 src/main/kotlin/lotto/domain/LottoNumbers.kt diff --git a/src/main/kotlin/lotto/domain/Lotto.kt b/src/main/kotlin/lotto/domain/Lotto.kt index 8098cf8b56..8d4fa5bda4 100644 --- a/src/main/kotlin/lotto/domain/Lotto.kt +++ b/src/main/kotlin/lotto/domain/Lotto.kt @@ -1,40 +1,36 @@ package lotto.domain class Lotto( - val numbers: List, + val numbers: LottoNumbers, ) { init { require(numbers.size == NUMBERS_COUNT) { "로또 번호는 항상 ${NUMBERS_COUNT}개 여야 합니다." } - require(numbers.distinct().size == NUMBERS_COUNT) { + require(!numbers.hasDuplicate()) { "로또 번호는 중복이 없어야 합니다." } - require(numbers.isSortedNumber()) { + require(numbers.isSorted()) { "로또 번호는 항상 정렬되어야 합니다." } } fun match(winningLotto: WinningLotto): MatchedLotto { - val correctCount = winningLotto.lotto.numbers.count { numbers.contains(it) } + val correctCount = winningLotto.lotto.numbers.containsCount(numbers) val matchBonus = numbers.contains(winningLotto.bonusNumber) return MatchedLotto(this, LottoWinning.of(correctCount, matchBonus)) } - private fun List.isSortedNumber(): Boolean { - return map { it.value } - .zipWithNext { a, b -> a <= b } - .all { it } - } - companion object { const val NUMBERS_COUNT = 6 const val MIN_NUMBER = 1 const val MAX_NUMBER = 45 fun of(numbers: List): Lotto { - return Lotto(numbers.map { LottoNumber(it) }) + val lottoNumbers = LottoNumbers(numbers.map { LottoNumber(it) }) + + return Lotto(lottoNumbers) } } } diff --git a/src/main/kotlin/lotto/domain/LottoNumbers.kt b/src/main/kotlin/lotto/domain/LottoNumbers.kt new file mode 100644 index 0000000000..0930fa0ff9 --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoNumbers.kt @@ -0,0 +1,28 @@ +package lotto.domain + +@JvmInline +value class LottoNumbers(private val value: List) { + val size: Int + get() = value.size + + val numbers: List + get() = value.map { it.value } + + fun contains(lottoNumber: LottoNumber): Boolean { + return value.contains(lottoNumber) + } + + fun containsCount(other: LottoNumbers): Int { + return value.count { other.value.contains(it) } + } + + fun hasDuplicate(): Boolean { + return value.distinct() != value + } + + fun isSorted(): Boolean { + return value.map { it.value } + .zipWithNext { a, b -> a <= b } + .all { it } + } +} diff --git a/src/test/kotlin/lotto/domain/DefaultLottoGenerateStrategyTest.kt b/src/test/kotlin/lotto/domain/DefaultLottoGenerateStrategyTest.kt index c75b550915..a5c30ddabd 100644 --- a/src/test/kotlin/lotto/domain/DefaultLottoGenerateStrategyTest.kt +++ b/src/test/kotlin/lotto/domain/DefaultLottoGenerateStrategyTest.kt @@ -18,9 +18,8 @@ class DefaultLottoGenerateStrategyTest { val defaultLottoGenerateStrategy = DefaultLottoGenerateStrategy() val lotto = defaultLottoGenerateStrategy.generate() - val numbersSet = lotto.numbers.distinct() - assertThat(lotto.numbers.size).isEqualTo(numbersSet.size) + assertThat(lotto.numbers.hasDuplicate()).isFalse } @Test @@ -29,6 +28,6 @@ class DefaultLottoGenerateStrategyTest { val lotto = defaultLottoGenerateStrategy.generate() - assertThat(lotto.numbers).isSorted + assertThat(lotto.numbers.isSorted()).isTrue } } diff --git a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt index 2a59afbe3c..67a4151a73 100644 --- a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt +++ b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt @@ -13,6 +13,6 @@ class LottoGeneratorTest { val generator = LottoGenerator(lottoGenerateStrategy) val lotto = generator.publish() - assertThat(lotto.numbers.map { it.value }).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) + assertThat(lotto.numbers.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) } } diff --git a/src/test/kotlin/lotto/domain/LottoTest.kt b/src/test/kotlin/lotto/domain/LottoTest.kt index 11ec63e4df..0511a20f48 100644 --- a/src/test/kotlin/lotto/domain/LottoTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTest.kt @@ -15,7 +15,7 @@ class LottoTest { val lotto = Lotto.of(numbers) - assertThat(lotto.numbers.map { it.value }).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) + assertThat(lotto.numbers.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) } @Test From 4fa3fddece8e459adab961c3a24a9727200d3035 Mon Sep 17 00:00:00 2001 From: dean Date: Sat, 2 Dec 2023 21:00:17 +0900 Subject: [PATCH 4/7] =?UTF-8?q?=EC=88=98=EB=8F=99=20=EB=A1=9C=EB=98=90=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/Main.kt | 30 +++++++++++++++---- ...rategy.kt => AutoLottoGenerateStrategy.kt} | 2 +- .../kotlin/lotto/domain/LottoGenerator.kt | 4 +-- src/main/kotlin/lotto/domain/LottoNumbers.kt | 8 +++++ src/main/kotlin/lotto/domain/LottoStore.kt | 16 +++++++--- src/main/kotlin/lotto/domain/Lottos.kt | 4 +++ .../domain/ManualLottoGenerateStrategy.kt | 9 ++++++ src/main/kotlin/lotto/ui/InputView.kt | 15 ++++++++++ src/main/kotlin/lotto/ui/ResultView.kt | 4 +-- ...st.kt => AutoLottoGenerateStrategyTest.kt} | 14 ++++----- .../kotlin/lotto/domain/LottoGeneratorTest.kt | 4 +-- .../kotlin/lotto/domain/LottoStoreTest.kt | 5 ++-- 12 files changed, 88 insertions(+), 27 deletions(-) rename src/main/kotlin/lotto/domain/{DefaultLottoGenerateStrategy.kt => AutoLottoGenerateStrategy.kt} (82%) create mode 100644 src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt rename src/test/kotlin/lotto/domain/{DefaultLottoGenerateStrategyTest.kt => AutoLottoGenerateStrategyTest.kt} (52%) diff --git a/src/main/kotlin/lotto/Main.kt b/src/main/kotlin/lotto/Main.kt index a3fb80e9dd..7e206cc887 100644 --- a/src/main/kotlin/lotto/Main.kt +++ b/src/main/kotlin/lotto/Main.kt @@ -1,22 +1,40 @@ package lotto -import lotto.domain.DefaultLottoGenerateStrategy +import lotto.domain.AutoLottoGenerateStrategy import lotto.domain.Lotto -import lotto.domain.LottoGenerator import lotto.domain.LottoMatcher import lotto.domain.LottoNumber +import lotto.domain.LottoNumbers import lotto.domain.LottoStore +import lotto.domain.Lottos +import lotto.domain.ManualLottoGenerateStrategy import lotto.domain.WinningLotto import lotto.ui.InputView import lotto.ui.ResultView fun main() { - val generator = LottoGenerator(DefaultLottoGenerateStrategy()) - val store = LottoStore(generator) + val store = LottoStore() val money = InputView.inputMoney() - val boughtLottos = store.buyLottos(money) - ResultView.showBoughtLottos(boughtLottos) + val boughtManualLottoCounts = InputView.inputManualLottoCount() + + val manualLottosPrice = boughtManualLottoCounts * LottoStore.LOTTO_PRICE + + require(money >= manualLottosPrice) { + "로또를 구매할 돈이 부족합니다." + } + + val manualLottos = List(boughtManualLottoCounts) { + val lottoNumbers = LottoNumbers.of(InputView.inputManualLottoNumber()) + + store.buyLotto(ManualLottoGenerateStrategy(lottoNumbers)) + }.let { Lottos(it) } + + val autoLottos = store.buyLottos(money - manualLottosPrice, AutoLottoGenerateStrategy()) + + val boughtLottos = manualLottos + autoLottos + + ResultView.showBoughtLottos(boughtLottos, boughtManualLottoCounts) val winningLotto = WinningLotto(Lotto.of(InputView.inputWinningNumbers()), LottoNumber(InputView.inputBonusNumber())) val matchedLotto = LottoMatcher.matchAll(boughtLottos, winningLotto) diff --git a/src/main/kotlin/lotto/domain/DefaultLottoGenerateStrategy.kt b/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt similarity index 82% rename from src/main/kotlin/lotto/domain/DefaultLottoGenerateStrategy.kt rename to src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt index e06ac5e4fd..697545bc19 100644 --- a/src/main/kotlin/lotto/domain/DefaultLottoGenerateStrategy.kt +++ b/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt @@ -1,6 +1,6 @@ package lotto.domain -class DefaultLottoGenerateStrategy : LottoGenerateStrategy { +class AutoLottoGenerateStrategy : LottoGenerateStrategy { private val numberPool: IntRange = Lotto.MIN_NUMBER..Lotto.MAX_NUMBER override fun generate(): Lotto { val numbers = numberPool.shuffled() diff --git a/src/main/kotlin/lotto/domain/LottoGenerator.kt b/src/main/kotlin/lotto/domain/LottoGenerator.kt index d7bfbf0e96..a4219a727d 100644 --- a/src/main/kotlin/lotto/domain/LottoGenerator.kt +++ b/src/main/kotlin/lotto/domain/LottoGenerator.kt @@ -1,7 +1,7 @@ package lotto.domain -class LottoGenerator(private val lottoGenerateStrategy: LottoGenerateStrategy) { - fun publish(): Lotto { +class LottoGenerator { + fun publish(lottoGenerateStrategy: LottoGenerateStrategy): Lotto { return lottoGenerateStrategy.generate() } } diff --git a/src/main/kotlin/lotto/domain/LottoNumbers.kt b/src/main/kotlin/lotto/domain/LottoNumbers.kt index 0930fa0ff9..f54137f13c 100644 --- a/src/main/kotlin/lotto/domain/LottoNumbers.kt +++ b/src/main/kotlin/lotto/domain/LottoNumbers.kt @@ -25,4 +25,12 @@ value class LottoNumbers(private val value: List) { .zipWithNext { a, b -> a <= b } .all { it } } + + companion object { + fun of(numbers: List): LottoNumbers { + val lottoNumbers = numbers.map { LottoNumber(it) } + + return LottoNumbers(lottoNumbers) + } + } } diff --git a/src/main/kotlin/lotto/domain/LottoStore.kt b/src/main/kotlin/lotto/domain/LottoStore.kt index 3a8fb2ee75..1d50537f91 100644 --- a/src/main/kotlin/lotto/domain/LottoStore.kt +++ b/src/main/kotlin/lotto/domain/LottoStore.kt @@ -1,14 +1,22 @@ package lotto.domain -private const val LOTTO_PRICE = 1000 +class LottoStore { + private val lottoGenerator = LottoGenerator() -class LottoStore(private val lottoGenerator: LottoGenerator) { - fun buyLottos(money: Int): Lottos { + fun buyLotto(lottoGenerateStrategy: LottoGenerateStrategy): Lotto { + return lottoGenerator.publish(lottoGenerateStrategy) + } + + fun buyLottos(money: Int, lottoGenerateStrategy: LottoGenerateStrategy): Lottos { val lottoCount = money / LOTTO_PRICE val lottos = List(lottoCount) { - lottoGenerator.publish() + lottoGenerator.publish(lottoGenerateStrategy) } return Lottos(lottos) } + + companion object { + const val LOTTO_PRICE = 1000 + } } diff --git a/src/main/kotlin/lotto/domain/Lottos.kt b/src/main/kotlin/lotto/domain/Lottos.kt index b16d44454a..85f04df3f1 100644 --- a/src/main/kotlin/lotto/domain/Lottos.kt +++ b/src/main/kotlin/lotto/domain/Lottos.kt @@ -7,4 +7,8 @@ value class Lottos(val value: List) { return MatchedLottos(matchedLottos) } + + operator fun plus(other: Lottos): Lottos { + return Lottos(value + other.value) + } } diff --git a/src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt b/src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt new file mode 100644 index 0000000000..a0e7d709f5 --- /dev/null +++ b/src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt @@ -0,0 +1,9 @@ +package lotto.domain + +class ManualLottoGenerateStrategy( + private val lottoNumbers: LottoNumbers +) : LottoGenerateStrategy { + override fun generate(): Lotto { + return Lotto(lottoNumbers) + } +} diff --git a/src/main/kotlin/lotto/ui/InputView.kt b/src/main/kotlin/lotto/ui/InputView.kt index ed6501ac35..7165c9bb0a 100644 --- a/src/main/kotlin/lotto/ui/InputView.kt +++ b/src/main/kotlin/lotto/ui/InputView.kt @@ -7,6 +7,21 @@ object InputView { return readln().toInt() } + fun inputManualLottoCount(): Int { + println("수동으로 구매할 로또 수를 입력해 주세요.") + + return readln().toInt() + } + + fun inputManualLottoNumber(): List { + println("수동으로 구매할 번호를 입력해 주세요.") + + return readln() + .split(",") + .map { it.toInt() } + .sorted() + } + fun inputWinningNumbers(): List { println("지난 주 당첨 번호를 입력해 주세요.") diff --git a/src/main/kotlin/lotto/ui/ResultView.kt b/src/main/kotlin/lotto/ui/ResultView.kt index a2c1909ae6..deec19aacf 100644 --- a/src/main/kotlin/lotto/ui/ResultView.kt +++ b/src/main/kotlin/lotto/ui/ResultView.kt @@ -6,8 +6,8 @@ import lotto.domain.MatchedLottos import java.text.DecimalFormat object ResultView { - fun showBoughtLottos(lottos: Lottos) { - println("${lottos.value.size}개를 구매했습니다.") + fun showBoughtLottos(lottos: Lottos, manualLottoCount: Int) { + println("수동으로 ${manualLottoCount}장 자동으로 ${lottos.value.size - manualLottoCount}개를 구매했습니다.") lottos.value.forEach { println("numbers = ${it.numbers}") } diff --git a/src/test/kotlin/lotto/domain/DefaultLottoGenerateStrategyTest.kt b/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt similarity index 52% rename from src/test/kotlin/lotto/domain/DefaultLottoGenerateStrategyTest.kt rename to src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt index a5c30ddabd..8aeab3a8c2 100644 --- a/src/test/kotlin/lotto/domain/DefaultLottoGenerateStrategyTest.kt +++ b/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt @@ -3,30 +3,30 @@ package lotto.domain import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DefaultLottoGenerateStrategyTest { +class AutoLottoGenerateStrategyTest { @Test fun `번호를 6개가진 로또를 생성한다`() { - val defaultLottoGenerateStrategy = DefaultLottoGenerateStrategy() + val autoLottoGenerateStrategy = AutoLottoGenerateStrategy() - val lotto = defaultLottoGenerateStrategy.generate() + val lotto = autoLottoGenerateStrategy.generate() assertThat(lotto.numbers.size).isEqualTo(6) } @Test fun `중복된 번호가 생성되지 않는다`() { - val defaultLottoGenerateStrategy = DefaultLottoGenerateStrategy() + val autoLottoGenerateStrategy = AutoLottoGenerateStrategy() - val lotto = defaultLottoGenerateStrategy.generate() + val lotto = autoLottoGenerateStrategy.generate() assertThat(lotto.numbers.hasDuplicate()).isFalse } @Test fun `번호는 정렬되어 생성된다`() { - val defaultLottoGenerateStrategy = DefaultLottoGenerateStrategy() + val autoLottoGenerateStrategy = AutoLottoGenerateStrategy() - val lotto = defaultLottoGenerateStrategy.generate() + val lotto = autoLottoGenerateStrategy.generate() assertThat(lotto.numbers.isSorted()).isTrue } diff --git a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt index 67a4151a73..3fb322613f 100644 --- a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt +++ b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt @@ -10,8 +10,8 @@ class LottoGeneratorTest { Lotto.of(listOf(1, 2, 3, 4, 5, 6)) } - val generator = LottoGenerator(lottoGenerateStrategy) - val lotto = generator.publish() + val generator = LottoGenerator() + val lotto = generator.publish(lottoGenerateStrategy) assertThat(lotto.numbers.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) } diff --git a/src/test/kotlin/lotto/domain/LottoStoreTest.kt b/src/test/kotlin/lotto/domain/LottoStoreTest.kt index 2a7ff78093..2d6bab9b5e 100644 --- a/src/test/kotlin/lotto/domain/LottoStoreTest.kt +++ b/src/test/kotlin/lotto/domain/LottoStoreTest.kt @@ -17,10 +17,9 @@ class LottoStoreTest { ) fun `로또는 1000원당 한 장을 살 수 있다`(money: Int, lottoCount: Int) { val lottoGenerateStrategy = LottoGenerateStrategy { Lotto.of(listOf(1, 2, 3, 4, 5, 6)) } - val lottoGenerator = LottoGenerator(lottoGenerateStrategy) - val lottoStore = LottoStore(lottoGenerator) + val lottoStore = LottoStore() - val lottos = lottoStore.buyLottos(money) + val lottos = lottoStore.buyLottos(money, lottoGenerateStrategy) assertThat(lottos.value.size).isEqualTo(lottoCount) } From f085421af941472b394e891fd9c9f23baf4db4be Mon Sep 17 00:00:00 2001 From: dean Date: Sat, 2 Dec 2023 21:18:47 +0900 Subject: [PATCH 5/7] =?UTF-8?q?Lotto=EC=97=90=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=A0=81=EC=A0=88=ED=95=9C=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lotto/domain/AutoLottoGenerateStrategy.kt | 2 +- src/main/kotlin/lotto/domain/Lotto.kt | 14 ---- src/main/kotlin/lotto/domain/LottoNumber.kt | 9 ++- src/main/kotlin/lotto/domain/LottoNumbers.kt | 17 ++++- .../domain/AutoLottoGenerateStrategyTest.kt | 4 +- .../kotlin/lotto/domain/LottoNumberTest.kt | 15 ++++ .../kotlin/lotto/domain/LottoNumbersTest.kt | 43 ++++++++++++ src/test/kotlin/lotto/domain/LottoTest.kt | 70 +------------------ .../kotlin/lotto/domain/WinningLottoTest.kt | 16 +++++ 9 files changed, 102 insertions(+), 88 deletions(-) create mode 100644 src/test/kotlin/lotto/domain/LottoNumberTest.kt create mode 100644 src/test/kotlin/lotto/domain/LottoNumbersTest.kt create mode 100644 src/test/kotlin/lotto/domain/WinningLottoTest.kt diff --git a/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt b/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt index 697545bc19..adb37f7c51 100644 --- a/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt +++ b/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt @@ -1,7 +1,7 @@ package lotto.domain class AutoLottoGenerateStrategy : LottoGenerateStrategy { - private val numberPool: IntRange = Lotto.MIN_NUMBER..Lotto.MAX_NUMBER + private val numberPool: IntRange = LottoNumber.MIN_NUMBER..LottoNumber.MAX_NUMBER override fun generate(): Lotto { val numbers = numberPool.shuffled() .subList(0, Lotto.NUMBERS_COUNT) diff --git a/src/main/kotlin/lotto/domain/Lotto.kt b/src/main/kotlin/lotto/domain/Lotto.kt index 8d4fa5bda4..f5fa393cef 100644 --- a/src/main/kotlin/lotto/domain/Lotto.kt +++ b/src/main/kotlin/lotto/domain/Lotto.kt @@ -3,18 +3,6 @@ package lotto.domain class Lotto( val numbers: LottoNumbers, ) { - init { - require(numbers.size == NUMBERS_COUNT) { - "로또 번호는 항상 ${NUMBERS_COUNT}개 여야 합니다." - } - require(!numbers.hasDuplicate()) { - "로또 번호는 중복이 없어야 합니다." - } - require(numbers.isSorted()) { - "로또 번호는 항상 정렬되어야 합니다." - } - } - fun match(winningLotto: WinningLotto): MatchedLotto { val correctCount = winningLotto.lotto.numbers.containsCount(numbers) val matchBonus = numbers.contains(winningLotto.bonusNumber) @@ -24,8 +12,6 @@ class Lotto( companion object { const val NUMBERS_COUNT = 6 - const val MIN_NUMBER = 1 - const val MAX_NUMBER = 45 fun of(numbers: List): Lotto { val lottoNumbers = LottoNumbers(numbers.map { LottoNumber(it) }) diff --git a/src/main/kotlin/lotto/domain/LottoNumber.kt b/src/main/kotlin/lotto/domain/LottoNumber.kt index 7f58f411d0..735eace1dd 100644 --- a/src/main/kotlin/lotto/domain/LottoNumber.kt +++ b/src/main/kotlin/lotto/domain/LottoNumber.kt @@ -3,12 +3,17 @@ package lotto.domain @JvmInline value class LottoNumber(val value: Int) : Comparable { init { - require(value in Lotto.MIN_NUMBER..Lotto.MAX_NUMBER) { - "로또 번호는 항상 ${Lotto.MIN_NUMBER}에서 ${Lotto.MAX_NUMBER}사이 값이어야 합니다." + require(value in MIN_NUMBER..MAX_NUMBER) { + "로또 번호는 항상 ${MIN_NUMBER}에서 ${MAX_NUMBER}사이 값이어야 합니다." } } override fun compareTo(other: LottoNumber): Int { return value.compareTo(other.value) } + + companion object { + const val MIN_NUMBER = 1 + const val MAX_NUMBER = 45 + } } diff --git a/src/main/kotlin/lotto/domain/LottoNumbers.kt b/src/main/kotlin/lotto/domain/LottoNumbers.kt index f54137f13c..7c3f151844 100644 --- a/src/main/kotlin/lotto/domain/LottoNumbers.kt +++ b/src/main/kotlin/lotto/domain/LottoNumbers.kt @@ -2,6 +2,19 @@ package lotto.domain @JvmInline value class LottoNumbers(private val value: List) { + + init { + require(value.size == Lotto.NUMBERS_COUNT) { + "로또 번호는 항상 ${Lotto.NUMBERS_COUNT}개 여야 합니다." + } + require(!hasDuplicate()) { + "로또 번호는 중복이 없어야 합니다." + } + require(isSorted()) { + "로또 번호는 항상 정렬되어야 합니다." + } + } + val size: Int get() = value.size @@ -16,11 +29,11 @@ value class LottoNumbers(private val value: List) { return value.count { other.value.contains(it) } } - fun hasDuplicate(): Boolean { + private fun hasDuplicate(): Boolean { return value.distinct() != value } - fun isSorted(): Boolean { + private fun isSorted(): Boolean { return value.map { it.value } .zipWithNext { a, b -> a <= b } .all { it } diff --git a/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt b/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt index 8aeab3a8c2..51cb2b973d 100644 --- a/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt +++ b/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt @@ -19,7 +19,7 @@ class AutoLottoGenerateStrategyTest { val lotto = autoLottoGenerateStrategy.generate() - assertThat(lotto.numbers.hasDuplicate()).isFalse + assertThat(lotto.numbers.numbers.distinct().size).isEqualTo(6) } @Test @@ -28,6 +28,6 @@ class AutoLottoGenerateStrategyTest { val lotto = autoLottoGenerateStrategy.generate() - assertThat(lotto.numbers.isSorted()).isTrue + assertThat(lotto.numbers.numbers).isSorted } } diff --git a/src/test/kotlin/lotto/domain/LottoNumberTest.kt b/src/test/kotlin/lotto/domain/LottoNumberTest.kt new file mode 100644 index 0000000000..20bc6b31e1 --- /dev/null +++ b/src/test/kotlin/lotto/domain/LottoNumberTest.kt @@ -0,0 +1,15 @@ +package lotto.domain + +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource + +class LottoNumberTest { + @ValueSource(ints = [0, 46]) + @ParameterizedTest + fun `로또 번호는 1과 45 사이의 값이 아니면 안된다`(number: Int) { + assertThrows { + LottoNumber(number) + } + } +} diff --git a/src/test/kotlin/lotto/domain/LottoNumbersTest.kt b/src/test/kotlin/lotto/domain/LottoNumbersTest.kt new file mode 100644 index 0000000000..6361ec0240 --- /dev/null +++ b/src/test/kotlin/lotto/domain/LottoNumbersTest.kt @@ -0,0 +1,43 @@ +package lotto.domain + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class LottoNumbersTest { + @Test + fun `로또 번호는 중복 없는 6개의 숫자로 만들 수 있다`() { + val numbers = listOf(1, 2, 3, 4, 5, 6) + + val lotto = LottoNumbers.of(numbers) + + assertThat(lotto.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) + } + + @Test + fun `로또 번호는 6개가 아니면 안된다`() { + val numbers = listOf(1) + + assertThrows { + LottoNumbers.of(numbers) + } + } + + @Test + fun `로또 번호는 중복이 있으면 안된다`() { + val numbers = listOf(1, 1, 1, 1, 1, 1) + + assertThrows { + LottoNumbers.of(numbers) + } + } + + @Test + fun `로또 번호는 정렬되어 있지 않으면 안된다`() { + val numbers = listOf(6, 5, 4, 3, 2, 1) + + assertThrows { + LottoNumbers.of(numbers) + } + } +} diff --git a/src/test/kotlin/lotto/domain/LottoTest.kt b/src/test/kotlin/lotto/domain/LottoTest.kt index 0511a20f48..7de743a873 100644 --- a/src/test/kotlin/lotto/domain/LottoTest.kt +++ b/src/test/kotlin/lotto/domain/LottoTest.kt @@ -1,84 +1,20 @@ package lotto.domain import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.MethodSource import java.util.stream.Stream class LottoTest { - @Test - fun `로또는 중복 없는 6개의 숫자로 만들 수 있다`() { - val numbers = listOf(1, 2, 3, 4, 5, 6) - - val lotto = Lotto.of(numbers) - - assertThat(lotto.numbers.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) - } - - @Test - fun `로또 번호가 6개가 아니면 안된다`() { - val numbers = listOf(1) - - assertThrows { - Lotto.of(numbers) - } - } - - @Test - fun `로또 번호는 중복이 있으면 안된다`() { - val numbers = listOf(1, 1, 1, 1, 1, 1) - - assertThrows { - Lotto.of(numbers) - } - } - - @Test - fun `보너스 번호도 다른 번호와 중복될 수 없다`() { - val numbers = listOf(1, 1, 1, 1, 1, 7) - - assertThrows { - Lotto.of(numbers) - } - } - - @Test - fun `로또 번호는 1보다 작은게 있으면 안된다`() { - val numbers = listOf(0, 1, 1, 1, 1, 1) - - assertThrows { - Lotto.of(numbers) - } - } - - @Test - fun `로또 번호는 45보다 크면 안된다`() { - val numbers = listOf(46, 1, 1, 1, 1, 1) - - assertThrows { - Lotto.of(numbers) - } - } - - @Test - fun `로또 번호는 정렬되어 있지 않으면 안된다`() { - val numbers = listOf(6, 5, 4, 3, 2, 1) - - assertThrows { - Lotto.of(numbers) - } - } @ParameterizedTest @MethodSource("provideLotto") - fun `당첨 번호가 포함되어있으면 Winning 값을 변경해준다`(lotto: Lotto, expectedWinning: LottoWinning) { + fun `번호를 매치하면 MatchedLotto로 변경된다`(lotto: Lotto, expectedWinning: LottoWinning) { val winningLotto = WinningLotto(Lotto.of(listOf(1, 2, 3, 4, 5, 6)), LottoNumber(7)) - val checkedLotto = lotto.match(winningLotto) + val matchedLotto = lotto.match(winningLotto) - val actualWinning = checkedLotto.winning + val actualWinning = matchedLotto.winning assertThat(actualWinning).isEqualTo(expectedWinning) } diff --git a/src/test/kotlin/lotto/domain/WinningLottoTest.kt b/src/test/kotlin/lotto/domain/WinningLottoTest.kt new file mode 100644 index 0000000000..c6b82b13fc --- /dev/null +++ b/src/test/kotlin/lotto/domain/WinningLottoTest.kt @@ -0,0 +1,16 @@ +package lotto.domain + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class WinningLottoTest { + @Test + fun `보너스 번호는 다른 로또 번호와 중복될 수 없다`() { + val numbers = listOf(1, 2, 3, 4, 5, 6) + val lotto = Lotto.of(numbers) + + assertThrows { + WinningLotto(lotto, LottoNumber(1)) + } + } +} From 6fc44fc8226fcbe4bcbc7b2b897a88d98e67f09a Mon Sep 17 00:00:00 2001 From: dean Date: Sat, 2 Dec 2023 21:19:58 +0900 Subject: [PATCH 6/7] =?UTF-8?q?LottoMatcher=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/lotto/Main.kt | 3 +-- src/main/kotlin/lotto/domain/LottoMatcher.kt | 7 ------- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 src/main/kotlin/lotto/domain/LottoMatcher.kt diff --git a/src/main/kotlin/lotto/Main.kt b/src/main/kotlin/lotto/Main.kt index 7e206cc887..e4c2ab1371 100644 --- a/src/main/kotlin/lotto/Main.kt +++ b/src/main/kotlin/lotto/Main.kt @@ -2,7 +2,6 @@ package lotto import lotto.domain.AutoLottoGenerateStrategy import lotto.domain.Lotto -import lotto.domain.LottoMatcher import lotto.domain.LottoNumber import lotto.domain.LottoNumbers import lotto.domain.LottoStore @@ -37,7 +36,7 @@ fun main() { ResultView.showBoughtLottos(boughtLottos, boughtManualLottoCounts) val winningLotto = WinningLotto(Lotto.of(InputView.inputWinningNumbers()), LottoNumber(InputView.inputBonusNumber())) - val matchedLotto = LottoMatcher.matchAll(boughtLottos, winningLotto) + val matchedLotto = boughtLottos.matchAll(winningLotto) val returnRate = matchedLotto.totalReward() / money.toDouble() diff --git a/src/main/kotlin/lotto/domain/LottoMatcher.kt b/src/main/kotlin/lotto/domain/LottoMatcher.kt deleted file mode 100644 index 810175a31f..0000000000 --- a/src/main/kotlin/lotto/domain/LottoMatcher.kt +++ /dev/null @@ -1,7 +0,0 @@ -package lotto.domain - -object LottoMatcher { - fun matchAll(lottos: Lottos, winningLotto: WinningLotto): MatchedLottos { - return lottos.matchAll(winningLotto) - } -} From 93c0bc29ddcf25c45edd2243906671b3e1c57f28 Mon Sep 17 00:00:00 2001 From: dean Date: Sat, 2 Dec 2023 21:29:43 +0900 Subject: [PATCH 7/7] =?UTF-8?q?LottoGenerateStrategy=20->=20LottoNumbersGe?= =?UTF-8?q?nerateStrategy=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/lotto/Main.kt | 11 +++---- .../lotto/domain/AutoLottoGenerateStrategy.kt | 12 ------- .../AutoLottoNumbersGenerateStrategy.kt | 12 +++++++ .../lotto/domain/LottoGenerateStrategy.kt | 5 --- .../kotlin/lotto/domain/LottoGenerator.kt | 4 +-- .../domain/LottoNumbersGenerateStrategy.kt | 5 +++ src/main/kotlin/lotto/domain/LottoStore.kt | 8 ++--- .../domain/ManualLottoGenerateStrategy.kt | 9 ----- .../ManualLottoNumbersGenerateStrategy.kt | 9 +++++ .../domain/AutoLottoGenerateStrategyTest.kt | 33 ------------------- .../kotlin/lotto/domain/LottoGeneratorTest.kt | 8 ++--- .../kotlin/lotto/domain/LottoNumbersTest.kt | 10 ------ .../kotlin/lotto/domain/LottoStoreTest.kt | 4 +-- 13 files changed, 43 insertions(+), 87 deletions(-) delete mode 100644 src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt create mode 100644 src/main/kotlin/lotto/domain/AutoLottoNumbersGenerateStrategy.kt delete mode 100644 src/main/kotlin/lotto/domain/LottoGenerateStrategy.kt create mode 100644 src/main/kotlin/lotto/domain/LottoNumbersGenerateStrategy.kt delete mode 100644 src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt create mode 100644 src/main/kotlin/lotto/domain/ManualLottoNumbersGenerateStrategy.kt delete mode 100644 src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt diff --git a/src/main/kotlin/lotto/Main.kt b/src/main/kotlin/lotto/Main.kt index e4c2ab1371..39ffbb9b86 100644 --- a/src/main/kotlin/lotto/Main.kt +++ b/src/main/kotlin/lotto/Main.kt @@ -1,12 +1,11 @@ package lotto -import lotto.domain.AutoLottoGenerateStrategy +import lotto.domain.AutoLottoNumbersGenerateStrategy import lotto.domain.Lotto import lotto.domain.LottoNumber -import lotto.domain.LottoNumbers import lotto.domain.LottoStore import lotto.domain.Lottos -import lotto.domain.ManualLottoGenerateStrategy +import lotto.domain.ManualLottoNumbersGenerateStrategy import lotto.domain.WinningLotto import lotto.ui.InputView import lotto.ui.ResultView @@ -24,12 +23,12 @@ fun main() { } val manualLottos = List(boughtManualLottoCounts) { - val lottoNumbers = LottoNumbers.of(InputView.inputManualLottoNumber()) + val lottoNumbers = InputView.inputManualLottoNumber() - store.buyLotto(ManualLottoGenerateStrategy(lottoNumbers)) + store.buyLotto(ManualLottoNumbersGenerateStrategy(lottoNumbers)) }.let { Lottos(it) } - val autoLottos = store.buyLottos(money - manualLottosPrice, AutoLottoGenerateStrategy()) + val autoLottos = store.buyLottos(money - manualLottosPrice, AutoLottoNumbersGenerateStrategy()) val boughtLottos = manualLottos + autoLottos diff --git a/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt b/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt deleted file mode 100644 index adb37f7c51..0000000000 --- a/src/main/kotlin/lotto/domain/AutoLottoGenerateStrategy.kt +++ /dev/null @@ -1,12 +0,0 @@ -package lotto.domain - -class AutoLottoGenerateStrategy : LottoGenerateStrategy { - private val numberPool: IntRange = LottoNumber.MIN_NUMBER..LottoNumber.MAX_NUMBER - override fun generate(): Lotto { - val numbers = numberPool.shuffled() - .subList(0, Lotto.NUMBERS_COUNT) - .sorted() - - return Lotto.of(numbers) - } -} diff --git a/src/main/kotlin/lotto/domain/AutoLottoNumbersGenerateStrategy.kt b/src/main/kotlin/lotto/domain/AutoLottoNumbersGenerateStrategy.kt new file mode 100644 index 0000000000..8140fe7663 --- /dev/null +++ b/src/main/kotlin/lotto/domain/AutoLottoNumbersGenerateStrategy.kt @@ -0,0 +1,12 @@ +package lotto.domain + +class AutoLottoNumbersGenerateStrategy : LottoNumbersGenerateStrategy { + private val numberPool: IntRange = LottoNumber.MIN_NUMBER..LottoNumber.MAX_NUMBER + override fun generate(): LottoNumbers { + return numberPool + .shuffled() + .subList(0, Lotto.NUMBERS_COUNT) + .sorted() + .let { LottoNumbers.of(it) } + } +} diff --git a/src/main/kotlin/lotto/domain/LottoGenerateStrategy.kt b/src/main/kotlin/lotto/domain/LottoGenerateStrategy.kt deleted file mode 100644 index 6b7b8259f4..0000000000 --- a/src/main/kotlin/lotto/domain/LottoGenerateStrategy.kt +++ /dev/null @@ -1,5 +0,0 @@ -package lotto.domain - -fun interface LottoGenerateStrategy { - fun generate(): Lotto -} diff --git a/src/main/kotlin/lotto/domain/LottoGenerator.kt b/src/main/kotlin/lotto/domain/LottoGenerator.kt index a4219a727d..e103ef55c7 100644 --- a/src/main/kotlin/lotto/domain/LottoGenerator.kt +++ b/src/main/kotlin/lotto/domain/LottoGenerator.kt @@ -1,7 +1,7 @@ package lotto.domain class LottoGenerator { - fun publish(lottoGenerateStrategy: LottoGenerateStrategy): Lotto { - return lottoGenerateStrategy.generate() + fun publish(lottoNumbersGenerateStrategy: LottoNumbersGenerateStrategy): Lotto { + return Lotto(lottoNumbersGenerateStrategy.generate()) } } diff --git a/src/main/kotlin/lotto/domain/LottoNumbersGenerateStrategy.kt b/src/main/kotlin/lotto/domain/LottoNumbersGenerateStrategy.kt new file mode 100644 index 0000000000..81233af66c --- /dev/null +++ b/src/main/kotlin/lotto/domain/LottoNumbersGenerateStrategy.kt @@ -0,0 +1,5 @@ +package lotto.domain + +fun interface LottoNumbersGenerateStrategy { + fun generate(): LottoNumbers +} diff --git a/src/main/kotlin/lotto/domain/LottoStore.kt b/src/main/kotlin/lotto/domain/LottoStore.kt index 1d50537f91..740d7ef4d3 100644 --- a/src/main/kotlin/lotto/domain/LottoStore.kt +++ b/src/main/kotlin/lotto/domain/LottoStore.kt @@ -3,14 +3,14 @@ package lotto.domain class LottoStore { private val lottoGenerator = LottoGenerator() - fun buyLotto(lottoGenerateStrategy: LottoGenerateStrategy): Lotto { - return lottoGenerator.publish(lottoGenerateStrategy) + fun buyLotto(lottoNumbersGenerateStrategy: LottoNumbersGenerateStrategy): Lotto { + return lottoGenerator.publish(lottoNumbersGenerateStrategy) } - fun buyLottos(money: Int, lottoGenerateStrategy: LottoGenerateStrategy): Lottos { + fun buyLottos(money: Int, lottoNumbersGenerateStrategy: LottoNumbersGenerateStrategy): Lottos { val lottoCount = money / LOTTO_PRICE val lottos = List(lottoCount) { - lottoGenerator.publish(lottoGenerateStrategy) + lottoGenerator.publish(lottoNumbersGenerateStrategy) } return Lottos(lottos) diff --git a/src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt b/src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt deleted file mode 100644 index a0e7d709f5..0000000000 --- a/src/main/kotlin/lotto/domain/ManualLottoGenerateStrategy.kt +++ /dev/null @@ -1,9 +0,0 @@ -package lotto.domain - -class ManualLottoGenerateStrategy( - private val lottoNumbers: LottoNumbers -) : LottoGenerateStrategy { - override fun generate(): Lotto { - return Lotto(lottoNumbers) - } -} diff --git a/src/main/kotlin/lotto/domain/ManualLottoNumbersGenerateStrategy.kt b/src/main/kotlin/lotto/domain/ManualLottoNumbersGenerateStrategy.kt new file mode 100644 index 0000000000..a52ec6b491 --- /dev/null +++ b/src/main/kotlin/lotto/domain/ManualLottoNumbersGenerateStrategy.kt @@ -0,0 +1,9 @@ +package lotto.domain + +class ManualLottoNumbersGenerateStrategy( + private val lottoNumbers: List, +) : LottoNumbersGenerateStrategy { + override fun generate(): LottoNumbers { + return LottoNumbers.of(lottoNumbers) + } +} diff --git a/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt b/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt deleted file mode 100644 index 51cb2b973d..0000000000 --- a/src/test/kotlin/lotto/domain/AutoLottoGenerateStrategyTest.kt +++ /dev/null @@ -1,33 +0,0 @@ -package lotto.domain - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class AutoLottoGenerateStrategyTest { - @Test - fun `번호를 6개가진 로또를 생성한다`() { - val autoLottoGenerateStrategy = AutoLottoGenerateStrategy() - - val lotto = autoLottoGenerateStrategy.generate() - - assertThat(lotto.numbers.size).isEqualTo(6) - } - - @Test - fun `중복된 번호가 생성되지 않는다`() { - val autoLottoGenerateStrategy = AutoLottoGenerateStrategy() - - val lotto = autoLottoGenerateStrategy.generate() - - assertThat(lotto.numbers.numbers.distinct().size).isEqualTo(6) - } - - @Test - fun `번호는 정렬되어 생성된다`() { - val autoLottoGenerateStrategy = AutoLottoGenerateStrategy() - - val lotto = autoLottoGenerateStrategy.generate() - - assertThat(lotto.numbers.numbers).isSorted - } -} diff --git a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt index 3fb322613f..d48d679a79 100644 --- a/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt +++ b/src/test/kotlin/lotto/domain/LottoGeneratorTest.kt @@ -5,13 +5,13 @@ import org.junit.jupiter.api.Test class LottoGeneratorTest { @Test - fun `특정 규칙으로 로또를 발행할 수 있다`() { - val lottoGenerateStrategy = LottoGenerateStrategy { - Lotto.of(listOf(1, 2, 3, 4, 5, 6)) + fun `특정 규칙으로 로또번호를 발행할 수 있다`() { + val lottoNumbersGenerateStrategy = LottoNumbersGenerateStrategy { + LottoNumbers.of(listOf(1, 2, 3, 4, 5, 6)) } val generator = LottoGenerator() - val lotto = generator.publish(lottoGenerateStrategy) + val lotto = generator.publish(lottoNumbersGenerateStrategy) assertThat(lotto.numbers.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) } diff --git a/src/test/kotlin/lotto/domain/LottoNumbersTest.kt b/src/test/kotlin/lotto/domain/LottoNumbersTest.kt index 6361ec0240..f19238a4c0 100644 --- a/src/test/kotlin/lotto/domain/LottoNumbersTest.kt +++ b/src/test/kotlin/lotto/domain/LottoNumbersTest.kt @@ -1,19 +1,9 @@ package lotto.domain -import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows class LottoNumbersTest { - @Test - fun `로또 번호는 중복 없는 6개의 숫자로 만들 수 있다`() { - val numbers = listOf(1, 2, 3, 4, 5, 6) - - val lotto = LottoNumbers.of(numbers) - - assertThat(lotto.numbers).isEqualTo(listOf(1, 2, 3, 4, 5, 6)) - } - @Test fun `로또 번호는 6개가 아니면 안된다`() { val numbers = listOf(1) diff --git a/src/test/kotlin/lotto/domain/LottoStoreTest.kt b/src/test/kotlin/lotto/domain/LottoStoreTest.kt index 2d6bab9b5e..b7a05bac36 100644 --- a/src/test/kotlin/lotto/domain/LottoStoreTest.kt +++ b/src/test/kotlin/lotto/domain/LottoStoreTest.kt @@ -16,10 +16,10 @@ class LottoStoreTest { ] ) fun `로또는 1000원당 한 장을 살 수 있다`(money: Int, lottoCount: Int) { - val lottoGenerateStrategy = LottoGenerateStrategy { Lotto.of(listOf(1, 2, 3, 4, 5, 6)) } + val lottoNumbersGenerateStrategy = LottoNumbersGenerateStrategy { LottoNumbers.of(listOf(1, 2, 3, 4, 5, 6)) } val lottoStore = LottoStore() - val lottos = lottoStore.buyLottos(money, lottoGenerateStrategy) + val lottos = lottoStore.buyLottos(money, lottoNumbersGenerateStrategy) assertThat(lottos.value.size).isEqualTo(lottoCount) }