Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸš€ 3단계 - 둜또(2λ“±) #1141

Open
wants to merge 20 commits into
base: sjjeong
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
20d2f4b
refactor: LottoPreset λ§Œλ“€κΈ°
sjjeong Jan 7, 2025
d7f1b78
refactor: Lotto의 lottoNumbersλ₯Ό Set으둜 λ³€κ²½
sjjeong Jan 7, 2025
4d39584
refactor: 45λΌλŠ” λ§€μ§λ„˜λ²„λ₯Ό μƒμˆ˜λ‘œ μΆ”μΆœ
sjjeong Jan 7, 2025
1dbdff1
refactor: 도메인 λ‘œμ§μ—μ„œ λ·° μ˜μ‘΄μ„± 제거
sjjeong Jan 7, 2025
17ffe03
refactor: domain μ„±κ²©μ˜ ν΄λž˜μŠ€λ“€ νŒ¨ν‚€μ§€ 이동
sjjeong Jan 7, 2025
cc4ec52
refactor: LottosλΌλŠ” 일급 μ»¬λ ‰μ…˜ μΆ”κ°€
sjjeong Jan 7, 2025
703f515
refactor: Input을 μœ„ν•΄ Output으둜 좜λ ₯ν•˜λŠ” λ‘œμ§μ„ 이동
sjjeong Jan 7, 2025
764631a
refactor: λ‹Ήμ²¨λ²ˆν˜Έ μž…λ ₯의 λ°˜ν™˜νƒ€μž… λ³€κ²½
sjjeong Jan 7, 2025
c6c5237
feat: λ³΄λ„ˆμŠ€λ³Ό 2λ“± κΈ°λŠ₯ μΆ”κ°€
sjjeong Jan 7, 2025
7176b68
feat: μΆœμ„ν•˜λŠ” μˆœμ„œ λ³€κ²½
sjjeong Jan 7, 2025
414e25e
fix: LottoResult.totalPrizeMoney νƒ€μž…μ„ Long으둜 λ³€κ²½
sjjeong Jan 7, 2025
aabe9dc
test: PrizeTest에 당첨 개수 ν…ŒμŠ€νŠΈ μΆ”κ°€
sjjeong Jan 8, 2025
02afe69
refactor: Companion Object Factory Functions 으둜 λ³€κ²½
sjjeong Jan 20, 2025
63e5a3a
refactor: Companion Object Factory Functions 으둜 λ³€κ²½
sjjeong Jan 20, 2025
bca0683
refactor: Lottos둜 ν•¨μˆ˜ 이동
sjjeong Jan 20, 2025
f6e9af8
refactor: method reference μ‚¬μš©
sjjeong Jan 20, 2025
427d34e
refactor: ν•¨μˆ˜ μ²΄μ΄λ‹μ—μ„œ κ°œν–‰ μΆ”κ°€
sjjeong Jan 20, 2025
8800291
refactor: ParameterizedTest둜 λ³€κ²½
sjjeong Jan 20, 2025
5b3d260
test: PrizeTest에 μΌ€μ΄μŠ€ μΆ”κ°€
sjjeong Jan 20, 2025
c665edb
refactor: rangeλ₯Ό companion object둜 μΆ”μΆœ
sjjeong Jan 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions src/main/kotlin/lotto/Lotto.kt

This file was deleted.

12 changes: 0 additions & 12 deletions src/main/kotlin/lotto/LottoNumber.kt

This file was deleted.

31 changes: 0 additions & 31 deletions src/main/kotlin/lotto/LottoResult.kt

This file was deleted.

16 changes: 0 additions & 16 deletions src/main/kotlin/lotto/LottoVendingMachine.kt

This file was deleted.

17 changes: 0 additions & 17 deletions src/main/kotlin/lotto/Prize.kt

This file was deleted.

19 changes: 9 additions & 10 deletions src/main/kotlin/lotto/application/LottoApplication.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package lotto.application

import lotto.Lotto
import lotto.LottoResult
import lotto.LottoVendingMachine
import lotto.domain.Lotto
import lotto.domain.LottoNumber
import lotto.domain.Lottos
import lotto.view.InputView
import lotto.view.OutputView

Expand All @@ -12,18 +12,17 @@ class LottoApplication(
) {

fun run() {
outputView.showInputMoneyMessage()
val money = inputView.inputMoney()
val lotto = LottoVendingMachine.buyLotto(money)
val lotto = Lottos.buyLotto(money)
outputView.showLottoCount(lotto)
outputView.showLotto(lotto)

outputView.showInputWinningNumbersMessage()
val winningNumbers: List<Int> = inputView.inputWinningNumbers()
val winningLotto: Lotto = inputView.inputWinningNumbers()
val bonusNumber: LottoNumber = inputView.inputBonusNumber()

val lottoResult= LottoResult.makeLottoResult(
winningLotto = Lotto(*winningNumbers.toIntArray()),
lottos = lotto,
val lottoResult = lotto.getResult(
winningLotto = winningLotto,
bonusLottoNumber = bonusNumber
)
outputView.showResult(lottoResult, money)
}
Expand Down
35 changes: 35 additions & 0 deletions src/main/kotlin/lotto/domain/Lotto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package lotto.domain

class Lotto private constructor(val lottoNumbers: Set<LottoNumber>) {

init {
val lottoNumbersSize = lottoNumbers.size
require(lottoNumbersSize == LOTTO_SIZE)
}

constructor() : this(
LottoPreset.shuffled()
.take(6)
.sortedBy { it.number }
.toSet()
)

constructor(vararg number: Int) : this(
number.map(::LottoNumber)
.toSet()
)

fun countMatch(winningLotto: Lotto): Int {
return lottoNumbers.intersect(winningLotto.lottoNumbers)
.count()
}

operator fun contains(lottoNumber: LottoNumber): Boolean {
return lottoNumber in lottoNumbers
}

companion object {
private val LottoPreset = List(LottoNumber.END_LOTTO_NUMBER) { LottoNumber(it + 1) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ—¬λŸ¬ 번 μΈμŠ€ν„΄μŠ€ν™”ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” 객체에 λŒ€ν•΄ κ³ λ €ν•΄μ£Όμ…¨λ„€μš” πŸ‘

private const val LOTTO_SIZE = 6
}
}
14 changes: 14 additions & 0 deletions src/main/kotlin/lotto/domain/LottoNumber.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package lotto.domain

@JvmInline
value class LottoNumber(val number: Int) {
init {
require(number in lottoNumberRange)
}

companion object {
const val START_LOTTO_NUMBER = 1
const val END_LOTTO_NUMBER = 45
val lottoNumberRange = START_LOTTO_NUMBER..END_LOTTO_NUMBER
}
}
18 changes: 18 additions & 0 deletions src/main/kotlin/lotto/domain/LottoResult.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package lotto.domain

class LottoResult(private val result: Map<Prize, Int>) : Map<Prize, Int> by result {
private val totalPrizeMoney: Long
get() {
return result.map {
it.key.money.toLong() * it.value
}.sum()
}

override fun get(key: Prize): Int {
return result[key] ?: 0
}

fun getRateOfReturn(money: Int): Float {
return totalPrizeMoney.toFloat() / money
}
}
31 changes: 31 additions & 0 deletions src/main/kotlin/lotto/domain/Lottos.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package lotto.domain

class Lottos(lottos: List<Lotto>) {
val lottos: List<Lotto> = lottos.toList()

fun getResult(
winningLotto: Lotto,
bonusLottoNumber: LottoNumber,
): LottoResult {
val result = lottos.groupingBy { lotto ->
val matchCount = lotto.countMatch(winningLotto)
Prize.of(matchCount = matchCount, bonusLottoNumber = bonusLottoNumber, lotto = lotto)
}.eachCount()
return LottoResult(result)
}

companion object {
private const val LOTTO_PRICE = 1000

fun buyLotto(money: Int?): Lottos {
requireNotNull(money) {
"ꡬ맀 κΈˆμ•‘μ€ null이 μ•„λ‹ˆμ–΄μ•Ό 함"
}
require(money >= LOTTO_PRICE) {
"ꡬ맀 κΈˆμ•‘μ€ 1000 보닀 컀야 함"
}

return Lottos(List(money / LOTTO_PRICE) { Lotto() })
}
}
}
21 changes: 21 additions & 0 deletions src/main/kotlin/lotto/domain/Prize.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package lotto.domain

enum class Prize(val money: Int, val count: Int) {
FIRST(2_000_000_000, 6),
SECOND(30_000_000, 5),
THIRD(1_500_000, 5),
FOURTH(50_000, 4),
FIFTH(5_000, 3),
NONE(0, 0),
;

companion object {
fun of(matchCount: Int, bonusLottoNumber: LottoNumber, lotto: Lotto) = when (matchCount) {
6 -> FIRST
5 -> if (bonusLottoNumber in lotto) SECOND else THIRD
4 -> FOURTH
3 -> FIFTH
else -> NONE
}
}
}
19 changes: 17 additions & 2 deletions src/main/kotlin/lotto/view/InputView.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
package lotto.view

import lotto.domain.Lotto
import lotto.domain.LottoNumber

class InputView {
fun inputMoney(): Int {
println("κ΅¬μž…κΈˆμ•‘μ„ μž…λ ₯ν•΄ μ£Όμ„Έμš”.")
val input = readlnOrNull()?.toIntOrNull()
requireNotNull(input)
return input
}

fun inputWinningNumbers(): List<Int> {
return readlnOrNull()?.split(",")?.map { it.trim().toInt() } ?: emptyList()
fun inputWinningNumbers(): Lotto {
println("μ§€λ‚œ μ£Ό 당첨 번호λ₯Ό μž…λ ₯ν•΄ μ£Όμ„Έμš”.")
val winningNumbers: List<Int> = readlnOrNull()?.split(",")
?.map {
it.trim()
.toInt()
} ?: emptyList()
return Lotto(*winningNumbers.toIntArray())
}

fun inputBonusNumber(): LottoNumber {
println("λ³΄λ„ˆμŠ€ 볼을 μž…λ ₯ν•΄ μ£Όμ„Έμš”.")
return LottoNumber(readlnOrNull()?.toIntOrNull() ?: 0)
}
}
42 changes: 23 additions & 19 deletions src/main/kotlin/lotto/view/OutputView.kt
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
package lotto.view

import lotto.Lotto
import lotto.LottoResult
import lotto.Prize
import lotto.domain.LottoResult
import lotto.domain.Lottos
import lotto.domain.Prize

class OutputView {
fun showInputMoneyMessage() {
println("κ΅¬μž…κΈˆμ•‘μ„ μž…λ ₯ν•΄ μ£Όμ„Έμš”.")
fun showLottoCount(lottos: Lottos) {
val size = lottos.lottos
.size
println("${size}개λ₯Ό κ΅¬λ§€ν–ˆμŠ΅λ‹ˆλ‹€.")
}

fun showLottoCount(lotto: List<Lotto>) {
println("${lotto.size}개λ₯Ό κ΅¬λ§€ν–ˆμŠ΅λ‹ˆλ‹€.")
}

fun showLotto(lotto: List<Lotto>) {
lotto.forEach {
println(it)
}
}

fun showInputWinningNumbersMessage() {
println("μ§€λ‚œ μ£Ό 당첨 번호λ₯Ό μž…λ ₯ν•΄ μ£Όμ„Έμš”.")
fun showLotto(lottos: Lottos) {
lottos.lottos
.forEach {
println(
"[${
it.lottoNumbers.map { lottoNumber -> lottoNumber.number }
.joinToString(", ")
}]")
}
}

fun showResult(lottoResult: LottoResult, money: Int) {
println("당첨 톡계")
println("---------")
Prize.entries
.filter { it != Prize.NONE }
.sortedByDescending { it.count }
.reversed()
.forEach { prize ->
println("${prize.count}개 일치 (${prize.money}원) - ${lottoResult[prize]}개")
val title = if (prize == Prize.SECOND) {
"${prize.count}개 일치, λ³΄λ„ˆμŠ€ λ³Ό 일치 (${prize.money}원)"
} else {
"${prize.count}개 일치 (${prize.money}원)"
}
println("$title - ${lottoResult[prize]}개")
}

println(String.format("총 수읡λ₯ μ€ %.2fμž…λ‹ˆλ‹€.", lottoResult.getRateOfReturn(money)))
Expand Down
1 change: 1 addition & 0 deletions src/test/kotlin/lotto/LottoNumberTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package lotto

import io.kotest.assertions.throwables.shouldNotThrow
import io.kotest.assertions.throwables.shouldThrow
import lotto.domain.LottoNumber
import org.junit.jupiter.api.Test

class LottoNumberTest {
Expand Down
Loading