Skip to content

Commit 7cff569

Browse files
committed
feat: 딜러가 21을 초과하면 남은 플레이어들은 패에 상관없이 승리한다
1 parent 6f38f2b commit 7cff569

File tree

8 files changed

+120
-15
lines changed

8 files changed

+120
-15
lines changed

src/main/kotlin/blackjack/domain/Card.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ data class Card(
66
val rank: Rank,
77
val suit: Suit,
88
) {
9-
val score = rank.score
9+
val score: Int
10+
get() = rank.score
1011

11-
fun isAce(): Boolean {
12-
return rank == ACE
13-
}
12+
val isAce: Boolean
13+
get() = rank == ACE
1414

1515
companion object {
1616
val ALL: List<Card> =

src/main/kotlin/blackjack/domain/Cards.kt

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,35 @@
11
package blackjack.domain
22

3+
import blackjack.domain.MatchResult.DRAW
4+
import blackjack.domain.MatchResult.LOSS
5+
import blackjack.domain.MatchResult.WIN
6+
37
data class Cards(val values: List<Card>) {
48
val score: Int
59
get() = calculateScore()
610

11+
val isBust: Boolean
12+
get() = calculateScore() > BLACKJACK_SCORE_LIMIT
13+
714
fun scoreLowerThan(limit: Int): Boolean {
815
return score < limit
916
}
1017

18+
fun compareScore(other: Cards): MatchResult {
19+
return when {
20+
score > other.score -> WIN
21+
score < other.score -> LOSS
22+
else -> DRAW
23+
}
24+
}
25+
1126
fun add(card: Card): Cards {
1227
return Cards(values + card)
1328
}
1429

1530
private fun calculateScore(): Int {
1631
val totalScore = values.sumOf { it.score }
17-
var aceCount = values.count { it.isAce() }
32+
var aceCount = values.count { it.isAce }
1833

1934
var adjustedScore = totalScore
2035
while (adjustedScore > BLACKJACK_SCORE_LIMIT && aceCount > 0) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package blackjack.domain
2+
3+
enum class MatchResult {
4+
WIN,
5+
LOSS,
6+
DRAW,
7+
}

src/main/kotlin/blackjack/domain/Participant.kt

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package blackjack.domain
22

3+
import blackjack.domain.MatchResult.WIN
4+
35
sealed class Participant(val name: String, val cards: Cards) {
46
abstract fun canHit(): Boolean
57

@@ -21,6 +23,13 @@ class Player(name: String, cards: Cards) : Participant(name, cards) {
2123
return Player(this.name, cards.add(card))
2224
}
2325

26+
fun compareScore(dealer: Dealer): MatchResult {
27+
if (dealer.isBust) {
28+
return WIN
29+
}
30+
return cards.compareScore(dealer.cards)
31+
}
32+
2433
companion object {
2534
private const val PLAYER_SCORE_LIMIT = 21
2635

@@ -31,6 +40,9 @@ class Player(name: String, cards: Cards) : Participant(name, cards) {
3140
}
3241

3342
class Dealer(cards: Cards) : Participant("딜러", cards) {
43+
val isBust: Boolean
44+
get() = cards.isBust
45+
3446
override fun canHit(): Boolean {
3547
return cards.scoreLowerThan(DEALER_SCORE_LIMIT)
3648
}

src/test/kotlin/blackjack/domain/CardTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ class CardTest : StringSpec({
1010
"카드는 에이스로 만들어진다면 에이스 카드이다" {
1111
val card = Card(ACE, SPADE)
1212

13-
card.isAce() shouldBe true
13+
card.isAce shouldBe true
1414
}
1515

1616
"카드는 스페이드로 만들어진다면 에이스 카드가 아니다" {
1717
val card = Card(THREE, SPADE)
1818

19-
card.isAce() shouldBe false
19+
card.isAce shouldBe false
2020
}
2121
})

src/test/kotlin/blackjack/domain/GameTableTest.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package blackjack.domain
22

3-
import blackjack.fixtures.createUsers
3+
import blackjack.fixtures.createPlayers
44
import io.kotest.core.spec.style.StringSpec
55
import io.kotest.matchers.shouldBe
66

77
class GameTableTest : StringSpec({
88
"최초 딜 시 카드를 2장 나누어준다" {
9-
val initCardReceivedUsers = GameTable(Deck.create()).dealInitCard(createUsers())
9+
val players = GameTable(Deck.create()).dealInitCard(createPlayers())
1010

11-
initCardReceivedUsers.forEach {
11+
players.forEach {
1212
it.cards.values.size shouldBe 2
1313
}
1414
}

src/test/kotlin/blackjack/domain/PlayerTest.kt

+75-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
package blackjack.domain
22

3+
import blackjack.domain.MatchResult.DRAW
4+
import blackjack.domain.MatchResult.LOSS
5+
import blackjack.domain.MatchResult.WIN
6+
import blackjack.domain.Suit.CLUB
7+
import blackjack.domain.Suit.DIAMOND
8+
import blackjack.domain.Suit.HEART
9+
import blackjack.domain.Suit.SPADE
310
import blackjack.fixtures.createCard
411
import io.kotest.core.spec.style.StringSpec
512
import io.kotest.data.forAll
613
import io.kotest.data.headers
714
import io.kotest.data.row
815
import io.kotest.data.table
16+
import io.kotest.inspectors.forAll
917
import io.kotest.matchers.shouldBe
1018

1119
class PlayerTest : StringSpec({
12-
"유저는 카드목록의 점수합이 21점 미만일 경우 카드를 더 받을 수 있다" {
20+
"플레이어는 카드목록의 점수합이 21점 미만일 경우 카드를 더 받을 수 있다" {
1321
table(
1422
headers("ranks"),
1523
row(listOf("2", "3", "4")),
@@ -23,7 +31,7 @@ class PlayerTest : StringSpec({
2331
}
2432
}
2533

26-
"유저는 카드목록의 점수합이 21점 이상할 경우 카드를 더 받을 수 없다" {
34+
"플레이어는 카드목록의 점수합이 21점 이상할 경우 카드를 더 받을 수 없다" {
2735
table(
2836
headers("ranks", "score"),
2937
row(listOf("J", "Q", "K"), 30),
@@ -39,7 +47,7 @@ class PlayerTest : StringSpec({
3947
}
4048
}
4149

42-
"유저는 카드 2장을 받은 후 점수 합이 21점인 경우 카드를 더 받지 못한다" {
50+
"플레이어는 카드 2장을 받은 후 점수 합이 21점인 경우 카드를 더 받지 못한다" {
4351
val cards = Cards(emptyList())
4452
val player =
4553
Player("홍길동", cards)
@@ -49,7 +57,7 @@ class PlayerTest : StringSpec({
4957
player.canHit() shouldBe false
5058
}
5159

52-
"유저는 카드 2장을 받은 후 점수 합이 21점 미만인 경우 카드를 더 받을 수 있다" {
60+
"플레이어는 카드 2장을 받은 후 점수 합이 21점 미만인 경우 카드를 더 받을 수 있다" {
5361
val cards = Cards(emptyList())
5462
val player =
5563
Player("홍길동", cards)
@@ -58,4 +66,67 @@ class PlayerTest : StringSpec({
5866

5967
player.canHit() shouldBe true
6068
}
69+
70+
"플레이어가 딜러보다 점수가 높다면 승리한다" {
71+
val cards = Cards(emptyList())
72+
val player =
73+
Player("홍길동", cards)
74+
.hit(createCard("10"))
75+
.hit(createCard("5"))
76+
val dealer = Dealer.create().hit(createCard("10"))
77+
78+
player.compareScore(dealer) shouldBe WIN
79+
}
80+
81+
"플레이어가 딜러보다 점수가 낮다면 패배한다" {
82+
val cards = Cards(emptyList())
83+
val player =
84+
Player("홍길동", cards)
85+
.hit(createCard("5"))
86+
val dealer =
87+
Dealer.create()
88+
.hit(createCard("10"))
89+
90+
player.compareScore(dealer) shouldBe LOSS
91+
}
92+
93+
"플레이어가 딜러보와 점수가 같다면 무승부다" {
94+
val cards = Cards(emptyList())
95+
val player =
96+
Player("홍길동", cards)
97+
.hit(createCard("5"))
98+
val dealer =
99+
Dealer.create()
100+
.hit(createCard("5"))
101+
102+
player.compareScore(dealer) shouldBe DRAW
103+
}
104+
105+
"플레이어의 패에 상관없이 딜러의 점수가 21점이 넘는다면 승리한다" {
106+
val cards = Cards(emptyList())
107+
val biggerScorePlayer =
108+
Player("김큰점수", cards)
109+
.hit(createCard("K", SPADE))
110+
.hit(createCard("Q", SPADE))
111+
.hit(createCard("J", SPADE))
112+
val smallerScorePlayer =
113+
Player("박작은점수", cards)
114+
.hit(createCard("K", HEART))
115+
.hit(createCard("Q", HEART))
116+
.hit(createCard("J", HEART))
117+
val sameScorePlayer =
118+
Player("최같은점수", cards)
119+
.hit(createCard("10", CLUB))
120+
.hit(createCard("10", CLUB))
121+
.hit(createCard("3", CLUB))
122+
val dealer =
123+
Dealer.create()
124+
.hit(createCard("10", DIAMOND))
125+
.hit(createCard("10", DIAMOND))
126+
.hit(createCard("3", DIAMOND))
127+
128+
listOf(biggerScorePlayer, smallerScorePlayer, sameScorePlayer).forAll { player ->
129+
player.compareScore(dealer) shouldBe WIN
130+
}
131+
}
61132
})

src/test/kotlin/blackjack/fixtures/UserFixtures.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ package blackjack.fixtures
33
import blackjack.domain.Cards
44
import blackjack.domain.Player
55

6-
fun createUsers(names: List<String> = listOf("홍길동", "홍길덩")): List<Player> {
6+
fun createPlayers(names: List<String> = listOf("홍길동", "홍길덩")): List<Player> {
77
return names.map { Player(it, Cards(emptyList())) }
88
}

0 commit comments

Comments
 (0)