-
Notifications
You must be signed in to change notification settings - Fork 320
[step4] 블랙잭 (베팅) & step3 코드리뷰 반영 #812
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
base: sarahan774
Are you sure you want to change the base?
Changes from 25 commits
dc0a080
0f27917
daa723b
4fd6961
126be39
ce186a3
8b26a92
ec35146
38c0b9d
995344b
3e26696
9944f63
17e1d6b
bf2dcc2
ae042c1
1ab98c9
6861336
d6ac32a
204492f
c2de14a
7f3f1ce
4ab56d9
4d5b3ca
8876e4b
e77f4f5
28a20fa
334f5d8
4a2a268
7c81404
3c5be6d
223331d
fde1866
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,23 @@ | ||
| package blackjack.domain | ||
|
|
||
| import java.math.BigDecimal | ||
| import java.math.RoundingMode | ||
|
|
||
| @JvmInline | ||
| value class BetMoney(private val amount: BigDecimal) { | ||
| fun getOriginalBetAmount(): BigDecimal { | ||
| return amount | ||
| } | ||
|
|
||
| fun getAmountOnBlackJack(): BigDecimal { | ||
| return amount.multiply((1.5).toBigDecimal()).setScale(0, RoundingMode.DOWN) | ||
| } | ||
|
|
||
| fun getAmountOnBust(): BigDecimal { | ||
| return -(amount) | ||
| } | ||
|
|
||
| fun getAmountOnLose(): BigDecimal { | ||
| return -(amount) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,51 @@ | ||
| package blackjack.domain | ||
|
|
||
| import java.math.BigDecimal | ||
|
|
||
| class Dealer( | ||
| private val drawCard: () -> Card, | ||
| ) : Participant(drawCard = drawCard) { | ||
| fun initPlayers( | ||
| fetchPlayerNames: () -> List<String>, | ||
| getBettingAmount: (String) -> BigDecimal, | ||
| onPlayerInit: (List<String>) -> Unit, | ||
| ): Players { | ||
| val names = fetchPlayerNames() | ||
| val players = names.map { name -> Player(name = name, drawCard = drawCard) } | ||
| val nameAndBets = names.associateWith(getBettingAmount) | ||
| val players = | ||
| Players( | ||
| nameAndBets.map { (name, bet) -> | ||
| Player( | ||
| name = name, | ||
| betMoney = BetMoney(bet), | ||
| drawCard = drawCard, | ||
| ) | ||
| }, | ||
| ) | ||
| onPlayerInit(names) | ||
| return Players(value = players) | ||
| return players | ||
| } | ||
|
|
||
| fun drawOneMoreCardIfNeeded(onDrawCard: () -> Unit) { | ||
| addCardIfAvailable(requireCard = { drawCard() }, onDrawCard = onDrawCard) | ||
| addCardIfAvailable(requireCard = drawCard, onDrawCard = onDrawCard) | ||
| } | ||
|
|
||
| override fun isAddCardEnabled(): Boolean { | ||
| return cardsSum <= 16 | ||
| return cardsSum <= DEALER_DRAW_ONE_MORE_CARD_THRESHOLD | ||
| } | ||
|
|
||
| fun getCardForInitialDisplay(): Card { | ||
| require(cards.value.isNotEmpty()) { "Dealer should be initialized with $DEALER_CARD_COUNT cards." } | ||
| return cards.value[0] | ||
| } | ||
|
|
||
| fun adjustProfit(playerProfit: ProfitMoney) { | ||
| val profit = profitMoney.getCurrentProfit() - playerProfit.getCurrentProfit() | ||
| profitMoney.set(profit) | ||
| } | ||
|
|
||
| companion object { | ||
| private const val DEALER_CARD_COUNT = 2 | ||
| private const val DEALER_DRAW_ONE_MORE_CARD_THRESHOLD = 16 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package blackjack.domain | ||
|
|
||
| enum class GameResult { | ||
| WIN, | ||
| BUST, | ||
| LOSE, | ||
| PUSH, | ||
| BLACK_JACK, | ||
| ; | ||
|
|
||
| companion object { | ||
| fun fromScores( | ||
| dealerScore: Int, | ||
| playerScore: Int, | ||
| ): GameResult { | ||
| return when { | ||
| dealerScore > Card.MAX_SUM -> WIN // Dealer bust | ||
| playerScore > Card.MAX_SUM -> BUST // Player bust | ||
| dealerScore > playerScore -> LOSE | ||
| playerScore > dealerScore -> WIN | ||
| else -> PUSH | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,53 @@ | ||
| package blackjack.domain | ||
|
|
||
| import java.math.BigDecimal | ||
|
|
||
| class Player( | ||
| val name: String, | ||
| private val betMoney: BetMoney, | ||
| private val drawCard: () -> Card, | ||
| ) : Participant(drawCard = drawCard) { | ||
| private lateinit var currentCard: Card | ||
|
|
||
| fun play( | ||
| isDrawCard: (String) -> Boolean, | ||
| onDrawCard: () -> Unit, | ||
| onExitPlay: () -> Unit, | ||
| ) { | ||
| while (isDrawCard(name)) { | ||
| currentCard = drawCard() | ||
| val isCardAdded = addCardIfAvailable(requireCard = { currentCard }, onDrawCard = onDrawCard) | ||
| if (isCardAdded.not()) break | ||
| var shouldContinue = shouldContinueDrawing(isDrawCard) | ||
| while (shouldContinue) { | ||
| val isCardAdded = addCardIfAvailable(requireCard = drawCard, onDrawCard = onDrawCard) | ||
| shouldContinue = isCardAdded && shouldContinueDrawing(isDrawCard) | ||
| } | ||
| onExitPlay() | ||
| } | ||
|
|
||
| fun getGameResultWith(dealer: Dealer): GameResult { | ||
| return when { | ||
| this.isBlackJackInitially && dealer.isBlackJackInitially.not() -> GameResult.BLACK_JACK | ||
| this.isBlackJackInitially && dealer.isBlackJackInitially -> GameResult.PUSH | ||
| else -> GameResult.fromScores(dealer.cardsSum, this.cardsSum) | ||
| } | ||
| } | ||
|
|
||
| fun setProfitMoneyFromGameResult(result: GameResult) { | ||
| val betMoney = getBetMoneyFromGameResult(result) | ||
| profitMoney.set(betMoney) | ||
| } | ||
|
||
|
|
||
| private fun getBetMoneyFromGameResult(gameResult: GameResult): BigDecimal { | ||
| return when (gameResult) { | ||
| GameResult.BLACK_JACK -> betMoney.getAmountOnBlackJack() | ||
| GameResult.WIN -> betMoney.getOriginalBetAmount() | ||
| GameResult.PUSH -> betMoney.getOriginalBetAmount() | ||
| GameResult.LOSE -> betMoney.getAmountOnLose() | ||
| GameResult.BUST -> betMoney.getAmountOnBust() | ||
| } | ||
| } | ||
|
||
|
|
||
| private fun shouldContinueDrawing(isDrawCard: (String) -> Boolean): Boolean { | ||
| return isDrawCard(name) | ||
| } | ||
|
|
||
| override fun isAddCardEnabled(): Boolean { | ||
| return currentCard.isOverMaxSum(cardsSum).not() | ||
| return cardsSum < Card.MAX_SUM | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,17 @@ | ||
| package blackjack.domain | ||
|
|
||
| class PlayerResultCalculator { | ||
| @Deprecated("deprecated - step3 에서만 사용됨") | ||
|
||
| object PlayerResultCalculator { | ||
| fun calculate( | ||
| dealerScore: Int, | ||
| playerScore: Int, | ||
| ): PlayerResult { | ||
| ): GameResult { | ||
| return when { | ||
| dealerScore > 21 -> PlayerResult.WIN | ||
| playerScore > 21 -> PlayerResult.LOSE | ||
| playerScore > dealerScore -> PlayerResult.WIN | ||
| else -> PlayerResult.LOSE | ||
| dealerScore > Card.MAX_SUM -> GameResult.WIN | ||
| playerScore > Card.MAX_SUM -> GameResult.BUST | ||
| dealerScore > playerScore -> GameResult.LOSE | ||
| playerScore > dealerScore -> GameResult.WIN | ||
| else -> GameResult.PUSH | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package blackjack.domain | ||
|
|
||
| import java.math.BigDecimal | ||
|
|
||
| class ProfitMoney { | ||
| private var current: BigDecimal = BigDecimal.ZERO | ||
|
|
||
| fun getCurrentProfit(): BigDecimal { | ||
| return current | ||
| } | ||
|
|
||
| fun set(amount: BigDecimal) { | ||
| current = amount | ||
| } | ||
| } | ||
|
Comment on lines
+5
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. kotlin을 사용하신다면 가능한 불변한 객체를 설계하여 사용하시는것을 권장드립니다~ https://kotlinlang.org/docs/coding-conventions.html#idiomatic-use-of-language-features |
||
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.
여러가지 상태를 관리하는것 같습니다.
Cards를 가지고 점수를 계산하고 이러한 상태가 관리되는것 같은데요
디자인 패턴중 상태패턴을 이용한다면 이러한 부분을 개선해볼 수 있을것 같습니다.
반드시 개선을 바라는 부분은 아니니 참고만 해주셔도 좋습니다. 😄
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.
@pci2676 요거 혹시 간단하게 예시를 주실 수 있을까요?
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.
블랙잭 피드백에 나와있는 내용이군요!
이거 근데 현재 구조에서 적용하려면 코드를 아예 새로 짜야 할 것 같아서
별도로 한번 적용 해보는 연습을 해봐야 할 것 같습니다.
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.
제가 드리는 리뷰를 반드시 반영할 필요는 없으니 참고만 해주셔도 됩니다~