-
Notifications
You must be signed in to change notification settings - Fork 75
[정승연] 연료 주입, 블랙잭 (Step1) #27
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: seungyeonjeong
Are you sure you want to change the base?
Changes from all commits
d6b0d2f
c8876cf
8d9dd7e
cf23f3a
952a44b
39a00f8
d2c8c91
c4260e9
3f8e6f7
d2d00e6
6d980da
de5e6c6
5125c16
4770d77
787ac1d
b97be07
849b9b1
940fb0e
001161e
4ae4e68
b505c92
b5c3814
c74faa9
81d8921
dcd8f4b
7a1bf32
04e744a
4dd6ddb
2a4894c
015ea73
9edf9ed
97e6457
2c2d980
27c5f3f
2d05151
7ca8326
55b62b9
cde826e
317b7dc
2019fc6
0e6fe11
8dfac2c
9bf6d84
f7fa94e
c6ae257
fe72065
ebf319e
f804509
12d9584
1bad02b
41acbdf
8f65321
157a9a5
69de10d
0d305fe
397f22e
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,60 @@ | ||
# java-blackjack | ||
# java-blackjack | ||
|
||
# 연료주입 | ||
|
||
### 기능요구사항 | ||
- [x] Sonata 2대, Avante 1대, K5 2대로 총 5대의 차량이 있다. | ||
- [x] 여행할 목적지의 대략적인 이동거리를 입력받는다. | ||
- [x] 차량 별로 필요한 연료를 주입받는다. | ||
- [x] 차량 별로 주입해야할 연료량을 확인할 수 있는 보고서를 생성한다. | ||
|
||
### 프로그래밍 요구 사항 | ||
- 상속과 추상 메서드를 활용한다. | ||
- 위 요구사항을 if/else 절을 쓰지 않고 구현해야 한다. | ||
|
||
# 블랙잭 | ||
|
||
### 기능요구사항 | ||
- [x] 게임에 참여할 사람의 이름을 입력받을 수 있다. 이름은 쉼표를 기준으로 분리한다 | ||
ex) pobi, jason | ||
- [x] 카드의 숫자 계산은 카드 숫자를 기본으로 한다. | ||
- [x] 예외로 Ace는 1 또는 11로 계산할 수 있다. | ||
- [x] King, Queen, Jack은 각각 10으로 계산한다. | ||
- [x] 게임을 시작하면 플레이어는 두 장의 카드를 지급 받는다. | ||
- [x] 숫자 합이 21을 넘지 않으면 카드를 계속 뽑을 수 있다. | ||
- [x] 딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없다. | ||
- [x] 가지고 있는 카드 숫자 합이 21을 초과하면 게임에서 진다. | ||
- [x] 가지고 있는 카드 숫자 합이 21이거나 21을 초과하지 않으면서 21에 가장 가까운 플레이어가 승리한다. | ||
- [x] 게임을 완료한 후 각 플레이어별로 승패를 출력한다. | ||
|
||
### 프로그래밍 요구 사항 | ||
- 자바 코드 컨벤션을 지키면서 프로그래밍한다. | ||
- 기본적으로 Google Java Style Guide을 원칙으로 한다. | ||
- 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다. | ||
- indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록 구현한다. 1까지만 허용한다. | ||
- 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. | ||
- 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. | ||
- 3항 연산자를 쓰지 않는다. | ||
- else 예약어를 쓰지 않는다. | ||
- else 예약어를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. | ||
- 힌트: if문에서 값을 반환하는 방식으로 구현하면 else 예약어를 사용하지 않아도 된다. | ||
- 모든 기능을 TDD로 구현해 단위 테스트가 존재해야 한다. 단, UI(System.out, System.in) 로직은 제외 | ||
- 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 구분한다. | ||
- UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다. | ||
- 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. | ||
- 함수(또는 메소드)가 한 가지 일만 하도록 최대한 작게 만들어라. | ||
- 배열 대신 컬렉션을 사용한다. | ||
- 모든 원시 값과 문자열을 포장한다 | ||
- 줄여 쓰지 않는다(축약 금지). | ||
- 일급 컬렉션을 쓴다. | ||
### 추가된 요구 사항 | ||
- 모든 엔티티를 작게 유지한다. | ||
- 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다. | ||
- 딜러와 플레이어에서 발생하는 중복 코드를 제거해야 한다. | ||
|
||
# multiple authors | ||
git commit -m "commit message | ||
|
||
|
||
Co-authored-by: seungyeonjeong <crowsy@naver.com> | ||
Co-authored-by: YuYangWoo <yuyw0712@naver.com> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package blackjack; | ||
|
||
import blackjack.controller.GameLauncher; | ||
|
||
public class Application { | ||
|
||
public static void main(String[] args) { | ||
GameLauncher gameLauncher = new GameLauncher(); | ||
gameLauncher.start(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package blackjack.controller; | ||
|
||
import blackjack.domain.gamer.Dealer; | ||
import blackjack.domain.gamer.Gamer; | ||
import blackjack.domain.matchInfo.MatchResultBoard; | ||
import blackjack.domain.gamer.Player; | ||
import blackjack.domain.gamer.Players; | ||
import blackjack.view.InputView; | ||
import blackjack.view.OutputView; | ||
|
||
public class GameLauncher { | ||
|
||
private static final int BLACK_JACK_SUM_LIMIT = 21; | ||
|
||
public void start() { | ||
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. 메서드가 10 line을 넘어가는 것 같아요!!
|
||
String[] playerNames = InputView.readPlayerName(); | ||
OutputView.printGamePlayer(playerNames); | ||
|
||
OutputView.printCardsSetting(playerNames); | ||
|
||
Dealer dealer = new Dealer(); | ||
OutputView.printDealerCardsSetting(dealer, true); | ||
|
||
Players players = new Players(playerNames); | ||
OutputView.printPlayersStatus(players); | ||
for (Player player : players.getPlayers()) { | ||
getCardOrNot(player); | ||
} | ||
|
||
if (dealer.getCardOrNot(dealer)) { | ||
OutputView.printDealerAddCard(); | ||
} | ||
|
||
OutputView.printDealerCardSum(dealer); | ||
OutputView.printPlayerCardSum(players); | ||
Comment on lines
+34
to
+35
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호출을 한번으로 줄일 수 없을까요? View호출이 Console이아닌 Network기반이라면 Network비용이 더 소모될 것 같아요! |
||
|
||
OutputView.printFinalGameResult(); | ||
MatchResultBoard matchResultBoard = players.playMatch(dealer); | ||
OutputView.printDealerMatchResult(dealer, matchResultBoard.getDealerMatchResultInfo()); | ||
OutputView.printPlayersMatchResult(matchResultBoard.getPlayersMatchResultInfo()); | ||
|
||
} | ||
|
||
private void getCardOrNot(Gamer player) { | ||
while (InputView.readAddCardOrNot(player) && player.calcScore(player) < BLACK_JACK_SUM_LIMIT) { | ||
player.addCard(player.getCards()); | ||
OutputView.printPlayerStatus(player); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package blackjack.domain.card; | ||
|
||
public enum Suit { | ||
CLUBS("클로버"), | ||
DIAMONDS("다이아몬드"), | ||
HEARTS("하트"), | ||
SPADES("스페이드"); | ||
|
||
private final String value; | ||
|
||
Suit(final String value) { | ||
this.value = value; | ||
} | ||
|
||
public String getValue() { | ||
return value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package blackjack.domain.card; | ||
|
||
import java.util.Objects; | ||
|
||
public class Card { | ||
private final Denomination denomination; | ||
private final Suit suit; | ||
|
||
public Card(final Denomination denomination, final Suit suit) { | ||
this.denomination = denomination; | ||
this.suit = suit; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Card card = (Card) o; | ||
return denomination == card.denomination && suit == card.suit; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(denomination, suit); | ||
} | ||
|
||
public Denomination getDenomination() { | ||
return denomination; | ||
} | ||
|
||
public Suit getSuit() { | ||
return suit; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package blackjack.domain.card; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class Cards { | ||
private static List<Card> cardList = new ArrayList<>(); | ||
|
||
static { | ||
for(Denomination denomination : Denomination.values()) { | ||
for(Suit suit : Suit.values()) { | ||
cardList.add(new Card(denomination, suit)); | ||
} | ||
} | ||
} | ||
|
||
public static List<Card> getCardList() { | ||
return cardList; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package blackjack.domain.card; | ||
|
||
public enum Denomination { | ||
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); | ||
|
||
private final String name; | ||
private final int value; | ||
|
||
Denomination(final String name, final int value) { | ||
this.name = name; | ||
this.value = value; | ||
} | ||
|
||
public boolean isAce() { | ||
return this == ACE; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public int getValue() { | ||
return value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package blackjack.domain.gamer; | ||
|
||
import blackjack.domain.card.Card; | ||
import java.util.List; | ||
|
||
public class Dealer extends Gamer { | ||
|
||
private static final int DEALER_SUM_LIMIT = 16; | ||
public Dealer() { | ||
super("딜러"); | ||
} | ||
|
||
public Dealer(List<Card> cards) { | ||
super("딜러", cards); | ||
} | ||
|
||
public boolean getCardOrNot(Dealer dealer) { | ||
if (dealer.calcScore(dealer) < DEALER_SUM_LIMIT) { | ||
dealer.addCard(dealer.getCards()); | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,96 @@ | ||||||||||
package blackjack.domain.gamer; | ||||||||||
|
||||||||||
import blackjack.domain.card.Card; | ||||||||||
import blackjack.domain.card.Cards; | ||||||||||
import blackjack.domain.card.Denomination; | ||||||||||
import java.util.ArrayList; | ||||||||||
import java.util.Collections; | ||||||||||
import java.util.List; | ||||||||||
import java.util.stream.Collectors; | ||||||||||
|
||||||||||
public abstract class Gamer { | ||||||||||
private static final String ERROR_NOT_ENOUGH_CARD = "덱에 남아있는 카드가 없습니다."; | ||||||||||
private static final int TEN = 10; | ||||||||||
private static final int THRESHOLD = 21; | ||||||||||
private static final int INIT_CARD_COUNT = 2; | ||||||||||
|
||||||||||
private List<Card> cardsBundle = Cards.getCardList(); | ||||||||||
private List<Card> cards = new ArrayList<>(); | ||||||||||
private String name; | ||||||||||
|
||||||||||
public Gamer(String name) { | ||||||||||
this.name = name; | ||||||||||
this.cards = initSetting(); | ||||||||||
} | ||||||||||
|
||||||||||
public Gamer(String name, List<Card> cards) { | ||||||||||
this.name = name; | ||||||||||
for(Card card : cards) { | ||||||||||
this.cards.add(card); | ||||||||||
} | ||||||||||
Comment on lines
+28
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.
Suggested change
|
||||||||||
for(Card card : cards) { | ||||||||||
cardsBundle.remove(card); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
private List<Card> initSetting() { | ||||||||||
Collections.shuffle(cardsBundle); | ||||||||||
this.cards = cardsBundle.stream() | ||||||||||
.limit(INIT_CARD_COUNT) | ||||||||||
.collect(Collectors.toList()); | ||||||||||
removeCard(); | ||||||||||
removeCard(); | ||||||||||
return this.cards; | ||||||||||
} | ||||||||||
|
||||||||||
public int calcScore(Gamer player) { | ||||||||||
int score = player.cards.stream() | ||||||||||
.map(Card::getDenomination) | ||||||||||
.mapToInt(Denomination::getValue) | ||||||||||
.sum(); | ||||||||||
|
||||||||||
long aceCount = player.cards.stream().filter(card -> card.getDenomination().isAce()) | ||||||||||
.count(); | ||||||||||
for (int i = 0; i < aceCount; i++) { | ||||||||||
score = adjustScore(score); | ||||||||||
} | ||||||||||
return score; | ||||||||||
} | ||||||||||
|
||||||||||
private int adjustScore(int score) { | ||||||||||
if (score + TEN <= THRESHOLD) { | ||||||||||
score += TEN; | ||||||||||
} | ||||||||||
return score; | ||||||||||
} | ||||||||||
|
||||||||||
public List<Card> addCard(List<Card> cards) { | ||||||||||
cards.add(cardsBundle.get(0)); | ||||||||||
removeCard(); | ||||||||||
return cards; | ||||||||||
} | ||||||||||
|
||||||||||
private void removeCard() { | ||||||||||
try { | ||||||||||
cardsBundle.remove(0); | ||||||||||
} catch (RuntimeException runtimeException) { | ||||||||||
throw new RuntimeException(ERROR_NOT_ENOUGH_CARD); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
public boolean isBlackJack(Gamer player) { | ||||||||||
return calcScore(player) == THRESHOLD; | ||||||||||
} | ||||||||||
|
||||||||||
public boolean isBust(Gamer player) { | ||||||||||
return calcScore(player) > THRESHOLD; | ||||||||||
} | ||||||||||
|
||||||||||
public List<Card> getCards() { | ||||||||||
return cards; | ||||||||||
} | ||||||||||
|
||||||||||
public String getName() { | ||||||||||
return name; | ||||||||||
} | ||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package blackjack.domain.gamer; | ||
|
||
import blackjack.domain.card.Card; | ||
import blackjack.domain.matchInfo.MatchResult; | ||
import java.util.List; | ||
|
||
public class Player extends Gamer { | ||
|
||
public Player(final String name) { | ||
super(name); | ||
} | ||
|
||
public Player(final String name, final List<Card> cards) { | ||
super(name, cards); | ||
} | ||
|
||
public MatchResult getMatchResult(final Gamer player, final Gamer dealer) { | ||
return MatchResult.calcMatchResult(player, dealer); | ||
} | ||
|
||
} |
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.
기능 구현 목록 작성 👍