-
Notifications
You must be signed in to change notification settings - Fork 75
[박효정] 연료 주입, 블랙잭 (Step 1) #47
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: judy5050
Are you sure you want to change the base?
Changes from all commits
7be777d
f1985fb
9ce23cd
6d4d637
1f44c48
4b1ce8b
41bbc18
5a02cc7
c8d9181
18629ed
b1486aa
e8d2d78
151b0d4
36af6d5
16699df
a55c743
fa5905d
3dd4f68
754087e
5c6ebe8
9b05903
7c3352a
c0e7999
1d6d1ef
0d26b30
dfeecf4
fccc5fc
eb50a57
32ec9fe
b7e9073
d45db41
76af023
316a510
acb4123
4da5a3a
2065276
15404c0
d85d6e7
e774da4
66d3ef6
502a5bd
ec398cc
1193866
a09581c
14b4ec5
e7d4691
ccb5359
05ce88d
cd1e181
5e3663f
e3f49f6
a5158db
007cf1c
10c15b2
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,33 @@ | ||
# java-blackjack | ||
# java-blackjack | ||
|
||
## 연료 주입 | ||
|
||
### 기능 요구사항 | ||
|
||
- [X] 각 보유 차량 (5대) 렌트할 때 대략적인 이동거리를 입력 | ||
- [X] 자동차 객체 생성 시 생성자에 이동거리 주입 | ||
- [X] 연료량 계산 | ||
- [X] 연료 주입에 필요한 연료량 보고서 생성 | ||
|
||
### 프로그래밍 요구사항 | ||
|
||
- [X] 상속 / 추상 메서드 활용 | ||
- [X] 조건문 X | ||
|
||
### 블랙잭 | ||
|
||
- [x] 카드계산 | ||
- [x] 카드의 숫자 계산은 카드 숫자를 기본으로 하며, 예외로 Ace는 1 또는 11로 계산할 수 있으며, King, Queen, Jack은 각각 10으로 계산 | ||
- [x] 카드지급 기준 | ||
- [x] 게임을 시작하면 플레이어는 두 장의 카드를 지급 받음 | ||
- [x] 21을 넘지 않을 경우 원한다면 얼마든지 카드를 계속 뽑을 수 있음 | ||
-[x] 딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없음 | ||
- [x] 승자 결정 기준 | ||
- [x] 두 장의 카드 숫자를 합쳐 21을 초과하지 않으면서 21에 가깝게 만들면 이김 | ||
- [x] 게임을 완료한 후 각 플레이어별로 승패를 출력 | ||
|
||
### 프로그래밍 요구사항 | ||
|
||
- [x] 모든 엔티티를 작게 유지 | ||
- [x] 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않음 | ||
- [x] 딜러와 플레이어에서 발생하는 중복 코드를 제거해야 함 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package blackjack; | ||
|
||
import blackjack.controller.GameController; | ||
|
||
public class Application { | ||
|
||
|
||
public static void main(String[] args) { | ||
|
||
final GameController gameController = new GameController(); | ||
gameController.run(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package blackjack.controller; | ||
|
||
import static blackjack.domain.Dealer.DEALER_DRAW_LIMIT; | ||
|
||
import blackjack.domain.Dealer; | ||
import blackjack.domain.Deck; | ||
import blackjack.domain.Players; | ||
import blackjack.domain.ScoreBoard; | ||
import blackjack.view.InputView; | ||
import blackjack.view.ResultView; | ||
|
||
public class GameController { | ||
|
||
private final Players players; | ||
private final Dealer dealer; | ||
|
||
public GameController() { | ||
this.players = Players.create(InputView.getNames()); | ||
this.dealer = new Dealer(); | ||
} | ||
|
||
public void run() { | ||
final Deck deck = Deck.create(); | ||
|
||
setUpPerson(deck); | ||
play(deck); | ||
showGameResult(); | ||
} | ||
|
||
private void setUpPerson(final Deck deck) { | ||
ResultView.margin(); | ||
|
||
players.initializeDeck(deck); | ||
dealer.initializeDeck(deck); | ||
Comment on lines
+33
to
+34
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. players가 아니라 더 상위 클래스인 Persons로 dealer와 players들을 동시에 묶는다면 이 로직은 |
||
|
||
ResultView.shareCards(dealer.nameInfo().getPersonName(), players.nameInfos()); | ||
ResultView.openCardInfo(dealer.openCards(), players.openCards()); | ||
} | ||
|
||
private void play(final Deck deck) { | ||
ResultView.margin(); | ||
|
||
playersJudgment(deck); | ||
dealerJudgment(deck); | ||
|
||
ResultView.scoreboard(dealer.scoreInfo()); | ||
ResultView.scoreboard(players.scoreInfos()); | ||
} | ||
|
||
private void showGameResult() { | ||
ScoreBoard scoreBoard = players.match(dealer); | ||
ResultView.matchResult(scoreBoard.dealerMatches(dealer), | ||
scoreBoard.playerMatches()); | ||
} | ||
|
||
private void playersJudgment(final Deck deck) { | ||
while (players.hasActivePlayer()) { | ||
activePlayerJudgement(deck); | ||
} | ||
} | ||
|
||
private void activePlayerJudgement(final Deck deck) { | ||
while (players.checkActivePlayerCanDrawCard() && InputView.drawChoice( | ||
players.getActivePlayerNameInfo())) { | ||
players.drawCardToActivePlayer(deck); | ||
ResultView.playerCardsInfo(players.getActivePlayerCardInfo()); | ||
} | ||
players.nextActivePlayer(); | ||
} | ||
|
||
private void dealerJudgment(final Deck deck) { | ||
ResultView.margin(); | ||
|
||
while (dealer.canDrawCard()) { | ||
dealer.drawCard(deck); | ||
ResultView.dealerDrawDecision(dealer.nameInfo(), DEALER_DRAW_LIMIT); | ||
} | ||
|
||
ResultView.margin(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.Objects; | ||
|
||
public class Card { | ||
|
||
private static final String CARD_NAME_FORMAT = "%s%s"; | ||
|
||
private final CardNumber cardNumber; | ||
private final Suit suit; | ||
|
||
public Card(final CardNumber cardNumber, final Suit suit) { | ||
this.cardNumber = cardNumber; | ||
this.suit = suit; | ||
} | ||
|
||
public boolean isAce() { | ||
return cardNumber.isAce(); | ||
} | ||
|
||
public String getCardName() { | ||
return String.format(CARD_NAME_FORMAT, cardNumber.getInitial(), suit.getName()); | ||
} | ||
Comment on lines
+21
to
+23
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. View에 의존적인 코드인 것 같아요. 🤔 |
||
|
||
public int getCardScore() { | ||
return cardNumber.getScore(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Card card = (Card) o; | ||
return suit == card.suit && cardNumber == card.cardNumber; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(suit, cardNumber); | ||
} | ||
Comment on lines
+29
to
+44
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. Card 객체의 동등성을 정의할 필요가 있나요? 🤔 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package blackjack.domain; | ||
|
||
public enum CardNumber { | ||
|
||
ACE("A", 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); | ||
Comment on lines
+15
to
+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. 이 상수들도 |
||
|
||
private final String initial; | ||
private final int score; | ||
|
||
CardNumber(final String initial, final int score) { | ||
this.initial = initial; | ||
this.score = score; | ||
} | ||
|
||
public boolean isAce() { | ||
return this == ACE; | ||
} | ||
|
||
public int getScore() { | ||
return this.score; | ||
} | ||
|
||
public String getInitial() { | ||
return this.initial; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class Cards { | ||
|
||
private static final int ADDITION_ACE_SCORE = 10; | ||
private static final int LIMITED_ACE_SCORE = 11; | ||
private static final int REFERENCE_POINT = 21; | ||
private static final String CARD_SIZE_ZERO_ERROR = "카드가 존재하지 않습니다."; | ||
private static final int FRONT = 0; | ||
|
||
private final List<Card> cards; | ||
|
||
public Cards(final List<Card> cards) { | ||
this.cards = cards; | ||
} | ||
|
||
public int size() { | ||
return cards.size(); | ||
} | ||
|
||
public int totalScore() { | ||
final int score = cards.stream() | ||
.mapToInt(Card::getCardScore) | ||
.sum(); | ||
|
||
if (hasAce() && score <= LIMITED_ACE_SCORE) { | ||
return score + ADDITION_ACE_SCORE; | ||
} | ||
return score; | ||
} | ||
|
||
public void add(final Card drawCard) { | ||
cards.add(drawCard); | ||
} | ||
|
||
private boolean hasAce() { | ||
return cards.stream().anyMatch(Card::isAce); | ||
} | ||
|
||
public List<String> openCardOne() { | ||
if (cards.isEmpty()) { | ||
throw new RuntimeException(CARD_SIZE_ZERO_ERROR); | ||
} | ||
return Arrays.asList(cards.get(FRONT).getCardName()); | ||
} | ||
|
||
public List<String> openCardAll() { | ||
return cards.stream() | ||
.map(Card::getCardName) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public boolean isBust() { | ||
return totalScore() > REFERENCE_POINT; | ||
} | ||
|
||
public boolean blackjack() { | ||
return totalScore() == REFERENCE_POINT; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,30 @@ | ||||||||||||||
package blackjack.domain; | ||||||||||||||
|
||||||||||||||
import blackjack.dto.CardInfo; | ||||||||||||||
import blackjack.dto.MatchInfo; | ||||||||||||||
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. 불필요한 import문은 제거해주세요! 🙏 |
||||||||||||||
import java.util.ArrayList; | ||||||||||||||
|
||||||||||||||
public class Dealer extends Person { | ||||||||||||||
|
||||||||||||||
public static final int DEALER_DRAW_LIMIT = 16; | ||||||||||||||
private static final String DEALER_NAME = "딜러"; | ||||||||||||||
|
||||||||||||||
public Dealer(final String userName,final Cards 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. 습관적으로 |
||||||||||||||
super(userName, cards); | ||||||||||||||
} | ||||||||||||||
Comment on lines
+12
to
+14
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. Dealer의 이름은 항상
Suggested change
|
||||||||||||||
|
||||||||||||||
public Dealer() { | ||||||||||||||
this(DEALER_NAME, new Cards(new ArrayList<>())); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
@Override | ||||||||||||||
public boolean canDrawCard() { | ||||||||||||||
return cards.totalScore() <= DEALER_DRAW_LIMIT; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
@Override | ||||||||||||||
public CardInfo openCards() { | ||||||||||||||
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. 추가로 도메인 객체의 리턴 값을 DTO로 바로 변환하여 반환하는 것 또한 |
||||||||||||||
return new CardInfo(userName, cards.openCardOne()); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package blackjack.domain; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class Deck { | ||
|
||
private static final int REMOVE_INDEX = 0; | ||
private final List<Card> cards; | ||
Comment on lines
+12
to
+13
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 Deck(final List<Card> cards) { | ||
this.cards = cards; | ||
} | ||
|
||
public static Deck create() { | ||
final List<Card> cards = createEntireCards(); | ||
Collections.shuffle(cards); | ||
return new Deck(cards); | ||
} | ||
|
||
public Card drawCard() { | ||
if (cards.isEmpty()) { | ||
throw new RuntimeException("더 이상 카드를 뽑을 수 없습니다."); | ||
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.remove(REMOVE_INDEX); | ||
} | ||
|
||
public int deckSize() { | ||
return cards.size(); | ||
} | ||
|
||
private static List<Card> createEntireCards() { | ||
return Arrays.stream(CardNumber.values()) | ||
.flatMap(Deck::createEntireSuitCards) | ||
.collect(Collectors.toCollection(LinkedList::new)); | ||
} | ||
|
||
private static Stream<Card> createEntireSuitCards(final CardNumber cardNumber) { | ||
return Arrays.stream(Suit.values()) | ||
.map(suit -> new Card(cardNumber, suit)); | ||
} | ||
Comment on lines
+36
to
+45
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. Deck으로 쓰이는 카드들은 카드의 형태와 갯수들이 정해져있고 재사용할 확률이 높다고 생각해요. 😃 |
||
} |
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.
Controller는 상태를 가지면 안돼요. 👀
필요하다면 Controller의 메서드 안에서 객체를 직접 생성해서 사용해야해요. 😃
또한 Controller에 비즈니스 로직이 상당수 존재하는 것 같아요. 🙄
players
와dealer
를 상태로 가지는 새로운 객체(= BlackJack)를 만들어보면 어떨까요? 🤗