-
Notifications
You must be signed in to change notification settings - Fork 75
[박지현] 연료 주입, 블랙잭 (Step1) #37
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: jihyunhillpark
Are you sure you want to change the base?
Changes from all commits
78838ee
76baf2a
572a12f
ef8ae71
b2c6ca7
1d32d74
8fbfde3
e6ffc5c
1a6cd6c
df8c047
42c3c1f
fb8df81
8507816
aa70fd3
bcc45be
c0caff4
2e0d35d
750bb83
3ec67a7
a3f1de0
57df031
966bd00
3e50ca1
131a640
2cbc1e0
087506a
7aae53a
e0783b0
f5591ff
51f72fb
2346f97
6ebcf44
df9f9e8
a8aafeb
d1759fb
5e39a05
cbd3f09
8fce6da
4a7d92b
858753e
1a3569b
c95aeb4
ccdac4c
a2f4d6f
22cb340
daaa860
cfd0ecd
f21535a
0873b35
a984d8b
031c81d
6dd2a34
6ecc4d9
4a20002
f0726bd
e24a2d5
74a299a
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,40 @@ | ||
# java-blackjack | ||
# 연료 주입 | ||
## 기능 요구 사항 | ||
우리 회사는 렌터카를 운영하고 있다 | ||
현재 보유하고 있는 차량은 Sonata 2대, Avante 1대, K5 2대로 총 5대의 차량을 보유하고 있다. | ||
고객이 인터넷으로부터 예약할 때 여행할 목적지의 대략적인 이동거리를 입력 받는다. | ||
이 이동거리를 활용해 차량 별로 필요한 연료를 주입한다. | ||
차량 별로 주입해야 할 연료량을 확인할 수 있는 보고서를 생성해야 한다. | ||
|
||
각 차량별 연비는 다음과 같다. | ||
* Sonata : 10km/리터 | ||
* Avante : 15km/리터 | ||
* K5 : 13km/리터 | ||
|
||
## 기능 구현 사항 | ||
- [x] 자동차를 보유하는 렌터카 회사는 factory method를 사용해 생성한다. RentCompany#create() | ||
- [x] 자동차 인스턴스를 생성할 시 이동할 거리를 인자로 받는다. | ||
- [x] RentCar 추상 클래스는 필드에 대한 getter 메소드를 가지는 Car 인터페이스를 구현한다. | ||
- [x] 렌터카 회사에 있는 자동차들은 RentCar 추상클래스를 상속받는다. RentCar - Sonata, Avante, K5 | ||
|
||
# 블랙잭 | ||
## 기능 요구 사항 | ||
블랙잭 게임은 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 숫자를 가지는 쪽이 이기는 게임이다. | ||
카드의 숫자 계산은 카드 숫자를 기본으로 하며, 예외로 Ace는 1 또는 11로 계산할 수 있으며, King, Queen, Jack은 각각 10으로 계산한다. | ||
게임을 시작하면 플레이어는 두 장의 카드를 지급 받으며, 두 장의 카드 숫자를 합쳐 21을 초과하지 않으면서 21에 가깝게 만들면 이긴다. 21을 넘지 않을 경우 원한다면 얼마든지 카드를 계속 뽑을 수 있다. | ||
딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없다. | ||
게임을 완료한 후 각 플레이어별로 승패를 출력한다. | ||
|
||
## 기능 구현 사항 | ||
- [x] 게임에 참여할 사람을 쉼표로 구분한다. - InputView | ||
- [x] 카드는 숫자랑 문양으로 이루어진다. - Card | ||
- [x] 숫자와 문양은 Enum 형태로 관리한다. | ||
- [ ] Ace는 1또는 11로 계산할 수 있다. | ||
- [x] King, Queen, Jack은 각각 10으로 계산한다. | ||
- [x] 카드는 덱으로 관리한다. - CardDeck | ||
- [x] 게임을 시작할 때 shuffle을 한 번 수행한다. | ||
- [x] 카드는 문양 + 숫자 조합이 하나씩만 존재한다. | ||
- [ ] 게임을 시작하면 딜러를 포함한 모든 플레이어들에게 카드를 2장씩 나누어준다. | ||
- [ ] 딜레를 제외한 플레이어는 21을 초과하지 않을 때까지 카드를 계속 받을지 선택한다. | ||
- [ ] 딜러는 처음 받은 카드 두 장의 합이 16이하면 한 장의 카드를 더 받는다. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package blackjack; | ||
|
||
import blackjack.controller.BlackJackController; | ||
|
||
public class BlackJackMain { | ||
|
||
public static void main(String[] args) { | ||
BlackJackController blackJackController = new BlackJackController(); | ||
blackJackController.run(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package blackjack.controller; | ||
|
||
import blackjack.domain.CardDeck; | ||
import blackjack.domain.Dealer; | ||
import blackjack.domain.Game; | ||
import blackjack.domain.GameResult; | ||
import blackjack.domain.Player; | ||
import blackjack.domain.Players; | ||
import blackjack.dto.PlayerDTO; | ||
import blackjack.dto.FinalScoreDTO; | ||
import blackjack.view.InputView; | ||
import blackjack.view.OutputView; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class BlackJackController { | ||
|
||
public BlackJackController() { | ||
} | ||
|
||
public void run() { | ||
List<String> playerNames = InputView.inputPlayerNames(); | ||
CardDeck deck = new CardDeck(); | ||
Dealer dealer = Dealer.create(); | ||
Players players = new Players(playerNames); | ||
|
||
Game game = new Game(dealer, players, deck); | ||
game.init(); | ||
|
||
printResultOfDeal(dealer, players, playerNames); | ||
|
||
playerTurn(deck, players); | ||
dealerTurn(deck, dealer); | ||
|
||
printFinalResult(dealer, players); | ||
printWinOrLose(dealer, players); | ||
} | ||
|
||
|
||
private void printResultOfDeal(Dealer dealer, Players players, List<String> playerNames) { | ||
List<PlayerDTO> results = new ArrayList<>(); | ||
results.add(PlayerDTO.from(dealer)); | ||
for (Player player : players.get()) { | ||
results.add(PlayerDTO.from(player)); | ||
} | ||
|
||
OutputView.printCards(String.join(", ", playerNames), results); | ||
} | ||
|
||
private void playerTurn(CardDeck deck, Players players) { | ||
for (Player player : players.get()) { | ||
askMoreCard(deck, player); | ||
} | ||
} | ||
|
||
private void askMoreCard(CardDeck deck, Player player) { | ||
while (!player.isBusted()) { | ||
boolean answer = InputView.askHitOrStand(player.getName()); | ||
if (!answer) { | ||
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. 여기도 depth가 2를 넘어가는 것 같아요! |
||
break; | ||
} | ||
|
||
player.hit(deck); | ||
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.
Game객체를 조금더 활용해보면 어떨까요? |
||
OutputView.printCard(PlayerDTO.from(player)); | ||
} | ||
} | ||
|
||
private void dealerTurn(CardDeck deck, Dealer dealer) { | ||
while (dealer.checkHitOrNot()) { | ||
dealer.hit(deck); | ||
OutputView.printDealerHit(); | ||
} | ||
} | ||
|
||
private void printFinalResult(Dealer dealer, Players players) { | ||
List<FinalScoreDTO> results = new ArrayList<>(); | ||
results.add(FinalScoreDTO.from(dealer)); | ||
for (Player player : players.get()) { | ||
results.add(FinalScoreDTO.from(player)); | ||
} | ||
|
||
OutputView.printGameResults(results); | ||
} | ||
|
||
private void printWinOrLose(Dealer dealer, Players players) { | ||
GameResult gameResult = new GameResult(); | ||
gameResult.mapResults(players, dealer); | ||
OutputView.printWinOrLose(gameResult); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package blackjack.domain; | ||
|
||
public class Card { | ||
private final Suit suit; | ||
private final Denomination denomination; | ||
|
||
public Card(Suit suit, Denomination denomination) { | ||
this.suit = suit; | ||
this.denomination = denomination; | ||
} | ||
|
||
public Denomination getDenomination() { | ||
return denomination; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
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. 여기도 toString재정의에 대해 다시한번 고려해주시면 좋을 것 같아요! |
||
return denomination.getAlias() + suit.getName(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class CardDeck { | ||
|
||
private final List<Card> cardDeck; | ||
|
||
public CardDeck() { | ||
cardDeck = initDeck(); | ||
} | ||
|
||
public List<Card> initDeck() { | ||
List<Card> deck = new ArrayList<>(); | ||
for (Suit suit : Suit.values()) { | ||
for (Denomination denomination : Denomination.values()) { | ||
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. depth가 2를 넘어가는 것 같아요! 아래의 요구사항을 지켜보면 어떨까요?
|
||
deck.add(new Card(suit, denomination)); | ||
} | ||
} | ||
Collections.shuffle(deck); | ||
return deck; | ||
} | ||
|
||
public Card popCard() { | ||
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. cardDeck이 비어있으면 에러가 발생할 것 같은데, 이에 대한 핸들링을 해주면 어떨까요? |
||
int target = cardDeck.size() - 1; | ||
Card card = cardDeck.get(target); | ||
cardDeck.remove(target); | ||
|
||
return card; | ||
} | ||
|
||
public boolean contains(Card target) { | ||
return cardDeck.contains(target); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,44 @@ | ||||||
package blackjack.domain; | ||||||
|
||||||
import java.util.List; | ||||||
import java.util.stream.Collectors; | ||||||
|
||||||
public class Cards { | ||||||
|
||||||
private final List<Card> cards; | ||||||
|
||||||
public Cards(List<Card> cards) { | ||||||
this.cards = cards; | ||||||
} | ||||||
|
||||||
public void addCard(Card card) { | ||||||
cards.add(card); | ||||||
} | ||||||
|
||||||
public int getScore() { | ||||||
int total = cards.stream().mapToInt(card -> card.getDenomination().getScore()).sum(); | ||||||
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
|
||||||
int aceCount = (int) cards.stream().filter(card -> card.getDenomination().isAce()).count(); | ||||||
for (int i = 0; i < aceCount; i++) { | ||||||
total = checkAceOneOrEleven(total); | ||||||
} | ||||||
|
||||||
return total; | ||||||
} | ||||||
|
||||||
private int checkAceOneOrEleven(int total) { | ||||||
if (total + 10 <= 21) { | ||||||
return total + 10; | ||||||
Comment on lines
+29
to
+30
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 total; | ||||||
} | ||||||
|
||||||
public List<Card> getCards() { | ||||||
return cards; | ||||||
} | ||||||
|
||||||
public List<String> getCardNames() { | ||||||
return cards.stream() | ||||||
.map(Card::toString) | ||||||
.collect(Collectors.toList()); | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.ArrayList; | ||
|
||
public class Dealer extends Participant { | ||
|
||
private static final String NAME_TAG = "딜러 카드: "; | ||
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 static final int LIMIT_MORE_CARD = 16; | ||
|
||
public Dealer(Cards cards) { | ||
super(cards); | ||
} | ||
|
||
public static Dealer create() { | ||
Cards cards = new Cards(new ArrayList<>()); | ||
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 new Dealer(cards); | ||
} | ||
|
||
public boolean checkHitOrNot() { | ||
return getScore() <= LIMIT_MORE_CARD; | ||
} | ||
|
||
public String openOneCard() { | ||
return getCardNames().get(0); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package blackjack.domain; | ||
|
||
public enum Denomination { | ||
ACE(1, "A"), | ||
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(10, "J"), | ||
QUEEN(10, "Q"), | ||
KING(10, "K"); | ||
|
||
private final int score; | ||
private final String alias; | ||
|
||
Denomination(final int score, final String alias) { | ||
this.score = score; | ||
this.alias = alias; | ||
} | ||
|
||
public boolean isAce() { | ||
return this == ACE; | ||
} | ||
|
||
public int getScore() { | ||
return score; | ||
} | ||
|
||
public String getAlias() { | ||
return alias; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
Comment on lines
+3
to
+4
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 class Game { | ||
|
||
private final Players players; | ||
private final Dealer dealer; | ||
private final CardDeck deck; | ||
|
||
public Game(Dealer dealer, Players players, CardDeck deck) { | ||
this.players = players; | ||
this.dealer = dealer; | ||
this.deck = deck; | ||
} | ||
|
||
public void init() { | ||
dealer.deal(deck); | ||
players.deal(deck); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package blackjack.domain; | ||
|
||
import static blackjack.utils.Constant.LOSE; | ||
import static blackjack.utils.Constant.PUSH; | ||
import static blackjack.utils.Constant.WIN; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class GameResult { | ||
|
||
private final Map<String, String> playerResults = new HashMap<>(); | ||
private final Map<String, Integer> dealersResults = new HashMap<>(); | ||
|
||
public void mapResults(Players players, Dealer dealer) { | ||
for (Player player : players.get()) { | ||
playerResults.put(player.getName(), player.getGameResult(dealer)); | ||
} | ||
updateDealerResult(dealer); | ||
} | ||
|
||
private void updateDealerResult(Dealer dealer) { | ||
for (String result : playerResults.values()) { | ||
if (dealer.isBusted()) { | ||
dealersResults.put(LOSE, dealersResults.getOrDefault(LOSE, 0) + 1); | ||
continue; | ||
} | ||
String deal = WIN; | ||
if (result.equals(WIN)) { | ||
deal = LOSE; | ||
} | ||
if (result.equals(PUSH)) { | ||
deal = PUSH; | ||
} | ||
dealersResults.put(deal, dealersResults.getOrDefault(deal, 0) + 1); | ||
} | ||
} | ||
|
||
public Map<String, String> getPlayerResults() { | ||
return playerResults; | ||
} | ||
|
||
public String getDealerResult() { | ||
StringBuilder result = new StringBuilder(); | ||
List<String> orders = Arrays.asList(WIN, PUSH, LOSE); | ||
|
||
for (String order : orders) { | ||
if (dealersResults.containsKey(order)) { | ||
result.append(dealersResults.get(order)).append(order); | ||
} | ||
} | ||
|
||
return result.toString(); | ||
} | ||
|
||
} |
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.
기능 요구 사항 작성 👍