-
Notifications
You must be signed in to change notification settings - Fork 74
[김성현] 연료 주입 및 블랙잭(1단계) #23
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
base: kim-svadoz
Are you sure you want to change the base?
Changes from 174 commits
cb02376
b97ac62
d313574
4da1ef3
4cedf61
ccde597
fce513d
0a9a9ec
0e531c0
788ca21
cbcc6a0
2425fc7
e2eddd1
482793e
0573a5c
e43744a
1deb60b
d8a753e
6609962
bc9021d
769fba3
04e2258
9d57098
5285a06
71f7796
38b9202
8d56730
5fc6a94
b96f688
3ab57d3
dd5f319
f062dac
c30d1e8
0062d44
00e32f9
c06cbc2
0f4111b
1fd696b
df6f0bf
d97b2c6
68d9c1d
a2c4f92
810d8a4
33e4137
349996d
492ab61
900c114
dafc7cc
8d30a6d
4dafdc9
9774590
0e5e941
ef0c462
9457616
70e688c
212ff4f
176ee2f
ff55ccd
b521d58
c15d518
972447c
bca2a79
030bf46
90056e2
d719731
cea8f93
86799b7
8947cb3
a3c0f07
6974cd1
81e21a8
53fa7a1
0c3361f
be15ff6
30a0189
f93fbd4
5858e73
520b607
c49b06e
44a0d82
4006f75
bab3a01
c67556e
22d41b5
446ef1d
e1fdc0f
f11d6aa
fe5a66b
c9a7ef7
87b93b3
e4b0c93
9972ae7
db75b6f
8a2977d
3ea2ca9
b9adb4f
7cd211c
614e604
6cdd78c
f3dd988
35dcfb3
2c53c7b
a7fe789
64e08ab
258454c
2944f07
2f56aa6
4f72ffe
e05f946
c1900ce
5b875ca
bf6984e
a075f48
8e11872
c3d9a00
48e9949
f34a1c0
9f3dfde
7ec5ea4
7aba82d
0816dbb
66144aa
19cb561
c1f0bfd
24226e4
9caa918
d37b745
98a8e02
f62c760
dc27fa9
e2e3b6d
5f47bbe
d333559
95d67a3
e7881a8
1b2d2f9
6c7cb0c
dcd2709
e157204
9c5e2a4
e5e7553
52a8b1e
a307ae7
3b23a3f
0c94cbd
f1af70c
248feb6
bf78849
0e7f9a5
3e8521b
5056122
a0aa83e
dc2977e
6cdd436
fb105cc
5c31940
2567ff0
c86ac82
d07149f
33d178c
ed64b73
f6f71e1
d81a84f
726aca7
3818a2f
857e174
57591ed
0350654
339c214
fb20edf
d49b8fc
fc179f6
4e769a4
aab1025
22526cd
7254e35
f4bddcf
b720860
144e58c
bcb3124
cb7b253
32dcc56
816e608
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 +1,50 @@ | ||
| # java-blackjack | ||
| # java-blackjack | ||
|
|
||
| ## 기능 | ||
|
|
||
| ### Car | ||
| - [X] 이동거리로 주입해야할 연료량을 계산한다. | ||
| - [X] 차종을 리턴한다. | ||
| - [X] 연료량을 리턴한다. | ||
|
|
||
| ### RentCompany | ||
| - [X] InputView를 생성한다. | ||
| - [X] InputView로 부터 받은 이동거리로 Car를 생성한다. | ||
| - [X] ReportView를 생성한다. | ||
| - [X] Car로부터 받은 연료량으로 ReportView를 생성한다. | ||
|
|
||
| ### InputView | ||
| - [X] 이동거리 입력 받는다. | ||
|
|
||
| ### ReportView | ||
| - [X] 차량별 주입해야할 연료량을 출력한다. | ||
|
|
||
|
|
||
| ## 블랙잭 기능 요구사항 | ||
|
|
||
| ### 입력 | ||
| - [x] 게임에 참여할 사람의 이름을 입력한다. | ||
| - [x] 쉼표 기준으로 분리한다 | ||
|
|
||
| ### 출력 | ||
| - [ ] | ||
|
|
||
| ### 카드 | ||
| - [x] Ace는 1 또는 11로 계산한다. | ||
| - [x] King, Queen, Jack은 10으로 계산한다. | ||
| - [x] 나머지 카드는 카드숫자를 기본으로 계산한다. | ||
|
|
||
| ### 게임 | ||
| - [x] 게임시작 시 2장의 카드를 지급 받는다. | ||
| - [x] 21을 초과하지 않으면 카드를 계속 받을 수 있다. | ||
| - [x] 21을 초과하면 패배로 처리한다. | ||
| - [x] 21을 초과하지 않으면서 21에 가까운 사람이 이긴다. | ||
| #### 딜러 | ||
| - [x] 처음에 받은 2장의 합계가 16이하면 1장을 추가로 지급받는다. | ||
|
|
||
| # TODO | ||
| - [x] 플레이어를 추상클래스 혹은 인터페이스로 구현하기 | ||
| - [x] 딜러가 한장 더 받는다는 메시지를 맨 마지막에 위치 | ||
| - [x] 딜러의 상대적 최종 승패 구현 | ||
| - [x] 단위 테스트 보완하기 | ||
| - [x] 최종승패 딜러 로직 버그 수정 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package blackjack; | ||
|
|
||
| import blackjack.controller.GameController; | ||
|
|
||
| public class Application { | ||
|
|
||
| public static void main(String[] args) { | ||
| GameController gameController = new GameController(); | ||
| gameController.start(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| package blackjack.controller; | ||
|
|
||
| import blackjack.domain.card.CardPack; | ||
| import blackjack.domain.gameplayer.GamePlayer; | ||
| import blackjack.domain.gameplayer.GamePlayers; | ||
| import blackjack.domain.gameplayer.Names; | ||
| import blackjack.view.InputView; | ||
| import blackjack.view.OutputView; | ||
| import java.util.List; | ||
|
|
||
| public class GameController { | ||
|
|
||
| public void start() { | ||
| final CardPack cardPack = new CardPack(); | ||
| final GamePlayers gamePlayers = new GamePlayers(getConsoleNames()); | ||
|
|
||
| initializeGame(gamePlayers, cardPack); | ||
| printInitialStatus(gamePlayers); | ||
|
|
||
| playGame(gamePlayers, cardPack); | ||
| printFinalStatus(gamePlayers); | ||
| } | ||
|
|
||
| private Names getConsoleNames() { | ||
| try { | ||
| return convertStringToNames(InputView.getPlayerName()); | ||
| } catch (IllegalArgumentException e) { | ||
| e.printStackTrace(); | ||
| return getConsoleNames(); | ||
| } | ||
| } | ||
|
|
||
| private Names convertStringToNames(String names) { | ||
| return new Names(names); | ||
| } | ||
|
|
||
| public void initializeGame(final GamePlayers gamePlayers, final CardPack cardPack) { | ||
| List<GamePlayer> players = gamePlayers.getAllPlayers(); | ||
|
|
||
| players.forEach(player -> { | ||
| player.receiveCard(cardPack.pick()); | ||
| player.receiveCard(cardPack.pick()); | ||
| }); | ||
| } | ||
|
|
||
| private void printInitialStatus(GamePlayers gamePlayers) { | ||
| printInitialMessage(gamePlayers); | ||
| printCardAllStatus(gamePlayers); | ||
| } | ||
|
|
||
| private void printInitialMessage(GamePlayers gamePlayers) { | ||
| OutputView.printInitialMessage(gamePlayers); | ||
| } | ||
|
|
||
| private void printCardAllStatus(GamePlayers gamePlayers) { | ||
| OutputView.printCardAllStatus(gamePlayers); | ||
|
Comment on lines
+43
to
+57
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. OutputView 를 두 번 호출 하는 행위는 return 을 두 번하는 것과 유사한데요 |
||
| } | ||
|
|
||
| public void playGame(GamePlayers gamePlayers, CardPack cardPack) { | ||
| final List<GamePlayer> players = gamePlayers.getPlayers(); | ||
| final GamePlayer dealer = gamePlayers.getDealer(); | ||
|
|
||
| for (final GamePlayer player : players) { | ||
| playerGameProcess(player, cardPack); | ||
| } | ||
| dealerGameProcess(dealer, cardPack); | ||
| } | ||
|
|
||
| private void playerGameProcess(final GamePlayer player, CardPack cardPack) { | ||
| while (player.isContinue() && InputView.getPlayerChoice(player)) { | ||
| player.receiveCard(cardPack.pick()); | ||
| OutputView.printCardStatus(player); | ||
| } | ||
|
|
||
| OutputView.printCardStatus(player); | ||
| } | ||
|
|
||
| private void dealerGameProcess(final GamePlayer dealer, CardPack cardPack) { | ||
| while (dealer.isLowerThanBound()) { | ||
| dealer.receiveCard(cardPack.pick()); | ||
| OutputView.printDealerAcceptCard(); | ||
| } | ||
| } | ||
|
|
||
| private void printFinalStatus(GamePlayers gamePlayers) { | ||
| printCardResult(gamePlayers); | ||
| printGameResult(gamePlayers); | ||
| } | ||
|
|
||
| private void printCardResult(GamePlayers gamePlayers) { | ||
| OutputView.printCardResult(gamePlayers); | ||
| } | ||
|
|
||
| private void printGameResult(GamePlayers gamePlayers) { | ||
| OutputView.printGameResult(gamePlayers); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| public class Card { | ||
|
|
||
| private final CardSymbol cardSymbol; | ||
| private final CardType cardType; | ||
|
|
||
| public Card(final CardSymbol cardSymbol, final CardType cardType) { | ||
| this.cardSymbol = cardSymbol; | ||
| this.cardType = cardType; | ||
| } | ||
|
|
||
| public CardSymbol getCardSymbol() { | ||
| return cardSymbol; | ||
| } | ||
|
|
||
| public CardType getCardType() { | ||
| return cardType; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class CardPack { | ||
|
|
||
| private static final int FRONT = 0; | ||
|
|
||
| private final List<Card> cardPack; | ||
|
|
||
| public CardPack() { | ||
| this.cardPack = create(); | ||
|
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. 블랙잭 게임이 한 번이 아닌 계속 할 수 있다면 매번 카드를 52장 생성할 것 같아요 |
||
| } | ||
|
|
||
| private List<Card> create() { | ||
|
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. create 되어 상태 값인 cardPack 을 테스트할 때 shuffle 로 인해 테스트가 어려울 것 같아요 |
||
| final List<Card> cards = new ArrayList<>(); | ||
| for (final CardSymbol symbol : CardSymbol.values()) { | ||
| Arrays.stream(CardType.values()) | ||
| .forEach(type -> cards.add(new Card(symbol, type))); | ||
| } | ||
| Collections.shuffle(cards); | ||
| return new ArrayList<>(cards); | ||
| } | ||
|
|
||
| public List<Card> getCardPack() { | ||
| return Collections.unmodifiableList(cardPack); | ||
|
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 pick() { | ||
| return cardPack.remove(FRONT); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| public enum CardSymbol { | ||
| SPADE("스페이드"), | ||
| DIAMOND("다이아몬드"), | ||
| CLOVER("클로버"), | ||
| HEART("하트"); | ||
|
|
||
| private final String symbol; | ||
|
|
||
| CardSymbol(final String symbol) { | ||
| this.symbol = symbol; | ||
| } | ||
|
|
||
| public String getSymbol() { | ||
| return this.symbol; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| public enum CardType { | ||
| ACE("A", 11, 1), | ||
| TWO("2", 2), | ||
| THREE("3", 3), | ||
| FOUR("4", 4), | ||
| FIVE("5", 5), | ||
| SIX("6", 6), | ||
| SEVEN("7", 7), | ||
| EIGHT("8", 8), | ||
| NINE("9", 9), | ||
| TEN("10", 10), | ||
| JACK("J", 10), | ||
| QUEEN("Q", 10), | ||
| KING("K", 10); | ||
|
|
||
| private final String name; | ||
| private final int point; | ||
| private int lowerAcePoint; | ||
|
|
||
| CardType(String name, int point) { | ||
| this.name = name; | ||
| this.point = point; | ||
| } | ||
|
|
||
| CardType(String name, int point, int lowerAcePoint) { | ||
| this.name = name; | ||
| this.point = point; | ||
| this.lowerAcePoint = lowerAcePoint; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return this.name; | ||
| } | ||
|
|
||
| public int getPoint() { | ||
| return this.point; | ||
| } | ||
|
|
||
| public int getLowerAcePoint() { | ||
| return this.lowerAcePoint; | ||
| } | ||
|
|
||
| public boolean isAce() { | ||
| return this == CardType.ACE; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class Cards { | ||
|
|
||
| private static final int BLACK_JACK = 21; | ||
|
|
||
| private final List<Card> cards; | ||
|
|
||
| public Cards() { | ||
| this.cards = new ArrayList<>(); | ||
| } | ||
|
|
||
| public void receiveCard(final Card card) { | ||
| cards.add(card); | ||
| } | ||
|
|
||
| public List<Card> toList() { | ||
| return Collections.unmodifiableList(cards); | ||
| } | ||
|
|
||
| public int calculateCards() { | ||
| final int sumOfCards = getSumOfCards(); | ||
| final int aceCount = getAceCount(); | ||
|
|
||
| if (sumOfCards > BLACK_JACK && aceCount > 0) { | ||
| return getBestSumWithAce(sumOfCards); | ||
| } | ||
| return sumOfCards; | ||
| } | ||
|
|
||
| private int getAceCount() { | ||
| return (int) cards.stream() | ||
| .filter(card -> card.getCardType().isAce()) | ||
| .count(); | ||
| } | ||
|
|
||
| private int getSumOfCards() { | ||
| return cards.stream() | ||
| .map(Card::getCardType) | ||
| .mapToInt(CardType::getPoint) | ||
| .sum(); | ||
| } | ||
|
|
||
| private int getBestSumWithAce(final int sum) { | ||
| final int lowerAcePoint = CardType.ACE.getLowerAcePoint(); | ||
| final int higherAcePoint = CardType.ACE.getPoint(); | ||
|
|
||
| int aceCount = getAceCount(); | ||
| int totalPoint = sum; | ||
|
|
||
| while (aceCount > 0 && totalPoint > BLACK_JACK) { | ||
| totalPoint = totalPoint - higherAcePoint + lowerAcePoint; | ||
| aceCount--; | ||
| } | ||
| return totalPoint; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package blackjack.domain.gameplayer; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class Dealer extends GamePlayer { | ||
|
|
||
| private static final String DEALER = "딜러"; | ||
| private static final int DEALER_BOUND = 16; | ||
| private static final String DealerResult = "%d승 %d패"; | ||
|
|
||
| public Dealer() { | ||
| this(new Name(DEALER)); | ||
| } | ||
|
|
||
| public Dealer(final Name name) { | ||
| super(name); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isLowerThanBound() { | ||
| return getScore() <= DEALER_BOUND; | ||
| } | ||
|
|
||
| @Override | ||
| public String getGameResult(List<GamePlayer> players) { | ||
| int winCount = 0; | ||
| if (isContinue()) { | ||
| winCount = findWinCount(getScore(), players); | ||
| } | ||
| int loseCount = players.size() - winCount; | ||
|
|
||
| return String.format(DealerResult, winCount, loseCount); | ||
| } | ||
|
|
||
| private int findWinCount(int dealerScore, List<GamePlayer> players) { | ||
| return (int) players.stream() | ||
| .filter(player -> player.isContinue() && player.getScore() < dealerScore) | ||
| .count(); | ||
| } | ||
| } |
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.
InputView 에서는 데이터만 받고 생성자를 통해서 상태 값을 초기화 하고
객체의 책임을 구현해보는 것이 어떨까요?