-
Notifications
You must be signed in to change notification settings - Fork 320
Step 3 - Blackjack (Dealer) #835
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: krrong
Are you sure you want to change the base?
Changes from 14 commits
79cfc01
474c3f1
166ab49
1cdebe6
f04df3d
f42a446
3596118
80bc838
12e2bd7
373986f
5a961df
4c69f75
ba2e68e
9bca013
1a90565
aa0a9ef
70f62ed
e21c4f6
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,3 +1,10 @@ | ||
| import card.Deck | ||
| import card.PlayingCard | ||
| import participant.Dealer | ||
| import participant.Participant | ||
| import participant.Player | ||
| import state.Bust | ||
| import state.FirstTurn | ||
| import view.InputView | ||
| import view.OutputView | ||
|
|
||
|
|
@@ -8,22 +15,55 @@ class Casino( | |
| fun run() { | ||
| val deck = Deck(PlayingCard.ALL.shuffled()) | ||
| val names = inputView.getPlayerNames() | ||
| val players = names.map { Player(it, Hand(deck.drawCard(2))) } | ||
| outputView.printFirstTurn(players) | ||
| val players = names.map { Player(it, FirstTurn(Hand(emptyList()))) } | ||
| val dealer = Dealer(state = FirstTurn(Hand(emptyList()))) | ||
|
|
||
| players.forEach { turn(it, deck) } | ||
| players.forEach { outputView.printScore(it) } | ||
| val participants: List<Participant> = players + dealer | ||
| repeat(2) { participants.forEach { it.drawCard(deck.drawOne()) } } | ||
|
|
||
| outputView.printFirstTurn(participants) | ||
|
|
||
| participants.forEach { turn(it, deck) } | ||
| participants.forEach { outputView.printScore(it) } | ||
|
|
||
| val winningResult = WinningResult() | ||
| participants.forEach { | ||
| when (it) { | ||
| is Player -> { | ||
| val result = winningResult.versus(dealer, it) | ||
| outputView.printResult(it, result) | ||
| } | ||
| is Dealer -> { | ||
| outputView.printDealerResult(it, winningResult.getResult()) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private fun turn( | ||
| player: Player, | ||
| participant: Participant, | ||
| deck: Deck, | ||
| ) { | ||
| while (true) { | ||
| val response = inputView.getResponse(player.name) | ||
| if (!response || player.hand.isBust()) return | ||
| player.drawCard(deck.drawCard(1).first()) | ||
| outputView.printPlayerCards(player) | ||
| when (participant) { | ||
|
||
| is Player -> { | ||
| val response = inputView.getResponse(participant.name) | ||
| if (!response) { | ||
| participant.stay() | ||
| return | ||
| } | ||
| } | ||
| is Dealer -> { | ||
| if (participant.score() > 17) { | ||
| participant.stay() | ||
| return | ||
| } | ||
| outputView.printDealerDrawGuide() | ||
| } | ||
| } | ||
| participant.drawCard(deck.drawOne()) | ||
| outputView.printPlayerCards(participant) | ||
| if (participant.state is Bust) return | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| enum class GameResult { | ||
| WIN, | ||
| LOSE, | ||
| DRAW, | ||
| ; | ||
|
|
||
| companion object { | ||
| fun getApposite(result: GameResult): GameResult { | ||
| return when (result) { | ||
| WIN -> LOSE | ||
| DRAW -> DRAW | ||
| LOSE -> WIN | ||
| } | ||
| } | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import GameResult.Companion.getApposite | ||
| import GameResult.DRAW | ||
| import GameResult.LOSE | ||
| import GameResult.WIN | ||
| import participant.Participant | ||
| import state.Blackjack | ||
| import state.Bust | ||
| import state.Stay | ||
|
|
||
| class WinningResult { | ||
|
||
| private val dealerResult: MutableMap<GameResult, Int> = | ||
| mutableMapOf( | ||
| WIN to 0, | ||
| LOSE to 0, | ||
| DRAW to 0, | ||
| ) | ||
|
|
||
| fun getResult() = dealerResult.toMap() | ||
|
|
||
| fun versus( | ||
| dealer: Participant, | ||
| player: Participant, | ||
| ): GameResult { | ||
| val result = determineResult(dealer, player) | ||
| dealerResult[result] = dealerResult.getValue(result) + 1 | ||
| return getApposite(result) | ||
| } | ||
|
|
||
| private fun determineResult( | ||
| dealer: Participant, | ||
| player: Participant, | ||
| ): GameResult { | ||
| return when (dealer.state) { | ||
| is Bust -> LOSE | ||
| is Blackjack -> if (player.state is Blackjack) DRAW else WIN | ||
| is Stay -> | ||
| when { | ||
| dealer.score() < player.score() -> LOSE | ||
| dealer.score() == player.score() -> DRAW | ||
| else -> WIN | ||
| } | ||
| else -> throw IllegalStateException() | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| package card | ||
|
|
||
| class Deck(cards: List<PlayingCard>) { | ||
| private val _cards = cards.toMutableList() | ||
| val cards: List<PlayingCard> | ||
| get() = _cards.toList() | ||
|
|
||
| fun drawCard(count: Int): List<PlayingCard> { | ||
| return List(count) { _cards.removeFirst() } | ||
| fun drawOne(): PlayingCard { | ||
| return _cards.removeFirst() | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| package card | ||
|
|
||
| enum class Denomination(val score: Int) { | ||
| ACE(1), | ||
| TWO(2), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| package card | ||
|
|
||
| enum class Suit { | ||
| CLUB, | ||
| DIAMOND, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package participant | ||
|
|
||
| import card.PlayingCard | ||
| import state.State | ||
|
|
||
| class Dealer(name: String = "Dealer", override var state: State) : Participant(name) { | ||
| override fun showCardFirst(): List<PlayingCard> { | ||
| return listOf(state.hand.cards.first()) | ||
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package participant | ||
|
|
||
| import card.PlayingCard | ||
| import state.State | ||
|
|
||
| abstract class Participant(val name: String) { | ||
| abstract var state: State | ||
|
|
||
| abstract fun showCardFirst(): List<PlayingCard> | ||
|
|
||
| fun score(): Int { | ||
| return state.hand.score() | ||
| } | ||
|
|
||
| fun stay() { | ||
| state = state.stay() | ||
| } | ||
|
|
||
| fun drawCard(card: PlayingCard) { | ||
| state = state.drawCard(card) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package participant | ||
|
|
||
| import card.PlayingCard | ||
| import state.State | ||
|
|
||
| class Player(name: String, override var state: State) : Participant(name) { | ||
| override fun showCardFirst(): List<PlayingCard> { | ||
| return state.hand.cards | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package state | ||
|
|
||
| import Hand | ||
|
|
||
| class Blackjack(hand: Hand) : Finished(hand) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package state | ||
|
|
||
| import Hand | ||
|
|
||
| class Bust(hand: Hand) : Finished(hand) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package state | ||
|
|
||
| import Hand | ||
| import card.PlayingCard | ||
|
|
||
| abstract class Finished(override val hand: Hand) : State { | ||
| override fun drawCard(card: PlayingCard): State { | ||
| throw IllegalStateException() | ||
| } | ||
|
|
||
| override fun stay(): State { | ||
| return this | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package state | ||
|
|
||
| import Hand | ||
| import card.PlayingCard | ||
|
|
||
| class FirstTurn(override val hand: Hand) : State { | ||
| override fun drawCard(card: PlayingCard): State { | ||
| hand.add(card) | ||
|
|
||
| if (hand.size == 2) { | ||
| if (hand.isBlackjack()) return Blackjack(hand) | ||
| return Hit(hand) | ||
| } | ||
| return FirstTurn(hand) | ||
| } | ||
|
|
||
| override fun stay(): State { | ||
| throw IllegalStateException() | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package state | ||
|
|
||
| import Hand | ||
| import card.PlayingCard | ||
|
|
||
| class Hit(override val hand: Hand) : State { | ||
| override fun drawCard(card: PlayingCard): State { | ||
| hand.add(card) | ||
|
|
||
| return if (hand.isBust()) { | ||
| return Bust(hand) | ||
| } else { | ||
| Hit(hand) | ||
| } | ||
| } | ||
|
|
||
| override fun stay(): State { | ||
| return Stay(hand) | ||
| } | ||
| } |
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.
How do you think this conditional could be refactored?
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.
I think it's also possible by using polymorphism like above!