Skip to content
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

๐Ÿš€ 4๋‹จ๊ณ„ - ๋ธ”๋ž™์žญ(๋ฒ ํŒ…) #827

Open
wants to merge 4 commits into
base: sjjeong
Choose a base branch
from
32 changes: 14 additions & 18 deletions src/main/kotlin/blackjack/BlackjackApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package blackjack
import blackjack.domain.BlackjackResults
import blackjack.domain.BlackjackShoe
import blackjack.domain.Dealer
import blackjack.domain.Participant
import blackjack.domain.Participants
import blackjack.view.InputView
import blackjack.view.OutputView

Expand All @@ -15,29 +15,25 @@ class BlackjackApplication(
fun run() {
val blackjackShoe = BlackjackShoe()
val (dealer, participantList) = ready(blackjackShoe)
play(dealer = dealer, participantList = participantList, blackjackShoe = blackjackShoe)
finish(dealer = dealer, participantList = participantList)
play(dealer = dealer, participants = participantList, blackjackShoe = blackjackShoe)
finish(dealer = dealer, participants = participantList)
}

private fun ready(blackjackShoe: BlackjackShoe): Pair<Dealer, List<Participant>> {
val participantNames = inputView.getParticipantNames()
private fun ready(blackjackShoe: BlackjackShoe): Pair<Dealer, Participants> {
val participantNames: List<String> = inputView.getParticipantNames()
val participants = Participants(participantNames = participantNames.toTypedArray())
inputView.requestBettingMoney(participants)

val dealer = Dealer()
val participants = participantNames.map { name -> Participant(name.trim()) }

dealer.receiveCard(blackjackShoe.draw())
participants.forEach { participant ->
repeat(2) {
participant.receiveCard(blackjackShoe.draw())
}
}
dealer.setupCard(blackjackShoe = blackjackShoe)
participants.setupCard(blackjackShoe = blackjackShoe)

outputView.showReady(dealer = dealer, participants = participants)
return dealer to participants
}

private fun play(dealer: Dealer, participantList: List<Participant>, blackjackShoe: BlackjackShoe) {
participantList.forEach { participant ->
private fun play(dealer: Dealer, participants: Participants, blackjackShoe: BlackjackShoe) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ready()๋‚˜ play()์˜ ๊ฒฝ์šฐ dealer๏ฟฝ, participants๋ฅผ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ€์ง„ BlackjackGame ๊ฐ์ฒด์—๊ฒŒ ์—ญํ• ์„ ์œ„์ž„ํ•ด๋ณผ ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”. ๐Ÿ˜ƒ
๋ฌผ๋ก  ์ค‘๊ฐ„์— ์ž…๋ ฅ๋ฐ›๋Š” ๋ถ€๋ถ„๋“ค์ด ์žˆ์–ด์„œ, ์กฐ๊ธˆ ์–ด๋ ต๊ฒŒ ๋Š๊ปด์ง€์‹ค ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™๋„ค์š”.

์ด ๋ฐฉํ–ฅ์œผ๋กœ ํ•œ๋ฒˆ ๊ณ ๋ฏผํ•ด๋ณด์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”!

participants.forEach { participant ->
while (participant.canReceiveCard && inputView.getMoreCard(participant)) {
val card = blackjackShoe.draw()
participant.receiveCard(card)
Expand All @@ -52,10 +48,10 @@ class BlackjackApplication(
}
}

private fun finish(dealer: Dealer, participantList: List<Participant>) {
private fun finish(dealer: Dealer, participants: Participants) {
outputView.showDealerInfo(dealer = dealer)
outputView.showParticipantsInfo(participantList)
outputView.showResult(BlackjackResults(dealer = dealer, participants = participantList))
outputView.showParticipantsInfo(participants)
outputView.showResult(BlackjackResults(dealer = dealer, participants = participants))
}

}
Expand Down
23 changes: 11 additions & 12 deletions src/main/kotlin/blackjack/domain/BlackjackResults.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@ class BlackjackResults(
val participants: List<Participant>,
) {

val result: Map<BlackjackResult, List<Participant>> = run {
val result: List<Player> = run {
val dealerScore = dealer.score
participants.groupBy { participant ->
val participantScore = participant.score

when {
participantScore > dealerScore -> BlackjackResult.WIN
participantScore < dealerScore -> BlackjackResult.LOSE
else -> BlackjackResult.DRAW
participants.forEach { participant ->
val participantScore = participant.score
val bettingMoney = when {
(participantScore <= Const.NUMBER_BLACKJACK && participantScore > dealerScore) || dealerScore > Const.NUMBER_BLACKJACK -> participant.bettingMoney
(dealerScore <= Const.NUMBER_BLACKJACK && participantScore < dealerScore) || participantScore > Const.NUMBER_BLACKJACK -> -participant.bettingMoney
else -> 0
}

dealer.money -= bettingMoney
participant.money += bettingMoney
}
}

enum class BlackjackResult {
WIN,
LOSE,
DRAW,
listOf(dealer, *participants.toTypedArray())
}
}
5 changes: 5 additions & 0 deletions src/main/kotlin/blackjack/domain/Const.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package blackjack.domain

object Const {
const val NUMBER_BLACKJACK = 21
}
4 changes: 4 additions & 0 deletions src/main/kotlin/blackjack/domain/Dealer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ data class Dealer(
override val canReceiveCard: Boolean
get() = score <= CAN_RECEIVE_CARD_SCORE

override fun setupCard(blackjackShoe: BlackjackShoe) {
receiveCard(blackjackShoe.draw())
}

companion object {
private const val DEFAULT_DEALER_NAME = "๋”œ๋Ÿฌ"
private const val CAN_RECEIVE_CARD_SCORE = 16
Expand Down
9 changes: 9 additions & 0 deletions src/main/kotlin/blackjack/domain/Participant.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@ package blackjack.domain
data class Participant(
override val name: String
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name ํ”„๋กœํผํ‹ฐ๋Š” ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•  ํ•„์š” ์—†์ด, ๋‹จ์ˆœํžˆ Player์˜ ์ƒ์„ฑ์ž ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋งŒํ•ด์ฃผ๋ฉด ๋  ๊ฒƒ ๊ฐ™์€๋ฐ์š”.
์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์‹  ์ด์œ ๊ฐ€ ์žˆ์œผ์‹ค๊นŒ์š”? ๐Ÿ˜ƒ

) : Player(name = name) {
var bettingMoney: Int = 0

override val canReceiveCard: Boolean
get() {
return score <= CAN_RECEIVE_CARD_SCORE
}

override fun setupCard(blackjackShoe: BlackjackShoe) {
repeat(NUMBER_OF_INIT_CARD) {
receiveCard(blackjackShoe.draw())
}
}

companion object {
private const val CAN_RECEIVE_CARD_SCORE = 21
private const val NUMBER_OF_INIT_CARD = 2
}
}
10 changes: 10 additions & 0 deletions src/main/kotlin/blackjack/domain/Participants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package blackjack.domain

class Participants(private val participants: List<Participant>): List<Participant> by participants {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by ํ‚ค์›Œ๋“œ ํ™œ์šฉ ๐Ÿ‘๐Ÿ’ฏ

ํ˜„์žฌ Participants ์ผ๊ธ€์ปฌ๋ ‰์…˜์„ by ํ‚ค์›Œ๋“œ๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•ด์ฃผ์…จ๋„ค์š”.
by ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์˜ ์žฅ์ ๊ณผ ๋‹จ์ ์„ ์•Œ๊ณ  ๊ณ„์‹ ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. :)

๊ฐ€๋ณ๊ฒŒ ์ฝ”๋ฉ˜ํŠธ๋กœ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”. ๐Ÿ˜


constructor(vararg participantNames: String): this(participantNames.map { name -> Participant(name.trim()) })

fun setupCard(blackjackShoe: BlackjackShoe) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setupCard ๋ผ๋Š” ํ‘œํ˜„๋ณด๋‹ค๋Š” ์กฐ๊ธˆ ๋” (๋Šฅ๋™์ ์ธ) ๊ฐ์ฒด์˜ ์ž…์žฅ์—์„œ ํ–‰์œ„๋ฅผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์€(?) ๋„ค์ด๋ฐ์„ ๊ณ ๋ คํ•ด๋ณด๋ฉด ์–ด๋–จ๊นŒ ์‹ถ์–ด์š”.

์ฐธ๊ฐ€์ž์˜ ์ž…์žฅ์—์„œ ์ดˆ๊ธฐ ํŒจ๋ฅผ ๋ฝ‘๋Š”๋‹ค ์™€ ๊ฐ™์€ ํ–‰์œ„์  ๊ด€์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด

์ฐธ๊ฐ€์ž.์ดˆ๊ธฐ ํŒจ๋ฅผ ๋ฝ‘๋Š”๋‹ค ์™€ ๊ฐ™์ด ํ‘œํ˜„ํ•˜๋ฉด ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์กฐ๊ธˆ ๋” ์‰ฝ์ง€ ์•Š์„๊นŒ์š”? ๐Ÿ˜ƒ

participants.forEach { participant -> participant.setupCard(blackjackShoe) }
}
}
4 changes: 4 additions & 0 deletions src/main/kotlin/blackjack/domain/Player.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ abstract class Player(
return score
}

var money: Int = 0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ผญ ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ ธ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, ๊ฐœ์ธ์ ์ธ ์ƒ๊ฐ์œผ๋กœ๋Š” ์ฝ๊ธฐ์ „์šฉ ํ”„๋กœํผํ‹ฐ๋ณด๋‹ค๋Š” ์‹ค์ œ Palyer์˜ ์ƒํƒœ๊ฐ’์ธ money๊ฐ€ ๋” ์ƒ์œ„์— ์žˆ์–ด์•ผํ•˜์ง€ ์•Š์„๊นŒ ์‹ถ์–ด์š”. ๐Ÿค”


abstract fun setupCard(blackjackShoe: BlackjackShoe)

fun receiveCard(card: Card) {
_cardList.add(card)
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/kotlin/blackjack/view/InputView.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package blackjack.view

import blackjack.domain.Participant
import blackjack.domain.Participants

class InputView {

Expand All @@ -19,4 +20,13 @@ class InputView {
}
}

fun requestBettingMoney(participants: Participants) {
println()
participants.forEach { participant ->
println("${participant.name}์˜ ๋ฐฐํŒ… ๊ธˆ์•ก์€?")
val bettingMoney = readlnOrNull()?.toIntOrNull() ?: error("๋ฐฐํŒ…์€ ")
participant.bettingMoney = bettingMoney
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Participant๊ฐ€ View์—์„œ ๋ฒ ํŒ…์„ ํ•˜๊ณ ์žˆ๊ตฐ์š”? ๐Ÿค”
์ด ๊ธฐ๋Šฅ์€ ๋„๋ฉ”์ธ ๋กœ์ง์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ์š”? ๐Ÿ˜ƒ

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Participant ๊ฐ์ฒด์—๊ฒŒ ๋ฒ ํŒ…์„ํ•˜๋ผ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋ณด๋ฉด ์–ด๋–จ๊นŒ์š”? ๐Ÿ˜ƒ

}
}

}
20 changes: 5 additions & 15 deletions src/main/kotlin/blackjack/view/OutputView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import blackjack.domain.BlackjackResults
import blackjack.domain.Card
import blackjack.domain.Dealer
import blackjack.domain.Participant
import blackjack.domain.Participants

class OutputView {
fun showReady(dealer: Dealer, participants: List<Participant>) {
fun showReady(dealer: Dealer, participants: Participants) {
println("\n${dealer.name}์™€ ${participants.joinToString { it.name }}์—๊ฒŒ 2์žฅ์˜ ๋‚˜๋ˆ„์—ˆ์Šต๋‹ˆ๋‹ค.")

showDealerCard(dealer)
Expand Down Expand Up @@ -39,20 +40,9 @@ class OutputView {
}

fun showResult(blackjackResults: BlackjackResults) {
println("\n## ์ตœ์ข…์ŠนํŒจ")
val result = blackjackResults.result
val participantWin = result[BlackjackResults.BlackjackResult.WIN].orEmpty()
val participantLose = result[BlackjackResults.BlackjackResult.LOSE].orEmpty()
val participantDraw = result[BlackjackResults.BlackjackResult.DRAW].orEmpty()
println("${blackjackResults.dealer.name}: ${participantLose.size}์Šน ${participantWin.size}ํŒจ ${participantDraw.size}๋ฌด")
participantWin.forEach {
println("${it.name}: ์Šน")
}
participantLose.forEach {
println("${it.name}: ํŒจ")
}
participantDraw.forEach {
println("${it.name}: ๋ฌด")
println("\n## ์ตœ์ข… ์ˆ˜์ต")
blackjackResults.result.forEach { player ->
println("${player.name}: ${player.money}")
}
}

Expand Down
59 changes: 53 additions & 6 deletions src/test/kotlin/blackjack/BlackjackResultsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ class BlackjackResultsTest {
Participant("a").apply {
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.NINE))
bettingMoney = 10000
}
)
)

val actual = blackjackResults.result[BlackjackResults.BlackjackResult.LOSE]?.size
val actual = blackjackResults.result.first().money
actual.shouldNotBeNull()
actual shouldBe 1
actual shouldBe 10000
}

@Test
Expand All @@ -42,13 +43,14 @@ class BlackjackResultsTest {
Participant("a").apply {
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
bettingMoney = 10000
}
)
)

val actual = blackjackResults.result[BlackjackResults.BlackjackResult.WIN]?.size
val actual = blackjackResults.result.first().money
actual.shouldNotBeNull()
actual shouldBe 1
actual shouldBe -10000
}

@Test
Expand All @@ -62,12 +64,57 @@ class BlackjackResultsTest {
Participant("a").apply {
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
bettingMoney = 10000
}
)
)

val actual = blackjackResults.result[BlackjackResults.BlackjackResult.DRAW]?.size
val actual = blackjackResults.result.first().money
actual.shouldNotBeNull()
actual shouldBe 1
actual shouldBe 0
}

@Test
fun `๋”œ๋Ÿฌ๊ฐ€ ๋ฒ„์ŠคํŠธ๋ฉด ์ฐธ๊ฐ€์ž์˜ ์Šน`() {
val blackjackResults = BlackjackResults(
Dealer().apply {
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
},
listOf(
Participant("a").apply {
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
bettingMoney = 10000
},
)
)

val actual = blackjackResults.result.first().money
actual.shouldNotBeNull()
actual shouldBe -10000
}

@Test
fun `์ฐธ๊ฐ€์ž๊ฐ€ ๋ฒ„์ŠคํŠธ๋ฉด ๋”œ๋Ÿฌ๊ฐ€ ์Šน`() {
val blackjackResults = BlackjackResults(
Dealer().apply {
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
},
listOf(
Participant("a").apply {
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
receiveCard(Card(Suit.SPADE, Rank.KING))
bettingMoney = 10000
},
)
)

val actual = blackjackResults.result.first().money
actual.shouldNotBeNull()
actual shouldBe 10000
}
}