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

[부나] 2단계 블랙잭 제출합니다. #51

Merged
merged 54 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
cee6072
refactor: 블랙잭 시작 및 결과 출력을 콜백으로 변경
tmdgh1592 Mar 9, 2023
8fb287a
refactor: 블랙잭 클래스에서 카드를 뽑는 메서드를 하나로 통합
tmdgh1592 Mar 9, 2023
c4fb5d2
refactor: 카드 목록 클래스의 초기화 블럭 제거
tmdgh1592 Mar 9, 2023
0a9b547
refactor: 승패 여부 비교시 버스트면 무조건 패배를 반환하도록 변경
tmdgh1592 Mar 9, 2023
5177a64
refactor: 플레이어와 딜러의 카드 뽑는 메서드를 하나로 병합
tmdgh1592 Mar 9, 2023
07d9b0f
refactor: 딜러가 카드를 뽑을 수 있는 최대 점수를 나타내는 상수명 변경
tmdgh1592 Mar 9, 2023
d8b7aa7
feat: 배팅 금액 구현
tmdgh1592 Mar 10, 2023
7bf3611
refactor: 도메인 패키지 분리
tmdgh1592 Mar 10, 2023
132e040
docs: 카드 상태에 대한 기능 목록 추가
tmdgh1592 Mar 10, 2023
a071837
refactor: 도메인 모델의 테스트 코드 패키지 분리
tmdgh1592 Mar 10, 2023
e414092
feat: 카드 상태 구현
tmdgh1592 Mar 10, 2023
176986d
feat: 카드 상태에 수익 계산 기능 구현
tmdgh1592 Mar 10, 2023
877b078
refactor: 카드를 뽑을 때 참여자의 카드 상태를 확인하도록 변경
tmdgh1592 Mar 11, 2023
2a8cb70
feat: 수익을 계산하는 기능 구현
tmdgh1592 Mar 11, 2023
f687945
refactor: 불필요한 코드 제거 및 코드 간결화
tmdgh1592 Mar 11, 2023
f4a21ea
refactor: 불필요한 코드 제거
tmdgh1592 Mar 11, 2023
92798ed
fix: 상대방이 버스트가 아닐 때 원금 회수받는 오류 수정
tmdgh1592 Mar 11, 2023
4595c77
refactor: 게임 결과 반환 형식 변경
tmdgh1592 Mar 11, 2023
7ee70b8
refactor: 베팅 금액에서 최소 금액 비교시 Extension 사용하지 않도록 변경
tmdgh1592 Mar 12, 2023
8af1ffe
refactor: 블랙잭의 객체 생성시 카드덱과 참여자를 전달받도록 수정
tmdgh1592 Mar 12, 2023
0f7a4a4
fix: 딜러가 스테이할 때 상태 변화가 발생하지 않는 오류 수정
tmdgh1592 Mar 12, 2023
896d407
refactor: 첫 카드 드로우시 호출되는 콜백을 블랙잭 클래스에서 호출하도록 변경
tmdgh1592 Mar 12, 2023
ee7b7ed
refactor: 버스트 상태의 수익률 프로퍼티를 -1.0으로 변경
tmdgh1592 Mar 12, 2023
83aba92
refactor: 더 이상 카드를 뽑을 수 없는 상태에서 카드를 뽑거나 스테이시 자기 자신을 반환하도록 변경
tmdgh1592 Mar 12, 2023
41892b4
refactor: 스테이 상태에서 수익 계산 로직 일부를 when으로 변경
tmdgh1592 Mar 12, 2023
16f09ab
refactor: 카드를 뽑을 수 있는지 여부를 드로우시 참여자 내부에서 확인하도록 변경
tmdgh1592 Mar 12, 2023
35d5537
refactor: 카드 상태에서 종료됐는지가 아니라 아직 드로윙중인지 확인하도록 변경
tmdgh1592 Mar 12, 2023
74d0f87
feat: 참여자 목록에 딜러가 포함되어 있는지 확인하는 기능 구현
tmdgh1592 Mar 12, 2023
9d851a4
refactor: 카드 상태에서 드로우시 검사를 구현메서드 하지 않도록 변경
tmdgh1592 Mar 12, 2023
4c25cca
refactor: 카드 목록에 카드 추가시 새로운 카드 목록 객체를 반환하도록 변경
tmdgh1592 Mar 12, 2023
cf5c16f
refactor: 콜백 대신 블랙잭 이벤트 리스너를 통해 전달하도록 변경
tmdgh1592 Mar 12, 2023
62e1058
refactor: BetMoney가 Money를 조합하도록 변경
tmdgh1592 Mar 12, 2023
b1caf71
refactor: 블랙잭 이벤트 리스너를 listener 패키지로 이동
tmdgh1592 Mar 12, 2023
72ed81c
refactor: 수익을 얻는 기능을 플레이어와 딜러에서 각각 수행하도록 변경
tmdgh1592 Mar 12, 2023
c0762c4
refactor: 드로우 함수에서 무조건 카드를 뽑는 플래그명 변경
tmdgh1592 Mar 13, 2023
23b598f
refactor: 베팅 금액이 정수를 입력받을 수 있도록 변경
tmdgh1592 Mar 13, 2023
bd1d2fa
refactor: 금액을 더하는 기능 제거
tmdgh1592 Mar 13, 2023
f56c2b1
test: 참여자 테스트 코드 수정
tmdgh1592 Mar 13, 2023
11a0413
test: 도메인 테스트 코드 작성
tmdgh1592 Mar 13, 2023
db927b9
refactor: 출력뷰에서 블랙잭 이벤트 리스너를 구현하도록 변경
tmdgh1592 Mar 13, 2023
29d1702
test: 배팅 금액이 음수인지 체크하는 테스트 코드명 변경
tmdgh1592 Mar 13, 2023
4f1168c
refactor: 참여자 수익 계산시 상대방 탐색 로직 변경
tmdgh1592 Mar 13, 2023
e9b1bb8
refactor: 딜러의 수익을 구하는 코드를 체이닝 형식으로 변경
tmdgh1592 Mar 13, 2023
ced7b32
refactor: 블랙잭 시작 메서드의 로직 분리
tmdgh1592 Mar 13, 2023
cab990f
refactor: 카드 종료 상태에서 earningRate 접근제한자를 protected로 변경
tmdgh1592 Mar 13, 2023
9ca1c95
refactor: 참여자들의 최대 드로우 가능 점수를 각 클래스의 동반 객체에서 정의하도록 변경
tmdgh1592 Mar 13, 2023
0df5719
refactor: 참여자 목록에 딜려 검증과 동시에 프로퍼티 초기화 하도록 변경
tmdgh1592 Mar 13, 2023
d3f52de
refactor: 참여자 목록에 딜려 검증과 동시에 프로퍼티 초기화 하도록 변경
tmdgh1592 Mar 13, 2023
5359d41
test: 실패 테스트 코드 수정
tmdgh1592 Mar 13, 2023
88f0528
refactor: 참여자 스테이 메서드 접근제한자를 protected로 변경
tmdgh1592 Mar 13, 2023
138c879
fix: 딜러가 플레이어들의 손익과 동일한 값을 반환하는 버그 수정
tmdgh1592 Mar 13, 2023
7e32de2
test: 딜러 손익 계산하는 테스트 추가
tmdgh1592 Mar 13, 2023
3f8534f
refactor: 딜러가 카드를 뽑았을 때 더 뽑을 수 없으면 스테이 상태로 반환하도록 변경
tmdgh1592 Mar 13, 2023
679ab4f
test: 참여자들이 순서대로 카드를 뽑는 테스트 코드 변경
tmdgh1592 Mar 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 42 additions & 11 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,87 @@
- 게임을 완료한 후 각 플레이어별로 승패를 출력한다.

# 기능 목록
- 카드 모양
### 카드 모양
- [x] 카드 모양에는 스페이드, 다이아몬드, 하트, 클로버가 있다.

- 카드 숫자
### 카드 숫자
- [x] 카드 숫자의 범위는 1부터 13이다.
- [x] 카드 숫자를 문자로 반환한다.
- [x] 1, 11, 12, 13은 각각 A, J, Q, K로 반환한다.
- [x] 2 ~ 10은 그대로 반환한다.
- [x] 카드 숫자를 정수형으로 반환한다.

- 카드
### 카드
- [x] 카드는 각 모양별로 2부터 10, A, J, Q, K가 존재한다.

- 플레이어의 카드 목록
### 플레이어의 카드 목록
- [x] 카드 목록에 카드를 추가한다.
- [x] 총 점수를 반환한다.
- [x] 단, A는 기존 총 점수에 11점을 더한 값이 21점 이하이면 11점으로 계산하고, 21점을 초과하면 1점으로 계산한다.
- [x] 단, J, Q, K는 모두 10점으로 계산한다.
- [x] 2 ~ 10은 그대로 계산한다.

- 카드덱
### 카드덱
- [x] 카드 하나를 뽑는다.
- [x] 카드덱은 아직 뽑히지 않은 카드를 갖는다.
- [x] 뽑은 카드는 아직 뽑히지 않은 카드 중 하나여야 한다.

- 플레이어
### 플레이어
- [x] 플레이어는 이름을 갖는다.
- [x] 플레이어는 카드 목록에 카드를 추가한다.
- [x] 플레이어는 자신이 뽑은 카드 목록을 갖는다.
- [x] 플레이어는 카드의 합이 21을 초과하지 않는지 확인한다.
- [x] 자신의 점수를 반환한다.
- [x] 자신이 가진 카드를 반환한다.

- 플레이어들
### 플레이어들
- [x] 모든 플레이어의 카드를 2장씩 뽑는다.

- 딜러
### 딜러
- [x] 딜러는 스테이인지 확인한다.
- [x] 카드의 합이 17점 이상이면 스테이이다.
- [x] 카드의 합이 16점 이하이면 스테이가 아니다.
- [x] 딜러는 자신이 보유한 첫번째 카드를 반환한다.

- 승부 결과
### 승부 결과
- [x] 플레이어의 승패를 결정한다.
- [x] 플레이어가 21점을 초과하면 패배한다.
- [x] 딜러만 21점을 초과하면 플레이어가 승리한다.
- [x] 딜러와 플레이어 모두 21점을 초과하지 않고 플레이어가 딜러보다 점수가 높으면 플레이어가 승리한다.
- [x] 딜러와 플레이어 모두 21점을 초과하지 않고 플레이어와 딜러의 점수가 같으면 무승부이다.
- [x] 딜러와 플레이어 모두 21점을 초과하지 않고 딜러가 플레이어보다 점수가 높으면 플레이어가 패배한다.

- 명령어
### 명령어
- [x] 명령어는 y 또는 n이다.
- [x] 단, 대소문자를 구분하지 않는다.
- [x] 단, 대소문자를 구분하지 않는다.

### 배팅 금액
- [x] 배팅 금액은 1000원 단위의 양수이다.

### 카드 상태
- [ ] `Running` 카드를 뽑을 수 있는 상태는 2가지이다.
- [x] `Started` 카드를 2장 미만 보유하여 추가로 뽑아야 하는 상태이다.
- 드로우
- [x] 총 뽑은 카드가 2장 미만이라면 Started 상태를 반환한다.
- [x] 처음 카드 2장이 21점 미만이면 Hit 상태를 반환한다.
- [x] 처음 카드 2장이 21점이면 Blackjack 상태를 반환한다.
- [x] `Hit` 카드를 2장 이상 보유하며 추가로 뽑을 수 있는 상태이다.
- 드로우
- [x] 카드 점수가 21점 초과이면 Bust 상태를 반환한다.
- [x] 카드 점수가 21점 이하이면 Hit 상태를 반환한다.
- [x] `Finished` 카드를 뽑을 수 없는 상태는 3가지이다.
- [x] `Blackjack` 처음 2장의 카드 점수의 합이 21점인 상태이다.
- [x] `Stay` 카드를 더 뽑지 않고 상태를 마친 상태이다.
- [x] `Bust` 카드 점수가 21점을 초과한 상태이다.
- [x] Stay 상태를 반환한다.

### 수익 계산
- [x] `Running` 상태는 수익을 계산할 수 없다.
- [x] `Player`가 `Bust`이면 투자 금액을 모두 잃는다.
- [x] `Dealer`가 `Bust`이면 `Bust`가 아닌 `Player`들은 투자한 금액만큼 수익을 얻는다. (플레이어가 투자한 금액만큼 수익을 잃는다.)
- [x] 서로 `Blackjack`이면 투자 금액을 그대로 반환한다. (수익 없음)
- [x] `Player`만 `Blackjack`이면 투자 금액의 `1.5배`를 반환한다.
- [x] 서로 `Stay`일 때 점수를 비교한다.
- [x] 점수가 같으면 무승부이다. (수익 없음)
- [x] 점수가 높은 참여자가 승리한다. (투자한 금액만큼 수익을 얻는다.)
- [x] 점수가 낮은 참여자는 패배한다. (투자 금액을 모두 잃는다.)
3 changes: 3 additions & 0 deletions src/main/kotlin/blackjack/Extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package blackjack

fun Int.isGreaterThan(value: Int): Boolean = this > value
34 changes: 8 additions & 26 deletions src/main/kotlin/blackjack/controller/BlackjackController.kt
Original file line number Diff line number Diff line change
@@ -1,36 +1,18 @@
package blackjack.controller

import blackjack.domain.Blackjack
import blackjack.domain.CardDeck
import blackjack.domain.Player
import blackjack.domain.card.CardDeck
import blackjack.view.InputView
import blackjack.view.OutputView

class BlackjackController {
fun start() {
with(initBlackjack()) {
setUpCard(this)

val result = start(onDrawn = OutputView::printDrawn)
OutputView.printBlackjackResult(result)
}
}

private fun initBlackjack(): Blackjack = Blackjack(CardDeck(), enrollPlayers())

private fun enrollPlayers(): List<Player> = InputView.inputNames().map { name ->
Player(name, needToDraw = {
InputView.inputDrawCommand(name)
})
}

private fun setUpCard(blackJack: Blackjack) {
drawInitialCards(blackJack)
OutputView.printFirstOpenCards(blackJack.getFirstOpenCards())
OutputView.printInterval()
}

private fun drawInitialCards(blackJack: Blackjack) {
blackJack.readyToStart()
Blackjack(CardDeck()).start(
players = InputView.inputPlayers(),
onStartFirstDrawn = OutputView::printFirstDrawnMessage,
onFirstDrawn = OutputView::printFirstOpenCards,
onDrawnMore = OutputView::printAllCards,
onEndGame = OutputView::printBlackjackResult
)
}
}
33 changes: 18 additions & 15 deletions src/main/kotlin/blackjack/domain/Blackjack.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package blackjack.domain

class Blackjack(private val deck: CardDeck, private val participants: Participants) {
constructor(deck: CardDeck, players: List<Player>) : this(deck, Participants(listOf(Dealer()) + players))
import blackjack.domain.card.CardDeck
import blackjack.domain.participant.Dealer
import blackjack.domain.participant.Participant
import blackjack.domain.participant.Participants
import blackjack.domain.participant.Player
import blackjack.domain.result.GameResult

fun readyToStart() {
participants.drawFirst(deck)
}

fun start(onDrawn: (Participant) -> Unit): BlackjackResult {
participants.takePlayerTurns(deck, onDrawn)
participants.takeDealerTurns(deck, onDrawn)
class Blackjack(private val deck: CardDeck) {
fun start(
players: List<Player>,
onStartFirstDrawn: (Participants) -> Unit,
onFirstDrawn: (Participant) -> Unit,
onDrawnMore: (Participant) -> Unit,
onEndGame: (List<GameResult>) -> Unit,
) {
val finishedParticipants = Participants(players + Dealer())
.drawFirst(deck, onStartFirstDrawn, onFirstDrawn)
.takeTurns(deck, onDrawnMore)

return BlackjackResult(
participants.getCardResults(),
participants.getMatchResults(),
)
onEndGame(finishedParticipants.getGameResult())
}

fun getFirstOpenCards(): Map<String, List<Card>> = participants.getFirstOpenCards()
}
6 changes: 0 additions & 6 deletions src/main/kotlin/blackjack/domain/BlackjackResult.kt

This file was deleted.

7 changes: 0 additions & 7 deletions src/main/kotlin/blackjack/domain/CardResult.kt

This file was deleted.

11 changes: 0 additions & 11 deletions src/main/kotlin/blackjack/domain/Dealer.kt

This file was deleted.

5 changes: 0 additions & 5 deletions src/main/kotlin/blackjack/domain/GameResult.kt

This file was deleted.

8 changes: 0 additions & 8 deletions src/main/kotlin/blackjack/domain/MatchResult.kt

This file was deleted.

32 changes: 0 additions & 32 deletions src/main/kotlin/blackjack/domain/Participant.kt

This file was deleted.

84 changes: 0 additions & 84 deletions src/main/kotlin/blackjack/domain/Participants.kt

This file was deleted.

7 changes: 0 additions & 7 deletions src/main/kotlin/blackjack/domain/Player.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package blackjack.domain
package blackjack.domain.card

data class Card(val number: CardNumber, val suit: Suit) {
fun getScore(): Int = number.score
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package blackjack.domain
package blackjack.domain.card

class CardDeck(deck: List<Card> = Card.all().shuffled()) {
constructor(vararg cards: Card) : this(cards.toList())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package blackjack.domain
package blackjack.domain.card

enum class CardNumber(val score: Int) {
ACE(1),
Expand Down
Loading