-
Notifications
You must be signed in to change notification settings - Fork 357
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
Step2 로또 자동 #595
base: leehaeina
Are you sure you want to change the base?
Step2 로또 자동 #595
Changes from all commits
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 |
---|---|---|
@@ -1 +1,24 @@ | ||
# kotlin-lotto | ||
# kotlin-lotto | ||
|
||
## 자동 만들기 TODO | ||
### 1. Input View | ||
- [ ] 구입금액 입력받기 | ||
- [ ] 당첨번호 입력받기 | ||
|
||
### 2. Output View | ||
- [ ] 생성된 로또번호 출력하기 | ||
- [ ] 당첨통계 출력하기 | ||
|
||
### 3. Service | ||
- [X] 자동번호 등록하기 | ||
- [X] 랜덤번호 생성하기 | ||
- [X] 당첨번호 등록하기 | ||
- [x] 통계내기 - 당첨 개수 확인하기 | ||
- [ ] 통계내기 - 등수계산하기 | ||
- [ ] 통계내기 - 수익률계산하기 | ||
|
||
### 4. Domain | ||
- [ ] 로또번호 - 구매번호 | ||
- [ ] 로또번호 - 당첨번호 | ||
- [ ] input - 구입금액 | ||
- [ ] 통계 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import UI.InputView | ||
import UI.OutputView | ||
import domain.LottoInput | ||
import domain.WinningLotto | ||
import service.AutoNumberGenerator | ||
import service.CalculateWinningStatistic | ||
import service.RandomNumberGenerator | ||
import service.WinningNumberRegister | ||
|
||
class LottoController { | ||
fun start() { | ||
val inputView = InputView | ||
val outputView = OutputView | ||
|
||
val lottoInput = inputView.purchaseInputView() | ||
outputView.ticketCountView(lottoInput.purchaseCount!!) | ||
|
||
val randomNumberGenerator = RandomNumberGenerator(1, 45) | ||
val autoNumberGenerator = AutoNumberGenerator(randomNumberGenerator) | ||
val generatedLottos = autoNumberGenerator.saveAfterGenerate(lottoInput.purchaseCount) | ||
outputView.purchaseLottoView(generatedLottos) | ||
|
||
val winning = inputView.winningLottoInputView() | ||
lottoInput.of(LottoInput(winningLotto = winning)) | ||
|
||
val winningNumberRegister = WinningNumberRegister(randomNumberGenerator) | ||
val winningLotto = winningNumberRegister.register(lottoInput) | ||
|
||
outputView.statisticDividerView() | ||
|
||
val calculateWinningStatistic = CalculateWinningStatistic() | ||
val ranks = calculateWinningStatistic.calculateRank(generatedLottos, winningLotto) | ||
//output ranks statisticPrizeView | ||
val prize = calculateWinningStatistic.calculatePrize(ranks) | ||
val rate = calculateWinningStatistic.calculateRate(prize, lottoInput.purchaseAmount!!) | ||
outputView.statisticRateView(rate) | ||
|
||
|
||
} | ||
} | ||
|
||
fun main() { | ||
LottoController().start() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package UI | ||
|
||
import domain.LottoInput | ||
|
||
object InputView { | ||
|
||
fun purchaseInputView(): LottoInput { | ||
println("구입금액을 입력해 주세요.") | ||
val inputPrice = readln().trim() | ||
return LottoInput( | ||
purchaseAmount = inputPrice.toInt(), | ||
purchaseCount = inputPrice.toInt() / 1000 | ||
) | ||
} | ||
|
||
fun winningLottoInputView(): List<Int> { | ||
println("지난 주 당첨 번호를 입력해 주세요.") | ||
val input = readln().trim() | ||
return input.split(",").map { it.toInt() } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package UI | ||
|
||
import domain.LottoInput | ||
import domain.PurchasedLotto | ||
import domain.Rank | ||
|
||
object OutputView { | ||
|
||
fun ticketCountView(ticketCount: Int) { | ||
println("${ticketCount}개를 구매했습니다.") | ||
} | ||
|
||
fun purchaseLottoView(purchasedLottos: List<PurchasedLotto>) { | ||
purchasedLottos.forEach{ | ||
println(it.numbers.joinToString { "," }) | ||
} | ||
} | ||
|
||
fun statisticDividerView() { | ||
println("당첨 통계") | ||
println("---------") | ||
} | ||
|
||
fun statisticRateView(rate: Double) { | ||
print("총 수익률은 ${rate}입니다.") | ||
println("(기준이 1이기 때문에 결과적으로 ${if (rate >= 1) "이익" else "손해"}라는 의미임)") | ||
} | ||
|
||
fun statisticPrizeView(rank: Rank, winCount: Int) { | ||
println("${rank.matchedCount}개 일치 (${rank.prize}원) - ${winCount}개") | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package domain | ||
|
||
interface Lotto { | ||
val numbers: List<Int> | ||
Comment on lines
+3
to
+4
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. Int를 래핑해서 로또 번호 하나를 나타내는 객체를 만들어보는 것은 어떨까요? |
||
val winningCount: Int? | ||
} | ||
|
||
class PurchasedLotto(override val numbers: List<Int>, override val winningCount: Int = 0) : Lotto { | ||
fun calculateWinningCount(winningLotto: WinningLotto): Int{ | ||
return winningLotto.numbers.filter { | ||
this.numbers.contains(it) | ||
}.size | ||
} | ||
} | ||
|
||
class WinningLotto(override val numbers: List<Int>, override val winningCount: Int? = null) : Lotto | ||
Comment on lines
+8
to
+16
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,15 @@ | ||
package domain | ||
|
||
class LottoInput( | ||
val purchaseCount: Int? = 0, | ||
val purchaseAmount: Int? = 0, | ||
val winningLotto: List<Int>? = listOf() | ||
) { | ||
fun of(lottoInput: LottoInput): LottoInput { | ||
return LottoInput( | ||
purchaseCount = lottoInput.purchaseCount ?: this.purchaseCount, | ||
purchaseAmount = lottoInput.purchaseAmount ?: this.purchaseAmount, | ||
winningLotto = lottoInput.winningLotto ?: this.winningLotto | ||
) | ||
} | ||
Comment on lines
+3
to
+14
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,17 @@ | ||
package domain | ||
|
||
enum class Rank(val matchedCount: Int? = 0, val prize: Int = 0) { | ||
FAIL(null, 0), | ||
Comment on lines
+3
to
+4
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. enum class의 항목들이 이미 모든 값을 갖고 있기 때문에, default parameter를 갖지 않아도 되어 보입니다. |
||
FOURTH(3, 5000), | ||
THIRD(4, 50000), | ||
SECOND(5, 1500000), | ||
FIRST(6, 2000000000); | ||
Comment on lines
+7
to
+8
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 isNotBoom(): Boolean = this != FAIL | ||
|
||
companion object { | ||
fun find(matchedCount: Int): Rank { | ||
return values().find { it.matchedCount == matchedCount } ?: FAIL | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package domain | ||
|
||
class Statistic(val prize : Int, val rate: Double) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package service | ||
|
||
import domain.PurchasedLotto | ||
|
||
class AutoNumberGenerator( | ||
private val randomNumberGenerator: RandomNumberGenerator | ||
) { | ||
fun saveAfterGenerate(count: Int): List<PurchasedLotto>{ | ||
val result = mutableListOf<PurchasedLotto>() | ||
for(i:Int in 0 until count){ | ||
result.add(PurchasedLotto(randomNumberGenerator.getGeneratedNumber())) | ||
} | ||
return result | ||
Comment on lines
+9
to
+13
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등을 활용해보는 것은 어떨까요? |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package service | ||
|
||
import domain.PurchasedLotto | ||
import domain.Rank | ||
import domain.WinningLotto | ||
|
||
class CalculateWinningStatistic { | ||
fun calculateRank(candidate: List<PurchasedLotto>, winningLotto: WinningLotto): List<Rank> = | ||
candidate.map { Rank.find(it.calculateWinningCount(winningLotto)) } | ||
|
||
fun calculatePrize(ranks: List<Rank>): Int = | ||
Rank.values().fold(0) { totalPrize, nowRank -> totalPrize + nowRank.prize } | ||
|
||
fun calculateRate(prize: Int, purchase: Int): Double = | ||
prize.toDouble() / prize | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package service | ||
|
||
class RandomNumberGenerator(override val startNumber: Int, override val endNumber: Int) : | ||
NumberGenerator { | ||
override fun getGeneratedNumber(): List<Int> = | ||
(startNumber..endNumber).map { it }.shuffled().slice(0..5) | ||
} | ||
|
||
interface NumberGenerator { | ||
fun getGeneratedNumber(): List<Int> | ||
val startNumber: Int | ||
val endNumber: Int | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package service | ||
|
||
import domain.LottoInput | ||
import domain.WinningLotto | ||
|
||
class WinningNumberRegister( | ||
private val randomNumberGenerator: RandomNumberGenerator | ||
) { | ||
fun register(input : LottoInput): WinningLotto{ | ||
return WinningLotto(numbers = input.winningLotto!!) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import org.junit.jupiter.api.Test | ||
import service.AutoNumberGenerator | ||
import service.RandomNumberGenerator | ||
|
||
class AutoNumberGeneratorTest { | ||
|
||
var autoNumberGenerator: AutoNumberGenerator | ||
var randomNumberGenerator = RandomNumberGenerator(1,45) | ||
init { | ||
autoNumberGenerator = AutoNumberGenerator(randomNumberGenerator) | ||
} | ||
@Test | ||
fun `자동번호생성테스트`() { | ||
val result = autoNumberGenerator.saveAfterGenerate(3) | ||
for (i: Int in 0 until result.size) { | ||
println(result.get(i).numbers) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import domain.PurchasedLotto | ||
import domain.WinningLotto | ||
import org.junit.jupiter.api.Test | ||
|
||
class LottoTest { | ||
|
||
@Test | ||
fun `calculateWinningLottoTest`(){ | ||
val target = listOf<Int>(1,2,3,4,5,6) | ||
val winning = listOf<Int>(1,6,7,8,9,10) | ||
val winningLotto = WinningLotto(numbers = winning) | ||
val purchasedLotto = PurchasedLotto(numbers = target) | ||
val winningCount = purchasedLotto.calculateWinningCount(winningLotto) | ||
println(winningCount) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import org.junit.jupiter.api.Test | ||
import service.RandomNumberGenerator | ||
|
||
class RandomNumberGeneratorTest { | ||
|
||
@Test | ||
fun `랜덤하게`(){ | ||
val randomNumberGenerator = RandomNumberGenerator(1,45) | ||
println(randomNumberGenerator.getGeneratedNumber()) | ||
} | ||
} |
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.
object는 변수에 할당 없이 바로 접근해서 메서드를 호출해보는 것은 어떨까요?