Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
d6b0d2f
docs: 연료 주입 기능 요구사항 정리
seungyeon-1231 Feb 11, 2022
c8876cf
feat: InputView, OutputView 코드 작성
seungyeon-1231 Feb 11, 2022
8d9dd7e
feat: 자동차들이 상속받을 수 있는 Car 클래스 구현
seungyeon-1231 Feb 11, 2022
cf23f3a
feat: 자동차를 상속 받는 자동차 객체를 구현
seungyeon-1231 Feb 11, 2022
952a44b
feat: RentCompany 클래스 구현
seungyeon-1231 Feb 11, 2022
39a00f8
feat: 연료 주입을 위한 Application 구현
seungyeon-1231 Feb 11, 2022
d2c8c91
docs: 기능요구사항 기능 구현 완료
seungyeon-1231 Feb 11, 2022
c4260e9
docs: Blackjack 기능 요구사항 정리
seungyeon-1231 Feb 11, 2022
3f8e6f7
feat: 카드의 종류를 나타내는 Denomination Enum class로 구현
YuYangWoo Feb 14, 2022
d2d00e6
test: 카드의 종류를 나타내는 Denomination 테스트코드 구현
YuYangWoo Feb 14, 2022
6d980da
feat: OutputView.java 출력을 담당하는 View 구현
YuYangWoo Feb 14, 2022
de5e6c6
feat: InputView.java 입력을 담당하는 View 구현
YuYangWoo Feb 14, 2022
5125c16
feat: 카드의 종류를 나타내는 Suit Enum class 구현
YuYangWoo Feb 14, 2022
4770d77
test: Denomination과 suit을 사용해 CardTest 구현
YuYangWoo Feb 14, 2022
787ac1d
feat: Card.java denomination와 suit을 상태로 가지는 객체 생성
YuYangWoo Feb 14, 2022
b97be07
feat: Denomination 카드의 이름과 값을 가지도록 enum class 수정
YuYangWoo Feb 14, 2022
849b9b1
test: CardsTest.java 모든 카드를 출력하는 테스트 코드 작성
YuYangWoo Feb 14, 2022
940fb0e
feat: Cards.java static 필드로 모든 카드 추가
YuYangWoo Feb 14, 2022
001161e
test: PlayerTest 플레이어 테스트 코드 구현
YuYangWoo Feb 14, 2022
4ae4e68
feat: player는 초기에 카드가 섞여서 2개씩 주어진다.
YuYangWoo Feb 14, 2022
b505c92
feat: Players의 이름을 받아 List<Player>를 구현
YuYangWoo Feb 14, 2022
b5c3814
docs: 기능요구사항 반항 사항 반영
YuYangWoo Feb 14, 2022
c74faa9
feat: 딜러와 플레이어가 상속하는 Gamer 클래스 구현
YuYangWoo Feb 15, 2022
81d8921
feat: 게임의 딜러를 구현하는 클래스 구현
YuYangWoo Feb 15, 2022
dcd8f4b
feat: 겹치는 코드 상속으로 중복 제거
YuYangWoo Feb 15, 2022
7a1bf32
feat: 딜러와 플레이의 상태를 출력하는 코드 구현
YuYangWoo Feb 15, 2022
04e744a
feat: 플레이어가 카드를 더 받는 로직 Gamer.java에 구현
YuYangWoo Feb 15, 2022
4dd6ddb
feat: Player가 가진 카드의 합을 반환하는 로직 구현
YuYangWoo Feb 15, 2022
2a4894c
feat: 플레이어가 카드를 더 받을지 안받을지 로직 구현
YuYangWoo Feb 15, 2022
015ea73
feat: dealer와 player의 cardSum 구하는 코드 구현
YuYangWoo Feb 15, 2022
9edf9ed
feat: 딜러와 플레이어의 gameResult를 구하는 로직
YuYangWoo Feb 15, 2022
97e6457
feat: 게임의 결과를 구하고 카드의 합을 구하는 출력문 구현
YuYangWoo Feb 15, 2022
2c2d980
feat: Ace는 예외로 1이나 11로 계산할 수 있는 코드 로직 구현 - Player
YuYangWoo Feb 16, 2022
27c5f3f
refactor: Ace가 있을 경우 계산하는 로직 리팩토링
YuYangWoo Feb 16, 2022
2d05151
refactor: 메서드 네이밍 수정
YuYangWoo Feb 16, 2022
7ca8326
refactor: 딜러와 플레이어의 승, 패 로직 구현
YuYangWoo Feb 16, 2022
55b62b9
refactor: 딜러와 플레이어의 승, 패 로직 리팩토링
YuYangWoo Feb 16, 2022
cde826e
refactor: 메서드 코드 간격 수정
YuYangWoo Feb 16, 2022
317b7dc
refactor: 중복되는 코드를 Car.class로 위임
YuYangWoo Feb 17, 2022
2019fc6
refactor: 패키지 구조 변경
YuYangWoo Feb 17, 2022
0e6fe11
refactor: player와 dealer의 중복된 코드를 Gamer로 위임
YuYangWoo Feb 17, 2022
8dfac2c
refactor: 중복된 코드 Gamer에 위임
YuYangWoo Feb 17, 2022
9bf6d84
refactor: 생성자 네이밍 변경
YuYangWoo Feb 17, 2022
f7fa94e
refactor: Gamer를 이용한 일급객체 초기화
YuYangWoo Feb 17, 2022
c6ae257
refactor: Gamer를 이용한 일급객체 초기화 - Gamer Player
YuYangWoo Feb 17, 2022
fe72065
refactor: LinkedHashMap을 사용해 결과 순서보장
YuYangWoo Feb 17, 2022
ebf319e
test: 모든 카드는 52장이다.
YuYangWoo Feb 17, 2022
f804509
test: GamerTest.java 에 Gamer에 대한 테스트 로직 구현
YuYangWoo Feb 17, 2022
12d9584
test: GamerTest.java 에 Gamer에 대한 테스트 로직 구현
YuYangWoo Feb 17, 2022
1bad02b
test: PlayerTest 테스트 코드 구현
YuYangWoo Feb 17, 2022
41acbdf
refactor: 방어적 복사 적용
YuYangWoo Feb 17, 2022
8f65321
refactor: Dealer.java 16이하면 카드를 더받는 로직 Dealer에 책임 위임
YuYangWoo Feb 17, 2022
157a9a5
test: Dealer 테스트 로직 구현
YuYangWoo Feb 17, 2022
69de10d
fix: 카드가 중복이 되는 경우 이슈 해결
YuYangWoo Feb 17, 2022
0d305fe
refactor: 코드 정렬 및 final 추가
YuYangWoo Feb 17, 2022
397f22e
refactor: 코드 정렬 및 final 추가
YuYangWoo Feb 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,60 @@
# java-blackjack
# java-blackjack

# 연료주입
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기능 구현 목록 작성 👍


### 기능요구사항
- [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>
12 changes: 12 additions & 0 deletions src/main/java/blackjack/Application.java
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();
}

}
50 changes: 50 additions & 0 deletions src/main/java/blackjack/controller/GameLauncher.java
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() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드가 10 line을 넘어가는 것 같아요!!
아래의 요구사항을 지켜보면 어떨까요?

함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다.
함수(또는 메소드)가 한 가지 일만 하도록 최대한 작게 만들어라.

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
Copy link

Choose a reason for hiding this comment

The 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);
}
}
}
18 changes: 18 additions & 0 deletions src/main/java/blackjack/domain/Card/Suit.java
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;
}
}
39 changes: 39 additions & 0 deletions src/main/java/blackjack/domain/card/Card.java
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;
}

}
22 changes: 22 additions & 0 deletions src/main/java/blackjack/domain/card/Cards.java
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;
}

}
37 changes: 37 additions & 0 deletions src/main/java/blackjack/domain/card/Denomination.java
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;
}
}
24 changes: 24 additions & 0 deletions src/main/java/blackjack/domain/gamer/Dealer.java
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;
}
}
96 changes: 96 additions & 0 deletions src/main/java/blackjack/domain/gamer/Gamer.java
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
Copy link

@vsh123 vsh123 Feb 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addAll을 이용해보면 어떨까요?

Suggested change
for(Card card : cards) {
this.cards.add(card);
}
this.cards.addAll(cards);

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;
}
}
21 changes: 21 additions & 0 deletions src/main/java/blackjack/domain/gamer/Player.java
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);
}

}
Loading