-
Notifications
You must be signed in to change notification settings - Fork 0
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
[오렌지] 블랙잭 미션 제출합니다. #1
base: master
Are you sure you want to change the base?
Changes from all commits
3dfe0a1
88cdd0b
0595db4
cee048c
5570d56
719e1c7
016bd97
f8c9d20
176562c
6ef10b7
c9b4270
457056c
79af801
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,5 +1,35 @@ | ||
# java-blackjack | ||
블랙잭 게임 미션 저장소 | ||
|
||
## 요구사항 | ||
+ [x] 플레이어 이름 입력 | ||
+ [x] , 기준으로 분리 | ||
+ [x] 미입력, 공백 입력 등 예외처리 | ||
+ [x] 배팅 금액 입력 | ||
+ [x] 모든 플레이어의 배팅 금액 입력 | ||
+ [x] 미입력, 문자입력, 0 이하 입력 등 예외처리 | ||
+ [x] 딜러, 플레이어 모두에게 무작위의 2장의 카드 지급 | ||
+ [x] 나누어준 카드 출력 | ||
+ [x] 딜러는 1장만 출력, 플레이어는 2장 모두 출력 | ||
+ [x] 각 플레이어의 카드 합이 21이하인 경우 카드 더 받을지 질문 | ||
+ [x] 플레이어 마다 진행, n 입력 혹은 합이 21초과인경우 중지 | ||
+ [x] y(Y),n(N) 외의 입력 예외처리 | ||
+ [x] y 입력한 경우 무작위의 카드 장한 더 지 | ||
+ [x] 카드를 받은 플레이어의 모든 카드 출력 | ||
+ [x] 딜러의 경우 16 이하인 경우 카드 한 장 더 지급 | ||
+ [x] 딜러와 플레이어의 카드, 점수 합 출력 | ||
+ [x] 카드 계산 구현 | ||
+ [x] 카드의 숫자 계산은 카드 숫자를 기본으로 함. | ||
+ [x] 예외로 Ace는 1 또는 11로 계산 가능 | ||
+ [x] ace 제외 카드 합 <= 10 인 경우 ace 는 11로 계산 | ||
+ [x] King, Queen, Jack은 각각 10 | ||
+ [x] 수익 금액 구현 | ||
+ [x] 플레이어의 카드 합만 21 인 경우(블랙잭) 수익은 배팅금액 * 1.5 | ||
+ [x] 딜러와 플레이어 모두 블랙잭인 경우 수익은 배팅금액 * 1 | ||
+ [x] 합이 21 초과, 지는 경우면 수익은 배팅금액 * -1 | ||
+ [x] 21 이하이면서 21에 가까운 경우 수익은 배팅금액 * 1 | ||
+ [x] 플레이어와 딜러 무승부인 경우(모두 21 초과, 동점)인 경우 수익은 0 | ||
|
||
|
||
## 우아한테크코스 코드리뷰 | ||
* [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import controller.Controller; | ||
import view.InputView; | ||
import view.OutputView; | ||
|
||
public class BlackJackApplication { | ||
|
||
public static void main(String[] args) { | ||
Controller controller = new Controller(new InputView(), new OutputView()); | ||
controller.run(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package controller; | ||
|
||
import domain.Game; | ||
import domain.card.Deck; | ||
import domain.money.EarningMoney; | ||
import domain.user.*; | ||
import view.InputView; | ||
import view.OutputView; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
public class Controller { | ||
|
||
private final InputView inputView; | ||
private final OutputView outputView; | ||
private Players players; | ||
private Dealer dealer; | ||
|
||
public Controller(final InputView inputView, final OutputView outputView) { | ||
this.inputView = inputView; | ||
this.outputView = outputView; | ||
} | ||
|
||
public void run() { | ||
Game game = createGame(); | ||
play(game); | ||
calculateResult(); | ||
} | ||
|
||
private Game createGame() { | ||
List<Name> names = inputView.inputNames() | ||
.stream() | ||
.map(Name::new) | ||
.collect(Collectors.toList()); | ||
Map<Name, Integer> inputs = inputView.inputBettingMonies(names); | ||
players = PlayerFactory.createPlayers(inputs); | ||
dealer = new Dealer(); | ||
return new Game(new Deck()); | ||
} | ||
|
||
private void play(Game game) { | ||
game.drawFirst(players, dealer); | ||
outputView.printFirstCards(dealer, players.getPlayers()); | ||
playPlayers(game); | ||
playDealer(game); | ||
} | ||
|
||
private void playPlayers(Game game) { | ||
for (Player player : players.getPlayers()) { | ||
playPlayer(player, game); | ||
} | ||
} | ||
|
||
private void playPlayer(Player player, Game game) { | ||
while (player.canDrawCard() && inputView.inputWantMoreCard(player)) { | ||
game.draw(player); | ||
outputView.printCards(player); | ||
} | ||
if (player.canDrawCard()) { | ||
player.stay(); | ||
} | ||
} | ||
|
||
private void playDealer(Game game) { | ||
if (dealer.canDrawCard()) { | ||
outputView.printDealerHit(); | ||
game.draw(dealer); | ||
} | ||
} | ||
|
||
private void calculateResult() { | ||
EarningMoney earningMoney = new EarningMoney(); | ||
outputView.printResultCards(dealer, players); | ||
outputView.printEarningMoney(EarningMoney.calculateMoney(dealer, players)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,33 @@ | ||||||||||||||||||||||||||||||||
package domain; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
import domain.card.Card; | ||||||||||||||||||||||||||||||||
import domain.card.Deck; | ||||||||||||||||||||||||||||||||
import domain.user.Dealer; | ||||||||||||||||||||||||||||||||
import domain.user.Participant; | ||||||||||||||||||||||||||||||||
import domain.user.Players; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
import java.util.ArrayList; | ||||||||||||||||||||||||||||||||
import java.util.List; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
public class Game { | ||||||||||||||||||||||||||||||||
public static final int FIRST_DRAW_NUMBER = 2; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
private Deck deck; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
public Game(Deck deck) { | ||||||||||||||||||||||||||||||||
this.deck = deck; | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
public void drawFirst(Players players, Dealer dealer) { | ||||||||||||||||||||||||||||||||
List<Card> drawCards = new ArrayList<>(); | ||||||||||||||||||||||||||||||||
for (int index = 0; index < players.size() * FIRST_DRAW_NUMBER; index++) { | ||||||||||||||||||||||||||||||||
drawCards.add(deck.deal()); | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
players.firstDraw(drawCards); | ||||||||||||||||||||||||||||||||
dealer.drawFirst(deck.deal(), deck.deal()); | ||||||||||||||||||||||||||||||||
Comment on lines
+22
to
+27
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.
|
||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
Comment on lines
+21
to
+28
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.
Suggested change
Players에 딜러도 포함된다면 깔끔한 코드를 가져갈 수 있을 것 같아요. |
||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
public void draw(Participant participant) { | ||||||||||||||||||||||||||||||||
participant.draw(deck.deal()); | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package domain.card; | ||
|
||
import java.util.Objects; | ||
|
||
public class Card { | ||
private final Symbol symbol; | ||
|
||
private final Type type; | ||
Comment on lines
+6
to
+8
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. 별건 아니지만,, 둘이 사이가 안좋나요..? |
||
|
||
public Card(Symbol symbol, Type type) { | ||
this.symbol = symbol; | ||
this.type = type; | ||
} | ||
|
||
public boolean isAce() { | ||
return symbol == Symbol.ACE; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Card card = (Card) o; | ||
return symbol == card.symbol && | ||
type == card.type; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(symbol, type); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return symbol + " " + type; | ||
} | ||
|
||
public int getScore() { | ||
return symbol.getScore(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package domain.card; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class CardFactory { | ||
|
||
public static List<Card> create() { | ||
List<Card> cards = new ArrayList<>(); | ||
Symbol[] symbols = Symbol.values(); | ||
for (Symbol symbol : symbols) { | ||
createByType(cards, symbol); | ||
} | ||
return cards; | ||
} | ||
|
||
private static void createByType(final List<Card> cards, final Symbol symbol) { | ||
Type[] types = Type.values(); | ||
for (Type type : types) { | ||
cards.add(new Card(symbol, type)); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,17 @@ | ||||||
package domain.card; | ||||||
|
||||||
import java.util.Collections; | ||||||
import java.util.List; | ||||||
|
||||||
public class Deck { | ||||||
private final List<Card> cards; | ||||||
|
||||||
public Deck() { | ||||||
cards = CardFactory.create(); | ||||||
Collections.shuffle(cards); | ||||||
} | ||||||
|
||||||
public Card deal() { | ||||||
return cards.remove(0); | ||||||
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.
Suggested change
|
||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,71 @@ | ||||||
package domain.card; | ||||||
|
||||||
import java.util.ArrayList; | ||||||
import java.util.Collections; | ||||||
import java.util.List; | ||||||
|
||||||
import static domain.Game.FIRST_DRAW_NUMBER; | ||||||
|
||||||
public class Hands { | ||||||
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. 블랙잭에서 한 명의 플레이어가 가지는 패를
Suggested change
|
||||||
public static final int TEN = 10; | ||||||
public static final int ELEVEN = 11; | ||||||
public static final int BLACKJACK = 21; | ||||||
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. 21이 블랙잭이냐? 라고 했을 때 아닐수도 있다고 생각되는 네이밍이네요. |
||||||
public static final int DEALER_BUST_NUMBER = 17; | ||||||
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. 17이 딜러가 버스트 하는 기준인가요? 제가 알고있는 바로는 |
||||||
|
||||||
private final List<Card> cards; | ||||||
|
||||||
public Hands() { | ||||||
this.cards = new ArrayList<>(); | ||||||
} | ||||||
|
||||||
public List<Card> getCards() { | ||||||
return Collections.unmodifiableList(cards); | ||||||
} | ||||||
|
||||||
public void add(final Card card) { | ||||||
cards.add(card); | ||||||
} | ||||||
|
||||||
public boolean isBust() { | ||||||
return sum() > BLACKJACK; | ||||||
} | ||||||
|
||||||
public int sum() { | ||||||
int sum = cards.stream() | ||||||
.mapToInt(Card::getScore) | ||||||
.sum(); | ||||||
if (isAceNotExist() || isAceOne(sum)) { | ||||||
return sum; | ||||||
} | ||||||
return sum + TEN; | ||||||
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. Ace를 1 또는 11이 아니라 1 또는 20으로 볼 수 있다면? |
||||||
} | ||||||
|
||||||
private boolean isAceOne(int sum) { | ||||||
return isAceExist() && sum > ELEVEN; | ||||||
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. 버스트 기준이 25로 바뀐다면 |
||||||
} | ||||||
|
||||||
private boolean isAceExist() { | ||||||
return cards.stream() | ||||||
.anyMatch(Card::isAce); | ||||||
} | ||||||
|
||||||
private boolean isAceNotExist() { | ||||||
return !isAceExist(); | ||||||
} | ||||||
|
||||||
public boolean isBlackjack() { | ||||||
return cards.size() == FIRST_DRAW_NUMBER && sum() == BLACKJACK; | ||||||
} | ||||||
|
||||||
public boolean isDealerBust() { | ||||||
return sum() >= DEALER_BUST_NUMBER; | ||||||
} | ||||||
Comment on lines
+60
to
+62
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. 딜러도 버스트는 21이 아닐까요..? |
||||||
|
||||||
public boolean isBiggerThan(Hands hands) { | ||||||
return sum() > hands.sum(); | ||||||
} | ||||||
|
||||||
public boolean isSame(Hands hands) { | ||||||
return sum() == hands.sum(); | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package domain.card; | ||
|
||
public enum Symbol { | ||
ACE(1), | ||
TWO(2), | ||
THREE(3), | ||
FOUR(4), | ||
FIVE(5), | ||
SIX(6), | ||
SEVEN(7), | ||
EIGHT(8), | ||
NINE(9), | ||
TEN(10), | ||
JACK(10), | ||
QUEEN(10), | ||
KING(10); | ||
|
||
private final int score; | ||
|
||
Symbol(final int score) { | ||
this.score = score; | ||
} | ||
|
||
public int getScore() { | ||
return score; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package domain.card; | ||
|
||
public enum Type { | ||
SPADE, | ||
DIAMOND, | ||
HEART, | ||
CLUB | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package domain.money; | ||
|
||
public class BettingMoney { | ||
|
||
public static final int MIN_BETTING_MONEY = 1; | ||
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. 블랙잭이 가지는 |
||
|
||
private final int bettingMoney; | ||
|
||
public BettingMoney(final int bettingMoney) { | ||
validate(bettingMoney); | ||
this.bettingMoney = bettingMoney; | ||
} | ||
|
||
private void validate(final int bettingMoney) { | ||
if (bettingMoney < MIN_BETTING_MONEY) { | ||
throw new IllegalArgumentException("배팅금액은 1원 이상이어야 합니다. 입력금액 : " + bettingMoney); | ||
} | ||
} | ||
|
||
public int getBettingMoney() { | ||
return bettingMoney; | ||
} | ||
} |
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.
어떤 역할을 하는 컨트롤러인지 명시적인 네이밍을 주는게 좋을 것 같아요.