-
Notifications
You must be signed in to change notification settings - Fork 467
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단계 - 블랙잭 베팅] 밍트(김명지) 미션 제출합니다. #917
Changes from 74 commits
1d49443
ed249a7
11f3d12
8b59a43
7822af9
e90dbd5
695f8c2
f334a71
f0035cf
d168ccd
80cbd3e
5e7d3f9
cd4e9d3
4eb0495
ea6ac4d
b41d91c
9b9621d
771552d
b6a7c6d
9ad6f26
52bc2f3
28a7f5b
703b530
3ea4a2d
0bdd7e5
75b083a
2ac950b
e26a62f
43a2777
2891c37
4794cc4
aaa5ec1
b3755bf
3b82b14
88383ef
3173adc
0e443d4
dce4437
fef342f
8b1440c
c7f2053
c1065b3
af96464
e4b1985
1cf9c4f
29cd964
e6b787d
625c364
4239190
85311bf
44ca30e
b547d5f
e17290f
3998e14
7751769
af26315
034c56a
320b8dc
d2dec38
49287fe
b734b57
6b5538e
4968d7f
65f4a1a
30d1256
752936a
1d5ed4a
e005f9d
565fc34
c6ebc74
40f8b2d
fff6821
28bd9e3
ae7730a
e6a314f
1788c58
fb87c4d
88c36af
0970a53
895516a
db803c2
b27a59c
7f578a0
684059f
332b645
dce6e70
077c78d
f57d475
23c121e
421011d
f290b64
d3fc276
2118e6a
19ab440
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,19 +1,21 @@ | ||
package blackjack; | ||
|
||
import blackjack.controller.BlackjackController; | ||
import blackjack.controller.Controller; | ||
import blackjack.blackjack.card.Deck; | ||
import blackjack.view.InputView; | ||
import blackjack.view.ResultView; | ||
import java.util.Scanner; | ||
|
||
public class Application { | ||
public final class Application { | ||
|
||
public static void main(String[] args) { | ||
final BlackjackController blackjackController = makeController(); | ||
blackjackController.run(); | ||
Controller controller = makeController(); | ||
controller.startGame(Deck.shuffled()); | ||
} | ||
|
||
private static BlackjackController makeController() { | ||
final InputView inputView = new InputView(); | ||
private static Controller makeController() { | ||
final InputView inputView = new InputView(new Scanner(System.in)); | ||
final ResultView resultView = new ResultView(); | ||
return new BlackjackController(inputView, resultView); | ||
return new Controller(inputView, resultView); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package blackjack.blackjack; | ||
|
||
import blackjack.blackjack.card.Deck; | ||
import blackjack.blackjack.participant.Participants; | ||
import blackjack.blackjack.participant.Player; | ||
import blackjack.blackjack.result.ProfitResult; | ||
import java.util.ArrayDeque; | ||
import java.util.Queue; | ||
|
||
public final class BlackjackGame { | ||
|
||
private final Participants participants; | ||
|
||
private Queue<Player> players; | ||
|
||
public BlackjackGame(final Participants participants) { | ||
this.participants = participants; | ||
this.players = new ArrayDeque<>(participants.findHitEligiblePlayers().getPlayers()); | ||
} | ||
|
||
public void dealInitialCards(final Deck deck) { | ||
participants.dealInitialCards(deck); | ||
} | ||
|
||
public boolean isPlaying() { | ||
return !players.isEmpty(); | ||
} | ||
|
||
public Player findCurrentTurnPlayer() { | ||
return players.poll(); | ||
} | ||
|
||
public ProfitResult makeProfitResult() { | ||
return participants.makeDealerWinningResult(); | ||
} | ||
|
||
public Participants getParticipants() { | ||
return participants; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package blackjack.blackjack.card; | ||
|
||
import java.util.Objects; | ||
|
||
public final class Card { | ||
|
||
private final Suit suit; | ||
private final Denomination denomination; | ||
|
||
public Card(final Suit suit, final Denomination denomination) { | ||
this.suit = suit; | ||
this.denomination = denomination; | ||
} | ||
|
||
public boolean isAce() { | ||
return this.denomination == Denomination.A; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (!(o instanceof final Card card)) { | ||
return false; | ||
} | ||
return suit == card.suit && denomination == card.denomination; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(suit, denomination); | ||
} | ||
|
||
public Suit getSuit() { | ||
return suit; | ||
} | ||
|
||
public String getDenominationName() { | ||
return denomination.getName(); | ||
} | ||
|
||
public int getCardMinNumber() { | ||
return denomination.getMinNumber(); | ||
} | ||
|
||
public int getCardMaxNumber() { | ||
return denomination.getMaxNumber(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package blackjack.blackjack.card; | ||
|
||
import blackjack.blackjack.card.generator.DeckGenerator; | ||
import blackjack.blackjack.card.generator.ShuffleDeckGenerator; | ||
import blackjack.util.ExceptionMessage; | ||
import java.util.Deque; | ||
import java.util.stream.IntStream; | ||
|
||
public final class Deck { | ||
|
||
private final Deque<Card> cards; | ||
|
||
public Deck(final DeckGenerator deckGenerator) { | ||
this.cards = deckGenerator.makeDeck(); | ||
} | ||
|
||
public static Deck shuffled() { | ||
return new Deck(new ShuffleDeckGenerator()); | ||
} | ||
|
||
public Hand drawCardsByCount(final int count) { | ||
return new Hand(IntStream.range(0, count) | ||
.mapToObj(o -> drawCard()) | ||
.toList()); | ||
} | ||
|
||
public Card drawCard() { | ||
Card card = cards.pollFirst(); | ||
if (card == null) { | ||
throw new IllegalStateException(ExceptionMessage.makeMessage("[ERROR] 카드가 더이상 없습니다.")); | ||
} | ||
return card; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package blackjack.blackjack.card; | ||
|
||
import java.util.Set; | ||
|
||
public enum Denomination { | ||
|
||
A(1), | ||
TWO(2), | ||
THREE(3), | ||
FOUR(4), | ||
FIVE(5), | ||
SIX(6), | ||
SEVEN(7), | ||
EIGHT(8), | ||
NINE(9), | ||
TEN(10), | ||
K(10), | ||
Q(10), | ||
J(10); | ||
|
||
private static final Set<Denomination> SPECIAL_CARD_SCORE = Set.of(Denomination.A, Denomination.K, | ||
Denomination.Q, Denomination.J); | ||
private static final int ACE_MAX_NUMBER = 11; | ||
|
||
private final int score; | ||
|
||
Denomination(final int score) { | ||
this.score = score; | ||
} | ||
|
||
public String getName() { | ||
if (SPECIAL_CARD_SCORE.contains(this)) { | ||
return this.name(); | ||
} | ||
return String.valueOf(score); | ||
} | ||
|
||
public int getMinNumber() { | ||
return score; | ||
} | ||
|
||
public int getMaxNumber() { | ||
if (this == A) { | ||
return ACE_MAX_NUMBER; | ||
} | ||
return score; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,29 @@ | ||
package blackjack.domain.card; | ||
package blackjack.blackjack.card; | ||
|
||
import blackjack.util.ExceptionMessage; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
public class Hand { | ||
public final class Hand { | ||
|
||
public static final int BURST_THRESHOLD = 21; | ||
private static final int ACE_SUBTRACT = 10; | ||
private static final int BLACKJACK_SIZE = 2; | ||
private static final int DEALER_THRESHOLD = 16; | ||
|
||
private final List<Card> hand; | ||
|
||
public Hand(final List<Card> hand) { | ||
this.hand = new ArrayList<>(hand); | ||
} | ||
|
||
public int calculateResult() { | ||
public Hand(final Card card) { | ||
this(List.of(card)); | ||
} | ||
|
||
public int calculateScore() { | ||
int maxScore = calculateMaxScore(hand); | ||
if (isNotBurst(maxScore)) { | ||
return maxScore; | ||
|
@@ -30,10 +37,31 @@ public int calculateWithHardHand() { | |
.sum(); | ||
} | ||
|
||
public void add(final Card card) { | ||
hand.add(card); | ||
} | ||
|
||
public void addAll(final Hand givenHand) { | ||
hand.addAll(givenHand.getHand()); | ||
} | ||
|
||
public boolean isBlackjack() { | ||
return hand.size() == BLACKJACK_SIZE && calculateScore() == BURST_THRESHOLD; | ||
} | ||
|
||
public boolean isBust() { | ||
return calculateScore() > BURST_THRESHOLD; | ||
} | ||
|
||
public boolean isDealerStay() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dealer가 stay 상태인가에 대한 정의는 DealerRunning 객체에서 직접 판단하는게 좋지 않을까 싶어요. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞습니다! |
||
return calculateScore() > DEALER_THRESHOLD; | ||
} | ||
|
||
public Hand subHand(final int startInclusive, final int endExclusive) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
동작과 네이밍의 의미를 설명해주시면 조금 더 이해가 될 것 같아요. 😃 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
메서드명이 직관적이지 않은 것 같아서, |
||
validateIndex(startInclusive, endExclusive); | ||
return new Hand(hand.subList(startInclusive, endExclusive)); | ||
} | ||
|
||
private int calculateMaxScore(final List<Card> cards) { | ||
return cards.stream() | ||
.mapToInt(Card::getCardMaxNumber) | ||
|
@@ -58,6 +86,16 @@ private int countAce(final List<Card> cards) { | |
.count(); | ||
} | ||
|
||
private void validateIndex(final int start, final int end) { | ||
final int size = hand.size(); | ||
if (start < 0 || end < 0 || start >= size || end > size) { | ||
throw new IllegalArgumentException(ExceptionMessage.makeMessage("인덱스는 0 이상 hand 크기 이하여야 합니다")); | ||
} | ||
if (start > end) { | ||
throw new IllegalArgumentException(ExceptionMessage.makeMessage("끝 인덱스는 시작 인덱스보다 커야합니다")); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (!(o instanceof final Hand hand1)) { | ||
|
@@ -71,19 +109,15 @@ public int hashCode() { | |
return Objects.hashCode(hand); | ||
} | ||
|
||
public List<Card> getHand() { | ||
return Collections.unmodifiableList(hand); | ||
} | ||
|
||
public Hand getPartialCards(int start, int end) { | ||
return new Hand(hand.subList(start, end)); | ||
public int getSize() { | ||
return hand.size(); | ||
} | ||
|
||
public Card getFirstCard() { | ||
return hand.getFirst(); | ||
} | ||
|
||
public int getSize() { | ||
return hand.size(); | ||
public List<Card> getHand() { | ||
return Collections.unmodifiableList(hand); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package blackjack.blackjack.card; | ||
|
||
public enum Suit { | ||
|
||
SPADE, | ||
DIAMOND, | ||
HEART, | ||
CLOB; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package blackjack.blackjack.card.generator; | ||
|
||
import blackjack.blackjack.card.Card; | ||
import java.util.Deque; | ||
|
||
public interface DeckGenerator { | ||
|
||
Deque<Card> makeDeck(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package blackjack.blackjack.card.generator; | ||
|
||
import blackjack.blackjack.card.Card; | ||
import blackjack.blackjack.card.Denomination; | ||
import blackjack.blackjack.card.Suit; | ||
import java.util.ArrayDeque; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.Deque; | ||
import java.util.List; | ||
|
||
public final class ShuffleDeckGenerator implements DeckGenerator { | ||
|
||
private static final List<Card> INITIAL_CARDS; | ||
|
||
static { | ||
INITIAL_CARDS = Arrays.stream(Suit.values()) | ||
.flatMap(suit -> Arrays.stream(Denomination.values()) | ||
.map(cardScore -> new Card(suit, cardScore))) | ||
.toList(); | ||
} | ||
|
||
@Override | ||
public Deque<Card> makeDeck() { | ||
final List<Card> cards = new ArrayList<>(INITIAL_CARDS); | ||
Collections.shuffle(cards); | ||
return new ArrayDeque<>(cards); | ||
} | ||
} |
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.
hand 객체가 상태로 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.
그렇네요! 클래스명과 필드명을 동일하게 하면 내부 필드를 가리키는지, 객체를 가리키는지 혼란스러울 수 있겠네요! 어색하기도 하고요. 수정했습니다!
refactor: 클래스명과 필드명를 다르게 수정