From 287bbff130c157e18fb53e17f745f80dd93ca961 Mon Sep 17 00:00:00 2001 From: theo-94 Date: Wed, 12 Jul 2023 01:00:48 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat=20:=20=EB=94=9C=EB=9F=AC=EC=97=90?= =?UTF-8?q?=EA=B2=8C=EB=8F=84=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EB=B6=84?= =?UTF-8?q?=EB=B0=B0=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 딜러의 점수가 17점 이상이면 추가로 카드를 받을 수 없도록 구현 --- README.md | 6 +++ src/main/kotlin/blackjack/BlackJackGame.kt | 31 +++++++++----- src/main/kotlin/blackjack/domain/Dealer.kt | 41 +++++++------------ .../kotlin/blackjack/domain/Distributor.kt | 40 ++++++++++++++++++ src/main/kotlin/blackjack/domain/Player.kt | 7 +++- src/main/kotlin/blackjack/view/DisplayView.kt | 26 +++++++++--- .../kotlin/blackjack/domain/DealerTest.kt | 38 +++++++++++++++++ 7 files changed, 146 insertions(+), 43 deletions(-) create mode 100644 src/main/kotlin/blackjack/domain/Distributor.kt create mode 100644 src/test/kotlin/blackjack/domain/DealerTest.kt diff --git a/README.md b/README.md index d1f319e5d6..a5323380e3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ - 카드를 더 줄 때마다 해당 player가 갖고있는 카드를 출력한다. - 모든 플레이어가 카드를 더 이상 받지 않으면 결과를 출력한다. - 결과는 플레이어별로 갖고 있는 카드의 목록과 점수를 출력한다. +- 딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없다. +- 딜러가 21을 초과하면 그 시점까지 남아 있던 플레이어들은 가지고 있는 패에 상관 없이 승리한다. +- 게임을 완료한 후 각 플레이어별로 승패를 출력한다. ## 테스트 구현 목록 - [x] Test 1 : Player 객체에 이름을 부여할 수 있다. @@ -32,4 +35,7 @@ - view라서 테스트 미구현 - [x] Test 4 : Player별 점수를 계산할 수 있다. - card의 리스트를 감싼 Cards 객체에게 점수 계산을 위임 +- [x] Test 5 : 딜러의 점수가 17점 이상이면 추가로 카드를 받을 수 없다. + - Dealer가 Player를 상속하도록 하고 addCard 로직을 바꿔서 구현 +- diff --git a/src/main/kotlin/blackjack/BlackJackGame.kt b/src/main/kotlin/blackjack/BlackJackGame.kt index f4ebfa458e..1f9a2d9661 100644 --- a/src/main/kotlin/blackjack/BlackJackGame.kt +++ b/src/main/kotlin/blackjack/BlackJackGame.kt @@ -1,6 +1,7 @@ package blackjack import blackjack.domain.Dealer +import blackjack.domain.Distributor import blackjack.domain.Player import blackjack.domain.Players import blackjack.domain.card.CardDeck @@ -14,29 +15,37 @@ class BlackJackGame { val players = Players(names) DisplayView.dealOutCards(players) - val dealer = Dealer(CardDeck()) - dealer.dealOutCards(players) - DisplayView.cardsOfPlayers(players) + val distributor = Distributor(CardDeck()) + val dealer = Dealer() - dealOutAdditionalCards(dealer, players) - DisplayView.result(players) + distributor.dealOutCards(dealer, players) + DisplayView.cardsOfPlayers(dealer, players) + + dealOutAdditionalCards(distributor, players) + dealOutAdditionalCard(distributor, dealer) + DisplayView.finalScore(dealer, players) } - private fun dealOutAdditionalCards(dealer: Dealer, players: Players) { + private fun dealOutAdditionalCards(distributor: Distributor, players: Players) { players.players.forEach { - dealOutAdditionalCard(dealer, it) + dealOutAdditionalCard(distributor, it) } } - private fun dealOutAdditionalCard(dealer: Dealer, player: Player) { + private fun dealOutAdditionalCard(distributor: Distributor, player: Player) { DisplayView.dealOutAdditionalCard(player) if (InputView.inputAdditionalCard() == "y") { - dealer.dealOutCard(player) - takeAnotherCard(dealer, player) + distributor.dealOutCard(player) + takeAnotherCard(distributor, player) } } - private fun takeAnotherCard(dealer: Dealer, player: Player) { + private fun dealOutAdditionalCard(distributor: Distributor, dealer: Dealer) { + distributor.dealOutCard(dealer) + DisplayView.dealOutAdditionalCard(dealer) + } + + private fun takeAnotherCard(dealer: Distributor, player: Player) { if (player.getScore() >= MAX_SCORE) { dealOutAdditionalCard(dealer, player) } diff --git a/src/main/kotlin/blackjack/domain/Dealer.kt b/src/main/kotlin/blackjack/domain/Dealer.kt index 8f80f56162..e2aa56300a 100644 --- a/src/main/kotlin/blackjack/domain/Dealer.kt +++ b/src/main/kotlin/blackjack/domain/Dealer.kt @@ -1,39 +1,28 @@ package blackjack.domain import blackjack.domain.card.Card -import blackjack.domain.card.CardDeck -import kotlin.random.Random +import blackjack.domain.card.Cards -class Dealer( - private val cardDeck: CardDeck -) { +class Dealer(name: String, cards: Cards = Cards()) : Player(name, cards) { + var isFinished = false - /** - * 플레이어들에게 2장씩 카드를 분배함 - */ - fun dealOutCards(players: Players) { - repeat(DEAL_OUT_CARD_AMOUNT){ - players.players.forEach{ dealOutCard(it) } - } - } + constructor(cards: Cards = Cards()) : this(DEALER_DISPLAY_NAME, cards) - /** - * 플레이어들에게 1장씩 카드를 분배함 - */ - fun dealOutCard(player: Player) { - player.cards.addCard(peekCard()) + // 17점이 넘으면 호출되어도 더 이상 카드를 추가하지 않는다 + override fun addCard(card: Card) { + if (isAddable()) { + super.addCard(card) + } else { + isFinished = true + } } - /** - * 카드덱에서 랜덤한 카드를 1장 꺼냄 - */ - private fun peekCard(): Card { - val random = Random.Default - val randomIndex = random.nextInt(cardDeck.cards.size) - return cardDeck.peekCard(randomIndex) + private fun isAddable(): Boolean { + return !isFinished && getScore() < LIMIT_SCORE } companion object { - const val DEAL_OUT_CARD_AMOUNT = 2 + private const val DEALER_DISPLAY_NAME = "딜러" + const val LIMIT_SCORE = 17 } } diff --git a/src/main/kotlin/blackjack/domain/Distributor.kt b/src/main/kotlin/blackjack/domain/Distributor.kt new file mode 100644 index 0000000000..c2a14851ef --- /dev/null +++ b/src/main/kotlin/blackjack/domain/Distributor.kt @@ -0,0 +1,40 @@ +package blackjack.domain + +import blackjack.domain.card.Card +import blackjack.domain.card.CardDeck +import kotlin.random.Random + +class Distributor( + private val cardDeck: CardDeck +) { + + /** + * 딜러와 플레이어들에게 2장씩 카드를 분배함 + */ + fun dealOutCards(dealer: Dealer, players: Players) { + repeat(DEAL_OUT_CARD_AMOUNT) { + dealOutCard(dealer) + players.players.forEach { dealOutCard(it) } + } + } + + /** + * 플레이어들에게 1장씩 카드를 분배함 + */ + fun dealOutCard(player: Player) { + player.addCard(peekCard()) + } + + /** + * 카드덱에서 랜덤한 카드를 1장 꺼냄 + */ + private fun peekCard(): Card { + val random = Random.Default + val randomIndex = random.nextInt(cardDeck.cards.size) + return cardDeck.peekCard(randomIndex) + } + + companion object { + const val DEAL_OUT_CARD_AMOUNT = 2 + } +} diff --git a/src/main/kotlin/blackjack/domain/Player.kt b/src/main/kotlin/blackjack/domain/Player.kt index 9880346b94..4552715788 100644 --- a/src/main/kotlin/blackjack/domain/Player.kt +++ b/src/main/kotlin/blackjack/domain/Player.kt @@ -1,8 +1,9 @@ package blackjack.domain +import blackjack.domain.card.Card import blackjack.domain.card.Cards -data class Player( +open class Player( val name: String, val cards: Cards = Cards() ) { @@ -11,6 +12,10 @@ data class Player( return name } + open fun addCard(card: Card) { + cards.addCard(card) + } + fun getScore(): Int { return cards.getScore() } diff --git a/src/main/kotlin/blackjack/view/DisplayView.kt b/src/main/kotlin/blackjack/view/DisplayView.kt index 1971081fa7..b1714ec628 100644 --- a/src/main/kotlin/blackjack/view/DisplayView.kt +++ b/src/main/kotlin/blackjack/view/DisplayView.kt @@ -1,5 +1,6 @@ package blackjack.view +import blackjack.domain.Dealer import blackjack.domain.Player import blackjack.domain.Players @@ -7,15 +8,20 @@ object DisplayView { fun dealOutCards(players: Players) { val playersName = players.players.joinToString() - println("${playersName}에게 2장의 카드 나누었습니다.") + println("딜러와 ${playersName}에게 2장의 카드 나누었습니다.") } - fun cardsOfPlayers(players: Players) { + fun cardsOfPlayers(dealer: Dealer, players: Players) { + cardsOfDealer(dealer) players.players.forEach { cardsOfPlayer(it) } } + fun cardsOfDealer(dealer: Dealer) { + println("${dealer.name}: ${dealer.cards}") + } + fun cardsOfPlayer(player: Player) { println("${player.name}카드: ${player.cards}") } @@ -24,10 +30,20 @@ object DisplayView { println("${player}는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)") } - fun result(players: Players) { - players.players.forEach { - println("${it.name}카드: ${it.cards} - 결과: ${it.getScore()}") + fun dealOutAdditionalCard(dealer: Dealer) { + if (dealer.getScore() > Dealer.LIMIT_SCORE) { + println("딜러는 17이상이라 카드를 더 받지 않았습니다.") + } else { + println("딜러는 16이하라 한장의 카드를 더 받았습니다.") } } + fun finalScore(dealer: Dealer, players: Players) { + printFinalScore(dealer) + players.players.forEach { printFinalScore(it) } + } + + private fun printFinalScore(player: Player) { + println("${player.name}카드: ${player.cards} - 결과: ${player.getScore()}") + } } diff --git a/src/test/kotlin/blackjack/domain/DealerTest.kt b/src/test/kotlin/blackjack/domain/DealerTest.kt new file mode 100644 index 0000000000..c31b7e8996 --- /dev/null +++ b/src/test/kotlin/blackjack/domain/DealerTest.kt @@ -0,0 +1,38 @@ +package blackjack.domain + +import blackjack.domain.card.Card +import blackjack.domain.card.CardNumber +import blackjack.domain.card.CardSymbol +import blackjack.domain.card.Cards +import io.kotest.core.spec.style.StringSpec +import io.kotest.matchers.ints.shouldBeGreaterThan +import io.kotest.matchers.shouldBe + +class DealerTest : StringSpec({ + "17점이상의 카드를 가진 딜러는 카드를 받지 않는다" { + val cardsUnder17 = Cards(mutableListOf(Card(CardNumber.SIX, CardSymbol.DIAMOND), Card(CardNumber.JACK, CardSymbol.DIAMOND))) + val cardsScore17 = Cards(mutableListOf(Card(CardNumber.SEVEN, CardSymbol.HEART), Card(CardNumber.JACK, CardSymbol.HEART))) + val cardsOver17 = Cards(mutableListOf(Card(CardNumber.EIGHT, CardSymbol.SPADE), Card(CardNumber.JACK, CardSymbol.SPADE))) + + val firstDealer = Dealer("cardsUnder17", cardsUnder17) + val scoreOfFirstDealer = firstDealer.getScore() + + val secondDealer = Dealer("cardsScore17", cardsScore17) + val scoreOfSecondDealer = secondDealer.getScore() + + val thirdDealer = Dealer("cardsOver17", cardsOver17) + val scoreOfThirdDealer = thirdDealer.getScore() + + val additionalCard = Card(CardNumber.ACE, CardSymbol.CLOVER) + + // when + firstDealer.addCard(additionalCard) + secondDealer.addCard(additionalCard) + thirdDealer.addCard(additionalCard) + + // then + firstDealer.getScore() shouldBeGreaterThan scoreOfFirstDealer + secondDealer.getScore() shouldBe scoreOfSecondDealer + thirdDealer.getScore() shouldBe scoreOfThirdDealer + } +}) From 826b9e8317ad583e5fb5e56e5be637b1e6419c58 Mon Sep 17 00:00:00 2001 From: theo-94 Date: Thu, 13 Jul 2023 01:08:44 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat=20:=20=EB=94=9C=EB=9F=AC=EC=99=80?= =?UTF-8?q?=EC=9D=98=20=EC=A0=90=EC=88=98=EB=A5=BC=20=EB=B9=84=EA=B5=90?= =?UTF-8?q?=ED=95=B4=20=EA=B2=B0=EA=B3=BC=EB=A5=BC=20=ED=91=9C=EC=8B=9C?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/blackjack/BlackJackGame.kt | 12 +++++++++--- src/main/kotlin/blackjack/GameResult.kt | 6 ++++++ .../kotlin/blackjack/GameResultCalculator.kt | 18 ++++++++++++++++++ src/main/kotlin/blackjack/domain/Dealer.kt | 6 ++++++ src/main/kotlin/blackjack/domain/Player.kt | 6 ++++++ src/main/kotlin/blackjack/view/DisplayView.kt | 17 +++++++++++++---- 6 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/main/kotlin/blackjack/GameResult.kt create mode 100644 src/main/kotlin/blackjack/GameResultCalculator.kt diff --git a/src/main/kotlin/blackjack/BlackJackGame.kt b/src/main/kotlin/blackjack/BlackJackGame.kt index 1f9a2d9661..aba36e9aee 100644 --- a/src/main/kotlin/blackjack/BlackJackGame.kt +++ b/src/main/kotlin/blackjack/BlackJackGame.kt @@ -24,6 +24,9 @@ class BlackJackGame { dealOutAdditionalCards(distributor, players) dealOutAdditionalCard(distributor, dealer) DisplayView.finalScore(dealer, players) + + GameResultCalculator.getResult(dealer, players) + DisplayView.result(dealer, players) } private fun dealOutAdditionalCards(distributor: Distributor, players: Players) { @@ -41,12 +44,15 @@ class BlackJackGame { } private fun dealOutAdditionalCard(distributor: Distributor, dealer: Dealer) { - distributor.dealOutCard(dealer) - DisplayView.dealOutAdditionalCard(dealer) + val receiveNewCard = dealer.getScore() < Dealer.LIMIT_SCORE + if (receiveNewCard) { + distributor.dealOutCard(dealer) + } + DisplayView.dealOutAdditionalCard(receiveNewCard) } private fun takeAnotherCard(dealer: Distributor, player: Player) { - if (player.getScore() >= MAX_SCORE) { + if (player.getScore() < MAX_SCORE) { dealOutAdditionalCard(dealer, player) } } diff --git a/src/main/kotlin/blackjack/GameResult.kt b/src/main/kotlin/blackjack/GameResult.kt new file mode 100644 index 0000000000..ba4d1722eb --- /dev/null +++ b/src/main/kotlin/blackjack/GameResult.kt @@ -0,0 +1,6 @@ +package blackjack + +enum class GameResult(val description: String) { + WIN("승"), + LOSE("패") +} diff --git a/src/main/kotlin/blackjack/GameResultCalculator.kt b/src/main/kotlin/blackjack/GameResultCalculator.kt new file mode 100644 index 0000000000..73daa98078 --- /dev/null +++ b/src/main/kotlin/blackjack/GameResultCalculator.kt @@ -0,0 +1,18 @@ +package blackjack + +import blackjack.domain.Dealer +import blackjack.domain.Players + +object GameResultCalculator { + // 딜러와 각 플레이어의 점수를 비교해서 승패를 판별하고 기록함 + // 딜러가 21을 초과하면 그 시점까지 남아 있던 플레이어들은 가지고 있는 패에 상관 없이 승리한다 + fun getResult(dealer: Dealer, players: Players) { + val scoreOfDealer = dealer.getScore() + val isDealerLose = scoreOfDealer > BlackJackGame.MAX_SCORE + players.players.forEach { + val scoreOfPlayer = it.getScore() + it.getGameResult(isDealerLose || scoreOfPlayer > scoreOfDealer) + dealer.getGameResult(!isDealerLose && scoreOfDealer > scoreOfPlayer) + } + } +} diff --git a/src/main/kotlin/blackjack/domain/Dealer.kt b/src/main/kotlin/blackjack/domain/Dealer.kt index e2aa56300a..408142abf2 100644 --- a/src/main/kotlin/blackjack/domain/Dealer.kt +++ b/src/main/kotlin/blackjack/domain/Dealer.kt @@ -1,10 +1,12 @@ package blackjack.domain +import blackjack.GameResult import blackjack.domain.card.Card import blackjack.domain.card.Cards class Dealer(name: String, cards: Cards = Cards()) : Player(name, cards) { var isFinished = false + val gameResults = mutableListOf() constructor(cards: Cards = Cards()) : this(DEALER_DISPLAY_NAME, cards) @@ -17,6 +19,10 @@ class Dealer(name: String, cards: Cards = Cards()) : Player(name, cards) { } } + override fun getGameResult(win: Boolean) { + gameResults.add(if (win) GameResult.WIN else GameResult.LOSE) + } + private fun isAddable(): Boolean { return !isFinished && getScore() < LIMIT_SCORE } diff --git a/src/main/kotlin/blackjack/domain/Player.kt b/src/main/kotlin/blackjack/domain/Player.kt index 4552715788..5dc1ea71d5 100644 --- a/src/main/kotlin/blackjack/domain/Player.kt +++ b/src/main/kotlin/blackjack/domain/Player.kt @@ -1,5 +1,6 @@ package blackjack.domain +import blackjack.GameResult import blackjack.domain.card.Card import blackjack.domain.card.Cards @@ -7,6 +8,7 @@ open class Player( val name: String, val cards: Cards = Cards() ) { + lateinit var gameResult: GameResult override fun toString(): String { return name @@ -19,4 +21,8 @@ open class Player( fun getScore(): Int { return cards.getScore() } + + open fun getGameResult(win: Boolean) { + gameResult = if (win) GameResult.WIN else GameResult.LOSE + } } diff --git a/src/main/kotlin/blackjack/view/DisplayView.kt b/src/main/kotlin/blackjack/view/DisplayView.kt index b1714ec628..d59cb455b8 100644 --- a/src/main/kotlin/blackjack/view/DisplayView.kt +++ b/src/main/kotlin/blackjack/view/DisplayView.kt @@ -1,5 +1,6 @@ package blackjack.view +import blackjack.GameResult import blackjack.domain.Dealer import blackjack.domain.Player import blackjack.domain.Players @@ -30,11 +31,11 @@ object DisplayView { println("${player}는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)") } - fun dealOutAdditionalCard(dealer: Dealer) { - if (dealer.getScore() > Dealer.LIMIT_SCORE) { - println("딜러는 17이상이라 카드를 더 받지 않았습니다.") - } else { + fun dealOutAdditionalCard(received: Boolean) { + if (received) { println("딜러는 16이하라 한장의 카드를 더 받았습니다.") + } else { + println("딜러는 17이상이라 카드를 더 받지 않았습니다.") } } @@ -43,6 +44,14 @@ object DisplayView { players.players.forEach { printFinalScore(it) } } + fun result(dealer: Dealer, players: Players) { + println("\n## 최종 승패") + val dealerWinCnt = dealer.gameResults.count { it == GameResult.WIN } + val dealerLoseCnt = dealer.gameResults.count { it == GameResult.LOSE } + println("딜러: ${dealerWinCnt}승 ${dealerLoseCnt}패") + players.players.forEach { println("${it.name}: ${it.gameResult.description}") } + } + private fun printFinalScore(player: Player) { println("${player.name}카드: ${player.cards} - 결과: ${player.getScore()}") } From c9c6bded317cca3320414cb1a4495c06d275fee2 Mon Sep 17 00:00:00 2001 From: theo-94 Date: Wed, 19 Jul 2023 23:06:18 +0900 Subject: [PATCH 3/9] =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20:=20=EB=94=9C=EB=9F=AC=EA=B0=80=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EB=B0=9B=EC=9D=84=20=EC=88=98=20=EC=9E=88=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=EC=97=AC=EB=B6=80=EB=A5=BC=20=EA=B0=90=EC=B6=94?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/blackjack/BlackJackGame.kt | 6 +++--- src/main/kotlin/blackjack/domain/Dealer.kt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/blackjack/BlackJackGame.kt b/src/main/kotlin/blackjack/BlackJackGame.kt index aba36e9aee..aac54402d6 100644 --- a/src/main/kotlin/blackjack/BlackJackGame.kt +++ b/src/main/kotlin/blackjack/BlackJackGame.kt @@ -44,11 +44,11 @@ class BlackJackGame { } private fun dealOutAdditionalCard(distributor: Distributor, dealer: Dealer) { - val receiveNewCard = dealer.getScore() < Dealer.LIMIT_SCORE - if (receiveNewCard) { + val received = dealer.isReceivableNewCard() + if (received) { distributor.dealOutCard(dealer) } - DisplayView.dealOutAdditionalCard(receiveNewCard) + DisplayView.dealOutAdditionalCard(received) } private fun takeAnotherCard(dealer: Distributor, player: Player) { diff --git a/src/main/kotlin/blackjack/domain/Dealer.kt b/src/main/kotlin/blackjack/domain/Dealer.kt index 408142abf2..18625e2a03 100644 --- a/src/main/kotlin/blackjack/domain/Dealer.kt +++ b/src/main/kotlin/blackjack/domain/Dealer.kt @@ -5,14 +5,14 @@ import blackjack.domain.card.Card import blackjack.domain.card.Cards class Dealer(name: String, cards: Cards = Cards()) : Player(name, cards) { - var isFinished = false + private var isFinished = false val gameResults = mutableListOf() constructor(cards: Cards = Cards()) : this(DEALER_DISPLAY_NAME, cards) // 17점이 넘으면 호출되어도 더 이상 카드를 추가하지 않는다 override fun addCard(card: Card) { - if (isAddable()) { + if (isReceivableNewCard()) { super.addCard(card) } else { isFinished = true @@ -23,12 +23,12 @@ class Dealer(name: String, cards: Cards = Cards()) : Player(name, cards) { gameResults.add(if (win) GameResult.WIN else GameResult.LOSE) } - private fun isAddable(): Boolean { + fun isReceivableNewCard(): Boolean { return !isFinished && getScore() < LIMIT_SCORE } companion object { private const val DEALER_DISPLAY_NAME = "딜러" - const val LIMIT_SCORE = 17 + private const val LIMIT_SCORE = 17 } } From f0cc8cf81d4f50cdf20aefb6fcfcc3b21e0d7dbf Mon Sep 17 00:00:00 2001 From: theo-94 Date: Wed, 19 Jul 2023 23:12:33 +0900 Subject: [PATCH 4/9] =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20:=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EA=B0=80?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=20=EB=B0=9B=EC=9D=84=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=EC=A7=80=20=EC=97=AC=EB=B6=80=EB=A5=BC=20?= =?UTF-8?q?=EA=B0=90=EC=B6=94=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/blackjack/BlackJackGame.kt | 6 +++--- src/main/kotlin/blackjack/domain/Dealer.kt | 2 +- src/main/kotlin/blackjack/domain/Player.kt | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/blackjack/BlackJackGame.kt b/src/main/kotlin/blackjack/BlackJackGame.kt index aac54402d6..8dd9fb9780 100644 --- a/src/main/kotlin/blackjack/BlackJackGame.kt +++ b/src/main/kotlin/blackjack/BlackJackGame.kt @@ -51,9 +51,9 @@ class BlackJackGame { DisplayView.dealOutAdditionalCard(received) } - private fun takeAnotherCard(dealer: Distributor, player: Player) { - if (player.getScore() < MAX_SCORE) { - dealOutAdditionalCard(dealer, player) + private fun takeAnotherCard(distributor: Distributor, player: Player) { + if (player.isReceivableNewCard()) { + dealOutAdditionalCard(distributor, player) } } diff --git a/src/main/kotlin/blackjack/domain/Dealer.kt b/src/main/kotlin/blackjack/domain/Dealer.kt index 18625e2a03..e5b2e31fb0 100644 --- a/src/main/kotlin/blackjack/domain/Dealer.kt +++ b/src/main/kotlin/blackjack/domain/Dealer.kt @@ -23,7 +23,7 @@ class Dealer(name: String, cards: Cards = Cards()) : Player(name, cards) { gameResults.add(if (win) GameResult.WIN else GameResult.LOSE) } - fun isReceivableNewCard(): Boolean { + override fun isReceivableNewCard(): Boolean { return !isFinished && getScore() < LIMIT_SCORE } diff --git a/src/main/kotlin/blackjack/domain/Player.kt b/src/main/kotlin/blackjack/domain/Player.kt index 5dc1ea71d5..b18f9af8f6 100644 --- a/src/main/kotlin/blackjack/domain/Player.kt +++ b/src/main/kotlin/blackjack/domain/Player.kt @@ -1,5 +1,6 @@ package blackjack.domain +import blackjack.BlackJackGame import blackjack.GameResult import blackjack.domain.card.Card import blackjack.domain.card.Cards @@ -22,6 +23,10 @@ open class Player( return cards.getScore() } + open fun isReceivableNewCard(): Boolean { + return getScore() < BlackJackGame.MAX_SCORE + } + open fun getGameResult(win: Boolean) { gameResult = if (win) GameResult.WIN else GameResult.LOSE } From 521e56013f7153ddf28c108f8e1b9632ab5b5931 Mon Sep 17 00:00:00 2001 From: theo-94 Date: Wed, 19 Jul 2023 23:20:51 +0900 Subject: [PATCH 5/9] =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20:=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EC=99=80?= =?UTF-8?q?=20=EB=94=9C=EB=9F=AC=EC=9D=98=20=EA=B2=8C=EC=9E=84=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EC=84=A4=EC=A0=95=ED=95=98=EB=8A=94=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/blackjack/GameResultCalculator.kt | 4 ++-- src/main/kotlin/blackjack/domain/Dealer.kt | 2 +- src/main/kotlin/blackjack/domain/Player.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/blackjack/GameResultCalculator.kt b/src/main/kotlin/blackjack/GameResultCalculator.kt index 73daa98078..fea34cecc0 100644 --- a/src/main/kotlin/blackjack/GameResultCalculator.kt +++ b/src/main/kotlin/blackjack/GameResultCalculator.kt @@ -11,8 +11,8 @@ object GameResultCalculator { val isDealerLose = scoreOfDealer > BlackJackGame.MAX_SCORE players.players.forEach { val scoreOfPlayer = it.getScore() - it.getGameResult(isDealerLose || scoreOfPlayer > scoreOfDealer) - dealer.getGameResult(!isDealerLose && scoreOfDealer > scoreOfPlayer) + it.setGameResult(isDealerLose || scoreOfPlayer > scoreOfDealer) + dealer.setGameResult(!isDealerLose && scoreOfDealer > scoreOfPlayer) } } } diff --git a/src/main/kotlin/blackjack/domain/Dealer.kt b/src/main/kotlin/blackjack/domain/Dealer.kt index e5b2e31fb0..820e0f2068 100644 --- a/src/main/kotlin/blackjack/domain/Dealer.kt +++ b/src/main/kotlin/blackjack/domain/Dealer.kt @@ -19,7 +19,7 @@ class Dealer(name: String, cards: Cards = Cards()) : Player(name, cards) { } } - override fun getGameResult(win: Boolean) { + override fun setGameResult(win: Boolean) { gameResults.add(if (win) GameResult.WIN else GameResult.LOSE) } diff --git a/src/main/kotlin/blackjack/domain/Player.kt b/src/main/kotlin/blackjack/domain/Player.kt index b18f9af8f6..e8ff060e00 100644 --- a/src/main/kotlin/blackjack/domain/Player.kt +++ b/src/main/kotlin/blackjack/domain/Player.kt @@ -27,7 +27,7 @@ open class Player( return getScore() < BlackJackGame.MAX_SCORE } - open fun getGameResult(win: Boolean) { + open fun setGameResult(win: Boolean) { gameResult = if (win) GameResult.WIN else GameResult.LOSE } } From 5c9b3c5213f75aa7760a350752fb776ead4ded3c Mon Sep 17 00:00:00 2001 From: theo-94 Date: Sun, 23 Jul 2023 23:08:01 +0900 Subject: [PATCH 6/9] =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20:=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC=EB=A0=89?= =?UTF-8?q?=EC=85=98=20Players=EC=97=90=20=EC=9C=84=EC=9E=84=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/blackjack/BlackJackGame.kt | 4 ++-- src/main/kotlin/blackjack/GameResultCalculator.kt | 2 +- src/main/kotlin/blackjack/domain/Distributor.kt | 2 +- src/main/kotlin/blackjack/domain/Players.kt | 6 +----- src/main/kotlin/blackjack/view/DisplayView.kt | 8 ++++---- src/test/kotlin/blackjack/PlayerTest.kt | 4 ++-- 6 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/kotlin/blackjack/BlackJackGame.kt b/src/main/kotlin/blackjack/BlackJackGame.kt index 8dd9fb9780..5aa281a381 100644 --- a/src/main/kotlin/blackjack/BlackJackGame.kt +++ b/src/main/kotlin/blackjack/BlackJackGame.kt @@ -12,7 +12,7 @@ class BlackJackGame { fun start() { val names = InputView.inputNameOfPlayer() - val players = Players(names) + val players = Players(names.map { Player(it) }) DisplayView.dealOutCards(players) val distributor = Distributor(CardDeck()) @@ -30,7 +30,7 @@ class BlackJackGame { } private fun dealOutAdditionalCards(distributor: Distributor, players: Players) { - players.players.forEach { + players.forEach { dealOutAdditionalCard(distributor, it) } } diff --git a/src/main/kotlin/blackjack/GameResultCalculator.kt b/src/main/kotlin/blackjack/GameResultCalculator.kt index fea34cecc0..07a1de9a38 100644 --- a/src/main/kotlin/blackjack/GameResultCalculator.kt +++ b/src/main/kotlin/blackjack/GameResultCalculator.kt @@ -9,7 +9,7 @@ object GameResultCalculator { fun getResult(dealer: Dealer, players: Players) { val scoreOfDealer = dealer.getScore() val isDealerLose = scoreOfDealer > BlackJackGame.MAX_SCORE - players.players.forEach { + players.forEach { val scoreOfPlayer = it.getScore() it.setGameResult(isDealerLose || scoreOfPlayer > scoreOfDealer) dealer.setGameResult(!isDealerLose && scoreOfDealer > scoreOfPlayer) diff --git a/src/main/kotlin/blackjack/domain/Distributor.kt b/src/main/kotlin/blackjack/domain/Distributor.kt index c2a14851ef..8a7f3e4029 100644 --- a/src/main/kotlin/blackjack/domain/Distributor.kt +++ b/src/main/kotlin/blackjack/domain/Distributor.kt @@ -14,7 +14,7 @@ class Distributor( fun dealOutCards(dealer: Dealer, players: Players) { repeat(DEAL_OUT_CARD_AMOUNT) { dealOutCard(dealer) - players.players.forEach { dealOutCard(it) } + players.forEach { dealOutCard(it) } } } diff --git a/src/main/kotlin/blackjack/domain/Players.kt b/src/main/kotlin/blackjack/domain/Players.kt index 62752fe7d1..2e25403457 100644 --- a/src/main/kotlin/blackjack/domain/Players.kt +++ b/src/main/kotlin/blackjack/domain/Players.kt @@ -1,7 +1,3 @@ package blackjack.domain -data class Players( - val names: List -) { - val players: List = names.map { Player(it) } -} +data class Players(private val players: List) : List by players diff --git a/src/main/kotlin/blackjack/view/DisplayView.kt b/src/main/kotlin/blackjack/view/DisplayView.kt index d59cb455b8..2dfd37b1dc 100644 --- a/src/main/kotlin/blackjack/view/DisplayView.kt +++ b/src/main/kotlin/blackjack/view/DisplayView.kt @@ -8,13 +8,13 @@ import blackjack.domain.Players object DisplayView { fun dealOutCards(players: Players) { - val playersName = players.players.joinToString() + val playersName = players.joinToString() println("딜러와 ${playersName}에게 2장의 카드 나누었습니다.") } fun cardsOfPlayers(dealer: Dealer, players: Players) { cardsOfDealer(dealer) - players.players.forEach { + players.forEach { cardsOfPlayer(it) } } @@ -41,7 +41,7 @@ object DisplayView { fun finalScore(dealer: Dealer, players: Players) { printFinalScore(dealer) - players.players.forEach { printFinalScore(it) } + players.forEach { printFinalScore(it) } } fun result(dealer: Dealer, players: Players) { @@ -49,7 +49,7 @@ object DisplayView { val dealerWinCnt = dealer.gameResults.count { it == GameResult.WIN } val dealerLoseCnt = dealer.gameResults.count { it == GameResult.LOSE } println("딜러: ${dealerWinCnt}승 ${dealerLoseCnt}패") - players.players.forEach { println("${it.name}: ${it.gameResult.description}") } + players.forEach { println("${it.name}: ${it.gameResult.description}") } } private fun printFinalScore(player: Player) { diff --git a/src/test/kotlin/blackjack/PlayerTest.kt b/src/test/kotlin/blackjack/PlayerTest.kt index 874f79b502..a4a6c153ec 100644 --- a/src/test/kotlin/blackjack/PlayerTest.kt +++ b/src/test/kotlin/blackjack/PlayerTest.kt @@ -20,10 +20,10 @@ class PlayerTest : StringSpec({ "쉼표 기준으로 분리된 이름을 받아 Player들을 생성한다" { val nameList = listOf("pobi", "jason") - val players = Players(nameList) + val players = Players(nameList.map { Player(it) }) nameList.all { name -> - players.players.any { player -> + players.any { player -> player.name == name } } shouldBe true From 3e4aa37070b7bdd494fc4e91efe4d6a7c6b20d87 Mon Sep 17 00:00:00 2001 From: theo-94 Date: Sun, 23 Jul 2023 23:59:32 +0900 Subject: [PATCH 7/9] =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20:=20GameResultCalculator=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/blackjack/BlackJackGame.kt | 2 +- .../kotlin/blackjack/GameResultCalculator.kt | 2 +- .../blackjack/GameResultCalculatorTest.kt | 53 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/test/kotlin/blackjack/GameResultCalculatorTest.kt diff --git a/src/main/kotlin/blackjack/BlackJackGame.kt b/src/main/kotlin/blackjack/BlackJackGame.kt index 5aa281a381..15b63f450e 100644 --- a/src/main/kotlin/blackjack/BlackJackGame.kt +++ b/src/main/kotlin/blackjack/BlackJackGame.kt @@ -25,7 +25,7 @@ class BlackJackGame { dealOutAdditionalCard(distributor, dealer) DisplayView.finalScore(dealer, players) - GameResultCalculator.getResult(dealer, players) + GameResultCalculator.setResult(dealer, players) DisplayView.result(dealer, players) } diff --git a/src/main/kotlin/blackjack/GameResultCalculator.kt b/src/main/kotlin/blackjack/GameResultCalculator.kt index 07a1de9a38..be0321a71d 100644 --- a/src/main/kotlin/blackjack/GameResultCalculator.kt +++ b/src/main/kotlin/blackjack/GameResultCalculator.kt @@ -6,7 +6,7 @@ import blackjack.domain.Players object GameResultCalculator { // 딜러와 각 플레이어의 점수를 비교해서 승패를 판별하고 기록함 // 딜러가 21을 초과하면 그 시점까지 남아 있던 플레이어들은 가지고 있는 패에 상관 없이 승리한다 - fun getResult(dealer: Dealer, players: Players) { + fun setResult(dealer: Dealer, players: Players) { val scoreOfDealer = dealer.getScore() val isDealerLose = scoreOfDealer > BlackJackGame.MAX_SCORE players.forEach { diff --git a/src/test/kotlin/blackjack/GameResultCalculatorTest.kt b/src/test/kotlin/blackjack/GameResultCalculatorTest.kt new file mode 100644 index 0000000000..37c0ead0c1 --- /dev/null +++ b/src/test/kotlin/blackjack/GameResultCalculatorTest.kt @@ -0,0 +1,53 @@ +package blackjack + +import blackjack.domain.Dealer +import blackjack.domain.Player +import blackjack.domain.Players +import blackjack.domain.card.Card +import blackjack.domain.card.CardNumber +import blackjack.domain.card.CardSymbol +import blackjack.domain.card.Cards +import io.kotest.core.spec.style.StringSpec +import io.kotest.matchers.shouldBe + +class GameResultCalculatorTest : StringSpec({ + "딜러가 21점을 넘어가면 남아 있던 플레이어들은 점수에 관계 없이 승리한다" { + val dealer = Dealer( + "dealer", + Cards( + mutableListOf( + Card(CardNumber.JACK, CardSymbol.HEART), + Card(CardNumber.QUEEN, CardSymbol.HEART), + Card(CardNumber.KING, CardSymbol.HEART) + ) + ) + ) + val playerUnderMaxScore = Player( + "playerUnderMaxScore", + Cards( + mutableListOf( + Card(CardNumber.ACE, CardSymbol.HEART), + Card(CardNumber.SIX, CardSymbol.HEART), + Card(CardNumber.NINE, CardSymbol.HEART) + ) + ) + ) + val playerOverMaxScore = Player( + "playerOverMaxScore", + Cards( + mutableListOf( + Card(CardNumber.JACK, CardSymbol.HEART), + Card(CardNumber.QUEEN, CardSymbol.HEART), + Card(CardNumber.KING, CardSymbol.HEART) + ) + ) + ) + val players = Players(listOf(playerUnderMaxScore, playerOverMaxScore)) + + GameResultCalculator.setResult(dealer, players) + + players.forEach { + it.gameResult shouldBe GameResult.WIN + } + } +}) From 7547274214f52b2d9604b19a415628b68f99468f Mon Sep 17 00:00:00 2001 From: theo-94 Date: Mon, 24 Jul 2023 00:51:34 +0900 Subject: [PATCH 8/9] =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20:=20Cards=EC=97=90=EB=8F=84=20=EC=9C=84=EC=9E=84=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/blackjack/domain/card/Cards.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/blackjack/domain/card/Cards.kt b/src/main/kotlin/blackjack/domain/card/Cards.kt index 8ad24db9d4..34e315fe34 100644 --- a/src/main/kotlin/blackjack/domain/card/Cards.kt +++ b/src/main/kotlin/blackjack/domain/card/Cards.kt @@ -2,9 +2,7 @@ package blackjack.domain.card import blackjack.BlackJackGame -class Cards( - private val cards: MutableList = mutableListOf() -) { +class Cards(private val cards: MutableList = mutableListOf()) : MutableList by cards { fun addCard(card: Card) { cards += card } @@ -19,12 +17,11 @@ class Cards( } private fun isAceAvailable(score: Int): Boolean { - return cards.any { it.isAce() } - && (score + CardNumber.ACE_ADDITIONAL_SCORE) <= BlackJackGame.MAX_SCORE + return cards.any { it.isAce() } && + (score + CardNumber.ACE_ADDITIONAL_SCORE) <= BlackJackGame.MAX_SCORE } override fun toString(): String { return cards.joinToString() } - } From c8d174160a4dbb13d2f9cb9b5cf061c2ebe6c2e2 Mon Sep 17 00:00:00 2001 From: theo-94 Date: Mon, 24 Jul 2023 00:52:47 +0900 Subject: [PATCH 9/9] =?UTF-8?q?=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20:=20Distributor=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/DistributorTest.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/kotlin/blackjack/domain/DistributorTest.kt diff --git a/src/test/kotlin/blackjack/domain/DistributorTest.kt b/src/test/kotlin/blackjack/domain/DistributorTest.kt new file mode 100644 index 0000000000..5ceaa290c8 --- /dev/null +++ b/src/test/kotlin/blackjack/domain/DistributorTest.kt @@ -0,0 +1,21 @@ +package blackjack.domain + +import blackjack.domain.card.CardDeck +import blackjack.domain.card.Cards +import io.kotest.core.spec.style.StringSpec +import io.kotest.matchers.shouldBe + +class DistributorTest : StringSpec({ + "딜러와 플레이어들에 카드가 2장씩 분배 되었는지" { + val dealer = Dealer("dealer", Cards(mutableListOf())) + val player1 = Player("player1", Cards(mutableListOf())) + val player2 = Player("player2", Cards(mutableListOf())) + val players = Players(listOf(player1, player2)) + + val distributor = Distributor(CardDeck()) + distributor.dealOutCards(dealer, players) + + dealer.cards.size shouldBe 2 + players.forEach { player -> player.cards.size shouldBe 2 } + } +})