-
Notifications
You must be signed in to change notification settings - Fork 75
[한승진] 연료 주입, 블랙잭 (Step 1) #30
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: hsj-96
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
23ebdc6
37ccf9c
da2f554
a6159fb
3a04921
3771219
3ed43ac
63bcf1c
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,70 @@ | ||
# 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점 이상이면 추가로 받을 수 없다. | ||
게임을 완료한 후 각 플레이어별로 승패를 출력한다. | ||
|
||
- [X] 딜러, 플레이어 (공통) - Participant | ||
- 이름 | ||
- 보유 카드 | ||
- 승, 패 기록 | ||
- 첫번째 2장의 카드를 뽑음 | ||
- 이후 1장씩 카드를 뽑음 | ||
- 점수를 계산 | ||
- 보유하고 있는 카드 정보 반환 | ||
- [X] 딜러 - Dealer | ||
- 딜러는 카드 점수가 16 이하이면 카드를 1장 더 받음 | ||
- [X] 플레이어 - Player | ||
- 플레이어는 카드를 1장 더 받을지 안받을지 입력을 받아서 카드를 받음 | ||
|
||
- [X] 카드 - Card | ||
- 종류 : ♦︎다이아, ♥하트, ♠스페이드, ♣클로버 | ||
- 숫자 : 1 ~ 9, A (= 1, 11), K (= 10), Q (= 10), J (= 10) | ||
- 에이스 카드일 경우, 점수가 15 미만이면 에이스카드점수는 11점이 되고, 16이상이면 점수가 1점이 됨 | ||
- 카드 정보를 반환 | ||
|
||
- [X] 덱 - Deck | ||
- 카드 52장을 생성하고 관리 | ||
- 생성시 미리 덱을 섞어서 반환 | ||
- 카드를 여러장 뽑음 | ||
- 카드를 한장 뽑음 | ||
|
||
- [X] 사용자가 가지고 있는 카드 묶음 - ParticipantsCards | ||
- 가지고 있는 카드를 추가 | ||
- 카드의 점수를 계산 | ||
- 가지고 있는 카드의 정보를 반환 | ||
|
||
- [X] 게임 - GameController | ||
- 게임 진행 | ||
|
||
- [X] 입력 - InputView | ||
- 게임 참여자 입력 (쉼표로 구분) | ||
- 카드를 더 받을지 입력 (y/n) | ||
- 빈 입력을 허용하지 않음 | ||
|
||
- [X] 출력 - PrintView | ||
- 뽑은 카드 결과 출력 | ||
- 게임 결과 출력 | ||
- 최종 승패 출력 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package blackjack; | ||
|
||
import blackjack.controller.GameController; | ||
|
||
public class BlackjackApplication { | ||
|
||
public static void main(String[] args) { | ||
GameController.start(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package blackjack.controller; | ||
|
||
import blackjack.domain.Dealer; | ||
import blackjack.domain.Participants; | ||
import blackjack.domain.Players; | ||
import blackjack.view.InputView; | ||
import blackjack.view.PrintView; | ||
import java.util.List; | ||
|
||
public class GameController { | ||
|
||
public static void start() { | ||
List<String> name = InputView.inputNames(); | ||
|
||
Players players = Players.from(name); | ||
Dealer dealer = new Dealer("딜러"); | ||
Participants participants = Participants.from(players, dealer); | ||
|
||
participants.drawCardMultiple(2); | ||
PrintView.printFirstDrawCards(participants); | ||
|
||
participants.drawCardContinue(1); | ||
PrintView.printGameResult(participants); | ||
|
||
participants.judgeScore(); | ||
PrintView.printWinLose(participants); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
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 getScore(int currentScore) { | ||
return this.cardValue.intUnaryOperator.applyAsInt(currentScore); | ||
} | ||
|
||
public CardValue getCardValue() { | ||
return cardValue; | ||
} | ||
|
||
public String toString() { | ||
return cardValue.number + cardType.name; | ||
} | ||
|
||
public enum CardType { | ||
SPADE("스페이드"), | ||
CLOVER("클로버"), | ||
HEART("하트"), | ||
DIAMOND("다이아몬드"); | ||
|
||
private final String name; | ||
|
||
CardType(String name) { | ||
this.name = name; | ||
} | ||
} | ||
|
||
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()); | ||
} | ||
} | ||
} | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package blackjack.domain; | ||
|
||
public class Dealer extends Participant { | ||
|
||
public Dealer(String name) { | ||
super(name); | ||
} | ||
|
||
@Override | ||
public void drawCardMultiple(Deck deck, int number) { | ||
cards.addCards(deck.drawMultiple(number)); | ||
} | ||
|
||
@Override | ||
public void drawCardContinue(Deck deck) { | ||
if (cards.sumCardScore() > 17) { | ||
return; | ||
} | ||
System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); | ||
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. 앞선 미션에서 학습한 MVC패턴을 지켜보는 것은 어떨까요? |
||
cards.addCards(deck.drawMultiple(1)); | ||
} | ||
|
||
@Override | ||
public String scoreResult() { | ||
return name + " : " + winScore + "승" + loseScore + "패"; | ||
} | ||
} |
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)); | ||
} | ||
} | ||
} | ||
|
||
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) { | ||
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장의 Card를 덱으로 만들어 딜러와 플레이어에게 전달하는 방식으로 게임을 운영하는 것을 생각해 보면 구현에 도움이 될 것 같습니다. |
||
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,49 @@ | ||||||
package blackjack.domain; | ||||||
|
||||||
import java.util.ArrayList; | ||||||
|
||||||
abstract public class Participant { | ||||||
|
||||||
private static final String COLON = " : "; | ||||||
|
||||||
protected final String name; | ||||||
protected final ParticipantCards cards; | ||||||
protected int winScore, loseScore; | ||||||
|
||||||
public Participant(String name, ParticipantCards cards, int winCount, int loseCount) { | ||||||
this.name = name; | ||||||
this.cards = cards; | ||||||
this.winScore = winCount; | ||||||
this.loseScore = loseCount; | ||||||
} | ||||||
|
||||||
public Participant(String name) { | ||||||
this(name, new ParticipantCards(new ArrayList<>()), 0, 0); | ||||||
} | ||||||
|
||||||
public final void judgeScore(int maxScore) { | ||||||
if (sumCardScore() == maxScore) { | ||||||
winScore++; | ||||||
return; | ||||||
} | ||||||
loseScore++; | ||||||
} | ||||||
|
||||||
public final String getName() { | ||||||
return name; | ||||||
} | ||||||
|
||||||
public final String holdingInfo() { | ||||||
return name + COLON + cards.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. 앞서 학습한 MVC패턴을 적용해보면 어떨까요? |
||||||
} | ||||||
|
||||||
public final int sumCardScore() { | ||||||
return cards.sumCardScore(); | ||||||
} | ||||||
|
||||||
public abstract void drawCardMultiple(Deck deck, int number); | ||||||
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 abstract void drawCardContinue(Deck deck); | ||||||
|
||||||
public abstract String scoreResult(); | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class ParticipantCards { | ||
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 String COMMA = ", "; | ||
|
||
private final List<Card> cards; | ||
|
||
public ParticipantCards(List<Card> cards) { | ||
this.cards = new ArrayList<>(cards); | ||
} | ||
|
||
public void addCards(List<Card> drawCards) { | ||
cards.addAll(drawCards); | ||
} | ||
|
||
public int sumCardScore() { | ||
return cards.stream() | ||
.reduce(0, (x, y) -> x + y.getScore(x), Integer::sum); | ||
} | ||
|
||
public List<Card> getCards() { | ||
return Collections.unmodifiableList(cards); | ||
} | ||
|
||
public String toString() { | ||
StringBuilder sb = new StringBuilder(); | ||
|
||
for (int i = 0; i < cards.size(); i++) { | ||
sb.append(cards.get(i).toString()); | ||
if (i != cards.size() - 1) { | ||
sb.append(COMMA); | ||
} | ||
} | ||
|
||
return sb.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.
이렇게 수정해 컨트롤러에 메시지를 던지는 방식으로 수정해보는 것은 어떨까요?
그리고 21점이 넘으면 카드를 받을 수 없는 조건이 빠져있습니다.