-
Notifications
You must be signed in to change notification settings - Fork 0
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
[로또] 버디 미션 제출합니다. #12
base: stopmin-main
Are you sure you want to change the base?
Changes from all commits
437ff8e
eca1cb8
72d50b1
75473af
264e78a
db45d35
88644b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
.idea/workspace.xml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
package lotto | ||
|
||
fun main() { | ||
TODO("프로그램 구현") | ||
val lottoGame = LottoGame() | ||
lottoGame.run() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,28 @@ | ||
package lotto | ||
|
||
class Lotto(private val numbers: List<Int>) { | ||
class Lotto(val numbers: List<Number>) { | ||
init { | ||
require(numbers.size == 6) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. init()에서 중복 검사하면 중복 테스트 케이스 통과 할 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오~! 그렇군요 이거 그냥 예제코드에 있어서 그대로 썼는데 set도 꽤 좋은 것 같습니닷 |
||
} | ||
} | ||
|
||
enum class LottoPrize( | ||
val matchCount: Int, | ||
val prize: Int, | ||
val description: String, | ||
val isBonusMatched: Boolean = false | ||
) { | ||
THREE_MATCH(3, 5_000, "3개 일치 (5,000원)"), | ||
FOUR_MATCH(4, 50_000, "4개 일치 (50,000원)"), | ||
FIVE_MATCH(5, 1_500_000, "5개 일치 (1,500,000원)"), | ||
FIVE_PLUS_BONUS_MATCH(5, 30_000_000, "5개 일치, 보너스 볼 일치 (30,000,000원)", true), | ||
SIX_MATCH(6, 2_000_000_000, "6개 일치 (2,000,000,000원)"), | ||
LOSE(0, 0, "낙첨"); | ||
|
||
// TODO: 추가 기능 구현 | ||
companion object { | ||
fun findPrize(matchCount: Int, isBonusMatched: Boolean = false): LottoPrize { | ||
return entries.find { it.matchCount == matchCount && it.isBonusMatched == isBonusMatched } ?: LOSE | ||
} | ||
} | ||
Comment on lines
+15
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 간결하게 잘 구현하신 것 같아요 👍 |
||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package lotto | ||
|
||
import lotto.LottoPrize.Companion.findPrize | ||
|
||
|
||
class LottoGame { | ||
companion object { | ||
val lottoStore = LottoStore() | ||
} | ||
|
||
fun run() { | ||
val (purchasePrice, lottoCount) = lottoStore.receivePaymentForLotto() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. component N 사용하니 좋네요! 👍🏻 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저번에 빅터가 쓴거 보고 따라해봤습니닷 ㅎㅎ |
||
println("${lottoCount}개를 구매했습니다.") | ||
val generateLottoTickets = lottoStore.generateLottoTickets(lottoCount) | ||
|
||
printGenerateTickets(generateLottoTickets) | ||
|
||
val winningNumbers = lottoStore.askWinningNumbers() | ||
val bonusNumber = lottoStore.askBonusNumber() | ||
|
||
val (prizeList, prizeMoney) = checkPrizes(generateLottoTickets, winningNumbers, bonusNumber) | ||
val returnRate = getReturnRate(purchasePrice, prizeMoney) | ||
|
||
printGameResult(prizeList, returnRate) | ||
} | ||
|
||
private fun getReturnRate(purchasePrice: Int, prizeMoney: Long): Double = | ||
(prizeMoney.toDouble() / purchasePrice.toDouble() * 100.0) | ||
|
||
private fun printGameResult(prizeList: List<LottoPrize>, returnRate: Double) { | ||
println("당첨 통계") | ||
println("---") | ||
|
||
|
||
val result = prizeList.map { it.name }.groupingBy { it }.eachCount() | ||
|
||
listOf( | ||
LottoPrize.THREE_MATCH, | ||
LottoPrize.FOUR_MATCH, | ||
LottoPrize.FIVE_MATCH, | ||
LottoPrize.FIVE_PLUS_BONUS_MATCH, | ||
LottoPrize.SIX_MATCH, | ||
).map { o -> | ||
Comment on lines
+37
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 리스트를 생성하지 않아도 |
||
println("${o.description} - ${result.get(o.name) ?: 0}개") | ||
} | ||
|
||
println("총 수익률은 ${returnRate}%입니다.") | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 당첨 통계부분 간결하네요 ㄷㄷ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 엄 사실 map으로 사용한건 마음에 든다만 보름이 위에서 언급했듯이 굳이 리스트를 만든게 조금 문제였던 것 같아 좋은 코드인건 아닌 것 같네요 ㅠㅠㅠ 다음에 참고하실 때 보름님 말씀대로 |
||
|
||
private fun printGenerateTickets(generateLottoTickets: List<Lotto>) { | ||
for (generateLottoTicket in generateLottoTickets) { | ||
println(generateLottoTicket.numbers) | ||
} | ||
println() | ||
} | ||
} | ||
|
||
fun checkPrizes( | ||
generatedLottoTickets: List<Lotto>, | ||
winningNumbers: List<Int>, | ||
bonusNumber: Int | ||
): Pair<List<LottoPrize>, Long> { | ||
var prizeMoney: Long = 0 | ||
val prizeList = generatedLottoTickets.map { lotto -> | ||
val matchCount = lotto.numbers.count { it in winningNumbers } | ||
val isBonusMatched = bonusNumber in lotto.numbers | ||
findPrize(matchCount, isBonusMatched) | ||
} | ||
|
||
prizeList.forEach { o -> | ||
prizeMoney += o.prize | ||
} | ||
|
||
return Pair(prizeList, prizeMoney) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,96 @@ | ||||||
package lotto | ||||||
|
||||||
import camp.nextstep.edu.missionutils.Console | ||||||
import camp.nextstep.edu.missionutils.Randoms | ||||||
import java.lang.IllegalStateException | ||||||
import kotlin.jvm.Throws | ||||||
|
||||||
//import lotto.common.require | ||||||
|
||||||
class LottoStore { | ||||||
companion object { | ||||||
const val LOTTO_NUMBER_MIN = 1 | ||||||
const val LOTTO_NUMBER_MAX = 45 | ||||||
const val LOTTO_NUMBERS_PER_TICKET = 6 | ||||||
const val LOTTO_PRICE = 1000 | ||||||
Comment on lines
+12
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 상수 분리 👍👍👍 |
||||||
} | ||||||
|
||||||
fun receivePaymentForLotto(): Pair<Int, Int> { | ||||||
var purchasePrice: Int? | ||||||
println("구입급액을 입력해주세요.") | ||||||
do { | ||||||
val input = readLine() | ||||||
purchasePrice = input?.toIntOrNull() | ||||||
if (purchasePrice == null) { | ||||||
println("[ERROR] 숫자로 입력해야합니다.") | ||||||
throw NumberFormatException("[ERROR] 숫자로 입력해야합니다.") | ||||||
} else if (purchasePrice % LOTTO_PRICE != 0) { | ||||||
println("[ERROR] 숫자는 $LOTTO_PRICE(으)로 나누어 떨어져야 합니다.") | ||||||
purchasePrice = null // 입력이 유효하지 않으므로 null로 설정하여 다시 입력 받음 | ||||||
} | ||||||
// 유효한 입력을 받으면 자동으로 반복문에서 탈출 | ||||||
} while (purchasePrice == null) | ||||||
|
||||||
println() | ||||||
return Pair(purchasePrice!!, purchasePrice / LOTTO_PRICE) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
fun askWinningNumbers(): List<Int> { | ||||||
println("당첨 번호를 입력해주세요. 번호는 쉼표(,)로 구분하여 입력하세요:") | ||||||
var numbers: List<Int> | ||||||
do { | ||||||
numbers = readLine()?.split(",")?.mapNotNull { it.trim().toIntOrNull() } ?: emptyList() | ||||||
|
||||||
require(numbers.size == LOTTO_NUMBERS_PER_TICKET) { | ||||||
IllegalArgumentException("[ERROR] 정확히 $LOTTO_NUMBERS_PER_TICKET}개의 숫자를 입력해야 합니다.") | ||||||
} | ||||||
|
||||||
numbers.forEach { number -> | ||||||
require(number in LOTTO_NUMBER_MIN..LOTTO_NUMBER_MAX) { | ||||||
IllegalArgumentException("[ERROR] 숫자는 ${LOTTO_NUMBER_MIN}과 ${LOTTO_NUMBER_MAX} 사이여야 합니다.") | ||||||
} | ||||||
} | ||||||
} while (numbers.size != LOTTO_NUMBERS_PER_TICKET | ||||||
|| !numbers.all { it in LOTTO_NUMBER_MIN..LOTTO_NUMBER_MAX } | ||||||
) | ||||||
|
||||||
println() | ||||||
|
||||||
return numbers | ||||||
} | ||||||
|
||||||
fun askBonusNumber(): Int { | ||||||
println("보너스 번호를 입력해 주세요.") | ||||||
var bonusNumber: Int? | ||||||
do { | ||||||
try { | ||||||
bonusNumber = Console.readLine().toInt() | ||||||
check(bonusNumber in LOTTO_NUMBER_MIN..LOTTO_NUMBER_MAX) { NumberFormatException() } | ||||||
} catch (e: IllegalArgumentException) { | ||||||
bonusNumber = null | ||||||
println("[ERROR] 정확한 숫자 형식으로 입력해주세요.") | ||||||
} catch (e: IllegalStateException) { | ||||||
bonusNumber = null | ||||||
println("[ERROR] 숫자는 ${LOTTO_NUMBER_MIN}과 ${LOTTO_NUMBER_MAX} 사이여야 합니다.") | ||||||
} | ||||||
} while (bonusNumber !is Int) | ||||||
println() | ||||||
|
||||||
return bonusNumber!! | ||||||
} | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. askWinningNumbers()에서는 require를 사용하여 유효성을 검사하고 있지만, askBonusNumber()에서는 try-catch 구문을 사용하는데, 유효성 검사 방식을 통일하는 것은 어떨까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하!!! 맞네요!! 유효성 검사하는 방식을 통일시키고 뭔가 캡슐화 하는 것도 나쁘지 않을 것 같다는 생각이 듭니닷...!! 다음 미션에서는 반영해보겠습니다!! |
||||||
|
||||||
fun generateLottoTickets(count: Int): List<Lotto> { | ||||||
return List(count) { | ||||||
generateLotto() | ||||||
} | ||||||
} | ||||||
|
||||||
fun generateLotto() = Lotto(generateRandomNumbers(LOTTO_NUMBER_MIN, LOTTO_NUMBER_MAX, LOTTO_NUMBERS_PER_TICKET)) | ||||||
|
||||||
} | ||||||
|
||||||
|
||||||
fun generateRandomNumbers(startInclusive: Int, endInclusive: Int, count: Int): List<Number> = | ||||||
Randoms.pickUniqueNumbersInRange(startInclusive, endInclusive, count) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 에러코드를 분리하시려고 한 흔적이 보이네요!! 😆👍 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package lotto.common | ||
|
||
class ErrorCode { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
필드를 외부에 노출시키지 않도록, 캡슐화를 지키도록 코드 작성해보셔도 좋을 것 같습니다~!