-
Notifications
You must be signed in to change notification settings - Fork 75
[김현수] 연료 주입, blackjack (Step1) #42
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: hscom96
Are you sure you want to change the base?
Changes from all commits
b9c43d8
fcb9e17
85d2e1d
e857713
442e4b1
54702d2
bbec84c
4189d87
bba97a1
55e623f
d68dff7
9d2dc0e
1d9769b
8edbe2a
b6e6ec9
87a763a
30c85d0
f1613ad
d51daff
8ef9212
e30e64a
1cc0378
23a96d6
bccb7a7
f9c848f
75d1d93
412aa73
fd874ab
9458008
44e3e29
cb37623
e6fd564
4a89e46
d175ab6
fedd5d8
35608f3
d6f71b8
18eaeaf
56cc1e7
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 | ||
| # 연료 주입 | ||
|
|
||
| ## 기능 요구사항 | ||
| 우리 회사는 렌터카를 운영하고 있다. 현재 보유하고 있는 차량은 Sonata 2대, Avante 1대, K5 2대로 총 5대의 차량을 보유하고 있다. 고객이 인터넷으로부터 예약할 때 여행할 목적지의 대략적인 이동거리를 입력 받는다. 이 이동거리를 활용해 차량 별로 필요한 연료를 주입한다. 차량 별로 주입해야 할 연료량을 확인할 수 있는 보고서를 생성해야 한다. | ||
| 각 차량별 연비는 다음과 같다. | ||
| * Sonata : 10km/리터 | ||
| * Avante : 15km/리터 | ||
| * K5 : 13km/리터 | ||
|
|
||
| ## 기능 목록 | ||
|
|
||
| - [x] 회사를 생성한다. - RentCompany | ||
| - [x] 자동차를 생성한다. - RentCompany.addCar | ||
| - 종류 : Sonata, Avante, k5 | ||
| - 개수 : Sonata 2대, Avante 1대, K5 2대 | ||
| - [x] 주입해야할 연료량을 계산한다. - Car.getChargeQuantity() | ||
| - [x] 차량 별로 주입해야할 보고서를 생성한다. - RentCompany.generateReport() | ||
|
|
||
| # 블랙잭 | ||
|
|
||
| ## 기능 요구사항 | ||
| 블랙잭 게임을 변형한 프로그램을 구현한다. 블랙잭 게임은 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 숫자를 가지는 쪽이 이기는 게임이다. | ||
|
|
||
| 카드의 숫자 계산은 카드 숫자를 기본으로 하며, 예외로 Ace는 1 또는 11로 계산할 수 있으며, King, Queen, Jack은 각각 10으로 계산한다. | ||
| 게임을 시작하면 플레이어는 두 장의 카드를 지급 받으며, 두 장의 카드 숫자를 합쳐 21을 초과하지 않으면서 21에 가깝게 만들면 이긴다. 21을 넘지 않을 경우 원한다면 얼마든지 카드를 계속 뽑을 수 있다. | ||
| 딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없다. | ||
| 게임을 완료한 후 각 플레이어별로 승패를 출력한다. | ||
|
|
||
| - [ ] 딜러, 플레이어 (공통) - Participant | ||
| - 이름 | ||
| - 보유 카드 | ||
| - 승, 패 기록 | ||
| - 카드를 뽑음 | ||
| - [ ] 딜러 - Dealer | ||
| - [ ] 플레이어 - Player | ||
|
|
||
| - 카드 - Card | ||
| - 종류 : ♦︎다이아, ♥하트, ♠스페이드, ♣클로버 | ||
| - 숫자 : 1 ~ 9, A (= 1, 11), K (= 10), Q (= 10), J (= 10) | ||
|
|
||
| - 게임 - Game | ||
| - 게임 진행 | ||
| - 게임 종료 조건 확인 | ||
|
|
||
| - 입력 | ||
| - 게임 참여자 입력 (쉼표로 구분) | ||
| - 카드를 더 받을지 입력 (y/n) | ||
|
|
||
| - 결과 | ||
| - 최종 승패 출력 | ||
| 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,63 @@ | ||
| package blackjack.controller; | ||
|
|
||
| import blackjack.domain.Dealer; | ||
| import blackjack.domain.Deck; | ||
| import blackjack.domain.GameResult; | ||
| import blackjack.domain.Player; | ||
| import blackjack.domain.Players; | ||
| import blackjack.ui.BlackjackInput; | ||
| import blackjack.ui.BlackjackOutput; | ||
|
|
||
| public class GameController { | ||
|
|
||
| private static final String DEALER_NAME = "dealer"; | ||
| private static final int PLAYER_DRAW_SIZE = 1; | ||
| private static final int DEALER_DRAW_SIZE = 1; | ||
| private static final int FIRST_DRAW_SIZE = 2; | ||
|
|
||
| public void start() { | ||
| Deck deck = Deck.create(); | ||
|
|
||
| Players players = BlackjackInput.inputPlayerName(); | ||
| Dealer dealer = new Dealer(DEALER_NAME); | ||
|
|
||
| drawCardInit(deck, players, dealer); | ||
|
|
||
| drawCardFinal(deck, players, dealer); | ||
|
|
||
| BlackjackOutput.printFinalResult(GameResult.of(dealer, players)); | ||
| } | ||
|
|
||
| private void drawCardInit(Deck deck, Players players, Dealer dealer) { | ||
| BlackjackOutput.printDrawCard(players); | ||
| players.drawCardMultiple(deck, FIRST_DRAW_SIZE); | ||
| dealer.drawCardMultiple(deck, FIRST_DRAW_SIZE); | ||
| BlackjackOutput.printAllCard(players, dealer); | ||
|
|
||
| } | ||
|
|
||
| private void drawCardFinal(Deck deck, Players players, Dealer dealer) { | ||
| drawPlayersCard(deck, players, PLAYER_DRAW_SIZE); | ||
| boolean isDraw = dealer.drawCardMultiple(deck, DEALER_DRAW_SIZE); | ||
| if(isDraw){ | ||
| BlackjackOutput.printDealerDraw(); | ||
| } | ||
|
|
||
| BlackjackOutput.printAllCardWithSum(players, dealer); | ||
| } | ||
|
|
||
| private void drawPlayersCard(Deck deck, Players players, int size) { | ||
| if (!players.isTargetAvailable()) { | ||
| return; | ||
| } | ||
|
|
||
| Player player = players.getTarget(); | ||
| while (BlackjackInput.inputPlayerDraw(player)) { | ||
| player.drawCardMultiple(deck, size); | ||
| BlackjackOutput.printParticipantCard(player); | ||
| } | ||
|
|
||
| players.nextTargetIndex(); | ||
| drawPlayersCard(deck, players, size); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| package blackjack.domain; | ||
|
|
||
| import java.util.function.IntUnaryOperator; | ||
|
|
||
| public class Card { | ||
|
|
||
| private final CardType cardType; | ||
| private final CardValue cardValue; | ||
|
|
||
| Card(CardType cardType, CardValue cardValue) { | ||
| this.cardType = cardType; | ||
| this.cardValue = cardValue; | ||
| } | ||
|
|
||
| public int calculateScore(int currentScore) { | ||
| return this.cardValue.intUnaryOperator.applyAsInt(currentScore); | ||
| } | ||
|
|
||
| public CardValue getCardValue() { | ||
| return cardValue; | ||
| } | ||
|
|
||
| public String getCardTypeName() { | ||
| return cardType.name; | ||
| } | ||
|
|
||
| public String getNumber(){ | ||
| return cardValue.number; | ||
| } | ||
|
|
||
| public enum CardType { | ||
| SPADE("스페이드"), | ||
| CLOVER("클로버"), | ||
| HEART("하트"), | ||
| DIAMOND("다이아몬드"); | ||
|
|
||
| private final String name; | ||
|
|
||
| CardType(String name) { | ||
| this.name = name; | ||
| } | ||
| } | ||
|
Comment on lines
+31
to
+42
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 enum CardValue { | ||
| ACE("A", currentScore -> currentScore < 15 ? 11 : 1), | ||
| TWO("2", currentScore -> 2), | ||
| THREE("3", currentScore -> 3), | ||
| FOUR("4", currentScore -> 4), | ||
| FIVE("5", currentScore -> 5), | ||
| SIX("6", currentScore -> 6), | ||
| SEVEN("7", currentScore -> 7), | ||
| EIGHT("8", currentScore -> 8), | ||
| NINE("9", currentScore -> 9), | ||
| TEN("10", currentScore -> 10), | ||
| QUEEN("Q", currentScore -> 10), | ||
| JACK("J", currentScore -> 10), | ||
| KING("K", currentScore -> 10); | ||
|
|
||
| private final String number; | ||
| private final IntUnaryOperator intUnaryOperator; | ||
|
|
||
| CardValue(String number, IntUnaryOperator intUnaryOperator) { | ||
| this.number = number; | ||
| this.intUnaryOperator = intUnaryOperator; | ||
| } | ||
|
|
||
| public boolean isEqualCardValue(Card card){ | ||
| return this.equals(card.getCardValue()); | ||
| } | ||
|
Comment on lines
+44
to
+69
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. 따로 클래스로 분리해주는건 어떨까요? |
||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package blackjack.domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class Cards { | ||
|
|
||
| private final List<Card> cards; | ||
|
|
||
| public Cards(List<Card> cards) { | ||
| this.cards = new ArrayList<>(cards); | ||
| } | ||
|
|
||
| public void addCards(List<Card> drawCards) { | ||
| cards.addAll(drawCards); | ||
| } | ||
|
|
||
| public int sumCardScore() { | ||
|
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 cards.stream() | ||
| .reduce(0, (x, y) -> x + y.calculateScore(x), Integer::sum); | ||
| } | ||
|
|
||
| public List<Card> getCards() { | ||
| return Collections.unmodifiableList(cards); | ||
|
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.
https://tecoble.techcourse.co.kr/post/2021-04-26-defensive-copy-vs-unmodifiable/ |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package blackjack.domain; | ||
|
|
||
| public class Dealer extends Participant{ | ||
|
|
||
| public Dealer(String name) { | ||
| super(name); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean drawCardMultiple(Deck deck, int number) { | ||
| if(cards.sumCardScore() > 17) { | ||
| return false; | ||
| } | ||
| cards.addCards(deck.drawMultiple(number)); | ||
| return true; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package blackjack.domain; | ||
|
|
||
| import blackjack.domain.Card.CardType; | ||
| import blackjack.domain.Card.CardValue; | ||
| 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 class Deck { | ||
|
|
||
| private final Deque<Card> deck = new ArrayDeque<>(); | ||
|
|
||
| public Deck(List<CardType> cardTypes, List<CardValue> cardValues) { | ||
| for (CardType cardType : cardTypes) { | ||
| for (CardValue cardValue : cardValues) { | ||
| deck.add(new Card(cardType, cardValue)); | ||
| } | ||
| } | ||
|
Comment on lines
+17
to
+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. 요구사항에 |
||
| } | ||
|
|
||
| public static Deck create() { | ||
| List<CardType> types = Arrays.asList(CardType.values()); | ||
| Collections.shuffle(types); | ||
|
|
||
| List<CardValue> values = Arrays.asList(CardValue.values()); | ||
| Collections.shuffle(values); | ||
|
|
||
| return new Deck(types, values); | ||
| } | ||
|
|
||
| public List<Card> drawMultiple(int num) { | ||
| List<Card> cards = new ArrayList<>(); | ||
| for (int i = 0; i < num; i++) { | ||
| cards.add(draw()); | ||
| } | ||
| return cards; | ||
| } | ||
|
|
||
| public Card draw() { | ||
| if (deck.size() == 0) { | ||
| throw new IllegalStateException("패가 더이상 존재하지 않습니다."); | ||
| } | ||
| return deck.pop(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package blackjack.domain; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class GameResult { | ||
|
|
||
| private static final int SCORE_CRITERIA = 21; | ||
|
|
||
| private final List<Participant> participants; | ||
|
|
||
| private GameResult(List<Participant> participants) { | ||
| this.participants = new ArrayList<>(participants); | ||
| calculateGameResult(this.participants); | ||
| } | ||
|
|
||
| public static GameResult of(Dealer dealer, Players players) { | ||
| List<Participant> participants = new ArrayList<>(); | ||
| participants.add(dealer); | ||
| participants.addAll(players.getPlayers()); | ||
| return new GameResult(participants); | ||
| } | ||
|
|
||
| private void calculateGameResult(List<Participant> participants) { | ||
| int criteria = calculateCriteria(participants); | ||
| for(Participant participant: participants){ | ||
| participant.judgeScore(criteria); | ||
| } | ||
| } | ||
|
|
||
| private int calculateCriteria(List<Participant> participants){ | ||
| return participants.stream() | ||
| .mapToInt(Participant::sumCardScore) | ||
| .map(score-> Math.abs(score - SCORE_CRITERIA)) | ||
| .min() | ||
| .orElseThrow(() -> { | ||
| throw new IllegalStateException("최대값을 구할 수 없습니다."); | ||
| }); | ||
| } | ||
|
|
||
| public List<Participant> getParticipants() { | ||
| return Collections.unmodifiableList(participants); | ||
| } | ||
| } |
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.
다 완료 된 부분은 표시해주면 어떨까요?