Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
78838ee
docs: Update README.md
jihyunhillpark Feb 11, 2022
76baf2a
feat: Sonata 연비, 여행거리 관련 메소드 구현
jihyunhillpark Feb 11, 2022
572a12f
feat: Sonata 클래스 getName() 기능 구현
jihyunhillpark Feb 11, 2022
ef8ae71
feat: Avante 클래스 getDistancePerLiter() 기능 구현
Xxell-8 Feb 11, 2022
b2c6ca7
feat: Avante 클래스 getTripDistance() 구현
Xxell-8 Feb 11, 2022
1d32d74
feat: Avante 클래스 getName() 기능 구현
Xxell-8 Feb 11, 2022
8fbfde3
feat: K5 클래스 getDistancePerLiter() 기능 구현
Xxell-8 Feb 11, 2022
e6ffc5c
feat: Constant에 NEWLINE 상수 추가
Xxell-8 Feb 11, 2022
1a6cd6c
feat: K5 클래스 getTripDistance() 기능 구현
Xxell-8 Feb 11, 2022
df8c047
feat: K5 클래스 getName() 기능 구현
Xxell-8 Feb 11, 2022
42c3c1f
test: Sonata 연료 주입량 반환 테스트
Xxell-8 Feb 11, 2022
fb8df81
test: K5 연료 주입량 반환 테스트
Xxell-8 Feb 11, 2022
8507816
test: Avante 연료 주입량 반환 테스트
Xxell-8 Feb 11, 2022
aa70fd3
test: RentCompany report 반환 테스트
Xxell-8 Feb 11, 2022
bcc45be
feat: Constant에 DELIMITER, UNIT 상수 추가
Xxell-8 Feb 11, 2022
c0caff4
feat: TDD에 따른 RentCompany 기능 추가
Xxell-8 Feb 11, 2022
2e0d35d
feat: generateReport() 를 위한 toString() 메서드 추가
Xxell-8 Feb 11, 2022
750bb83
refactor: Car Interface 추가
jihyunhillpark Feb 14, 2022
3ec67a7
docs: 연료주입 기능 명세 update
jihyunhillpark Feb 14, 2022
a3f1de0
feat: Card를 구성하는 숫자와 문양 타입의 Enum 생성
jihyunhillpark Feb 14, 2022
57df031
feat: Card 클래스 구현
jihyunhillpark Feb 14, 2022
966bd00
feat: CardDeck 생성 기능 구현
jihyunhillpark Feb 14, 2022
3e50ca1
docs: update README.md
jihyunhillpark Feb 14, 2022
131a640
feat: 사용자 입력 기능 구현
jihyunhillpark Feb 14, 2022
2cbc1e0
feat: 문자열 스플릿을 위한 utils 추가
Xxell-8 Feb 15, 2022
087506a
feat: 사용자 입력을 위한 InputView 생성
Xxell-8 Feb 15, 2022
7aae53a
docs: Update README.md
Xxell-8 Feb 15, 2022
e0783b0
feat: Card를 담는 Cards 클래스 구현
Xxell-8 Feb 15, 2022
f5591ff
feat: Player 클래스 생성
Xxell-8 Feb 15, 2022
51f72fb
feat: 카드들의 점수를 계산해 반환하는 getScore() 추가
Xxell-8 Feb 15, 2022
2346f97
feat: Getter 추가
Xxell-8 Feb 15, 2022
6ebcf44
feat: 현재 점수를 반환하는 getScore() 메서드 추가
Xxell-8 Feb 15, 2022
df9f9e8
feat: 딜러가 추가로 카드를 받을지 말지 확인하는 메서드 추가
Xxell-8 Feb 15, 2022
a8aafeb
feat: hit 기능 구현
jihyunhillpark Feb 16, 2022
d1759fb
feat: play bust 확인 기능 구현
jihyunhillpark Feb 16, 2022
5e39a05
feat: 최신상황 업데이트
jihyunhillpark Feb 16, 2022
cbd3f09
feat: 카드명 출력을 위한 toString() 생성
Xxell-8 Feb 16, 2022
8fce6da
test: 첫 번째 카드 오픈 결과 테스트
Xxell-8 Feb 16, 2022
4a7d92b
feat: 새로운 딜러를 생성하는 팩토리 메서드 추가
Xxell-8 Feb 16, 2022
858753e
feat: 받은 카드 중 한 장을 반환하는 openCard() 생성
Xxell-8 Feb 16, 2022
1a3569b
refactor: 사용하지 않는 세팅 삭제
Xxell-8 Feb 16, 2022
c95aeb4
test: 플레이어가 가진 카드 출력 테스트 생성
Xxell-8 Feb 16, 2022
ccdac4c
feat: 플레이어가 가진 모든 카드를 출력하는 openCard() 생성
Xxell-8 Feb 16, 2022
a2f4d6f
feat: 카드 점수 집계 시, ace 계산 방식 추가
Xxell-8 Feb 16, 2022
22cb340
feat: BlackJackMain 메서드 생성
Xxell-8 Feb 16, 2022
daaa860
feat: 참여자 기본 Getter 추가
Xxell-8 Feb 16, 2022
cfd0ecd
refactor: 딜 이후 딜러의 첫 번째 카드만 반환하도록 수정
Xxell-8 Feb 16, 2022
f21535a
feat: 플레이어 전원에게 딜하는 메서드 추가
Xxell-8 Feb 16, 2022
0873b35
refactor: 상위 클래스와 중복되는 메서드 삭제
Xxell-8 Feb 16, 2022
a984d8b
feat: View 로직을 포함하지 않는 게임 관련 메서드 작성
Xxell-8 Feb 16, 2022
031c81d
feat: 카드 이름 리스트를 반환하는 메서드 추가
Xxell-8 Feb 16, 2022
6dd2a34
style: 잘못된 클래스 이름 수정 및 메서드 분리
Xxell-8 Feb 16, 2022
6ecc4d9
refactor: 사용자에게 y, n 입력 받는 메서드 처리 로직 일부 수정
Xxell-8 Feb 16, 2022
4a20002
feat: OutputView 추가
Xxell-8 Feb 16, 2022
f0726bd
feat: 출력을 위한 dto 추가
Xxell-8 Feb 16, 2022
e24a2d5
feat: 컨트롤러 작성
Xxell-8 Feb 16, 2022
74a299a
feat: blackjack 결과 관련 기능 수정
jihyunhillpark 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
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
# java-blackjack
# 연료 주입
## 기능 요구 사항
우리 회사는 렌터카를 운영하고 있다
Copy link

Choose a reason for hiding this comment

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

기능 요구 사항 작성 👍

현재 보유하고 있는 차량은 Sonata 2대, Avante 1대, K5 2대로 총 5대의 차량을 보유하고 있다.
고객이 인터넷으로부터 예약할 때 여행할 목적지의 대략적인 이동거리를 입력 받는다.
이 이동거리를 활용해 차량 별로 필요한 연료를 주입한다.
차량 별로 주입해야 할 연료량을 확인할 수 있는 보고서를 생성해야 한다.

각 차량별 연비는 다음과 같다.
* Sonata : 10km/리터
* Avante : 15km/리터
* K5 : 13km/리터

## 기능 구현 사항
- [x] 자동차를 보유하는 렌터카 회사는 factory method를 사용해 생성한다. RentCompany#create()
- [x] 자동차 인스턴스를 생성할 시 이동할 거리를 인자로 받는다.
- [x] RentCar 추상 클래스는 필드에 대한 getter 메소드를 가지는 Car 인터페이스를 구현한다.
- [x] 렌터카 회사에 있는 자동차들은 RentCar 추상클래스를 상속받는다. RentCar - Sonata, Avante, K5

# 블랙잭
## 기능 요구 사항
블랙잭 게임은 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 숫자를 가지는 쪽이 이기는 게임이다.
카드의 숫자 계산은 카드 숫자를 기본으로 하며, 예외로 Ace는 1 또는 11로 계산할 수 있으며, King, Queen, Jack은 각각 10으로 계산한다.
게임을 시작하면 플레이어는 두 장의 카드를 지급 받으며, 두 장의 카드 숫자를 합쳐 21을 초과하지 않으면서 21에 가깝게 만들면 이긴다. 21을 넘지 않을 경우 원한다면 얼마든지 카드를 계속 뽑을 수 있다.
딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없다.
게임을 완료한 후 각 플레이어별로 승패를 출력한다.

## 기능 구현 사항
- [x] 게임에 참여할 사람을 쉼표로 구분한다. - InputView
- [x] 카드는 숫자랑 문양으로 이루어진다. - Card
- [x] 숫자와 문양은 Enum 형태로 관리한다.
- [ ] Ace는 1또는 11로 계산할 수 있다.
- [x] King, Queen, Jack은 각각 10으로 계산한다.
- [x] 카드는 덱으로 관리한다. - CardDeck
- [x] 게임을 시작할 때 shuffle을 한 번 수행한다.
- [x] 카드는 문양 + 숫자 조합이 하나씩만 존재한다.
- [ ] 게임을 시작하면 딜러를 포함한 모든 플레이어들에게 카드를 2장씩 나누어준다.
- [ ] 딜레를 제외한 플레이어는 21을 초과하지 않을 때까지 카드를 계속 받을지 선택한다.
- [ ] 딜러는 처음 받은 카드 두 장의 합이 16이하면 한 장의 카드를 더 받는다.

11 changes: 11 additions & 0 deletions src/main/java/blackjack/BlackJackMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package blackjack;

import blackjack.controller.BlackJackController;

public class BlackJackMain {

public static void main(String[] args) {
BlackJackController blackJackController = new BlackJackController();
blackJackController.run();
}
}
91 changes: 91 additions & 0 deletions src/main/java/blackjack/controller/BlackJackController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package blackjack.controller;

import blackjack.domain.CardDeck;
import blackjack.domain.Dealer;
import blackjack.domain.Game;
import blackjack.domain.GameResult;
import blackjack.domain.Player;
import blackjack.domain.Players;
import blackjack.dto.PlayerDTO;
import blackjack.dto.FinalScoreDTO;
import blackjack.view.InputView;
import blackjack.view.OutputView;
import java.util.ArrayList;
import java.util.List;

public class BlackJackController {

public BlackJackController() {
}

public void run() {
List<String> playerNames = InputView.inputPlayerNames();
CardDeck deck = new CardDeck();
Dealer dealer = Dealer.create();
Players players = new Players(playerNames);

Game game = new Game(dealer, players, deck);
game.init();

printResultOfDeal(dealer, players, playerNames);

playerTurn(deck, players);
dealerTurn(deck, dealer);

printFinalResult(dealer, players);
printWinOrLose(dealer, players);
}


private void printResultOfDeal(Dealer dealer, Players players, List<String> playerNames) {
List<PlayerDTO> results = new ArrayList<>();
results.add(PlayerDTO.from(dealer));
for (Player player : players.get()) {
results.add(PlayerDTO.from(player));
}

OutputView.printCards(String.join(", ", playerNames), results);
}

private void playerTurn(CardDeck deck, Players players) {
for (Player player : players.get()) {
askMoreCard(deck, player);
}
}

private void askMoreCard(CardDeck deck, Player player) {
while (!player.isBusted()) {
boolean answer = InputView.askHitOrStand(player.getName());
if (!answer) {
Copy link

Choose a reason for hiding this comment

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

여기도 depth가 2를 넘어가는 것 같아요!

break;
}

player.hit(deck);
Copy link

Choose a reason for hiding this comment

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

Game이라는 객체에서 dealer와 player, Deck을 모두 가지고 있는데, 최초 2장을 뽑는 것 이외의 모든 작업은 Controller에서 하는게 어색해보이는데요!

Game객체를 조금더 활용해보면 어떨까요?

OutputView.printCard(PlayerDTO.from(player));
}
}

private void dealerTurn(CardDeck deck, Dealer dealer) {
while (dealer.checkHitOrNot()) {
dealer.hit(deck);
OutputView.printDealerHit();
}
}

private void printFinalResult(Dealer dealer, Players players) {
List<FinalScoreDTO> results = new ArrayList<>();
results.add(FinalScoreDTO.from(dealer));
for (Player player : players.get()) {
results.add(FinalScoreDTO.from(player));
}

OutputView.printGameResults(results);
}

private void printWinOrLose(Dealer dealer, Players players) {
GameResult gameResult = new GameResult();
gameResult.mapResults(players, dealer);
OutputView.printWinOrLose(gameResult);
}

}
20 changes: 20 additions & 0 deletions src/main/java/blackjack/domain/Card.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package blackjack.domain;

public class Card {
private final Suit suit;
private final Denomination denomination;

public Card(Suit suit, Denomination denomination) {
this.suit = suit;
this.denomination = denomination;
}

public Denomination getDenomination() {
return denomination;
}

@Override
public String toString() {
Copy link

Choose a reason for hiding this comment

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

여기도 toString재정의에 대해 다시한번 고려해주시면 좋을 것 같아요!

return denomination.getAlias() + suit.getName();
}
}
37 changes: 37 additions & 0 deletions src/main/java/blackjack/domain/CardDeck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package blackjack.domain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CardDeck {

private final List<Card> cardDeck;

public CardDeck() {
cardDeck = initDeck();
}

public List<Card> initDeck() {
List<Card> deck = new ArrayList<>();
for (Suit suit : Suit.values()) {
for (Denomination denomination : Denomination.values()) {
Copy link

Choose a reason for hiding this comment

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

depth가 2를 넘어가는 것 같아요! 아래의 요구사항을 지켜보면 어떨까요?

indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록 구현한다. 1까지만 허용한다.
예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.

deck.add(new Card(suit, denomination));
}
}
Collections.shuffle(deck);
return deck;
}

public Card popCard() {
Copy link

Choose a reason for hiding this comment

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

cardDeck이 비어있으면 에러가 발생할 것 같은데, 이에 대한 핸들링을 해주면 어떨까요?

int target = cardDeck.size() - 1;
Card card = cardDeck.get(target);
cardDeck.remove(target);

return card;
}

public boolean contains(Card target) {
return cardDeck.contains(target);
}
}
44 changes: 44 additions & 0 deletions src/main/java/blackjack/domain/Cards.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package blackjack.domain;

import java.util.List;
import java.util.stream.Collectors;

public class Cards {

private final List<Card> cards;

public Cards(List<Card> cards) {
this.cards = cards;
}

public void addCard(Card card) {
cards.add(card);
}

public int getScore() {
int total = cards.stream().mapToInt(card -> card.getDenomination().getScore()).sum();
Copy link

Choose a reason for hiding this comment

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

card.getScore()라는 메서드를 만들어보면 어떨까요?

Suggested change
int total = cards.stream().mapToInt(card -> card.getDenomination().getScore()).sum();
int total = cards.stream().mapToInt(card -> card.getScore()).sum();

int aceCount = (int) cards.stream().filter(card -> card.getDenomination().isAce()).count();
for (int i = 0; i < aceCount; i++) {
total = checkAceOneOrEleven(total);
}

return total;
}

private int checkAceOneOrEleven(int total) {
if (total + 10 <= 21) {
return total + 10;
Comment on lines +29 to +30
Copy link

Choose a reason for hiding this comment

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

매직넘버가 많아보여요~!

}
return total;
}

public List<Card> getCards() {
return cards;
}

public List<String> getCardNames() {
return cards.stream()
.map(Card::toString)
.collect(Collectors.toList());
}
}
26 changes: 26 additions & 0 deletions src/main/java/blackjack/domain/Dealer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package blackjack.domain;

import java.util.ArrayList;

public class Dealer extends Participant {

private static final String NAME_TAG = "딜러 카드: ";
Copy link

Choose a reason for hiding this comment

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

미사용 상수는 제거해주세요!

private static final int LIMIT_MORE_CARD = 16;

public Dealer(Cards cards) {
super(cards);
}

public static Dealer create() {
Cards cards = new Cards(new ArrayList<>());
Copy link

Choose a reason for hiding this comment

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

이런 생성의 경우 왜 빈 리스트를 넣는지 명확하지 못한 것 같아요!
팩터리 메서드와 같은 걸로 의미있는 생성을 해보면 어떨까요?

return new Dealer(cards);
}

public boolean checkHitOrNot() {
return getScore() <= LIMIT_MORE_CARD;
}

public String openOneCard() {
return getCardNames().get(0);
}
}
37 changes: 37 additions & 0 deletions src/main/java/blackjack/domain/Denomination.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package blackjack.domain;

public enum Denomination {
ACE(1, "A"),
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(10, "J"),
QUEEN(10, "Q"),
KING(10, "K");

private final int score;
private final String alias;

Denomination(final int score, final String alias) {
this.score = score;
this.alias = alias;
}

public boolean isAce() {
return this == ACE;
}

public int getScore() {
return score;
}

public String getAlias() {
return alias;
}
}
22 changes: 22 additions & 0 deletions src/main/java/blackjack/domain/Game.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package blackjack.domain;

import java.util.HashMap;
import java.util.Map;
Comment on lines +3 to +4
Copy link

Choose a reason for hiding this comment

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

둘다 미사용인 것 같아요!


public class Game {

private final Players players;
private final Dealer dealer;
private final CardDeck deck;

public Game(Dealer dealer, Players players, CardDeck deck) {
this.players = players;
this.dealer = dealer;
this.deck = deck;
}

public void init() {
dealer.deal(deck);
players.deal(deck);
}
}
58 changes: 58 additions & 0 deletions src/main/java/blackjack/domain/GameResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package blackjack.domain;

import static blackjack.utils.Constant.LOSE;
import static blackjack.utils.Constant.PUSH;
import static blackjack.utils.Constant.WIN;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GameResult {

private final Map<String, String> playerResults = new HashMap<>();
private final Map<String, Integer> dealersResults = new HashMap<>();

public void mapResults(Players players, Dealer dealer) {
for (Player player : players.get()) {
playerResults.put(player.getName(), player.getGameResult(dealer));
}
updateDealerResult(dealer);
}

private void updateDealerResult(Dealer dealer) {
for (String result : playerResults.values()) {
if (dealer.isBusted()) {
dealersResults.put(LOSE, dealersResults.getOrDefault(LOSE, 0) + 1);
continue;
}
String deal = WIN;
if (result.equals(WIN)) {
deal = LOSE;
}
if (result.equals(PUSH)) {
deal = PUSH;
}
dealersResults.put(deal, dealersResults.getOrDefault(deal, 0) + 1);
}
}

public Map<String, String> getPlayerResults() {
return playerResults;
}

public String getDealerResult() {
StringBuilder result = new StringBuilder();
List<String> orders = Arrays.asList(WIN, PUSH, LOSE);

for (String order : orders) {
if (dealersResults.containsKey(order)) {
result.append(dealersResults.get(order)).append(order);
}
}

return result.toString();
}

}
Loading