From dc2a8064f4c058ecfffd81690264d5fe2a6516a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=EC=9D=80=EC=9A=B0?= <80899085+be-student@users.noreply.github.com> Date: Wed, 8 Mar 2023 00:59:28 +0900 Subject: [PATCH 01/59] =?UTF-8?q?[1=EB=8B=A8=EA=B3=84=20-=20=EB=B8=94?= =?UTF-8?q?=EB=9E=99=EC=9E=AD=20=EA=B2=8C=EC=9E=84=20=EC=8B=A4=ED=96=89]?= =?UTF-8?q?=20=EB=88=84=EB=88=84(=EC=86=A1=EC=9D=80=EC=9A=B0)=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=EC=A0=9C=EC=B6=9C=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#?= =?UTF-8?q?456)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: 기능 목록 작성 * test: Name 객체 유효성 테스트 및 도메인 생성 * feat: Shape 도메인 생성 * test: Card 테스트 * feat: Card 도메인 생성 * feat: shuffle 객체 추가 * feat: deck을 생성할 때 factory 형태로 생성하는 기능 추가 * feat: cardPocket 점수 계산 기능 추가 * feat: Participant 도메인 생성 * feat: dealer 카드 DRAW여부 확인 기능 추가 및 테스트 * feat: blackjack 상수 추가 * feat: participant 카드 getter 기능 추가 * refactor: 테스트에서 사용되는 fixture 메서드로 분리 * feat: Player 기능 추가 * feat: Players 기능 및 테스트 추가 * refactor: 빈 CardPocket 생성 기능 추가 * feat: 결과를 저장하는 객체를 추가 * feat: dealer 에서 결과 계산 기능 추가 * docs: readme 작성 * feat: 출력 기능 작성 * feat: 입력 기능 추가 * fix: 딜러 점수 계산 방식 오류 수정 * feat: hasName 메서드로 검색 가능하도록 추가 * feat: 출력을 위한 메서드들 추가 * feat: 게임 객체 추가 * feat: controller 작성 * docs: 클래스 주석 작성 * docs: 사용하지 않는 주석 제거 * refactor: remove blackjackGame to controller * refactor: Optional 안 사용하도록 변경 * refactor: 메서드 분리만 * refactor: controller indent 2 메서드 분리 * refactor: factory 내부 indent 2 제거 * chore: 사용하지 않는 메서드 제거 * chore: 매개변수 타입 명칭 변경 * style: reformat * refactor: 한번에 결과를 반환하도록 변경 * style : 자바 컨벤션 수정 * docs: 사용하지 않는 주석 제거 * feat: 줄바꿈 변경 * refactor: 접근 제어자 더 좁은 방향으로 변경 * feat: util 클래스 생성 방지를 위한 private 생성자 추가 * feat: participant 쪽에 공통으로 draw 하는 메서드 추가 * refactor: 안 쓰이는 equals, hashcode 제거 * refactor: isAce 메서드와, score 메서드를 통해 결합도를 낮춤 * test: isAce 메서드와, 점수 계산 테스트 추가 * test: ace 가 현재 점수에 따라 다르게 계산되는 것 검증 추가 * refactor: 메서드 네이밍 변경 * test: 52장 제거 테스트 추가 * refactor: for문을 flatMap 형태로 stream 으로 변경 * refactor: set 형태 대신, distinct 로 중복 검사 변경 * feat: initialCardResponseDto 추가 * feat: CardsScoreResponse 작성 * feat: enum 의 이름을 기준으로 가져올 수 있도록 변경 * fix: getter로 꺼내오는 메서드 제거 * feat: 결과를 변환하는 전략 추가 * feat: resultTypeResponse 추가 * refactor: InitialCardResponse 적용 * feat: PlayerCardsResponse 적용 * feat: playersCardsResponse 추가 * refactor: FinalResultResponse 를 사용하도록 변경 * chore: 안 쓰이는 dto 제거 * chore: 안 쓰이는 변환 제거 * refactor: String format 대신 MessageFormat 사용 * refactor: 바로 도메인 객체를 받아서 변환하도록 변경 * refactor: util 로 이동 * refactor: 상수를 각각의 클래스로 옮김 * chore: 클래스 네이밍 변경 * feat: 컨트롤러에서 사용하는 로직을 game 객체로 이동 * refactor: dto 로 변환하는 작업을 game 쪽으로 이동 * refactor: blackjack game 안쪽에서 Players 를 생성하도록 변경 * refactor: getter를 비즈니스 로직에서 덜 사용하도록 변경 * feat: blackjack Rule 객체 추가 * feat: dealer 에서 계산 로직 제거 * feat: 결과를 계산하는 로직을 담당하는 객체 추가 * style: 메시지 줄바꿈 추가 * feat: innerClass 로 particiPantResult 이동 * refactor: 패키지 이동 * feat: 계속 반복되는 CustomException 으로 분리 * style: 줄바꿈 변경 * chore: 카드 포켓 에러 메시지 변경 * chore: 메서드명 변경 * chore: 에러 메시지 변경 * refactor: deck, deckFactory 패키지 변경 * chore: 주석 제거 * refactor: blackjackGame 패키지 변경 * refactor: 메서드 인라인 * refactor: response 에 있던 정적 팩토리 제거 * feat: blackJackRule 인터페이스로 분리 * fix: 테스트 깨진 것 제거 * feat: 점수 저장 기능 BlackJackGame 으로 이동 * fix: 제거된 클래스 관련 메서드 제거 * chore: 메서드명 popCard 로 변경 --------- Co-authored-by: DESKTOP-FNVN0HH\USER --- README.md | 76 ++++++++++ src/main/java/blackjack/Application.java | 14 ++ .../controller/BlackJackController.java | 78 ++++++++++ .../java/blackjack/domain/BlackJackRule.java | 9 ++ .../blackjack/domain/BlackJackRuleImpl.java | 39 +++++ .../java/blackjack/domain/ResultType.java | 17 +++ src/main/java/blackjack/domain/card/Card.java | 28 ++++ .../blackjack/domain/card/CardPocket.java | 62 ++++++++ src/main/java/blackjack/domain/card/Deck.java | 32 ++++ .../blackjack/domain/card/DeckFactory.java | 6 + .../java/blackjack/domain/card/Shape.java | 8 + .../domain/card/ShuffledDeckFactory.java | 25 ++++ .../java/blackjack/domain/card/Symbol.java | 31 ++++ .../blackjack/domain/participant/Dealer.java | 12 ++ .../blackjack/domain/participant/Name.java | 34 +++++ .../domain/participant/Participant.java | 33 +++++ .../domain/participant/Participants.java | 53 +++++++ .../blackjack/domain/participant/Player.java | 27 ++++ .../blackjack/domain/participant/Players.java | 98 ++++++++++++ .../exception/PlayerNotFoundException.java | 8 + .../response/CardConvertStrategy.java | 8 + .../java/blackjack/response/CardResponse.java | 26 ++++ .../response/DealerScoreResponse.java | 22 +++ .../response/FinalResultResponse.java | 23 +++ .../response/InitialCardResponse.java | 59 ++++++++ .../response/PlayerCardsResponse.java | 23 +++ .../response/PlayersCardsResponse.java | 45 ++++++ .../response/ResultConvertStrategy.java | 6 + .../response/ResultTypeResponse.java | 42 ++++++ .../java/blackjack/service/BlackJackGame.java | 140 ++++++++++++++++++ src/main/java/blackjack/util/Repeater.java | 29 ++++ .../view/CardConvertStrategyImpl.java | 56 +++++++ src/main/java/blackjack/view/DrawCommand.java | 20 +++ src/main/java/blackjack/view/InputView.java | 29 ++++ src/main/java/blackjack/view/OutputView.java | 137 +++++++++++++++++ .../view/ResultConvertStrategyImpl.java | 20 +++ .../blackjack/domain/BlackJackRuleTest.java | 10 ++ .../blackjack/domain/card/CardPocketTest.java | 70 +++++++++ .../java/blackjack/domain/card/CardTest.java | 40 +++++ .../java/blackjack/domain/card/DeckTest.java | 38 +++++ .../domain/participant/DealerTest.java | 58 ++++++++ .../domain/participant/NameTest.java | 31 ++++ .../domain/participant/ParticipantTest.java | 55 +++++++ .../domain/participant/PlayerTest.java | 46 ++++++ .../domain/participant/PlayersTest.java | 57 +++++++ 45 files changed, 1780 insertions(+) create mode 100644 src/main/java/blackjack/Application.java create mode 100644 src/main/java/blackjack/controller/BlackJackController.java create mode 100644 src/main/java/blackjack/domain/BlackJackRule.java create mode 100644 src/main/java/blackjack/domain/BlackJackRuleImpl.java create mode 100644 src/main/java/blackjack/domain/ResultType.java create mode 100644 src/main/java/blackjack/domain/card/Card.java create mode 100644 src/main/java/blackjack/domain/card/CardPocket.java create mode 100644 src/main/java/blackjack/domain/card/Deck.java create mode 100644 src/main/java/blackjack/domain/card/DeckFactory.java create mode 100644 src/main/java/blackjack/domain/card/Shape.java create mode 100644 src/main/java/blackjack/domain/card/ShuffledDeckFactory.java create mode 100644 src/main/java/blackjack/domain/card/Symbol.java create mode 100644 src/main/java/blackjack/domain/participant/Dealer.java create mode 100644 src/main/java/blackjack/domain/participant/Name.java create mode 100644 src/main/java/blackjack/domain/participant/Participant.java create mode 100644 src/main/java/blackjack/domain/participant/Participants.java create mode 100644 src/main/java/blackjack/domain/participant/Player.java create mode 100644 src/main/java/blackjack/domain/participant/Players.java create mode 100644 src/main/java/blackjack/domain/participant/exception/PlayerNotFoundException.java create mode 100644 src/main/java/blackjack/response/CardConvertStrategy.java create mode 100644 src/main/java/blackjack/response/CardResponse.java create mode 100644 src/main/java/blackjack/response/DealerScoreResponse.java create mode 100644 src/main/java/blackjack/response/FinalResultResponse.java create mode 100644 src/main/java/blackjack/response/InitialCardResponse.java create mode 100644 src/main/java/blackjack/response/PlayerCardsResponse.java create mode 100644 src/main/java/blackjack/response/PlayersCardsResponse.java create mode 100644 src/main/java/blackjack/response/ResultConvertStrategy.java create mode 100644 src/main/java/blackjack/response/ResultTypeResponse.java create mode 100644 src/main/java/blackjack/service/BlackJackGame.java create mode 100644 src/main/java/blackjack/util/Repeater.java create mode 100644 src/main/java/blackjack/view/CardConvertStrategyImpl.java create mode 100644 src/main/java/blackjack/view/DrawCommand.java create mode 100644 src/main/java/blackjack/view/InputView.java create mode 100644 src/main/java/blackjack/view/OutputView.java create mode 100644 src/main/java/blackjack/view/ResultConvertStrategyImpl.java create mode 100644 src/test/java/blackjack/domain/BlackJackRuleTest.java create mode 100644 src/test/java/blackjack/domain/card/CardPocketTest.java create mode 100644 src/test/java/blackjack/domain/card/CardTest.java create mode 100644 src/test/java/blackjack/domain/card/DeckTest.java create mode 100644 src/test/java/blackjack/domain/participant/DealerTest.java create mode 100644 src/test/java/blackjack/domain/participant/NameTest.java create mode 100644 src/test/java/blackjack/domain/participant/ParticipantTest.java create mode 100644 src/test/java/blackjack/domain/participant/PlayerTest.java create mode 100644 src/test/java/blackjack/domain/participant/PlayersTest.java diff --git a/README.md b/README.md index 556099c4de..10d729dcc7 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,79 @@ ## 우아한테크코스 코드리뷰 - [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) + +```mermaid +graph TD +의존성그래프 +BlackJackGame --> Players +BlackJackGame --> Deck +BlackJackGame --> Dealer + +Players --> Dealer +Dealer --> Player + +Participant --> CardPocket +Dealer --> Participant +Player --> Participant + +Players --> Player +Player --> Name +CardPocket --> Card + +Deck --> Card +Card --> Shape +Card --> Symbol +``` + +# 기능구현 목록 + +## UI + +1. 입력 + +- 참여할 사람을 입력한다 +- List으로 변환 및 반환한다 +- + +## 도메인 + +1. Deck + - [x] 카드를 생성한다 + - [x] 총 52장 + - [x] Shape마다 13장을 출력 + - [x] 카드를 나눠준다 + +2. BlackJack + - 딜러와 플레이어에게 카드를 2장씩 나눠준다. + -- 카드를 나눠준다 +3. Participant + - [x] 21 이상인지 확인하고 + - [x] 21 이상이라면, + - [x] 블랙잭인지 확인한다 = 받을 수 없음 + - [x] BURST인지 확인한다 = 받을 수 없음4 + - [x] 현재 점수를 숫자 형태로 반환한다 + - [x] 현재 카드를 반환한다 +4. Player + - [x] 21 미만이면, 받을 수 있다는 boolean +5. Dealer + - [x] 16 이하이면, 받을 수 있따는 boolean +6. CardPocket + - [x] 카드의 Symbol 점수를 계산한다.(ScoreCalculator 역할) + - 카드반환 한다 + - [x] 카드 계산 총합 반환 +7. Shape + - [x] enum 형태로 하트, 스페이스, 클로버, 다이아를 저장한다 +8. Symbol + - [x] a=1 2-9, j,q,k =10 + - [x] value는 int 형으로 저장한다 +9. Card + - [x] Shape와 Symbol을 저장하는 자료구조 + +10. Players + - [x] 플레이어 이름 중복 + - [x] 플레이어 수 1명이상, 5명 이하 + - [x] 플레이어에게 카드 나눠주기 + - [x] 플레이어의 draw여부 알기 +11. Name + - [x] isBlank 체크 + - [x] 100자 이하 체크 diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java new file mode 100644 index 0000000000..863b6b26f8 --- /dev/null +++ b/src/main/java/blackjack/Application.java @@ -0,0 +1,14 @@ +package blackjack; + +import blackjack.controller.BlackJackController; +import blackjack.domain.card.ShuffledDeckFactory; +import blackjack.view.InputView; +import blackjack.view.OutputView; + +public class Application { + + public static void main(final String[] args) { + final BlackJackController blackJackController = new BlackJackController(new InputView(), new OutputView()); + blackJackController.play(new ShuffledDeckFactory()); + } +} diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java new file mode 100644 index 0000000000..e744897f7f --- /dev/null +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -0,0 +1,78 @@ +package blackjack.controller; + +import static blackjack.util.Repeater.repeatUntilNoException; + +import blackjack.domain.card.DeckFactory; +import blackjack.service.BlackJackGame; +import blackjack.view.DrawCommand; +import blackjack.view.InputView; +import blackjack.view.OutputView; +import java.util.List; + +public class BlackJackController { + + private final InputView inputView; + private final OutputView outputView; + + public BlackJackController(final InputView inputView, final OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void play(final DeckFactory deckFactory) { + final BlackJackGame blackJackGame = repeatUntilNoException( + () -> BlackJackGame.of( + inputPlayerNames(), + deckFactory), + outputView::printError); + + blackJackGame.distributeInitialCard(); + outputView.printInitialCards(blackJackGame.getInitialCardResponse()); + + drawPlayersCards(blackJackGame); + drawDealerCards(blackJackGame); + + outputView.printFinalStatusOfDealer(blackJackGame.getDealerScoreResponse()); + outputView.printFinalStatusOfPlayers(blackJackGame.getPlayersCardsResponse()); + outputView.printFinalResult(blackJackGame.createFinalResultResponse()); + } + + private List inputPlayerNames() { + return inputView.inputPlayerNames(); + } + + private void drawPlayersCards(final BlackJackGame blackJackGame) { + for (final String playerName : blackJackGame.getPlayerNames()) { + drawPlayerCard(playerName, blackJackGame); + } + } + + private void drawPlayerCard(final String playerName, final BlackJackGame blackJackGame) { + DrawCommand playerInput = DrawCommand.DRAW; + while (blackJackGame.isPlayerDrawable(playerName) && playerInput != DrawCommand.STAY) { + playerInput = repeatUntilNoException( + () -> inputView.inputCommand(playerName), outputView::printError); + drawCard(playerName, blackJackGame, playerInput); + printPlayerResult(playerName, blackJackGame); + } + } + + private void drawCard(final String playerName, final BlackJackGame blackJackGame, + final DrawCommand playerInput) { + if (playerInput == DrawCommand.DRAW) { + blackJackGame.drawPlayerCard(playerName); + } + } + + private void printPlayerResult(final String playerName, final BlackJackGame blackJackGame) { + outputView.printCardStatusOfPlayer(blackJackGame.getPlayerCardsResponse(playerName)); + } + + private void drawDealerCards(final BlackJackGame blackJackGame) { + while (blackJackGame.isDealerDrawable()) { + blackJackGame.drawDealerCard(); + outputView.printDealerCardDrawMessage(); + } + } + +} diff --git a/src/main/java/blackjack/domain/BlackJackRule.java b/src/main/java/blackjack/domain/BlackJackRule.java new file mode 100644 index 0000000000..d85a0b014d --- /dev/null +++ b/src/main/java/blackjack/domain/BlackJackRule.java @@ -0,0 +1,9 @@ +package blackjack.domain; + +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; + +public interface BlackJackRule { + + ResultType calculateDealerResult(Dealer dealer, Player player); +} diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java new file mode 100644 index 0000000000..c9ff65b9b9 --- /dev/null +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -0,0 +1,39 @@ +package blackjack.domain; + +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; + +public class BlackJackRuleImpl implements BlackJackRule { + + private static final int BUST_POINT = 21; + + @Override + public ResultType calculateDealerResult(final Dealer dealer, final Player player) { + final int dealerScore = dealer.currentScore(); + final int playerScore = player.currentScore(); + if (isTie(dealerScore, playerScore)) { + return ResultType.TIE; + } + if (isDealerWin(dealerScore, playerScore)) { + return ResultType.WIN; + } + return ResultType.LOSE; + } + + private boolean isTie(final int dealerScore, final int playerScore) { + if (playerScore > BUST_POINT && dealerScore > BUST_POINT) { + return true; + } + return playerScore == dealerScore; + } + + private boolean isDealerWin(final int dealerScore, final int playerScore) { + if (playerScore > BUST_POINT) { + return true; + } + if (dealerScore > BUST_POINT) { + return false; + } + return dealerScore > playerScore; + } +} diff --git a/src/main/java/blackjack/domain/ResultType.java b/src/main/java/blackjack/domain/ResultType.java new file mode 100644 index 0000000000..f8bd8e7d96 --- /dev/null +++ b/src/main/java/blackjack/domain/ResultType.java @@ -0,0 +1,17 @@ +package blackjack.domain; + +public enum ResultType { + WIN, + TIE, + LOSE; + + public ResultType getOppositeResult() { + if (this == WIN) { + return LOSE; + } + if (this == TIE) { + return TIE; + } + return WIN; + } +} diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java new file mode 100644 index 0000000000..5134c1f77b --- /dev/null +++ b/src/main/java/blackjack/domain/card/Card.java @@ -0,0 +1,28 @@ +package blackjack.domain.card; + +public class Card { + + private final Shape shape; + private final Symbol symbol; + + public Card(final Shape shape, final Symbol symbol) { + this.shape = shape; + this.symbol = symbol; + } + + boolean isAce() { + return symbol.isAce(); + } + + int getScore() { + return symbol.getScore(); + } + + public Symbol getSymbol() { + return symbol; + } + + public Shape getShape() { + return shape; + } +} diff --git a/src/main/java/blackjack/domain/card/CardPocket.java b/src/main/java/blackjack/domain/card/CardPocket.java new file mode 100644 index 0000000000..c9906657ae --- /dev/null +++ b/src/main/java/blackjack/domain/card/CardPocket.java @@ -0,0 +1,62 @@ +package blackjack.domain.card; + +import java.util.ArrayList; +import java.util.List; + +public class CardPocket { + + private static final int BUST_SCORE = 21; + private static final int VALUE_ACE = 10; + private final List cards; + + private CardPocket(final List cards) { + validateCardPocket(cards); + this.cards = new ArrayList<>(cards); + } + + public static CardPocket empty() { + return new CardPocket(new ArrayList<>()); + } + + private void validateCardPocket(final List cards) { + if (cards == null) { + throw new IllegalArgumentException("카드에 null 값이 들어갈 수 없습니다"); + } + } + + public void addCard(final Card card) { + cards.add(card); + } + + public int calculateScore() { + final int countOfAce = countAce(); + int scoreOfCards = calculateMinimumScore(); + for (int i = 0; i < countOfAce; i++) { + scoreOfCards = calculateAceScore(scoreOfCards); + } + return scoreOfCards; + } + + private int countAce() { + return (int) cards.stream() + .filter(Card::isAce) + .count(); + } + + private int calculateMinimumScore() { + return cards.stream() + .mapToInt(Card::getScore) + .sum(); + } + + private int calculateAceScore(final int score) { + if (score + VALUE_ACE > BUST_SCORE) { + return score; + } + return score + VALUE_ACE; + } + + public List getCards() { + return List.copyOf(cards); + } +} diff --git a/src/main/java/blackjack/domain/card/Deck.java b/src/main/java/blackjack/domain/card/Deck.java new file mode 100644 index 0000000000..981601cf77 --- /dev/null +++ b/src/main/java/blackjack/domain/card/Deck.java @@ -0,0 +1,32 @@ +package blackjack.domain.card; + +import java.util.Queue; + +public class Deck { + + private static final int NUMBER_OF_CARDS_IN_DECK = 52; + + private final Queue cards; + + Deck(final Queue cards) { + validateCards(cards); + this.cards = cards; + } + + private void validateCards(final Queue cards) { + if (cards == null) { + throw new IllegalArgumentException("카드에 null 이 들어왔습니다"); + } + if (cards.size() != NUMBER_OF_CARDS_IN_DECK) { + throw new IllegalArgumentException( + "카드 숫자는 " + NUMBER_OF_CARDS_IN_DECK + "장이어야 합니다 현재 :" + cards.size() + "장"); + } + } + + public Card popCard() { + if (cards.isEmpty()) { + throw new IllegalArgumentException("덱에 카드가 없습니다"); + } + return cards.remove(); + } +} diff --git a/src/main/java/blackjack/domain/card/DeckFactory.java b/src/main/java/blackjack/domain/card/DeckFactory.java new file mode 100644 index 0000000000..3ca5497cae --- /dev/null +++ b/src/main/java/blackjack/domain/card/DeckFactory.java @@ -0,0 +1,6 @@ +package blackjack.domain.card; + +public interface DeckFactory { + + Deck generate(); +} diff --git a/src/main/java/blackjack/domain/card/Shape.java b/src/main/java/blackjack/domain/card/Shape.java new file mode 100644 index 0000000000..72b0709a8d --- /dev/null +++ b/src/main/java/blackjack/domain/card/Shape.java @@ -0,0 +1,8 @@ +package blackjack.domain.card; + +public enum Shape { + HEART, + DIAMOND, + SPADE, + CLOVER +} diff --git a/src/main/java/blackjack/domain/card/ShuffledDeckFactory.java b/src/main/java/blackjack/domain/card/ShuffledDeckFactory.java new file mode 100644 index 0000000000..a00516b0c9 --- /dev/null +++ b/src/main/java/blackjack/domain/card/ShuffledDeckFactory.java @@ -0,0 +1,25 @@ +package blackjack.domain.card; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class ShuffledDeckFactory implements DeckFactory { + + @Override + public Deck generate() { + final List cards = generateCards(); + Collections.shuffle(cards); + + return new Deck(new ArrayDeque<>(cards)); + } + + private List generateCards() { + return Arrays.stream(Shape.values()) + .flatMap(shape -> Arrays.stream(Symbol.values()) + .map(symbol -> new Card(shape, symbol))) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/blackjack/domain/card/Symbol.java b/src/main/java/blackjack/domain/card/Symbol.java new file mode 100644 index 0000000000..15a0df47aa --- /dev/null +++ b/src/main/java/blackjack/domain/card/Symbol.java @@ -0,0 +1,31 @@ +package blackjack.domain.card; + +public enum Symbol { + ACE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + TEN(10), + JACK(10), + QUEEN(10), + KING(10); + + private final int score; + + Symbol(final int score) { + this.score = score; + } + + public int getScore() { + return score; + } + + public boolean isAce() { + return this == ACE; + } +} diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java new file mode 100644 index 0000000000..89b4ae833c --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -0,0 +1,12 @@ +package blackjack.domain.participant; + +public class Dealer extends Participant { + + private static final int CARD_DRAW_POINT = 16; + + @Override + public boolean isDrawable() { + final int currentScore = currentScore(); + return currentScore <= CARD_DRAW_POINT; + } +} diff --git a/src/main/java/blackjack/domain/participant/Name.java b/src/main/java/blackjack/domain/participant/Name.java new file mode 100644 index 0000000000..7d3b09b4c5 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Name.java @@ -0,0 +1,34 @@ +package blackjack.domain.participant; + +public class Name { + + private static final int MAX_NAME_LENGTH = 100; + + private final String name; + + Name(final String name) { + validateName(name); + this.name = name; + } + + private void validateName(final String name) { + validateEmptyName(name); + validateLength(name); + } + + private void validateEmptyName(final String name) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("이름을 입력하지 않았습니다"); + } + } + + private void validateLength(final String name) { + if (name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("이름이 " + MAX_NAME_LENGTH + "글자를 초과했습니다"); + } + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java new file mode 100644 index 0000000000..84ea3f89b7 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -0,0 +1,33 @@ +package blackjack.domain.participant; + +import blackjack.domain.card.Card; +import blackjack.domain.card.CardPocket; +import java.util.List; + +public abstract class Participant { + + private final CardPocket cardPocket; + + Participant() { + cardPocket = CardPocket.empty(); + } + + public void drawInitialCard(final Card first, final Card second) { + cardPocket.addCard(first); + cardPocket.addCard(second); + } + + public void drawCard(final Card card) { + cardPocket.addCard(card); + } + + public int currentScore() { + return cardPocket.calculateScore(); + } + + public List getCards() { + return cardPocket.getCards(); + } + + public abstract boolean isDrawable(); +} diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java new file mode 100644 index 0000000000..77ae6a5b2e --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -0,0 +1,53 @@ +package blackjack.domain.participant; + +import blackjack.domain.card.Card; +import blackjack.domain.card.Deck; +import java.util.List; + +public class Participants { + + private final Players players; + private final Dealer dealer; + + public Participants(final Players players, final Dealer dealer) { + this.players = players; + this.dealer = dealer; + } + + public void distributeInitialCards(final Deck deck) { + players.distributeInitialCards(deck); + dealer.drawInitialCard(deck.popCard(), deck.popCard()); + } + + public Player findPlayerByName(final String playerName) { + return players.findPlayerByName(playerName); + } + + public boolean isPlayerDrawable(final String playerName) { + return players.isDrawable(playerName); + } + + public void drawPlayerCard(final String playerName, final Card card) { + players.draw(playerName, card); + } + + public boolean isDealerDrawable() { + return dealer.isDrawable(); + } + + public void drawDealerCard(final Card card) { + dealer.drawCard(card); + } + + public Dealer getDealer() { + return dealer; + } + + public Players getPlayers() { + return players; + } + + public List getPlayerNames() { + return players.getPlayerNames(); + } +} diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java new file mode 100644 index 0000000000..0553ad3ff9 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -0,0 +1,27 @@ +package blackjack.domain.participant; + +public class Player extends Participant { + + private final int BUST_POINT = 21; + + private final Name name; + + Player(final String name) { + this.name = new Name(name); + } + + @Override + public boolean isDrawable() { + final int currentScore = currentScore(); + return currentScore < BUST_POINT; + } + + public String getName() { + return name.getName(); + } + + boolean hasName(final String playerName) { + return name.getName() + .equals(playerName); + } +} diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java new file mode 100644 index 0000000000..141b61eb3f --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -0,0 +1,98 @@ +package blackjack.domain.participant; + +import blackjack.domain.card.Card; +import blackjack.domain.card.Deck; +import blackjack.domain.participant.exception.PlayerNotFoundException; +import java.util.List; +import java.util.stream.Collectors; + +public class Players { + + private static final int MAX_PLAYER_COUNT = 5; + private static final int MIN_PLAYER_COUNT = 1; + private static final String OVER_RANGE_MESSAGE = + "사용자 수는 " + MIN_PLAYER_COUNT + " 이상 " + MAX_PLAYER_COUNT + " 이하여야 합니다. 현재 : %s 명입니다"; + + private final List players; + + private Players(final List players) { + this.players = players; + } + + public static Players from(final List playerNames) { + validatePlayerNames(playerNames); + final List players = createPlayers(playerNames); + return new Players(players); + } + + private static List createPlayers(final List playerNames) { + return playerNames.stream() + .map(Player::new) + .collect(Collectors.toList()); + } + + private static void validatePlayerNames(final List playerNames) { + validateNull(playerNames); + validatePlayerCount(playerNames); + validateDuplicate(playerNames); + } + + private static void validateNull(final List playerNames) { + if (playerNames == null) { + throw new IllegalArgumentException("사용자 이름이 입력되지 않았습니다"); + } + } + + private static void validatePlayerCount(final List playerNames) { + if (MIN_PLAYER_COUNT > playerNames.size() || playerNames.size() > MAX_PLAYER_COUNT) { + throw new IllegalArgumentException(String.format(OVER_RANGE_MESSAGE, playerNames.size())); + } + } + + private static void validateDuplicate(final List playerNames) { + if (playerNames.stream().distinct().count() != playerNames.size()) { + throw new IllegalArgumentException("사용자의 이름이 중복됩니다."); + } + } + + void distributeInitialCards(final Deck deck) { + for (final Player player : players) { + final Card firstCard = deck.popCard(); + final Card secondCard = deck.popCard(); + player.drawInitialCard(firstCard, secondCard); + } + } + + List getPlayerNames() { + return players.stream() + .map(Player::getName) + .collect(Collectors.toList()); + } + + boolean isDrawable(final String playerName) { + return players.stream() + .filter(player -> player.hasName(playerName)) + .findFirst() + .map(Player::isDrawable) + .orElseThrow(PlayerNotFoundException::new); + } + + void draw(final String playerName, final Card card) { + final Player targetPlayer = players.stream() + .filter(player -> player.hasName(playerName)) + .findFirst() + .orElseThrow(PlayerNotFoundException::new); + targetPlayer.drawCard(card); + } + + Player findPlayerByName(final String name) { + return players.stream() + .filter(player -> player.hasName(name)) + .findFirst() + .orElseThrow(PlayerNotFoundException::new); + } + + public List getPlayers() { + return players; + } +} diff --git a/src/main/java/blackjack/domain/participant/exception/PlayerNotFoundException.java b/src/main/java/blackjack/domain/participant/exception/PlayerNotFoundException.java new file mode 100644 index 0000000000..376df990e4 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/exception/PlayerNotFoundException.java @@ -0,0 +1,8 @@ +package blackjack.domain.participant.exception; + +public class PlayerNotFoundException extends RuntimeException { + + public PlayerNotFoundException() { + super("없는 사용자 입니다"); + } +} diff --git a/src/main/java/blackjack/response/CardConvertStrategy.java b/src/main/java/blackjack/response/CardConvertStrategy.java new file mode 100644 index 0000000000..b629261468 --- /dev/null +++ b/src/main/java/blackjack/response/CardConvertStrategy.java @@ -0,0 +1,8 @@ +package blackjack.response; + +public interface CardConvertStrategy { + + String convertSymbol(String symbol); + + String convertShape(String shape); +} diff --git a/src/main/java/blackjack/response/CardResponse.java b/src/main/java/blackjack/response/CardResponse.java new file mode 100644 index 0000000000..22a506a66f --- /dev/null +++ b/src/main/java/blackjack/response/CardResponse.java @@ -0,0 +1,26 @@ +package blackjack.response; + +import blackjack.domain.card.Card; + +public class CardResponse { + + private final String symbol; + private final String shape; + + private CardResponse(final String symbol, final String shape) { + this.symbol = symbol; + this.shape = shape; + } + + public static CardResponse from(final Card card) { + return new CardResponse(card.getSymbol().name(), card.getShape().name()); + } + + public String getSymbol(final CardConvertStrategy cardConvertStrategy) { + return cardConvertStrategy.convertSymbol(symbol); + } + + public String getShape(final CardConvertStrategy cardConvertStrategy) { + return cardConvertStrategy.convertShape(shape); + } +} diff --git a/src/main/java/blackjack/response/DealerScoreResponse.java b/src/main/java/blackjack/response/DealerScoreResponse.java new file mode 100644 index 0000000000..a334504d99 --- /dev/null +++ b/src/main/java/blackjack/response/DealerScoreResponse.java @@ -0,0 +1,22 @@ +package blackjack.response; + +import java.util.List; + +public class DealerScoreResponse { + + private final List cards; + private final int score; + + public DealerScoreResponse(final List cards, final int score) { + this.cards = cards; + this.score = score; + } + + public List getCards() { + return cards; + } + + public int getScore() { + return score; + } +} diff --git a/src/main/java/blackjack/response/FinalResultResponse.java b/src/main/java/blackjack/response/FinalResultResponse.java new file mode 100644 index 0000000000..e88e6a4a6e --- /dev/null +++ b/src/main/java/blackjack/response/FinalResultResponse.java @@ -0,0 +1,23 @@ +package blackjack.response; + +import java.util.Map; + +public class FinalResultResponse { + + private final Map playersToResult; + private final Map dealerResult; + + public FinalResultResponse(final Map playersToResult, + final Map dealerResult) { + this.playersToResult = playersToResult; + this.dealerResult = dealerResult; + } + + public Map getPlayersToResult() { + return playersToResult; + } + + public Map getDealerResult() { + return dealerResult; + } +} diff --git a/src/main/java/blackjack/response/InitialCardResponse.java b/src/main/java/blackjack/response/InitialCardResponse.java new file mode 100644 index 0000000000..f976b933c2 --- /dev/null +++ b/src/main/java/blackjack/response/InitialCardResponse.java @@ -0,0 +1,59 @@ +package blackjack.response; + +import blackjack.domain.card.Card; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; +import blackjack.domain.participant.Players; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class InitialCardResponse { + + private final CardResponse dealerCard; + + private final Map> playerNameToCards; + + private InitialCardResponse(final CardResponse dealerCard, + final Map> playerNameToCards) { + this.dealerCard = dealerCard; + this.playerNameToCards = playerNameToCards; + } + + public static InitialCardResponse of( + final Players players, + final Dealer dealer) { + + final CardResponse dealerCard = CardResponse.from(dealer.getCards().get(0)); + final Map> playerNameToCards = generatePlayerNameToCards( + players.getPlayers()); + return new InitialCardResponse(dealerCard, playerNameToCards); + } + + private static Map> generatePlayerNameToCards( + final List players) { + return players.stream() + .collect(Collectors.toMap( + Player::getName, + player -> convertCards(player.getCards()), + (x, y) -> y, + LinkedHashMap::new) + ); + } + + private static List convertCards( + final List cards) { + return cards.stream() + .map(CardResponse::from) + .collect(Collectors.toList()); + } + + public CardResponse getDealerCard() { + return dealerCard; + } + + public Map> getPlayerNameToCards() { + return playerNameToCards; + } +} diff --git a/src/main/java/blackjack/response/PlayerCardsResponse.java b/src/main/java/blackjack/response/PlayerCardsResponse.java new file mode 100644 index 0000000000..f060c7c0f2 --- /dev/null +++ b/src/main/java/blackjack/response/PlayerCardsResponse.java @@ -0,0 +1,23 @@ +package blackjack.response; + +import java.util.List; + +public class PlayerCardsResponse { + + private final String name; + private final List cards; + + public PlayerCardsResponse(final String name, final List cards) { + this.name = name; + this.cards = cards; + } + + + public String getName() { + return name; + } + + public List getCards() { + return cards; + } +} diff --git a/src/main/java/blackjack/response/PlayersCardsResponse.java b/src/main/java/blackjack/response/PlayersCardsResponse.java new file mode 100644 index 0000000000..0ed104432d --- /dev/null +++ b/src/main/java/blackjack/response/PlayersCardsResponse.java @@ -0,0 +1,45 @@ +package blackjack.response; + +import blackjack.domain.participant.Player; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class PlayersCardsResponse { + + private final Map playerNameToResult; + + public PlayersCardsResponse(final Map playerNameToResult) { + this.playerNameToResult = playerNameToResult; + } + + public Map getPlayerNameToResult() { + return playerNameToResult; + } + + public static class CardsScore { + + private final int score; + private final List cards; + + private CardsScore(final int score, final List cards) { + this.score = score; + this.cards = cards; + } + + public static CardsScore of(final int score, final Player player) { + final List cardResponses = player.getCards().stream() + .map(CardResponse::from) + .collect(Collectors.toList()); + return new CardsScore(score, cardResponses); + } + + public int getScore() { + return score; + } + + public List getCards() { + return cards; + } + } +} diff --git a/src/main/java/blackjack/response/ResultConvertStrategy.java b/src/main/java/blackjack/response/ResultConvertStrategy.java new file mode 100644 index 0000000000..02e89f2beb --- /dev/null +++ b/src/main/java/blackjack/response/ResultConvertStrategy.java @@ -0,0 +1,6 @@ +package blackjack.response; + +public interface ResultConvertStrategy { + + String convertResult(String result); +} diff --git a/src/main/java/blackjack/response/ResultTypeResponse.java b/src/main/java/blackjack/response/ResultTypeResponse.java new file mode 100644 index 0000000000..5baa1919bf --- /dev/null +++ b/src/main/java/blackjack/response/ResultTypeResponse.java @@ -0,0 +1,42 @@ +package blackjack.response; + +import blackjack.domain.ResultType; +import java.util.Objects; + +public class ResultTypeResponse { + + private final String result; + + private ResultTypeResponse(final String result) { + this.result = result; + } + + public static ResultTypeResponse from(final ResultType resultType) { + return new ResultTypeResponse(resultType.name()); + } + + public static ResultTypeResponse from(final String resultType) { + return new ResultTypeResponse(resultType); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ResultTypeResponse that = (ResultTypeResponse) o; + return Objects.equals(result, that.result); + } + + @Override + public int hashCode() { + return Objects.hash(result); + } + + public String getResult(final ResultConvertStrategy resultConvertStrategy) { + return resultConvertStrategy.convertResult(result); + } +} diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java new file mode 100644 index 0000000000..71bdc94108 --- /dev/null +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -0,0 +1,140 @@ +package blackjack.service; + +import blackjack.domain.BlackJackRule; +import blackjack.domain.BlackJackRuleImpl; +import blackjack.domain.ResultType; +import blackjack.domain.card.Deck; +import blackjack.domain.card.DeckFactory; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Participants; +import blackjack.domain.participant.Player; +import blackjack.domain.participant.Players; +import blackjack.response.CardResponse; +import blackjack.response.DealerScoreResponse; +import blackjack.response.FinalResultResponse; +import blackjack.response.InitialCardResponse; +import blackjack.response.PlayerCardsResponse; +import blackjack.response.PlayersCardsResponse; +import blackjack.response.PlayersCardsResponse.CardsScore; +import blackjack.response.ResultTypeResponse; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class BlackJackGame { + + private final Participants participants; + private final Deck deck; + + private BlackJackGame(final Players players, final DeckFactory deckFactory) { + participants = new Participants(players, new Dealer()); + deck = deckFactory.generate(); + } + + public static BlackJackGame of(final List playerNames, final DeckFactory deckFactory) { + return new BlackJackGame(Players.from(playerNames), deckFactory); + } + + public void distributeInitialCard() { + participants.distributeInitialCards(deck); + } + + public boolean isPlayerDrawable(final String playerName) { + return participants.isPlayerDrawable(playerName); + } + + public void drawPlayerCard(final String playerName) { + participants.drawPlayerCard(playerName, deck.popCard()); + } + + public void drawDealerCard() { + participants.drawDealerCard(deck.popCard()); + } + + public boolean isDealerDrawable() { + return participants.isDealerDrawable(); + } + + public List getPlayerNames() { + return participants.getPlayerNames(); + } + + public InitialCardResponse getInitialCardResponse() { + return InitialCardResponse.of(participants.getPlayers(), participants.getDealer()); + } + + public PlayerCardsResponse getPlayerCardsResponse(final String playerName) { + final Player player = participants.findPlayerByName(playerName); + final List cardResponses = player.getCards().stream() + .map(CardResponse::from) + .collect(Collectors.toList()); + return new PlayerCardsResponse(player.getName(), cardResponses); + } + + public DealerScoreResponse getDealerScoreResponse() { + final Dealer dealer = participants.getDealer(); + final var cards = dealer.getCards().stream() + .map(CardResponse::from) + .collect(Collectors.toList()); + return new DealerScoreResponse(cards, dealer.currentScore()); + } + + public PlayersCardsResponse getPlayersCardsResponse() { + final Map playerNameToResult = participants.getPlayers().getPlayers().stream() + .collect(Collectors.toMap( + Player::getName, + player -> CardsScore.of(player.currentScore(), player), + (x, y) -> y, + LinkedHashMap::new) + ); + return new PlayersCardsResponse(playerNameToResult); + } + + public FinalResultResponse createFinalResultResponse() { + final BlackJackRule blackJackRule = new BlackJackRuleImpl(); + final ParticipantResults participantResults = new ParticipantResults(); + final Dealer dealer = participants.getDealer(); + participants.getPlayers().getPlayers().forEach(player -> { + final ResultType resultType = blackJackRule.calculateDealerResult(dealer, player); + participantResults.addPlayerResult(player.getName(), resultType); + }); + final Map playersToResult = participantResults.getPlayerNameToResultType(); + final Map playersToResultResponse = generatePlayersResult(playersToResult); + final Map dealerResult = generateDealerResult(playersToResult); + return new FinalResultResponse(playersToResultResponse, dealerResult); + } + + private LinkedHashMap generatePlayersResult( + final Map playersToResult) { + return playersToResult.entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + result -> ResultTypeResponse.from(result.getValue().getOppositeResult()), + (x, y) -> y, + LinkedHashMap::new)); + } + + private Map generateDealerResult(final Map playersToResult) { + return playersToResult.entrySet() + .stream() + .collect(Collectors.groupingBy( + result -> ResultTypeResponse.from(result.getValue()), + Collectors.counting())); + } + + private static class ParticipantResults { + + private final Map playerNameToResultType = new HashMap<>(); + + void addPlayerResult(final String playerName, final ResultType resultType) { + playerNameToResultType.put(playerName, resultType); + } + + Map getPlayerNameToResultType() { + return playerNameToResultType; + } + } +} diff --git a/src/main/java/blackjack/util/Repeater.java b/src/main/java/blackjack/util/Repeater.java new file mode 100644 index 0000000000..34d121f5c6 --- /dev/null +++ b/src/main/java/blackjack/util/Repeater.java @@ -0,0 +1,29 @@ +package blackjack.util; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class Repeater { + + private Repeater() { + } + + public static T repeatUntilNoException(final Supplier supplier, + final Consumer exceptionHandler) { + T result = null; + while (result == null) { + result = createOutputOrNull(supplier, exceptionHandler); + } + return result; + } + + private static T createOutputOrNull(final Supplier inputSupplier, + final Consumer exceptionHandler) { + try { + return inputSupplier.get(); + } catch (final IllegalArgumentException e) { + exceptionHandler.accept(e); + return null; + } + } +} diff --git a/src/main/java/blackjack/view/CardConvertStrategyImpl.java b/src/main/java/blackjack/view/CardConvertStrategyImpl.java new file mode 100644 index 0000000000..9a5a01222e --- /dev/null +++ b/src/main/java/blackjack/view/CardConvertStrategyImpl.java @@ -0,0 +1,56 @@ +package blackjack.view; + +import blackjack.response.CardConvertStrategy; + +public class CardConvertStrategyImpl implements CardConvertStrategy { + + @Override + public String convertSymbol(final String symbol) { + switch (symbol) { + case "ACE": + return "A"; + case "TWO": + return "2"; + case "THREE": + return "3"; + case "FOUR": + return "4"; + case "FIVE": + return "5"; + case "SIX": + return "6"; + case "SEVEN": + return "7"; + case "EIGHT": + return "8"; + case "NINE": + return "9"; + case "TEN": + return "10"; + case "JACK": + return "J"; + case "QUEEN": + return "Q"; + case "KING": + return "K"; + default: + throw new IllegalArgumentException("존재하지 않는 숫자 입니다"); + } + } + + @Override + public String convertShape(final String shape) { + switch (shape) { + case "SPADE": + return "스페이드"; + case "DIAMOND": + return "다이아몬드"; + case "HEART": + return "하트"; + case "CLOVER": + return "클로버"; + default: + throw new IllegalArgumentException("존재하지 않는 모양입니다"); + } + } +} diff --git a/src/main/java/blackjack/view/DrawCommand.java b/src/main/java/blackjack/view/DrawCommand.java new file mode 100644 index 0000000000..6d81fcd6ce --- /dev/null +++ b/src/main/java/blackjack/view/DrawCommand.java @@ -0,0 +1,20 @@ +package blackjack.view; + +import java.util.Arrays; + +public enum DrawCommand { + DRAW("y"), + STAY("n"); + public final String command; + + DrawCommand(final String command) { + this.command = command; + } + + public static DrawCommand from(final String command) { + return Arrays.stream(values()) + .filter(it -> it.command.equals(command)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("y, n 만 입력 가능합니다")); + } +} diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java new file mode 100644 index 0000000000..80e5b3a15d --- /dev/null +++ b/src/main/java/blackjack/view/InputView.java @@ -0,0 +1,29 @@ +package blackjack.view; + +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class InputView { + + private static final Scanner scanner = new Scanner(System.in); + private static final String INPUT_PLAYER_NAMES_MESSAGE = "게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"; + private static final String INPUT_COMMAND_MESSAGE = "{0}은/는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)"; + private static final String INPUT_DELIMITER = ","; + + public List inputPlayerNames() { + System.out.println(INPUT_PLAYER_NAMES_MESSAGE); + final String input = scanner.nextLine(); + return Arrays.stream(input.split(INPUT_DELIMITER, -1)) + .map(String::strip) + .collect(Collectors.toList()); + } + + public DrawCommand inputCommand(final String playerName) { + System.out.println(MessageFormat.format(INPUT_COMMAND_MESSAGE, playerName)); + final String input = scanner.nextLine(); + return DrawCommand.from(input); + } +} diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java new file mode 100644 index 0000000000..1bf88301b4 --- /dev/null +++ b/src/main/java/blackjack/view/OutputView.java @@ -0,0 +1,137 @@ +package blackjack.view; + +import blackjack.response.CardConvertStrategy; +import blackjack.response.CardResponse; +import blackjack.response.DealerScoreResponse; +import blackjack.response.FinalResultResponse; +import blackjack.response.InitialCardResponse; +import blackjack.response.PlayerCardsResponse; +import blackjack.response.PlayersCardsResponse; +import blackjack.response.PlayersCardsResponse.CardsScore; +import blackjack.response.ResultConvertStrategy; +import blackjack.response.ResultTypeResponse; +import java.text.MessageFormat; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class OutputView { + + private static final String OUTPUT_DISTRIBUTE_MESSAGE = "딜러와 {0}에게 2장을 나누었습니다."; + + private static final String OUTPUT_DEALER_STATUS_MESSAGE = "딜러는 16이하라 한장의 카드를 더 받았습니다."; + private static final String DELIMITER_BETWEEN_CARDS = ", "; + private static final String DELIMITER = ": "; + private static final String DEALER = "딜러"; + private static final String CARD = "카드"; + private static final String RESULT = " - 결과: "; + + private final CardConvertStrategy cardConvertStrategy = new CardConvertStrategyImpl(); + private final ResultConvertStrategy resultConvertStrategy = new ResultConvertStrategyImpl(); + + public void printInitialCards(final InitialCardResponse initialCardResponse) { + final Map> playerNameToCards = initialCardResponse.getPlayerNameToCards(); + printInitialMessage(playerNameToCards); + printInitialDealerCard(initialCardResponse.getDealerCard()); + playerNameToCards.forEach(this::printInitialPlayerCard); + System.out.println(); + } + + private void printInitialMessage(final Map> playerNameToCards) { + final String playerNames = String.join(DELIMITER_BETWEEN_CARDS, playerNameToCards.keySet()); + System.out.println(); + System.out.println(MessageFormat.format(OUTPUT_DISTRIBUTE_MESSAGE, playerNames)); + } + + private void printInitialDealerCard(final CardResponse cardResponse) { + System.out.println(DEALER + DELIMITER + convertCard(cardResponse)); + } + + private void printInitialPlayerCard(final String name, final List cards) { + final String card = cards.stream() + .map(this::convertCard) + .collect(Collectors.joining(DELIMITER_BETWEEN_CARDS)); + + System.out.println(name + CARD + DELIMITER + card); + } + + private String convertCard(final CardResponse cardResponse) { + final String convertedSymbol = cardResponse.getSymbol(cardConvertStrategy); + final String convertedShape = cardResponse.getShape(cardConvertStrategy); + + return convertedSymbol + convertedShape; + } + + public void printCardStatusOfPlayer(final PlayerCardsResponse playerCardsResponse) { + final String name = playerCardsResponse.getName(); + final String cards = playerCardsResponse.getCards() + .stream() + .map(this::convertCard) + .collect(Collectors.joining(DELIMITER_BETWEEN_CARDS)); + System.out.println(name + DELIMITER + cards); + } + + public void printDealerCardDrawMessage() { + System.out.println(); + System.out.println(OUTPUT_DEALER_STATUS_MESSAGE); + } + + public void printFinalStatusOfDealer(final DealerScoreResponse dealerScoreResponse) { + final String cards = dealerScoreResponse.getCards() + .stream() + .map(this::convertCard) + .collect(Collectors.joining(DELIMITER_BETWEEN_CARDS)); + System.out.println(); + System.out.println(DEALER + " " + CARD + DELIMITER + cards + RESULT + dealerScoreResponse.getScore()); + } + + public void printFinalStatusOfPlayers(final PlayersCardsResponse playersCardsResponse) { + playersCardsResponse.getPlayerNameToResult() + .forEach(this::printFinalStatusOfPlayer); + } + + private void printFinalStatusOfPlayer(final String name, final CardsScore cardsScore) { + final String cards = cardsScore.getCards() + .stream() + .map(this::convertCard) + .collect(Collectors.joining(DELIMITER_BETWEEN_CARDS)); + System.out.println(name + CARD + DELIMITER + cards + RESULT + cardsScore.getScore()); + } + + public void printFinalResult(final FinalResultResponse finalResultDto) { + System.out.println(); + System.out.println("## 최종 승패"); + System.out.print(DEALER + DELIMITER); + printDealerResult(finalResultDto.getDealerResult()); + printPlayersResult(finalResultDto.getPlayersToResult()); + } + + private void printDealerResult(final Map dealerResult) { + printDealer(dealerResult, ResultTypeResponse.from("WIN")); + printDealer(dealerResult, ResultTypeResponse.from("DRAW")); + printDealer(dealerResult, ResultTypeResponse.from("LOSE")); + System.out.println(); + } + + private void printPlayersResult(final Map playersResult) { + playersResult.forEach(this::printPlayerResult); + } + + private void printPlayerResult(final String name, final ResultTypeResponse resultTypeResponse) { + System.out.println(name + DELIMITER + resultTypeResponse.getResult(resultConvertStrategy)); + } + + private void printDealer( + final Map dealerResult, + final ResultTypeResponse resultTypeResponse) { + + if (dealerResult.containsKey(resultTypeResponse)) { + System.out.print( + dealerResult.get(resultTypeResponse) + resultTypeResponse.getResult(resultConvertStrategy)); + } + } + + public void printError(final Exception exception) { + System.out.println(exception.getMessage()); + } +} diff --git a/src/main/java/blackjack/view/ResultConvertStrategyImpl.java b/src/main/java/blackjack/view/ResultConvertStrategyImpl.java new file mode 100644 index 0000000000..7f26febfe0 --- /dev/null +++ b/src/main/java/blackjack/view/ResultConvertStrategyImpl.java @@ -0,0 +1,20 @@ +package blackjack.view; + +import blackjack.response.ResultConvertStrategy; + +public class ResultConvertStrategyImpl implements ResultConvertStrategy { + + @Override + public String convertResult(final String result) { + switch (result) { + case "WIN": + return "승"; + case "LOSE": + return "패"; + case "DRAW": + return "무"; + default: + throw new IllegalArgumentException("올바르지 않은 결과입니다."); + } + } +} diff --git a/src/test/java/blackjack/domain/BlackJackRuleTest.java b/src/test/java/blackjack/domain/BlackJackRuleTest.java new file mode 100644 index 0000000000..6fa5cbb0cf --- /dev/null +++ b/src/test/java/blackjack/domain/BlackJackRuleTest.java @@ -0,0 +1,10 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +/ diff --git a/src/test/java/blackjack/domain/card/CardPocketTest.java b/src/test/java/blackjack/domain/card/CardPocketTest.java new file mode 100644 index 0000000000..1fb04c46ba --- /dev/null +++ b/src/test/java/blackjack/domain/card/CardPocketTest.java @@ -0,0 +1,70 @@ +package blackjack.domain.card; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class CardPocketTest { + + private static final List cards = List.of(new Card(Shape.CLOVER, Symbol.ACE), + new Card(Shape.HEART, Symbol.EIGHT)); + + private CardPocket cardPocket; + + @BeforeEach + void setCardPocket() { + cardPocket = CardPocket.empty(); + cards.forEach(cardPocket::addCard); + } + + @Test + void 카드_포켓_안의_카드의_점수_계산() { + assertThat(cardPocket.calculateScore()) + .isEqualTo(19); + + } + + @Test + void 카드_포켓에_카드_추가한_후_카드의_점수_계산() { + cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.ACE)); + + assertThat(cardPocket.calculateScore()) + .isEqualTo(20); + + } + + @Test + void 카드_포켓에_카드_두번_추가한_후_카드의_점수_계산() { + cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.TEN)); + cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.EIGHT)); + + assertThat(cardPocket.calculateScore()) + .isEqualTo(27); + } + + @Test + void 카드_포켓에서_카드_가져오는_기능_추가() { + assertThat(cardPocket.getCards()) + .isEqualTo(cards); + } + + @Test + void 카드_포켓에서_Ace_의_점수_계산이_11_과_1로_잘_계산된다() { + final CardPocket cardPocket = CardPocket.empty(); + cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.ACE)); + cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.TEN)); + + assertThat(cardPocket.calculateScore()) + .isEqualTo(21); + + cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.ACE)); + assertThat(cardPocket.calculateScore()) + .isEqualTo(12); + } +} diff --git a/src/test/java/blackjack/domain/card/CardTest.java b/src/test/java/blackjack/domain/card/CardTest.java new file mode 100644 index 0000000000..b853886a28 --- /dev/null +++ b/src/test/java/blackjack/domain/card/CardTest.java @@ -0,0 +1,40 @@ +package blackjack.domain.card; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@DisplayNameGeneration(ReplaceUnderscores.class) +class CardTest { + + private final Shape shape = Shape.CLOVER; + private final Symbol symbol = Symbol.ACE; + private final Card card = new Card(shape, symbol); + + @Test + void 카드의_Symbol을_반환한다() { + assertThat(card.getSymbol()) + .isEqualTo(symbol); + } + + @Test + void 카드의_Shape를_반환한다() { + assertThat(card.getShape()) + .isEqualTo(shape); + } + + @Test + void 카드의_점수를_반환한다() { + assertThat(card.getScore()) + .isEqualTo(symbol.getScore()); + } + + @Test + void 카드가_Ace인지_확인한다() { + assertThat(card.isAce()) + .isEqualTo(symbol.isAce()); + } +} diff --git a/src/test/java/blackjack/domain/card/DeckTest.java b/src/test/java/blackjack/domain/card/DeckTest.java new file mode 100644 index 0000000000..9b2660d681 --- /dev/null +++ b/src/test/java/blackjack/domain/card/DeckTest.java @@ -0,0 +1,38 @@ +package blackjack.domain.card; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.ArrayDeque; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters"}) +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class DeckTest { + + @Test + void 생성시_null_이면_예외() { + assertThatThrownBy(() -> new Deck(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("카드에 null 이 들어왔습니다"); + } + + @Test + void 생성시_52장이_아니면_예외() { + assertThatThrownBy(() -> new Deck(new ArrayDeque<>())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("카드 숫자는 52장이어야 합니다 현재 :0장"); + } + + @Test + void 제거_시도를_52번보다_많이_하면_예외() { + final Deck deck = new ShuffledDeckFactory().generate(); + for (int i = 0; i < 52; i++) { + deck.popCard(); + } + assertThatThrownBy(deck::popCard) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("덱에 카드가 없습니다"); + } +} diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java new file mode 100644 index 0000000000..ff64706991 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -0,0 +1,58 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Symbol; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters"}) +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class DealerTest { + + private static final List overDrawPointCards = List.of( + new Card(Shape.CLOVER, Symbol.ACE), + new Card(Shape.HEART, Symbol.KING)); + private static final List underDrawPointCards = List.of( + new Card(Shape.CLOVER, Symbol.TWO), + new Card(Shape.HEART, Symbol.EIGHT)); + + @Test + void 딜러의_카드가_16_이하의_점수라면_드로우_합니다() { + final Dealer dealer = new Dealer(); + underDrawPointCards.forEach(dealer::drawCard); + + assertThat(dealer.isDrawable()) + .isTrue(); + } + + @Test + void 딜러의_카드가_17_이상의_점수라면_스테이_합니다() { + final Dealer dealer = new Dealer(); + overDrawPointCards.forEach(dealer::drawCard); + + assertThat(dealer.isDrawable()) + .isFalse(); + } + + @Nested + @DisplayName("딜러를 통해 결과를 계산하면") + class CalculateResultTest { + + private final Dealer dealer = new Dealer(); + private Player player; + + @BeforeEach + void setUp() { + dealer.drawCard(new Card(Shape.DIAMOND, Symbol.FIVE)); + player = new Player("pobi"); + } + } +} diff --git a/src/test/java/blackjack/domain/participant/NameTest.java b/src/test/java/blackjack/domain/participant/NameTest.java new file mode 100644 index 0000000000..d1242f6779 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/NameTest.java @@ -0,0 +1,31 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.stream.IntStream; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@DisplayNameGeneration(ReplaceUnderscores.class) +class NameTest { + + @Test + void 생성시_null이면_예외() { + assertThatThrownBy(() -> new Name(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("이름을 입력하지 않았습니다"); + } + + @Test + void 길이가_100글자_초과시_에러() { + final StringBuilder stringBuilder = new StringBuilder(); + IntStream.range(0, 100) + .forEach(stringBuilder::append); + + assertThatThrownBy(() -> new Name(stringBuilder.toString())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("이름이 100글자를 초과했습니다"); + } +} diff --git a/src/test/java/blackjack/domain/participant/ParticipantTest.java b/src/test/java/blackjack/domain/participant/ParticipantTest.java new file mode 100644 index 0000000000..f81f6f1544 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/ParticipantTest.java @@ -0,0 +1,55 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Symbol; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@DisplayNameGeneration(ReplaceUnderscores.class) +class ParticipantTest { + + private final Card[] cards = new Card[]{ + new Card(Shape.CLOVER, Symbol.ACE), + new Card(Shape.CLOVER, Symbol.ACE) + }; + private Participant participant; + + @BeforeEach + void setUp() { + participant = new Participant() { + @Override + public boolean isDrawable() { + return true; + } + }; + participant.drawInitialCard(cards[0], cards[1]); + } + + @Test + void 참가자는_점수를_계산할_수_있다() { + + final int score = participant.currentScore(); + + assertThat(score).isEqualTo(12); + } + + @Test + void 참가자는_추가로_드로우를_해서_점수를_계산할_수_있다() { + participant.drawCard(new Card(Shape.CLOVER, Symbol.ACE)); + + final int score = participant.currentScore(); + + assertThat(score).isEqualTo(13); + } + + @Test + void 참가자는_자기가_가지고_있는_카드를_확인할_수_있다() { + assertThat(participant.getCards()).containsExactly(cards); + } +} diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java new file mode 100644 index 0000000000..35d2caaa3a --- /dev/null +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -0,0 +1,46 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Symbol; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class PlayerTest { + + private static final List overDrawPointCards = List.of( + new Card(Shape.CLOVER, Symbol.ACE), + new Card(Shape.HEART, Symbol.KING)); + private static final List underDrawPointCards = List.of( + new Card(Shape.CLOVER, Symbol.TWO), + new Card(Shape.HEART, Symbol.EIGHT)); + + private Player player; + + @BeforeEach + void setup() { + player = new Player("pobi"); + } + + @Test + void 플레이어_카드의_점수가_21미만이면_드로우_할수있다() { + underDrawPointCards.forEach(player::drawCard); + assertThat(player.isDrawable()) + .isTrue(); + } + + @Test + void 플레이어_카드_점수가_21이상이면_드로우_할수없다() { + overDrawPointCards.forEach(player::drawCard); + assertThat(player.isDrawable()) + .isFalse(); + } + +} diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java new file mode 100644 index 0000000000..94caf40244 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -0,0 +1,57 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class PlayersTest { + + @Nested + @DisplayName("Players를 생성할 때") + class PlayerInitiatorTest { + + @Test + void 플레이어의_목록이_null_이면_예외() { + assertThatThrownBy(() -> Players.from(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사용자 이름이 입력되지 않았습니다"); + } + + @Test + void 플레이어의_수가_0명이면_예외() { + final List playerNames = new ArrayList<>(); + + assertThatThrownBy(() -> Players.from(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사용자 수는 1 이상 5 이하여야 합니다. 현재 : 0 명입니다"); + } + + @Test + void 플레이어의_수가_5명초과면_예외() { + final List playerNames = List.of("pobi", "crong", "honux", "wannte", "디디", "누누"); + + assertThatThrownBy(() -> Players.from(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사용자 수는 1 이상 5 이하여야 합니다. 현재 : 6 명입니다"); + } + + @Test + void 플레이어의_이름이_중복되면_예외() { + final List playerNames = List.of("pobi", "pobi", "honux", "wannte", "디디"); + + assertThatThrownBy(() -> Players.from(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사용자의 이름이 중복됩니다."); + } + } + + +} From aaf116035e830bc9e9b4e3bb8fd1f6df6f0edbc7 Mon Sep 17 00:00:00 2001 From: be-student Date: Wed, 8 Mar 2023 10:55:41 +0900 Subject: [PATCH 02/59] =?UTF-8?q?fix:=20=EC=95=88=20=EC=A7=80=EC=9B=8C?= =?UTF-8?q?=EC=A7=84=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/blackjack/domain/BlackJackRuleTest.java | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/test/java/blackjack/domain/BlackJackRuleTest.java diff --git a/src/test/java/blackjack/domain/BlackJackRuleTest.java b/src/test/java/blackjack/domain/BlackJackRuleTest.java deleted file mode 100644 index 6fa5cbb0cf..0000000000 --- a/src/test/java/blackjack/domain/BlackJackRuleTest.java +++ /dev/null @@ -1,10 +0,0 @@ -package blackjack.domain; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; - -/ From 86d31279dc59c7da813f54559521729dadcc3511 Mon Sep 17 00:00:00 2001 From: be-student Date: Thu, 9 Mar 2023 10:49:17 +0900 Subject: [PATCH 03/59] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=EA=B0=9D=EC=B2=B4=EC=97=90=20=EC=9D=B4=EB=A6=84=EC=9D=84=20?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20vie?= =?UTF-8?q?w=EC=97=90=20strategy=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/domain/card/Shape.java | 17 ++++-- .../java/blackjack/domain/card/Symbol.java | 34 ++++++----- .../response/CardConvertStrategy.java | 8 --- .../java/blackjack/response/CardResponse.java | 10 ++-- .../response/ResultConvertStrategy.java | 6 -- .../response/ResultTypeResponse.java | 4 +- .../view/CardConvertStrategyImpl.java | 56 ------------------- src/main/java/blackjack/view/OutputView.java | 13 ++--- .../view/ResultConvertStrategyImpl.java | 20 ------- 9 files changed, 44 insertions(+), 124 deletions(-) delete mode 100644 src/main/java/blackjack/response/CardConvertStrategy.java delete mode 100644 src/main/java/blackjack/response/ResultConvertStrategy.java delete mode 100644 src/main/java/blackjack/view/CardConvertStrategyImpl.java delete mode 100644 src/main/java/blackjack/view/ResultConvertStrategyImpl.java diff --git a/src/main/java/blackjack/domain/card/Shape.java b/src/main/java/blackjack/domain/card/Shape.java index 72b0709a8d..446b373e9e 100644 --- a/src/main/java/blackjack/domain/card/Shape.java +++ b/src/main/java/blackjack/domain/card/Shape.java @@ -1,8 +1,17 @@ package blackjack.domain.card; public enum Shape { - HEART, - DIAMOND, - SPADE, - CLOVER + HEART("하트"), + DIAMOND("다이아몬드"), + SPADE("스페이드"), + CLOVER("클로버"); + private final String name; + + Shape(final String name) { + this.name = name; + } + + public String getName() { + return name; + } } diff --git a/src/main/java/blackjack/domain/card/Symbol.java b/src/main/java/blackjack/domain/card/Symbol.java index 15a0df47aa..15f48a57a3 100644 --- a/src/main/java/blackjack/domain/card/Symbol.java +++ b/src/main/java/blackjack/domain/card/Symbol.java @@ -1,24 +1,26 @@ package blackjack.domain.card; public enum Symbol { - ACE(1), - TWO(2), - THREE(3), - FOUR(4), - FIVE(5), - SIX(6), - SEVEN(7), - EIGHT(8), - NINE(9), - TEN(10), - JACK(10), - QUEEN(10), - KING(10); + 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 name; - Symbol(final int score) { + Symbol(final int score, final String name) { this.score = score; + this.name = name; } public int getScore() { @@ -28,4 +30,8 @@ public int getScore() { public boolean isAce() { return this == ACE; } + + public String getName() { + return name; + } } diff --git a/src/main/java/blackjack/response/CardConvertStrategy.java b/src/main/java/blackjack/response/CardConvertStrategy.java deleted file mode 100644 index b629261468..0000000000 --- a/src/main/java/blackjack/response/CardConvertStrategy.java +++ /dev/null @@ -1,8 +0,0 @@ -package blackjack.response; - -public interface CardConvertStrategy { - - String convertSymbol(String symbol); - - String convertShape(String shape); -} diff --git a/src/main/java/blackjack/response/CardResponse.java b/src/main/java/blackjack/response/CardResponse.java index 22a506a66f..fae1cda56c 100644 --- a/src/main/java/blackjack/response/CardResponse.java +++ b/src/main/java/blackjack/response/CardResponse.java @@ -13,14 +13,14 @@ private CardResponse(final String symbol, final String shape) { } public static CardResponse from(final Card card) { - return new CardResponse(card.getSymbol().name(), card.getShape().name()); + return new CardResponse(card.getSymbol().getName(), card.getShape().getName()); } - public String getSymbol(final CardConvertStrategy cardConvertStrategy) { - return cardConvertStrategy.convertSymbol(symbol); + public String getSymbol() { + return symbol; } - public String getShape(final CardConvertStrategy cardConvertStrategy) { - return cardConvertStrategy.convertShape(shape); + public String getShape() { + return shape; } } diff --git a/src/main/java/blackjack/response/ResultConvertStrategy.java b/src/main/java/blackjack/response/ResultConvertStrategy.java deleted file mode 100644 index 02e89f2beb..0000000000 --- a/src/main/java/blackjack/response/ResultConvertStrategy.java +++ /dev/null @@ -1,6 +0,0 @@ -package blackjack.response; - -public interface ResultConvertStrategy { - - String convertResult(String result); -} diff --git a/src/main/java/blackjack/response/ResultTypeResponse.java b/src/main/java/blackjack/response/ResultTypeResponse.java index 5baa1919bf..16b6a04dc3 100644 --- a/src/main/java/blackjack/response/ResultTypeResponse.java +++ b/src/main/java/blackjack/response/ResultTypeResponse.java @@ -36,7 +36,7 @@ public int hashCode() { return Objects.hash(result); } - public String getResult(final ResultConvertStrategy resultConvertStrategy) { - return resultConvertStrategy.convertResult(result); + public String getResult() { + return result; } } diff --git a/src/main/java/blackjack/view/CardConvertStrategyImpl.java b/src/main/java/blackjack/view/CardConvertStrategyImpl.java deleted file mode 100644 index 9a5a01222e..0000000000 --- a/src/main/java/blackjack/view/CardConvertStrategyImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -package blackjack.view; - -import blackjack.response.CardConvertStrategy; - -public class CardConvertStrategyImpl implements CardConvertStrategy { - - @Override - public String convertSymbol(final String symbol) { - switch (symbol) { - case "ACE": - return "A"; - case "TWO": - return "2"; - case "THREE": - return "3"; - case "FOUR": - return "4"; - case "FIVE": - return "5"; - case "SIX": - return "6"; - case "SEVEN": - return "7"; - case "EIGHT": - return "8"; - case "NINE": - return "9"; - case "TEN": - return "10"; - case "JACK": - return "J"; - case "QUEEN": - return "Q"; - case "KING": - return "K"; - default: - throw new IllegalArgumentException("존재하지 않는 숫자 입니다"); - } - } - - @Override - public String convertShape(final String shape) { - switch (shape) { - case "SPADE": - return "스페이드"; - case "DIAMOND": - return "다이아몬드"; - case "HEART": - return "하트"; - case "CLOVER": - return "클로버"; - default: - throw new IllegalArgumentException("존재하지 않는 모양입니다"); - } - } -} diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 1bf88301b4..d12b081a38 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,6 +1,5 @@ package blackjack.view; -import blackjack.response.CardConvertStrategy; import blackjack.response.CardResponse; import blackjack.response.DealerScoreResponse; import blackjack.response.FinalResultResponse; @@ -8,7 +7,6 @@ import blackjack.response.PlayerCardsResponse; import blackjack.response.PlayersCardsResponse; import blackjack.response.PlayersCardsResponse.CardsScore; -import blackjack.response.ResultConvertStrategy; import blackjack.response.ResultTypeResponse; import java.text.MessageFormat; import java.util.List; @@ -26,9 +24,6 @@ public class OutputView { private static final String CARD = "카드"; private static final String RESULT = " - 결과: "; - private final CardConvertStrategy cardConvertStrategy = new CardConvertStrategyImpl(); - private final ResultConvertStrategy resultConvertStrategy = new ResultConvertStrategyImpl(); - public void printInitialCards(final InitialCardResponse initialCardResponse) { final Map> playerNameToCards = initialCardResponse.getPlayerNameToCards(); printInitialMessage(playerNameToCards); @@ -56,8 +51,8 @@ private void printInitialPlayerCard(final String name, final List } private String convertCard(final CardResponse cardResponse) { - final String convertedSymbol = cardResponse.getSymbol(cardConvertStrategy); - final String convertedShape = cardResponse.getShape(cardConvertStrategy); + final String convertedSymbol = cardResponse.getSymbol(); + final String convertedShape = cardResponse.getShape(); return convertedSymbol + convertedShape; } @@ -118,7 +113,7 @@ private void printPlayersResult(final Map playersRes } private void printPlayerResult(final String name, final ResultTypeResponse resultTypeResponse) { - System.out.println(name + DELIMITER + resultTypeResponse.getResult(resultConvertStrategy)); + System.out.println(name + DELIMITER + resultTypeResponse.getResult()); } private void printDealer( @@ -127,7 +122,7 @@ private void printDealer( if (dealerResult.containsKey(resultTypeResponse)) { System.out.print( - dealerResult.get(resultTypeResponse) + resultTypeResponse.getResult(resultConvertStrategy)); + dealerResult.get(resultTypeResponse) + resultTypeResponse.getResult()); } } diff --git a/src/main/java/blackjack/view/ResultConvertStrategyImpl.java b/src/main/java/blackjack/view/ResultConvertStrategyImpl.java deleted file mode 100644 index 7f26febfe0..0000000000 --- a/src/main/java/blackjack/view/ResultConvertStrategyImpl.java +++ /dev/null @@ -1,20 +0,0 @@ -package blackjack.view; - -import blackjack.response.ResultConvertStrategy; - -public class ResultConvertStrategyImpl implements ResultConvertStrategy { - - @Override - public String convertResult(final String result) { - switch (result) { - case "WIN": - return "승"; - case "LOSE": - return "패"; - case "DRAW": - return "무"; - default: - throw new IllegalArgumentException("올바르지 않은 결과입니다."); - } - } -} From 9bd63e20ac8a17b562ffa2a03b58434bae0b388a Mon Sep 17 00:00:00 2001 From: be-student Date: Thu, 9 Mar 2023 11:42:21 +0900 Subject: [PATCH 04/59] =?UTF-8?q?refactor:=20response=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=20=EB=8C=80=EC=8B=A0=20Collection=20=EC=9D=84=20=EB=84=98?= =?UTF-8?q?=EA=B8=B0=EB=8A=94=20=EA=B2=83=EC=9C=BC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BlackJackController.java | 57 +++++-------- .../java/blackjack/domain/ResultType.java | 16 +++- .../java/blackjack/domain/ResultType.java~ | 17 ++++ .../blackjack/domain/participant/Dealer.java | 6 ++ .../domain/participant/Participants.java | 4 + .../response/DealerScoreResponse.java | 22 ----- .../response/FinalResultResponse.java | 23 ----- .../response/InitialCardResponse.java | 59 ------------- .../response/PlayerCardsResponse.java | 23 ----- .../response/PlayersCardsResponse.java | 45 ---------- .../response/ResultTypeResponse.java | 2 +- .../java/blackjack/service/BlackJackGame.java | 84 ++++++++++--------- src/main/java/blackjack/view/OutputView.java | 73 ++++++++-------- 13 files changed, 148 insertions(+), 283 deletions(-) create mode 100644 src/main/java/blackjack/domain/ResultType.java~ delete mode 100644 src/main/java/blackjack/response/DealerScoreResponse.java delete mode 100644 src/main/java/blackjack/response/FinalResultResponse.java delete mode 100644 src/main/java/blackjack/response/InitialCardResponse.java delete mode 100644 src/main/java/blackjack/response/PlayerCardsResponse.java delete mode 100644 src/main/java/blackjack/response/PlayersCardsResponse.java diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java index e744897f7f..8022fb03f3 100644 --- a/src/main/java/blackjack/controller/BlackJackController.java +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -27,52 +27,37 @@ public void play(final DeckFactory deckFactory) { outputView::printError); blackJackGame.distributeInitialCard(); - outputView.printInitialCards(blackJackGame.getInitialCardResponse()); + outputView.printInitialCards(blackJackGame.getDealerFirstCard(), blackJackGame.getPlayerCards()); - drawPlayersCards(blackJackGame); - drawDealerCards(blackJackGame); - - outputView.printFinalStatusOfDealer(blackJackGame.getDealerScoreResponse()); - outputView.printFinalStatusOfPlayers(blackJackGame.getPlayersCardsResponse()); - outputView.printFinalResult(blackJackGame.createFinalResultResponse()); - } - - private List inputPlayerNames() { - return inputView.inputPlayerNames(); - } - - private void drawPlayersCards(final BlackJackGame blackJackGame) { for (final String playerName : blackJackGame.getPlayerNames()) { - drawPlayerCard(playerName, blackJackGame); + DrawCommand playerChoice = DrawCommand.DRAW; + while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { + playerChoice = inputPlayerChoice(playerName); + if (playerChoice == DrawCommand.DRAW) { + blackJackGame.drawPlayerCard(playerName); + } + outputView.printCardStatusOfPlayer(playerName, blackJackGame.getPlayerCardsResponse(playerName)); + } } - } - private void drawPlayerCard(final String playerName, final BlackJackGame blackJackGame) { - DrawCommand playerInput = DrawCommand.DRAW; - while (blackJackGame.isPlayerDrawable(playerName) && playerInput != DrawCommand.STAY) { - playerInput = repeatUntilNoException( - () -> inputView.inputCommand(playerName), outputView::printError); - drawCard(playerName, blackJackGame, playerInput); - printPlayerResult(playerName, blackJackGame); + while (blackJackGame.isDealerDrawable()) { + blackJackGame.drawDealerCard(); + outputView.printDealerCardDrawMessage(); } - } - private void drawCard(final String playerName, final BlackJackGame blackJackGame, - final DrawCommand playerInput) { - if (playerInput == DrawCommand.DRAW) { - blackJackGame.drawPlayerCard(playerName); - } + outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), blackJackGame.getDealerCardsResponse()); + outputView.printFinalStatusOfPlayers(blackJackGame.getPlayerCards(), blackJackGame.getPlayerScores()); + outputView.printFinalDealerResult(blackJackGame.getDealerResult()); + outputView.printFinalPlayersResult(blackJackGame.generatePlayersResult()); } - private void printPlayerResult(final String playerName, final BlackJackGame blackJackGame) { - outputView.printCardStatusOfPlayer(blackJackGame.getPlayerCardsResponse(playerName)); + private DrawCommand inputPlayerChoice(final String playerName) { + return repeatUntilNoException( + () -> inputView.inputCommand(playerName), outputView::printError); } - private void drawDealerCards(final BlackJackGame blackJackGame) { - while (blackJackGame.isDealerDrawable()) { - blackJackGame.drawDealerCard(); - outputView.printDealerCardDrawMessage(); - } + private List inputPlayerNames() { + return inputView.inputPlayerNames(); } } diff --git a/src/main/java/blackjack/domain/ResultType.java b/src/main/java/blackjack/domain/ResultType.java index f8bd8e7d96..ef71e53ad4 100644 --- a/src/main/java/blackjack/domain/ResultType.java +++ b/src/main/java/blackjack/domain/ResultType.java @@ -1,9 +1,15 @@ package blackjack.domain; public enum ResultType { - WIN, - TIE, - LOSE; + WIN("승"), + TIE("무"), + LOSE("패"); + + private final String name; + + ResultType(final String name) { + this.name = name; + } public ResultType getOppositeResult() { if (this == WIN) { @@ -14,4 +20,8 @@ public ResultType getOppositeResult() { } return WIN; } + + public String getName() { + return name; + } } diff --git a/src/main/java/blackjack/domain/ResultType.java~ b/src/main/java/blackjack/domain/ResultType.java~ new file mode 100644 index 0000000000..d2a1480964 --- /dev/null +++ b/src/main/java/blackjack/domain/ResultType.java~ @@ -0,0 +1,17 @@ +package blackjack.domain; + +public enum ResultType { + WIN("승"), + TIE("무"), + LOSE("패"); + + public ResultType getOppositeResult() { + if (this == WIN) { + return LOSE; + } + if (this == TIE) { + return TIE; + } + return WIN; + } +} diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 89b4ae833c..57428dbaa8 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -1,5 +1,7 @@ package blackjack.domain.participant; +import blackjack.domain.card.Card; + public class Dealer extends Participant { private static final int CARD_DRAW_POINT = 16; @@ -9,4 +11,8 @@ public boolean isDrawable() { final int currentScore = currentScore(); return currentScore <= CARD_DRAW_POINT; } + + public Card getFirstCard() { + return getCards().get(0); + } } diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index 77ae6a5b2e..af89d6d698 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -43,6 +43,10 @@ public Dealer getDealer() { return dealer; } + public List getPlayerCards(final String playerName) { + return players.findPlayerByName(playerName).getCards(); + } + public Players getPlayers() { return players; } diff --git a/src/main/java/blackjack/response/DealerScoreResponse.java b/src/main/java/blackjack/response/DealerScoreResponse.java deleted file mode 100644 index a334504d99..0000000000 --- a/src/main/java/blackjack/response/DealerScoreResponse.java +++ /dev/null @@ -1,22 +0,0 @@ -package blackjack.response; - -import java.util.List; - -public class DealerScoreResponse { - - private final List cards; - private final int score; - - public DealerScoreResponse(final List cards, final int score) { - this.cards = cards; - this.score = score; - } - - public List getCards() { - return cards; - } - - public int getScore() { - return score; - } -} diff --git a/src/main/java/blackjack/response/FinalResultResponse.java b/src/main/java/blackjack/response/FinalResultResponse.java deleted file mode 100644 index e88e6a4a6e..0000000000 --- a/src/main/java/blackjack/response/FinalResultResponse.java +++ /dev/null @@ -1,23 +0,0 @@ -package blackjack.response; - -import java.util.Map; - -public class FinalResultResponse { - - private final Map playersToResult; - private final Map dealerResult; - - public FinalResultResponse(final Map playersToResult, - final Map dealerResult) { - this.playersToResult = playersToResult; - this.dealerResult = dealerResult; - } - - public Map getPlayersToResult() { - return playersToResult; - } - - public Map getDealerResult() { - return dealerResult; - } -} diff --git a/src/main/java/blackjack/response/InitialCardResponse.java b/src/main/java/blackjack/response/InitialCardResponse.java deleted file mode 100644 index f976b933c2..0000000000 --- a/src/main/java/blackjack/response/InitialCardResponse.java +++ /dev/null @@ -1,59 +0,0 @@ -package blackjack.response; - -import blackjack.domain.card.Card; -import blackjack.domain.participant.Dealer; -import blackjack.domain.participant.Player; -import blackjack.domain.participant.Players; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class InitialCardResponse { - - private final CardResponse dealerCard; - - private final Map> playerNameToCards; - - private InitialCardResponse(final CardResponse dealerCard, - final Map> playerNameToCards) { - this.dealerCard = dealerCard; - this.playerNameToCards = playerNameToCards; - } - - public static InitialCardResponse of( - final Players players, - final Dealer dealer) { - - final CardResponse dealerCard = CardResponse.from(dealer.getCards().get(0)); - final Map> playerNameToCards = generatePlayerNameToCards( - players.getPlayers()); - return new InitialCardResponse(dealerCard, playerNameToCards); - } - - private static Map> generatePlayerNameToCards( - final List players) { - return players.stream() - .collect(Collectors.toMap( - Player::getName, - player -> convertCards(player.getCards()), - (x, y) -> y, - LinkedHashMap::new) - ); - } - - private static List convertCards( - final List cards) { - return cards.stream() - .map(CardResponse::from) - .collect(Collectors.toList()); - } - - public CardResponse getDealerCard() { - return dealerCard; - } - - public Map> getPlayerNameToCards() { - return playerNameToCards; - } -} diff --git a/src/main/java/blackjack/response/PlayerCardsResponse.java b/src/main/java/blackjack/response/PlayerCardsResponse.java deleted file mode 100644 index f060c7c0f2..0000000000 --- a/src/main/java/blackjack/response/PlayerCardsResponse.java +++ /dev/null @@ -1,23 +0,0 @@ -package blackjack.response; - -import java.util.List; - -public class PlayerCardsResponse { - - private final String name; - private final List cards; - - public PlayerCardsResponse(final String name, final List cards) { - this.name = name; - this.cards = cards; - } - - - public String getName() { - return name; - } - - public List getCards() { - return cards; - } -} diff --git a/src/main/java/blackjack/response/PlayersCardsResponse.java b/src/main/java/blackjack/response/PlayersCardsResponse.java deleted file mode 100644 index 0ed104432d..0000000000 --- a/src/main/java/blackjack/response/PlayersCardsResponse.java +++ /dev/null @@ -1,45 +0,0 @@ -package blackjack.response; - -import blackjack.domain.participant.Player; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class PlayersCardsResponse { - - private final Map playerNameToResult; - - public PlayersCardsResponse(final Map playerNameToResult) { - this.playerNameToResult = playerNameToResult; - } - - public Map getPlayerNameToResult() { - return playerNameToResult; - } - - public static class CardsScore { - - private final int score; - private final List cards; - - private CardsScore(final int score, final List cards) { - this.score = score; - this.cards = cards; - } - - public static CardsScore of(final int score, final Player player) { - final List cardResponses = player.getCards().stream() - .map(CardResponse::from) - .collect(Collectors.toList()); - return new CardsScore(score, cardResponses); - } - - public int getScore() { - return score; - } - - public List getCards() { - return cards; - } - } -} diff --git a/src/main/java/blackjack/response/ResultTypeResponse.java b/src/main/java/blackjack/response/ResultTypeResponse.java index 16b6a04dc3..978139de6a 100644 --- a/src/main/java/blackjack/response/ResultTypeResponse.java +++ b/src/main/java/blackjack/response/ResultTypeResponse.java @@ -12,7 +12,7 @@ private ResultTypeResponse(final String result) { } public static ResultTypeResponse from(final ResultType resultType) { - return new ResultTypeResponse(resultType.name()); + return new ResultTypeResponse(resultType.getName()); } public static ResultTypeResponse from(final String resultType) { diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 71bdc94108..609d1c01e5 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -3,6 +3,7 @@ import blackjack.domain.BlackJackRule; import blackjack.domain.BlackJackRuleImpl; import blackjack.domain.ResultType; +import blackjack.domain.card.Card; import blackjack.domain.card.Deck; import blackjack.domain.card.DeckFactory; import blackjack.domain.participant.Dealer; @@ -10,12 +11,6 @@ import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; import blackjack.response.CardResponse; -import blackjack.response.DealerScoreResponse; -import blackjack.response.FinalResultResponse; -import blackjack.response.InitialCardResponse; -import blackjack.response.PlayerCardsResponse; -import blackjack.response.PlayersCardsResponse; -import blackjack.response.PlayersCardsResponse.CardsScore; import blackjack.response.ResultTypeResponse; import java.util.HashMap; import java.util.LinkedHashMap; @@ -61,38 +56,50 @@ public List getPlayerNames() { return participants.getPlayerNames(); } - public InitialCardResponse getInitialCardResponse() { - return InitialCardResponse.of(participants.getPlayers(), participants.getDealer()); + public CardResponse getDealerFirstCard() { + final Card dealerFirstCard = participants.getDealer().getFirstCard(); + return CardResponse.from(dealerFirstCard); } - public PlayerCardsResponse getPlayerCardsResponse(final String playerName) { + public Map> getPlayerCards() { + final Map> playerCards = new HashMap<>(); + for (final String playerName : getPlayerNames()) { + final List cardResponses = participants.getPlayerCards(playerName).stream() + .map(CardResponse::from) + .collect(Collectors.toList()); + playerCards.put(playerName, cardResponses); + } + return playerCards; + } + + public Map getPlayerScores() { + final Map playerScores = new HashMap<>(); + for (final String playerName : getPlayerNames()) { + final Player player = participants.findPlayerByName(playerName); + playerScores.put(playerName, player.currentScore()); + } + return playerScores; + } + + public List getPlayerCardsResponse(final String playerName) { final Player player = participants.findPlayerByName(playerName); - final List cardResponses = player.getCards().stream() + return player.getCards().stream() .map(CardResponse::from) .collect(Collectors.toList()); - return new PlayerCardsResponse(player.getName(), cardResponses); } - public DealerScoreResponse getDealerScoreResponse() { + public List getDealerCardsResponse() { final Dealer dealer = participants.getDealer(); - final var cards = dealer.getCards().stream() + return dealer.getCards().stream() .map(CardResponse::from) .collect(Collectors.toList()); - return new DealerScoreResponse(cards, dealer.currentScore()); } - public PlayersCardsResponse getPlayersCardsResponse() { - final Map playerNameToResult = participants.getPlayers().getPlayers().stream() - .collect(Collectors.toMap( - Player::getName, - player -> CardsScore.of(player.currentScore(), player), - (x, y) -> y, - LinkedHashMap::new) - ); - return new PlayersCardsResponse(playerNameToResult); + public int getDealerScore() { + return participants.getDealer().currentScore(); } - public FinalResultResponse createFinalResultResponse() { + public Map getDealerResult() { final BlackJackRule blackJackRule = new BlackJackRuleImpl(); final ParticipantResults participantResults = new ParticipantResults(); final Dealer dealer = participants.getDealer(); @@ -101,30 +108,31 @@ public FinalResultResponse createFinalResultResponse() { participantResults.addPlayerResult(player.getName(), resultType); }); final Map playersToResult = participantResults.getPlayerNameToResultType(); - final Map playersToResultResponse = generatePlayersResult(playersToResult); - final Map dealerResult = generateDealerResult(playersToResult); - return new FinalResultResponse(playersToResultResponse, dealerResult); + return playersToResult.entrySet() + .stream() + .collect(Collectors.groupingBy( + result -> ResultTypeResponse.from(result.getValue()), + Collectors.counting())); } - private LinkedHashMap generatePlayersResult( - final Map playersToResult) { + public Map generatePlayersResult() { + final BlackJackRule blackJackRule = new BlackJackRuleImpl(); + final ParticipantResults participantResults = new ParticipantResults(); + final Dealer dealer = participants.getDealer(); + participants.getPlayers().getPlayers().forEach(player -> { + final ResultType resultType = blackJackRule.calculateDealerResult(dealer, player).getOppositeResult(); + participantResults.addPlayerResult(player.getName(), resultType); + }); + final Map playersToResult = participantResults.getPlayerNameToResultType(); return playersToResult.entrySet() .stream() .collect(Collectors.toMap( Map.Entry::getKey, - result -> ResultTypeResponse.from(result.getValue().getOppositeResult()), + result -> ResultTypeResponse.from(result.getValue()), (x, y) -> y, LinkedHashMap::new)); } - private Map generateDealerResult(final Map playersToResult) { - return playersToResult.entrySet() - .stream() - .collect(Collectors.groupingBy( - result -> ResultTypeResponse.from(result.getValue()), - Collectors.counting())); - } - private static class ParticipantResults { private final Map playerNameToResultType = new HashMap<>(); diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index d12b081a38..584c9ff4a3 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,12 +1,6 @@ package blackjack.view; import blackjack.response.CardResponse; -import blackjack.response.DealerScoreResponse; -import blackjack.response.FinalResultResponse; -import blackjack.response.InitialCardResponse; -import blackjack.response.PlayerCardsResponse; -import blackjack.response.PlayersCardsResponse; -import blackjack.response.PlayersCardsResponse.CardsScore; import blackjack.response.ResultTypeResponse; import java.text.MessageFormat; import java.util.List; @@ -24,10 +18,10 @@ public class OutputView { private static final String CARD = "카드"; private static final String RESULT = " - 결과: "; - public void printInitialCards(final InitialCardResponse initialCardResponse) { - final Map> playerNameToCards = initialCardResponse.getPlayerNameToCards(); + public void printInitialCards(final CardResponse dealerCard, + final Map> playerNameToCards) { printInitialMessage(playerNameToCards); - printInitialDealerCard(initialCardResponse.getDealerCard()); + printInitialDealerCard(dealerCard); playerNameToCards.forEach(this::printInitialPlayerCard); System.out.println(); } @@ -57,13 +51,12 @@ private String convertCard(final CardResponse cardResponse) { return convertedSymbol + convertedShape; } - public void printCardStatusOfPlayer(final PlayerCardsResponse playerCardsResponse) { - final String name = playerCardsResponse.getName(); - final String cards = playerCardsResponse.getCards() + public void printCardStatusOfPlayer(final String planerName, final List playerCardsResponse) { + final String cards = playerCardsResponse .stream() .map(this::convertCard) .collect(Collectors.joining(DELIMITER_BETWEEN_CARDS)); - System.out.println(name + DELIMITER + cards); + System.out.println(planerName + DELIMITER + cards); } public void printDealerCardDrawMessage() { @@ -71,47 +64,50 @@ public void printDealerCardDrawMessage() { System.out.println(OUTPUT_DEALER_STATUS_MESSAGE); } - public void printFinalStatusOfDealer(final DealerScoreResponse dealerScoreResponse) { - final String cards = dealerScoreResponse.getCards() + public void printFinalStatusOfDealer(final int score, final List dealerCards) { + final String cards = dealerCards .stream() .map(this::convertCard) .collect(Collectors.joining(DELIMITER_BETWEEN_CARDS)); System.out.println(); - System.out.println(DEALER + " " + CARD + DELIMITER + cards + RESULT + dealerScoreResponse.getScore()); + System.out.println(DEALER + " " + CARD + DELIMITER + cards + RESULT + score); } - public void printFinalStatusOfPlayers(final PlayersCardsResponse playersCardsResponse) { - playersCardsResponse.getPlayerNameToResult() - .forEach(this::printFinalStatusOfPlayer); + public void printFinalStatusOfPlayers(final Map> playersCardsResponse, + final Map playersScore) { + playersScore.keySet().forEach(name -> { + printFinalPlayerCard(name, playersCardsResponse.get(name)); + printFinalPlayerScore(name, playersScore.get(name)); + }); } - private void printFinalStatusOfPlayer(final String name, final CardsScore cardsScore) { - final String cards = cardsScore.getCards() - .stream() + + private void printFinalPlayerCard(final String name, final List cards) { + final String card = cards.stream() .map(this::convertCard) .collect(Collectors.joining(DELIMITER_BETWEEN_CARDS)); - System.out.println(name + CARD + DELIMITER + cards + RESULT + cardsScore.getScore()); + + System.out.print(name + CARD + DELIMITER + card); } - public void printFinalResult(final FinalResultResponse finalResultDto) { + private void printFinalPlayerScore(final String name, final int score) { + System.out.println(RESULT + score); + } + + public void printFinalResult(final Map dealerResult) { System.out.println(); System.out.println("## 최종 승패"); System.out.print(DEALER + DELIMITER); - printDealerResult(finalResultDto.getDealerResult()); - printPlayersResult(finalResultDto.getPlayersToResult()); + printDealerResult(dealerResult); } private void printDealerResult(final Map dealerResult) { - printDealer(dealerResult, ResultTypeResponse.from("WIN")); - printDealer(dealerResult, ResultTypeResponse.from("DRAW")); - printDealer(dealerResult, ResultTypeResponse.from("LOSE")); + printDealer(dealerResult, ResultTypeResponse.from("승")); + printDealer(dealerResult, ResultTypeResponse.from("무")); + printDealer(dealerResult, ResultTypeResponse.from("패")); System.out.println(); } - private void printPlayersResult(final Map playersResult) { - playersResult.forEach(this::printPlayerResult); - } - private void printPlayerResult(final String name, final ResultTypeResponse resultTypeResponse) { System.out.println(name + DELIMITER + resultTypeResponse.getResult()); } @@ -129,4 +125,15 @@ private void printDealer( public void printError(final Exception exception) { System.out.println(exception.getMessage()); } + + public void printFinalDealerResult(final Map dealerResult) { + System.out.println(); + System.out.println("## 최종 승패"); + System.out.print(DEALER + DELIMITER); + printDealerResult(dealerResult); + } + + public void printFinalPlayersResult(final Map playersResult) { + playersResult.forEach(this::printPlayerResult); + } } From 092f1aba23c84ca5d36724416e076c50a29c1fdf Mon Sep 17 00:00:00 2001 From: be-student Date: Thu, 9 Mar 2023 13:07:19 +0900 Subject: [PATCH 05/59] =?UTF-8?q?refactor:=20blackJackRule=20=EC=9D=84=20?= =?UTF-8?q?=EC=99=B8=EB=B6=80=EC=97=90=EC=84=9C=20=EC=A3=BC=EC=9E=85?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/controller/BlackJackController.java | 4 +++- src/main/java/blackjack/service/BlackJackGame.java | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java index 8022fb03f3..4b69b58481 100644 --- a/src/main/java/blackjack/controller/BlackJackController.java +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -2,6 +2,7 @@ import static blackjack.util.Repeater.repeatUntilNoException; +import blackjack.domain.BlackJackRuleImpl; import blackjack.domain.card.DeckFactory; import blackjack.service.BlackJackGame; import blackjack.view.DrawCommand; @@ -23,7 +24,8 @@ public void play(final DeckFactory deckFactory) { final BlackJackGame blackJackGame = repeatUntilNoException( () -> BlackJackGame.of( inputPlayerNames(), - deckFactory), + deckFactory, + new BlackJackRuleImpl()), outputView::printError); blackJackGame.distributeInitialCard(); diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 609d1c01e5..01314736da 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -1,7 +1,6 @@ package blackjack.service; import blackjack.domain.BlackJackRule; -import blackjack.domain.BlackJackRuleImpl; import blackjack.domain.ResultType; import blackjack.domain.card.Card; import blackjack.domain.card.Deck; @@ -22,14 +21,19 @@ public class BlackJackGame { private final Participants participants; private final Deck deck; + private final BlackJackRule blackJackRule; - private BlackJackGame(final Players players, final DeckFactory deckFactory) { + private BlackJackGame(final Players players, final DeckFactory deckFactory, final BlackJackRule blackJackRule) { participants = new Participants(players, new Dealer()); deck = deckFactory.generate(); + this.blackJackRule = blackJackRule; } - public static BlackJackGame of(final List playerNames, final DeckFactory deckFactory) { - return new BlackJackGame(Players.from(playerNames), deckFactory); + public static BlackJackGame of( + final List playerNames, + final DeckFactory deckFactory, + final BlackJackRule blackJackRule) { + return new BlackJackGame(Players.from(playerNames), deckFactory, blackJackRule); } public void distributeInitialCard() { @@ -100,7 +104,6 @@ public int getDealerScore() { } public Map getDealerResult() { - final BlackJackRule blackJackRule = new BlackJackRuleImpl(); final ParticipantResults participantResults = new ParticipantResults(); final Dealer dealer = participants.getDealer(); participants.getPlayers().getPlayers().forEach(player -> { @@ -116,7 +119,6 @@ public Map getDealerResult() { } public Map generatePlayersResult() { - final BlackJackRule blackJackRule = new BlackJackRuleImpl(); final ParticipantResults participantResults = new ParticipantResults(); final Dealer dealer = participants.getDealer(); participants.getPlayers().getPlayers().forEach(player -> { From bdd40b309dc56ecf6227face23a8afb8744bead7 Mon Sep 17 00:00:00 2001 From: be-student Date: Thu, 9 Mar 2023 16:33:29 +0900 Subject: [PATCH 06/59] =?UTF-8?q?refactor:=20=EC=84=9C=EB=B9=84=EC=8A=A4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B3=80=ED=99=98=EC=9D=84=20=ED=95=B4?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20=EC=97=AD=ED=95=A0=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BlackJackController.java | 24 +++-- .../blackjack/controller/DomainConverter.java | 81 ++++++++++++++++ .../blackjack/domain/participant/Players.java | 4 +- .../java/blackjack/service/BlackJackGame.java | 93 ++++++------------- src/main/java/blackjack/view/OutputView.java | 5 +- 5 files changed, 132 insertions(+), 75 deletions(-) create mode 100644 src/main/java/blackjack/controller/DomainConverter.java diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java index 4b69b58481..bd687df9c1 100644 --- a/src/main/java/blackjack/controller/BlackJackController.java +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -1,5 +1,11 @@ package blackjack.controller; +import static blackjack.controller.DomainConverter.convertCard; +import static blackjack.controller.DomainConverter.convertCards; +import static blackjack.controller.DomainConverter.convertDealerResults; +import static blackjack.controller.DomainConverter.convertPlayersCards; +import static blackjack.controller.DomainConverter.convertPlayersResult; +import static blackjack.controller.DomainConverter.getPlayerCards; import static blackjack.util.Repeater.repeatUntilNoException; import blackjack.domain.BlackJackRuleImpl; @@ -29,7 +35,10 @@ public void play(final DeckFactory deckFactory) { outputView::printError); blackJackGame.distributeInitialCard(); - outputView.printInitialCards(blackJackGame.getDealerFirstCard(), blackJackGame.getPlayerCards()); + + outputView.printInitialCards( + convertCard(blackJackGame.getDealerFirstCard()), + getPlayerCards(blackJackGame.getPlayers())); for (final String playerName : blackJackGame.getPlayerNames()) { DrawCommand playerChoice = DrawCommand.DRAW; @@ -38,7 +47,7 @@ public void play(final DeckFactory deckFactory) { if (playerChoice == DrawCommand.DRAW) { blackJackGame.drawPlayerCard(playerName); } - outputView.printCardStatusOfPlayer(playerName, blackJackGame.getPlayerCardsResponse(playerName)); + outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); } } @@ -47,10 +56,12 @@ public void play(final DeckFactory deckFactory) { outputView.printDealerCardDrawMessage(); } - outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), blackJackGame.getDealerCardsResponse()); - outputView.printFinalStatusOfPlayers(blackJackGame.getPlayerCards(), blackJackGame.getPlayerScores()); - outputView.printFinalDealerResult(blackJackGame.getDealerResult()); - outputView.printFinalPlayersResult(blackJackGame.generatePlayersResult()); + outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), + convertCards(blackJackGame.getDealerCards())); + outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), + blackJackGame.getPlayersScores()); + outputView.printFinalDealerResult(convertDealerResults(blackJackGame.generatePlayersResult())); + outputView.printFinalPlayersResult(convertPlayersResult(blackJackGame.generatePlayersResult())); } private DrawCommand inputPlayerChoice(final String playerName) { @@ -61,5 +72,4 @@ private DrawCommand inputPlayerChoice(final String playerName) { private List inputPlayerNames() { return inputView.inputPlayerNames(); } - } diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java new file mode 100644 index 0000000000..59e37cbc88 --- /dev/null +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -0,0 +1,81 @@ +package blackjack.controller; + +import blackjack.domain.ResultType; +import blackjack.domain.card.Card; +import blackjack.domain.participant.Players; +import blackjack.response.CardResponse; +import blackjack.response.ResultTypeResponse; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +class DomainConverter { + + private DomainConverter() { + } + + static CardResponse convertCard(final Card card) { + return CardResponse.from(card); + } + + static List convertCards(final List cards) { + return cards.stream() + .map(CardResponse::from) + .collect(Collectors.toList()); + } + + static Map> getPlayerCards(final Players players) { + final List playerNames = players.getPlayerNames(); + final Map> playerCards = new HashMap<>(); + for (final String playerName : playerNames) { + final List cardResponses = players.findPlayerByName(playerName) + .getCards() + .stream() + .map(CardResponse::from) + .collect(Collectors.toList()); + playerCards.put(playerName, cardResponses); + } + return playerCards; + } + + static Map> convertPlayersCards(final Map> playersCards) { + return playersCards.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> entry.getValue().stream() + .map(CardResponse::from) + .collect(Collectors.toList()), + (oldValue, newValue) -> newValue, + LinkedHashMap::new + )); + } + + static Map convertDealerResults(final Map generatePlayersResult) { + final Map dealerResult = new HashMap<>(); + final long dealerWinCount = generatePlayersResult.values().stream() + .filter(ResultType.WIN::equals) + .count(); + final long dealerLoseCount = generatePlayersResult.values().stream() + .filter(ResultType.LOSE::equals) + .count(); + final long drawCount = generatePlayersResult.values().stream() + .filter(ResultType.TIE::equals) + .count(); + dealerResult.put(ResultTypeResponse.from(ResultType.LOSE.getName()), dealerWinCount); + dealerResult.put(ResultTypeResponse.from(ResultType.WIN.getName()), dealerLoseCount); + dealerResult.put(ResultTypeResponse.from(ResultType.TIE.getName()), drawCount); + return dealerResult; + } + + static Map convertPlayersResult(final Map generatePlayersResult) { + return generatePlayersResult.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> ResultTypeResponse.from(entry.getValue().getName()), + (oldValue, newValue) -> newValue, + LinkedHashMap::new + )); + } +} diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 141b61eb3f..2dd88939f6 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -63,7 +63,7 @@ void distributeInitialCards(final Deck deck) { } } - List getPlayerNames() { + public List getPlayerNames() { return players.stream() .map(Player::getName) .collect(Collectors.toList()); @@ -85,7 +85,7 @@ void draw(final String playerName, final Card card) { targetPlayer.drawCard(card); } - Player findPlayerByName(final String name) { + public Player findPlayerByName(final String name) { return players.stream() .filter(player -> player.hasName(name)) .findFirst() diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 01314736da..2d1fa8fc22 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -7,15 +7,11 @@ import blackjack.domain.card.DeckFactory; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Participants; -import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; -import blackjack.response.CardResponse; -import blackjack.response.ResultTypeResponse; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; public class BlackJackGame { @@ -60,79 +56,50 @@ public List getPlayerNames() { return participants.getPlayerNames(); } - public CardResponse getDealerFirstCard() { - final Card dealerFirstCard = participants.getDealer().getFirstCard(); - return CardResponse.from(dealerFirstCard); + public Card getDealerFirstCard() { + return participants.getDealer().getFirstCard(); } - public Map> getPlayerCards() { - final Map> playerCards = new HashMap<>(); - for (final String playerName : getPlayerNames()) { - final List cardResponses = participants.getPlayerCards(playerName).stream() - .map(CardResponse::from) - .collect(Collectors.toList()); - playerCards.put(playerName, cardResponses); - } - return playerCards; + public Players getPlayers() { + return participants.getPlayers(); } - public Map getPlayerScores() { - final Map playerScores = new HashMap<>(); - for (final String playerName : getPlayerNames()) { - final Player player = participants.findPlayerByName(playerName); - playerScores.put(playerName, player.currentScore()); - } - return playerScores; + public Map generatePlayersResult() { + final ParticipantResults participantResults = new ParticipantResults(); + final Dealer dealer = participants.getDealer(); + participants.getPlayers().getPlayers().forEach(player -> { + final ResultType resultType = blackJackRule.calculateDealerResult(dealer, player).getOppositeResult(); + participantResults.addPlayerResult(player.getName(), resultType); + }); + return participantResults.getPlayerNameToResultType(); } - public List getPlayerCardsResponse(final String playerName) { - final Player player = participants.findPlayerByName(playerName); - return player.getCards().stream() - .map(CardResponse::from) - .collect(Collectors.toList()); + public List getPlayerCards(final String playerName) { + return participants.findPlayerByName(playerName) + .getCards(); } - public List getDealerCardsResponse() { - final Dealer dealer = participants.getDealer(); - return dealer.getCards().stream() - .map(CardResponse::from) - .collect(Collectors.toList()); + public int getDealerScore() { + return participants.getDealer() + .currentScore(); } - public int getDealerScore() { - return participants.getDealer().currentScore(); + public List getDealerCards() { + return participants.getDealer() + .getCards(); } - public Map getDealerResult() { - final ParticipantResults participantResults = new ParticipantResults(); - final Dealer dealer = participants.getDealer(); - participants.getPlayers().getPlayers().forEach(player -> { - final ResultType resultType = blackJackRule.calculateDealerResult(dealer, player); - participantResults.addPlayerResult(player.getName(), resultType); - }); - final Map playersToResult = participantResults.getPlayerNameToResultType(); - return playersToResult.entrySet() - .stream() - .collect(Collectors.groupingBy( - result -> ResultTypeResponse.from(result.getValue()), - Collectors.counting())); + public Map> getPlayersCards() { + final Map> playerCards = new HashMap<>(); + participants.getPlayers().getPlayers().forEach(player -> playerCards.put(player.getName(), player.getCards())); + return playerCards; } - public Map generatePlayersResult() { - final ParticipantResults participantResults = new ParticipantResults(); - final Dealer dealer = participants.getDealer(); - participants.getPlayers().getPlayers().forEach(player -> { - final ResultType resultType = blackJackRule.calculateDealerResult(dealer, player).getOppositeResult(); - participantResults.addPlayerResult(player.getName(), resultType); - }); - final Map playersToResult = participantResults.getPlayerNameToResultType(); - return playersToResult.entrySet() - .stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - result -> ResultTypeResponse.from(result.getValue()), - (x, y) -> y, - LinkedHashMap::new)); + public Map getPlayersScores() { + final Map playerScores = new LinkedHashMap<>(); + participants.getPlayers().getPlayers() + .forEach(player -> playerScores.put(player.getName(), player.currentScore())); + return playerScores; } private static class ParticipantResults { diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 584c9ff4a3..e0465d0add 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -116,9 +116,8 @@ private void printDealer( final Map dealerResult, final ResultTypeResponse resultTypeResponse) { - if (dealerResult.containsKey(resultTypeResponse)) { - System.out.print( - dealerResult.get(resultTypeResponse) + resultTypeResponse.getResult()); + if (dealerResult.get(resultTypeResponse) != 0) { + System.out.print(dealerResult.get(resultTypeResponse) + resultTypeResponse.getResult()); } } From 2931e752274c3d3b9361ce7c1cceb7b182b73599 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 20:51:00 +0900 Subject: [PATCH 07/59] =?UTF-8?q?feat:=20=EC=A0=90=EC=88=98=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=EC=BA=90=EC=8B=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/Participant.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 84ea3f89b7..dbfe1f7394 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -7,22 +7,28 @@ public abstract class Participant { private final CardPocket cardPocket; + private int cachedScore; Participant() { cardPocket = CardPocket.empty(); } - public void drawInitialCard(final Card first, final Card second) { - cardPocket.addCard(first); - cardPocket.addCard(second); + void drawInitialCard(final Card first, final Card second) { + drawCard(first); + drawCard(second); } - public void drawCard(final Card card) { + public boolean isBlackJack() { + return cardPocket.isBlackJack(); + } + + void drawCard(final Card card) { cardPocket.addCard(card); + cachedScore = cardPocket.calculateScore(); } public int currentScore() { - return cardPocket.calculateScore(); + return cachedScore; } public List getCards() { From 3c963feeebf3700edd33ee158b9a5df2490ded07 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 21:00:55 +0900 Subject: [PATCH 08/59] =?UTF-8?q?feat:=20resultType=20enum=20=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=98=EB=8C=80=20=EA=B2=B0=EA=B3=BC=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/domain/ResultType.java | 43 +++++++++++++------ .../java/blackjack/domain/ResultType.java~ | 17 -------- 2 files changed, 31 insertions(+), 29 deletions(-) delete mode 100644 src/main/java/blackjack/domain/ResultType.java~ diff --git a/src/main/java/blackjack/domain/ResultType.java b/src/main/java/blackjack/domain/ResultType.java index ef71e53ad4..c6b30b943b 100644 --- a/src/main/java/blackjack/domain/ResultType.java +++ b/src/main/java/blackjack/domain/ResultType.java @@ -1,9 +1,36 @@ package blackjack.domain; public enum ResultType { - WIN("승"), - TIE("무"), - LOSE("패"); + BLACKJACK_WIN("블랙잭 승리") { + @Override + public ResultType getOppositeResult() { + return BLACKJACK_LOSE; + } + }, + WIN("승") { + @Override + public ResultType getOppositeResult() { + return LOSE; + } + }, + TIE("무") { + @Override + public ResultType getOppositeResult() { + return TIE; + } + }, + LOSE("패") { + @Override + public ResultType getOppositeResult() { + return WIN; + } + }, + BLACKJACK_LOSE("블랙잭 패배") { + @Override + public ResultType getOppositeResult() { + return BLACKJACK_WIN; + } + }; private final String name; @@ -11,15 +38,7 @@ public enum ResultType { this.name = name; } - public ResultType getOppositeResult() { - if (this == WIN) { - return LOSE; - } - if (this == TIE) { - return TIE; - } - return WIN; - } + public abstract ResultType getOppositeResult(); public String getName() { return name; diff --git a/src/main/java/blackjack/domain/ResultType.java~ b/src/main/java/blackjack/domain/ResultType.java~ deleted file mode 100644 index d2a1480964..0000000000 --- a/src/main/java/blackjack/domain/ResultType.java~ +++ /dev/null @@ -1,17 +0,0 @@ -package blackjack.domain; - -public enum ResultType { - WIN("승"), - TIE("무"), - LOSE("패"); - - public ResultType getOppositeResult() { - if (this == WIN) { - return LOSE; - } - if (this == TIE) { - return TIE; - } - return WIN; - } -} From 886d8aed885af0dbc0ae53cbb4c72db793e0b89b Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 21:01:18 +0900 Subject: [PATCH 09/59] =?UTF-8?q?feat:=20=EB=B2=A0=ED=8C=85=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EC=9E=85=EB=A0=A5=20=EB=B0=9B=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/InputView.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index 80e5b3a15d..ebec12b02b 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -26,4 +26,14 @@ public DrawCommand inputCommand(final String playerName) { final String input = scanner.nextLine(); return DrawCommand.from(input); } + + public int inputPlayerMoney(final String playerName) { + System.out.println(MessageFormat.format("{0}의 배팅 금액은?", playerName)); + try { + return Integer.parseInt(scanner.nextLine()); + } catch (final NumberFormatException e) { + System.out.println("숫자만 입력해주세요."); + return inputPlayerMoney(playerName); + } + } } From acaf20f6d423440c498c10a94884179140656698 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 21:32:00 +0900 Subject: [PATCH 10/59] =?UTF-8?q?feat:=20=EC=B6=9C=EB=A0=A5=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/OutputView.java | 48 +++++--------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index e0465d0add..3708f4cc45 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,7 +1,6 @@ package blackjack.view; import blackjack.response.CardResponse; -import blackjack.response.ResultTypeResponse; import java.text.MessageFormat; import java.util.List; import java.util.Map; @@ -77,7 +76,7 @@ public void printFinalStatusOfPlayers(final Map> play final Map playersScore) { playersScore.keySet().forEach(name -> { printFinalPlayerCard(name, playersCardsResponse.get(name)); - printFinalPlayerScore(name, playersScore.get(name)); + printFinalPlayerScore(playersScore.get(name)); }); } @@ -90,49 +89,26 @@ private void printFinalPlayerCard(final String name, final List ca System.out.print(name + CARD + DELIMITER + card); } - private void printFinalPlayerScore(final String name, final int score) { + private void printFinalPlayerScore(final int score) { System.out.println(RESULT + score); } - public void printFinalResult(final Map dealerResult) { - System.out.println(); - System.out.println("## 최종 승패"); - System.out.print(DEALER + DELIMITER); - printDealerResult(dealerResult); - } - - private void printDealerResult(final Map dealerResult) { - printDealer(dealerResult, ResultTypeResponse.from("승")); - printDealer(dealerResult, ResultTypeResponse.from("무")); - printDealer(dealerResult, ResultTypeResponse.from("패")); - System.out.println(); - } - - private void printPlayerResult(final String name, final ResultTypeResponse resultTypeResponse) { - System.out.println(name + DELIMITER + resultTypeResponse.getResult()); - } - - private void printDealer( - final Map dealerResult, - final ResultTypeResponse resultTypeResponse) { - - if (dealerResult.get(resultTypeResponse) != 0) { - System.out.print(dealerResult.get(resultTypeResponse) + resultTypeResponse.getResult()); - } - } - public void printError(final Exception exception) { System.out.println(exception.getMessage()); } - public void printFinalDealerResult(final Map dealerResult) { + public void printFinalMoney(final Map calculatePlayersMoney) { System.out.println(); - System.out.println("## 최종 승패"); - System.out.print(DEALER + DELIMITER); - printDealerResult(dealerResult); + System.out.println("## 최종 수익"); + System.out.println(DEALER + DELIMITER + calculateDealerMoney(calculatePlayersMoney)); + calculatePlayersMoney.forEach((name, money) -> System.out.println(name + DELIMITER + money)); } - public void printFinalPlayersResult(final Map playersResult) { - playersResult.forEach(this::printPlayerResult); + private String calculateDealerMoney(final Map calculatePlayersMoney) { + int dealerMoney = 0; + for (final int money : calculatePlayersMoney.values()) { + dealerMoney -= money; + } + return String.valueOf(dealerMoney); } } From adc2c806b170bbaa13033829818527f8391d11aa Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 21:57:32 +0900 Subject: [PATCH 11/59] =?UTF-8?q?feat:=20=EC=B9=B4=EB=93=9C=20=ED=8F=AC?= =?UTF-8?q?=EC=BC=93=EC=97=90=20=EB=B8=94=EB=9E=99=EC=9E=AD=EC=9D=B8?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/domain/card/CardPocket.java | 5 +++++ .../blackjack/domain/card/CardPocketTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/main/java/blackjack/domain/card/CardPocket.java b/src/main/java/blackjack/domain/card/CardPocket.java index c9906657ae..5595c03597 100644 --- a/src/main/java/blackjack/domain/card/CardPocket.java +++ b/src/main/java/blackjack/domain/card/CardPocket.java @@ -6,6 +6,7 @@ public class CardPocket { private static final int BUST_SCORE = 21; + private static final int BLACKJACK_SCORE = 21; private static final int VALUE_ACE = 10; private final List cards; @@ -59,4 +60,8 @@ private int calculateAceScore(final int score) { public List getCards() { return List.copyOf(cards); } + + public boolean isBlackJack() { + return cards.size() == 2 && calculateScore() == BLACKJACK_SCORE; + } } diff --git a/src/test/java/blackjack/domain/card/CardPocketTest.java b/src/test/java/blackjack/domain/card/CardPocketTest.java index 1fb04c46ba..cd64e6d0b6 100644 --- a/src/test/java/blackjack/domain/card/CardPocketTest.java +++ b/src/test/java/blackjack/domain/card/CardPocketTest.java @@ -7,6 +7,8 @@ import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; @SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @@ -67,4 +69,18 @@ void setCardPocket() { assertThat(cardPocket.calculateScore()) .isEqualTo(12); } + + @ParameterizedTest + @CsvSource(value = {"ACE, TEN, true", "JACK, ACE, true", "ACE, ACE, false", "TEN, TEN, false"}) + void 블랙잭인_경우_2장으로_21점이_되는_경우_검증( + final Symbol firstSymbol, + final Symbol secondSymbol, + final boolean expected) { + final CardPocket cardPocket = CardPocket.empty(); + cardPocket.addCard(new Card(Shape.DIAMOND, firstSymbol)); + cardPocket.addCard(new Card(Shape.DIAMOND, secondSymbol)); + + assertThat(cardPocket.isBlackJack()) + .isEqualTo(expected); + } } From 36eb098af7c4328b6bce33365c0a619fcb6d40b1 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 21:58:29 +0900 Subject: [PATCH 12/59] =?UTF-8?q?feat:=20=EA=B0=81=EA=B0=81=EC=9D=98=20pla?= =?UTF-8?q?yerProfit=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/ResultType.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/blackjack/domain/ResultType.java b/src/main/java/blackjack/domain/ResultType.java index c6b30b943b..71d6f6daa3 100644 --- a/src/main/java/blackjack/domain/ResultType.java +++ b/src/main/java/blackjack/domain/ResultType.java @@ -1,31 +1,31 @@ package blackjack.domain; public enum ResultType { - BLACKJACK_WIN("블랙잭 승리") { + BLACKJACK_WIN("블랙잭 승리", 1.5) { @Override public ResultType getOppositeResult() { return BLACKJACK_LOSE; } }, - WIN("승") { + WIN("승", 1) { @Override public ResultType getOppositeResult() { return LOSE; } }, - TIE("무") { + TIE("무", 0) { @Override public ResultType getOppositeResult() { return TIE; } }, - LOSE("패") { + LOSE("패", -1) { @Override public ResultType getOppositeResult() { return WIN; } }, - BLACKJACK_LOSE("블랙잭 패배") { + BLACKJACK_LOSE("블랙잭 패배", -1) { @Override public ResultType getOppositeResult() { return BLACKJACK_WIN; @@ -33,9 +33,11 @@ public ResultType getOppositeResult() { }; private final String name; + private final double playerProfit; - ResultType(final String name) { + ResultType(final String name, final double playerProfit) { this.name = name; + this.playerProfit = playerProfit; } public abstract ResultType getOppositeResult(); @@ -43,4 +45,8 @@ public ResultType getOppositeResult() { public String getName() { return name; } + + public double getPlayerProfit() { + return playerProfit; + } } From 6e00bc03bf58916e5204e4bc009b6a2e9e9347e5 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 21:59:13 +0900 Subject: [PATCH 13/59] =?UTF-8?q?feat:=20=EB=B8=94=EB=9E=99=EC=9E=AD?= =?UTF-8?q?=EC=9D=B8=20=EA=B2=BD=EC=9A=B0=EC=97=90=20=EB=94=B0=EB=9D=BC?= =?UTF-8?q?=EC=84=9C=20=EC=88=98=EC=9D=B5=20=EB=B0=98=ED=99=98=ED=95=B4?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BlackJackController.java | 15 ++++++++--- .../blackjack/controller/DomainConverter.java | 25 +++++++++---------- .../blackjack/domain/BlackJackRuleImpl.java | 14 +++++++++++ .../java/blackjack/service/BlackJackGame.java | 20 +++++++++++++++ 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java index bd687df9c1..f3f6743d64 100644 --- a/src/main/java/blackjack/controller/BlackJackController.java +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -2,9 +2,7 @@ import static blackjack.controller.DomainConverter.convertCard; import static blackjack.controller.DomainConverter.convertCards; -import static blackjack.controller.DomainConverter.convertDealerResults; import static blackjack.controller.DomainConverter.convertPlayersCards; -import static blackjack.controller.DomainConverter.convertPlayersResult; import static blackjack.controller.DomainConverter.getPlayerCards; import static blackjack.util.Repeater.repeatUntilNoException; @@ -34,6 +32,10 @@ public void play(final DeckFactory deckFactory) { new BlackJackRuleImpl()), outputView::printError); + for (final String playerName : blackJackGame.getPlayerNames()) { + blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName)); + } + blackJackGame.distributeInitialCard(); outputView.printInitialCards( @@ -60,8 +62,13 @@ public void play(final DeckFactory deckFactory) { convertCards(blackJackGame.getDealerCards())); outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), blackJackGame.getPlayersScores()); - outputView.printFinalDealerResult(convertDealerResults(blackJackGame.generatePlayersResult())); - outputView.printFinalPlayersResult(convertPlayersResult(blackJackGame.generatePlayersResult())); + + outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); + } + + private int inputPlayerMoney(final String playerName) { + return repeatUntilNoException( + () -> inputView.inputPlayerMoney(playerName), outputView::printError); } private DrawCommand inputPlayerChoice(final String playerName) { diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java index 59e37cbc88..a6c0b08471 100644 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -5,6 +5,7 @@ import blackjack.domain.participant.Players; import blackjack.response.CardResponse; import blackjack.response.ResultTypeResponse; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -52,19 +53,17 @@ static Map> convertPlayersCards(final Map convertDealerResults(final Map generatePlayersResult) { - final Map dealerResult = new HashMap<>(); - final long dealerWinCount = generatePlayersResult.values().stream() - .filter(ResultType.WIN::equals) - .count(); - final long dealerLoseCount = generatePlayersResult.values().stream() - .filter(ResultType.LOSE::equals) - .count(); - final long drawCount = generatePlayersResult.values().stream() - .filter(ResultType.TIE::equals) - .count(); - dealerResult.put(ResultTypeResponse.from(ResultType.LOSE.getName()), dealerWinCount); - dealerResult.put(ResultTypeResponse.from(ResultType.WIN.getName()), dealerLoseCount); + static Map convertDealerResults(final Map generatePlayersResult) { + final Map dealerResult = new HashMap<>(); + final int dealerWinCount = Collections.frequency(generatePlayersResult.values(), ResultType.WIN); + final int dealerBlackJackWinCount = Collections.frequency(generatePlayersResult.values(), + ResultType.BLACKJACK_WIN); + final int dealerLoseCount = Collections.frequency(generatePlayersResult.values(), ResultType.LOSE); + final int dealerBlackJackLoseCount = Collections.frequency(generatePlayersResult.values(), + ResultType.BLACKJACK_LOSE); + final int drawCount = Collections.frequency(generatePlayersResult.values(), ResultType.TIE); + dealerResult.put(ResultTypeResponse.from(ResultType.LOSE.getName()), dealerWinCount + dealerBlackJackLoseCount); + dealerResult.put(ResultTypeResponse.from(ResultType.WIN.getName()), dealerLoseCount + dealerBlackJackWinCount); dealerResult.put(ResultTypeResponse.from(ResultType.TIE.getName()), drawCount); return dealerResult; } diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java index c9ff65b9b9..6b1c69b4ae 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -9,6 +9,12 @@ public class BlackJackRuleImpl implements BlackJackRule { @Override public ResultType calculateDealerResult(final Dealer dealer, final Player player) { + if (isBlackJackWin(dealer, player)) { + return ResultType.BLACKJACK_WIN; + } + if (isBlackJackLose(dealer, player)) { + return ResultType.BLACKJACK_LOSE; + } final int dealerScore = dealer.currentScore(); final int playerScore = player.currentScore(); if (isTie(dealerScore, playerScore)) { @@ -20,6 +26,14 @@ public ResultType calculateDealerResult(final Dealer dealer, final Player player return ResultType.LOSE; } + private boolean isBlackJackWin(final Dealer dealer, final Player player) { + return dealer.isBlackJack() && !player.isBlackJack(); + } + + private boolean isBlackJackLose(final Dealer dealer, final Player player) { + return !dealer.isBlackJack() && player.isBlackJack(); + } + private boolean isTie(final int dealerScore, final int playerScore) { if (playerScore > BUST_POINT && dealerScore > BUST_POINT) { return true; diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 2d1fa8fc22..a7f164ba69 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -18,6 +18,7 @@ public class BlackJackGame { private final Participants participants; private final Deck deck; private final BlackJackRule blackJackRule; + private final Map playerMoney = new LinkedHashMap<>(); private BlackJackGame(final Players players, final DeckFactory deckFactory, final BlackJackRule blackJackRule) { participants = new Participants(players, new Dealer()); @@ -102,6 +103,25 @@ public Map getPlayersScores() { return playerScores; } + public void addPlayerMoney(final String playerName, final int inputPlayerMoney) { + playerMoney.put(playerName, inputPlayerMoney); + } + + public Map calculatePlayersMoney() { + final Map resultPlayersMoney = new LinkedHashMap<>(); + final Map playerResult = generatePlayersResult(); + playerMoney.forEach((playerName, money) -> { + final ResultType resultType = playerResult.get(playerName); + final int playerWinningMoney = calculatePlayerMoney(money, resultType); + resultPlayersMoney.put(playerName, playerWinningMoney); + }); + return resultPlayersMoney; + } + + private int calculatePlayerMoney(final int money, final ResultType resultType) { + return (int) (money * resultType.getPlayerProfit()); + } + private static class ParticipantResults { private final Map playerNameToResultType = new HashMap<>(); From 077a5d4d8d2f003e4dfa5a8ccdd010b88c0eca6e Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:04:41 +0900 Subject: [PATCH 14/59] =?UTF-8?q?feat:=20rename=20hasBlackJack=20=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/BlackJackRuleImpl.java | 4 ++-- src/main/java/blackjack/domain/participant/Participant.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java index 6b1c69b4ae..b26ba7f0d0 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -27,11 +27,11 @@ public ResultType calculateDealerResult(final Dealer dealer, final Player player } private boolean isBlackJackWin(final Dealer dealer, final Player player) { - return dealer.isBlackJack() && !player.isBlackJack(); + return dealer.hasBlackJack() && !player.hasBlackJack(); } private boolean isBlackJackLose(final Dealer dealer, final Player player) { - return !dealer.isBlackJack() && player.isBlackJack(); + return !dealer.hasBlackJack() && player.hasBlackJack(); } private boolean isTie(final int dealerScore, final int playerScore) { diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index dbfe1f7394..814a2e199c 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -18,7 +18,7 @@ void drawInitialCard(final Card first, final Card second) { drawCard(second); } - public boolean isBlackJack() { + public boolean hasBlackJack() { return cardPocket.isBlackJack(); } From 2547f7202f54da6cf272e4023c4622353053a2eb Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:09:57 +0900 Subject: [PATCH 15/59] =?UTF-8?q?docs:=20=EC=A7=88=EB=AC=B8=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BlackJackController.java | 65 ++++++++++++++++--- .../blackjack/domain/BlackJackRuleImpl.java | 2 + 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java index f3f6743d64..f76ecab5af 100644 --- a/src/main/java/blackjack/controller/BlackJackController.java +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -24,6 +24,51 @@ public BlackJackController(final InputView inputView, final OutputView outputVie this.outputView = outputView; } + //이 메서드는 10라인도 훨씬 넘었고, 되게 복잡하게 되어있는데, 이렇게 두는 것이 좋은가요? + //원래대로 돌렸을 경우에, 훨씬 간단해보였던 것 같아요 +// public void play(final DeckFactory deckFactory) { +// final BlackJackGame blackJackGame = repeatUntilNoException( +// () -> BlackJackGame.of( +// inputPlayerNames(), +// deckFactory, +// new BlackJackRuleImpl()), +// outputView::printError); +// +// for (final String playerName : blackJackGame.getPlayerNames()) { +// blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName)); +// } +// +// blackJackGame.distributeInitialCard(); +// +// outputView.printInitialCards( +// convertCard(blackJackGame.getDealerFirstCard()), +// getPlayerCards(blackJackGame.getPlayers())); +// +// for (final String playerName : blackJackGame.getPlayerNames()) { +// DrawCommand playerChoice = DrawCommand.DRAW; +// while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { +// playerChoice = inputPlayerChoice(playerName); +// if (playerChoice == DrawCommand.DRAW) { +// blackJackGame.drawPlayerCard(playerName); +// } +// outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); +// } +// } +// +// while (blackJackGame.isDealerDrawable()) { +// blackJackGame.drawDealerCard(); +// outputView.printDealerCardDrawMessage(); +// } +// +// outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), +// convertCards(blackJackGame.getDealerCards())); +// outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), +// blackJackGame.getPlayersScores()); +// +// outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); +// } + + //한 메서드가 너무 길어지는 느낌이 드는 것 같은데요 이것은 어떤가요? public void play(final DeckFactory deckFactory) { final BlackJackGame blackJackGame = repeatUntilNoException( () -> BlackJackGame.of( @@ -43,14 +88,7 @@ public void play(final DeckFactory deckFactory) { getPlayerCards(blackJackGame.getPlayers())); for (final String playerName : blackJackGame.getPlayerNames()) { - DrawCommand playerChoice = DrawCommand.DRAW; - while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { - playerChoice = inputPlayerChoice(playerName); - if (playerChoice == DrawCommand.DRAW) { - blackJackGame.drawPlayerCard(playerName); - } - outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); - } + drawPlayerCard(blackJackGame, playerName); } while (blackJackGame.isDealerDrawable()) { @@ -66,6 +104,17 @@ public void play(final DeckFactory deckFactory) { outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); } + private void drawPlayerCard(final BlackJackGame blackJackGame, final String playerName) { + DrawCommand playerChoice = DrawCommand.DRAW; + while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { + playerChoice = inputPlayerChoice(playerName); + if (playerChoice == DrawCommand.DRAW) { + blackJackGame.drawPlayerCard(playerName); + } + outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); + } + } + private int inputPlayerMoney(final String playerName) { return repeatUntilNoException( () -> inputView.inputPlayerMoney(playerName), outputView::printError); diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java index b26ba7f0d0..33cb8ddce5 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -9,6 +9,8 @@ public class BlackJackRuleImpl implements BlackJackRule { @Override public ResultType calculateDealerResult(final Dealer dealer, final Player player) { + //이 부분이 애매해서 리팩토링을 해보려고 했는데, 더 좋은 방법이 생각나지 않아서 일단 이렇게 구현했습니다. + //enum 클래스에 BiPredicate를 추가해서 구현해보려고 했는데, enum 클래스에 메서드를 추가하는 것이 맞는지 잘 모르겠습니다. if (isBlackJackWin(dealer, player)) { return ResultType.BLACKJACK_WIN; } From be4591d333f7c9f4c2899f3cad0f5b9cd41aa90c Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:11:51 +0900 Subject: [PATCH 16/59] =?UTF-8?q?chore:=20=EC=95=88=20=EC=93=B0=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/controller/DomainConverter.java | 28 ------------------- .../blackjack/domain/card/CardPocketTest.java | 2 +- .../domain/participant/DealerTest.java | 17 ----------- .../domain/participant/ParticipantTest.java | 2 +- 4 files changed, 2 insertions(+), 47 deletions(-) diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java index a6c0b08471..da2cad340a 100644 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -1,11 +1,8 @@ package blackjack.controller; -import blackjack.domain.ResultType; import blackjack.domain.card.Card; import blackjack.domain.participant.Players; import blackjack.response.CardResponse; -import blackjack.response.ResultTypeResponse; -import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -52,29 +49,4 @@ static Map> convertPlayersCards(final Map convertDealerResults(final Map generatePlayersResult) { - final Map dealerResult = new HashMap<>(); - final int dealerWinCount = Collections.frequency(generatePlayersResult.values(), ResultType.WIN); - final int dealerBlackJackWinCount = Collections.frequency(generatePlayersResult.values(), - ResultType.BLACKJACK_WIN); - final int dealerLoseCount = Collections.frequency(generatePlayersResult.values(), ResultType.LOSE); - final int dealerBlackJackLoseCount = Collections.frequency(generatePlayersResult.values(), - ResultType.BLACKJACK_LOSE); - final int drawCount = Collections.frequency(generatePlayersResult.values(), ResultType.TIE); - dealerResult.put(ResultTypeResponse.from(ResultType.LOSE.getName()), dealerWinCount + dealerBlackJackLoseCount); - dealerResult.put(ResultTypeResponse.from(ResultType.WIN.getName()), dealerLoseCount + dealerBlackJackWinCount); - dealerResult.put(ResultTypeResponse.from(ResultType.TIE.getName()), drawCount); - return dealerResult; - } - - static Map convertPlayersResult(final Map generatePlayersResult) { - return generatePlayersResult.entrySet().stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - entry -> ResultTypeResponse.from(entry.getValue().getName()), - (oldValue, newValue) -> newValue, - LinkedHashMap::new - )); - } } diff --git a/src/test/java/blackjack/domain/card/CardPocketTest.java b/src/test/java/blackjack/domain/card/CardPocketTest.java index cd64e6d0b6..48c6b83bc8 100644 --- a/src/test/java/blackjack/domain/card/CardPocketTest.java +++ b/src/test/java/blackjack/domain/card/CardPocketTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@SuppressWarnings({"NonAsciiCharacters"}) @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class CardPocketTest { diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index ff64706991..3690a9cb95 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -6,11 +6,8 @@ import blackjack.domain.card.Shape; import blackjack.domain.card.Symbol; import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @SuppressWarnings({"NonAsciiCharacters"}) @@ -41,18 +38,4 @@ class DealerTest { assertThat(dealer.isDrawable()) .isFalse(); } - - @Nested - @DisplayName("딜러를 통해 결과를 계산하면") - class CalculateResultTest { - - private final Dealer dealer = new Dealer(); - private Player player; - - @BeforeEach - void setUp() { - dealer.drawCard(new Card(Shape.DIAMOND, Symbol.FIVE)); - player = new Player("pobi"); - } - } } diff --git a/src/test/java/blackjack/domain/participant/ParticipantTest.java b/src/test/java/blackjack/domain/participant/ParticipantTest.java index f81f6f1544..3080047c16 100644 --- a/src/test/java/blackjack/domain/participant/ParticipantTest.java +++ b/src/test/java/blackjack/domain/participant/ParticipantTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; import org.junit.jupiter.api.Test; -@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@SuppressWarnings({"NonAsciiCharacters"}) @DisplayNameGeneration(ReplaceUnderscores.class) class ParticipantTest { From f14ba4e80feb86fb0e834a677b2f4f7c8adc1738 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:21:56 +0900 Subject: [PATCH 17/59] =?UTF-8?q?refactor:=20=EB=B8=94=EB=9E=99=EC=9E=AD?= =?UTF-8?q?=20=EA=B2=8C=EC=9E=84=20=EC=8A=B9=ED=8C=A8=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EC=9D=B4=20=EC=97=86=EC=96=B4=EC=A7=80=EB=A9=B4=EC=84=9C=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=EC=97=86=EC=96=B4=EC=A7=84=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/domain/ResultType.java | 18 +++----- .../domain/participant/Participants.java | 4 -- .../response/ResultTypeResponse.java | 42 ------------------ .../java/blackjack/service/BlackJackGame.java | 44 +++++++------------ 4 files changed, 22 insertions(+), 86 deletions(-) delete mode 100644 src/main/java/blackjack/response/ResultTypeResponse.java diff --git a/src/main/java/blackjack/domain/ResultType.java b/src/main/java/blackjack/domain/ResultType.java index 71d6f6daa3..e74ed7dcc8 100644 --- a/src/main/java/blackjack/domain/ResultType.java +++ b/src/main/java/blackjack/domain/ResultType.java @@ -1,51 +1,45 @@ package blackjack.domain; public enum ResultType { - BLACKJACK_WIN("블랙잭 승리", 1.5) { + BLACKJACK_WIN(1.5) { @Override public ResultType getOppositeResult() { return BLACKJACK_LOSE; } }, - WIN("승", 1) { + WIN(1) { @Override public ResultType getOppositeResult() { return LOSE; } }, - TIE("무", 0) { + TIE(0) { @Override public ResultType getOppositeResult() { return TIE; } }, - LOSE("패", -1) { + LOSE(-1) { @Override public ResultType getOppositeResult() { return WIN; } }, - BLACKJACK_LOSE("블랙잭 패배", -1) { + BLACKJACK_LOSE(-1) { @Override public ResultType getOppositeResult() { return BLACKJACK_WIN; } }; - private final String name; private final double playerProfit; - ResultType(final String name, final double playerProfit) { - this.name = name; + ResultType(final double playerProfit) { this.playerProfit = playerProfit; } public abstract ResultType getOppositeResult(); - public String getName() { - return name; - } - public double getPlayerProfit() { return playerProfit; } diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index af89d6d698..77ae6a5b2e 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -43,10 +43,6 @@ public Dealer getDealer() { return dealer; } - public List getPlayerCards(final String playerName) { - return players.findPlayerByName(playerName).getCards(); - } - public Players getPlayers() { return players; } diff --git a/src/main/java/blackjack/response/ResultTypeResponse.java b/src/main/java/blackjack/response/ResultTypeResponse.java deleted file mode 100644 index 978139de6a..0000000000 --- a/src/main/java/blackjack/response/ResultTypeResponse.java +++ /dev/null @@ -1,42 +0,0 @@ -package blackjack.response; - -import blackjack.domain.ResultType; -import java.util.Objects; - -public class ResultTypeResponse { - - private final String result; - - private ResultTypeResponse(final String result) { - this.result = result; - } - - public static ResultTypeResponse from(final ResultType resultType) { - return new ResultTypeResponse(resultType.getName()); - } - - public static ResultTypeResponse from(final String resultType) { - return new ResultTypeResponse(resultType); - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final ResultTypeResponse that = (ResultTypeResponse) o; - return Objects.equals(result, that.result); - } - - @Override - public int hashCode() { - return Objects.hash(result); - } - - public String getResult() { - return result; - } -} diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index a7f164ba69..5345015835 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -7,11 +7,13 @@ import blackjack.domain.card.DeckFactory; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Participants; +import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; public class BlackJackGame { @@ -65,15 +67,6 @@ public Players getPlayers() { return participants.getPlayers(); } - public Map generatePlayersResult() { - final ParticipantResults participantResults = new ParticipantResults(); - final Dealer dealer = participants.getDealer(); - participants.getPlayers().getPlayers().forEach(player -> { - final ResultType resultType = blackJackRule.calculateDealerResult(dealer, player).getOppositeResult(); - participantResults.addPlayerResult(player.getName(), resultType); - }); - return participantResults.getPlayerNameToResultType(); - } public List getPlayerCards(final String playerName) { return participants.findPlayerByName(playerName) @@ -109,29 +102,24 @@ public void addPlayerMoney(final String playerName, final int inputPlayerMoney) public Map calculatePlayersMoney() { final Map resultPlayersMoney = new LinkedHashMap<>(); - final Map playerResult = generatePlayersResult(); - playerMoney.forEach((playerName, money) -> { - final ResultType resultType = playerResult.get(playerName); - final int playerWinningMoney = calculatePlayerMoney(money, resultType); - resultPlayersMoney.put(playerName, playerWinningMoney); - }); + final Dealer dealer = participants.getDealer(); + participants.getPlayers() + .getPlayers() + .forEach(calculateWinningMoney(resultPlayersMoney, dealer)); return resultPlayersMoney; } - private int calculatePlayerMoney(final int money, final ResultType resultType) { - return (int) (money * resultType.getPlayerProfit()); + private Consumer calculateWinningMoney(final Map resultPlayersMoney, final Dealer dealer) { + return player -> { + final ResultType playerResult = blackJackRule.calculateDealerResult(dealer, player) + .getOppositeResult(); + final int betMoney = playerMoney.get(player.getName()); + final int playerWinningMoney = calculatePlayerMoney(betMoney, playerResult); + resultPlayersMoney.put(player.getName(), playerWinningMoney); + }; } - private static class ParticipantResults { - - private final Map playerNameToResultType = new HashMap<>(); - - void addPlayerResult(final String playerName, final ResultType resultType) { - playerNameToResultType.put(playerName, resultType); - } - - Map getPlayerNameToResultType() { - return playerNameToResultType; - } + private int calculatePlayerMoney(final int money, final ResultType resultType) { + return (int) (money * resultType.getPlayerProfit()); } } From 7be40158c9b4cd2f1de68b413682ac0ef932bcae Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:31:20 +0900 Subject: [PATCH 18/59] =?UTF-8?q?chore:=20=EC=A4=84=EB=B0=94=EA=BF=88=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/controller/BlackJackController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java index f76ecab5af..150ccdd6a4 100644 --- a/src/main/java/blackjack/controller/BlackJackController.java +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -76,13 +76,11 @@ public void play(final DeckFactory deckFactory) { deckFactory, new BlackJackRuleImpl()), outputView::printError); - for (final String playerName : blackJackGame.getPlayerNames()) { blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName)); } blackJackGame.distributeInitialCard(); - outputView.printInitialCards( convertCard(blackJackGame.getDealerFirstCard()), getPlayerCards(blackJackGame.getPlayers())); @@ -90,7 +88,6 @@ public void play(final DeckFactory deckFactory) { for (final String playerName : blackJackGame.getPlayerNames()) { drawPlayerCard(blackJackGame, playerName); } - while (blackJackGame.isDealerDrawable()) { blackJackGame.drawDealerCard(); outputView.printDealerCardDrawMessage(); @@ -100,7 +97,6 @@ public void play(final DeckFactory deckFactory) { convertCards(blackJackGame.getDealerCards())); outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), blackJackGame.getPlayersScores()); - outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); } From b7f060ad9d0daa0f203d751ed4f7b514519b28be Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:31:36 +0900 Subject: [PATCH 19/59] =?UTF-8?q?refactor:=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=ED=8F=AC=EC=BC=93=EC=97=90=20=EC=A0=90=EC=88=98=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/CardPocket.java | 10 ++++++++-- .../java/blackjack/domain/participant/Participant.java | 4 +--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/blackjack/domain/card/CardPocket.java b/src/main/java/blackjack/domain/card/CardPocket.java index 5595c03597..3a2c36c286 100644 --- a/src/main/java/blackjack/domain/card/CardPocket.java +++ b/src/main/java/blackjack/domain/card/CardPocket.java @@ -9,6 +9,7 @@ public class CardPocket { private static final int BLACKJACK_SCORE = 21; private static final int VALUE_ACE = 10; private final List cards; + private int cachedScore; private CardPocket(final List cards) { validateCardPocket(cards); @@ -27,15 +28,20 @@ private void validateCardPocket(final List cards) { public void addCard(final Card card) { cards.add(card); + calculateCurrentScore(); } - public int calculateScore() { + private void calculateCurrentScore() { final int countOfAce = countAce(); int scoreOfCards = calculateMinimumScore(); for (int i = 0; i < countOfAce; i++) { scoreOfCards = calculateAceScore(scoreOfCards); } - return scoreOfCards; + cachedScore = scoreOfCards; + } + + public int calculateScore() { + return cachedScore; } private int countAce() { diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 814a2e199c..60b2b9ab31 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -7,7 +7,6 @@ public abstract class Participant { private final CardPocket cardPocket; - private int cachedScore; Participant() { cardPocket = CardPocket.empty(); @@ -24,11 +23,10 @@ public boolean hasBlackJack() { void drawCard(final Card card) { cardPocket.addCard(card); - cachedScore = cardPocket.calculateScore(); } public int currentScore() { - return cachedScore; + return cardPocket.calculateScore(); } public List getCards() { From 6e3773cab0c7283ff2e45c1d4afeb9f2154a0416 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:48:21 +0900 Subject: [PATCH 20/59] =?UTF-8?q?feat:=20=EB=8C=80=EC=86=8C=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=20=EA=B5=AC=EB=B6=84=20=EC=95=88=20=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/DrawCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/view/DrawCommand.java b/src/main/java/blackjack/view/DrawCommand.java index 6d81fcd6ce..cc369f743e 100644 --- a/src/main/java/blackjack/view/DrawCommand.java +++ b/src/main/java/blackjack/view/DrawCommand.java @@ -13,7 +13,7 @@ public enum DrawCommand { public static DrawCommand from(final String command) { return Arrays.stream(values()) - .filter(it -> it.command.equals(command)) + .filter(it -> it.command.equalsIgnoreCase(command)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("y, n 만 입력 가능합니다")); } From 618f9938d5e28aa44d8da1f94b84c2cc5b084e15 Mon Sep 17 00:00:00 2001 From: Be-student Date: Thu, 9 Mar 2023 22:56:25 +0900 Subject: [PATCH 21/59] =?UTF-8?q?docs:=20=EC=A7=88=EB=AC=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/controller/DomainConverter.java | 2 ++ src/main/java/blackjack/domain/BlackJackRuleImpl.java | 5 +++++ src/main/java/blackjack/domain/card/CardPocket.java | 3 +++ src/main/java/blackjack/domain/card/DeckFactory.java | 7 +++++++ src/main/java/blackjack/domain/participant/Name.java | 1 + src/main/java/blackjack/domain/participant/Players.java | 2 ++ 6 files changed, 20 insertions(+) diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java index da2cad340a..ad48f5b7b2 100644 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -9,6 +9,8 @@ import java.util.Map; import java.util.stream.Collectors; +//이 클래스는 controller 의 역할이지만, controller 에다가 두면, 너무 많은 역할을 하게 되는 것 같아서 분리하였습니다 +//이 클래스가 단순하게 유틸리티 비슷한 클래스인데, 이대로 괜찮을지 여쭤보고 싶어요 class DomainConverter { private DomainConverter() { diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java index 33cb8ddce5..127b8793e5 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -3,6 +3,11 @@ import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; +/** + * 이 클래스가 룰이 자주 변경될 수 있기에, 인터페이스를 둔다는 점은 좋은데요 + *

+ * 사실상 한 클래스만 존재하는 상황에서, 이를 interface로 빼는 것은 별로 의미가 없을 수 있어보이는데, 어떻게 생각하시나요? + */ public class BlackJackRuleImpl implements BlackJackRule { private static final int BUST_POINT = 21; diff --git a/src/main/java/blackjack/domain/card/CardPocket.java b/src/main/java/blackjack/domain/card/CardPocket.java index 3a2c36c286..da23510c20 100644 --- a/src/main/java/blackjack/domain/card/CardPocket.java +++ b/src/main/java/blackjack/domain/card/CardPocket.java @@ -41,7 +41,10 @@ private void calculateCurrentScore() { } public int calculateScore() { + // 캐싱된 값이 없는 경우에 계산 같은 작업이 없이, 그냥 반환하고 끝 처럼 보이는데요 메서드가 괜찮아보이시나요? + //아니면 계산하는 메서드를 호출하는 시늉이라도 주는게 좋을까요? return cachedScore; + // return calculateCurrentScore(); 같은 느낌으로 주석을 남겨두는 느낌은 어떤가요? } private int countAce() { diff --git a/src/main/java/blackjack/domain/card/DeckFactory.java b/src/main/java/blackjack/domain/card/DeckFactory.java index 3ca5497cae..2525be86b3 100644 --- a/src/main/java/blackjack/domain/card/DeckFactory.java +++ b/src/main/java/blackjack/domain/card/DeckFactory.java @@ -1,5 +1,12 @@ package blackjack.domain.card; +/** + * 엑을 생성하는 기능이 생각해보니, 팩토리로 구현될 이유가 있는지도 모르겠네요 + *

+ * 그냥 Card 를 생성하는 기능을 가지고 있는 클래스로 만들어도 될 것 같아요 이렇게 바꿔보는 것은 어떻게 생각하시나요 + *

+ * public interface CardFactory { Card generate(Shape shape, Symbol symbol); } + */ public interface DeckFactory { Deck generate(); diff --git a/src/main/java/blackjack/domain/participant/Name.java b/src/main/java/blackjack/domain/participant/Name.java index 7d3b09b4c5..4d2b29d644 100644 --- a/src/main/java/blackjack/domain/participant/Name.java +++ b/src/main/java/blackjack/domain/participant/Name.java @@ -4,6 +4,7 @@ public class Name { private static final int MAX_NAME_LENGTH = 100; + //이 부분도 Name name 이런 네이밍은 어떻게 바꿔보는 게 좋을까요? getName.getName 같은 방식으로 호출될 것 같아서 애매했어요 private final String name; Name(final String name) { diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 2dd88939f6..433ae07756 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -13,6 +13,8 @@ public class Players { private static final String OVER_RANGE_MESSAGE = "사용자 수는 " + MIN_PLAYER_COUNT + " 이상 " + MAX_PLAYER_COUNT + " 이하여야 합니다. 현재 : %s 명입니다"; + //일급 컬렉션의 변수 네이밍이 고민이 되네요 ㅠㅠ Players라는 클래스가 있으니 players라는 변수명이 적절한지 모르겠습니다. + //Player 가 여러개 있으니, Players 가 되는 것이 당연한데 이런 경우에는 어떤 것을 두어야 하나요? private final List players; private Players(final List players) { From 9a4e3ab540da7e99f53b9b5e4eeca3064869c9a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=EC=9D=80=EC=9A=B0?= <80899085+be-student@users.noreply.github.com> Date: Thu, 9 Mar 2023 23:20:45 +0900 Subject: [PATCH 22/59] =?UTF-8?q?docs:=20=ED=83=80=EC=9D=B4=ED=8B=80=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 10d729dcc7..c4ba7ce963 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,10 @@ - [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) ```mermaid +--- +title: 의존성그래프 +--- graph TD -의존성그래프 BlackJackGame --> Players BlackJackGame --> Deck BlackJackGame --> Dealer From 27a8fed483ffb7413bf2c6ee195caf674cfd3f6d Mon Sep 17 00:00:00 2001 From: Be-student Date: Fri, 10 Mar 2023 00:05:51 +0900 Subject: [PATCH 23/59] =?UTF-8?q?refactor:=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/controller/DomainConverter.java | 38 +++++++------- .../blackjack/domain/BlackJackRuleImpl.java | 52 ++++++++----------- 2 files changed, 42 insertions(+), 48 deletions(-) diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java index ad48f5b7b2..e929baff13 100644 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -1,12 +1,14 @@ package blackjack.controller; +import static java.util.stream.Collectors.toMap; + import blackjack.domain.card.Card; import blackjack.domain.participant.Players; import blackjack.response.CardResponse; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; //이 클래스는 controller 의 역할이지만, controller 에다가 두면, 너무 많은 역할을 하게 되는 것 같아서 분리하였습니다 @@ -27,27 +29,25 @@ static List convertCards(final List cards) { } static Map> getPlayerCards(final Players players) { - final List playerNames = players.getPlayerNames(); - final Map> playerCards = new HashMap<>(); - for (final String playerName : playerNames) { - final List cardResponses = players.findPlayerByName(playerName) - .getCards() - .stream() - .map(CardResponse::from) - .collect(Collectors.toList()); - playerCards.put(playerName, cardResponses); - } - return playerCards; + return players.getPlayerNames().stream() + .collect(toMap( + Function.identity(), + name -> generateCardResponses(players.findPlayerByName(name).getCards()) + )); + } + + static List generateCardResponses(final List cards) { + return cards.stream() + .map(CardResponse::from) + .collect(Collectors.toList()); } static Map> convertPlayersCards(final Map> playersCards) { - return playersCards.entrySet().stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - entry -> entry.getValue().stream() - .map(CardResponse::from) - .collect(Collectors.toList()), - (oldValue, newValue) -> newValue, + return playersCards.keySet().stream() + .collect(toMap( + Function.identity(), + name -> generateCardResponses(playersCards.get(name)), + (a, b) -> a, LinkedHashMap::new )); } diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java index 127b8793e5..d310c99bff 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -16,45 +16,39 @@ public class BlackJackRuleImpl implements BlackJackRule { public ResultType calculateDealerResult(final Dealer dealer, final Player player) { //이 부분이 애매해서 리팩토링을 해보려고 했는데, 더 좋은 방법이 생각나지 않아서 일단 이렇게 구현했습니다. //enum 클래스에 BiPredicate를 추가해서 구현해보려고 했는데, enum 클래스에 메서드를 추가하는 것이 맞는지 잘 모르겠습니다. - if (isBlackJackWin(dealer, player)) { - return ResultType.BLACKJACK_WIN; + if (dealer.hasBlackJack()) { + return playWithBlackjack(player); } - if (isBlackJackLose(dealer, player)) { - return ResultType.BLACKJACK_LOSE; - } - final int dealerScore = dealer.currentScore(); - final int playerScore = player.currentScore(); - if (isTie(dealerScore, playerScore)) { - return ResultType.TIE; - } - if (isDealerWin(dealerScore, playerScore)) { - return ResultType.WIN; + if (dealer.currentScore() > BUST_POINT) { + return playWithBust(player); } - return ResultType.LOSE; - } - - private boolean isBlackJackWin(final Dealer dealer, final Player player) { - return dealer.hasBlackJack() && !player.hasBlackJack(); + return playWithScore(dealer, player); } - private boolean isBlackJackLose(final Dealer dealer, final Player player) { - return !dealer.hasBlackJack() && player.hasBlackJack(); + private ResultType playWithBlackjack(final Player player) { + if (player.hasBlackJack()) { + return ResultType.TIE; + } + return ResultType.BLACKJACK_WIN; } - private boolean isTie(final int dealerScore, final int playerScore) { - if (playerScore > BUST_POINT && dealerScore > BUST_POINT) { - return true; + private ResultType playWithBust(final Player player) { + if (player.currentScore() > BUST_POINT) { + return ResultType.TIE; + } + if (player.hasBlackJack()) { + return ResultType.BLACKJACK_LOSE; } - return playerScore == dealerScore; + return ResultType.LOSE; } - private boolean isDealerWin(final int dealerScore, final int playerScore) { - if (playerScore > BUST_POINT) { - return true; + private ResultType playWithScore(final Dealer dealer, final Player player) { + if (player.hasBlackJack()) { + return ResultType.BLACKJACK_LOSE; } - if (dealerScore > BUST_POINT) { - return false; + if (player.currentScore() > BUST_POINT || dealer.currentScore() > player.currentScore()) { + return ResultType.WIN; } - return dealerScore > playerScore; + return ResultType.LOSE; } } From 7a8079d6656dbbf4d6b35c93ddea97ab763c1d0f Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 13:44:30 +0900 Subject: [PATCH 24/59] =?UTF-8?q?refactor:=20controller=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0=20application=20=EC=97=90=EC=84=9C=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=9D=84=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 59 +++++++- .../controller/BlackJackController.java | 127 ------------------ .../blackjack/controller/DomainConverter.java | 10 +- src/main/java/blackjack/view/InputView.java | 4 + 4 files changed, 65 insertions(+), 135 deletions(-) delete mode 100644 src/main/java/blackjack/controller/BlackJackController.java diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 863b6b26f8..01e74629b1 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -1,14 +1,67 @@ package blackjack; -import blackjack.controller.BlackJackController; +import static blackjack.controller.DomainConverter.convertCard; +import static blackjack.controller.DomainConverter.convertCards; +import static blackjack.controller.DomainConverter.convertPlayersCards; +import static blackjack.controller.DomainConverter.getPlayerCards; +import static blackjack.util.Repeater.repeatUntilNoException; + +import blackjack.domain.BlackJackRuleImpl; import blackjack.domain.card.ShuffledDeckFactory; +import blackjack.service.BlackJackGame; +import blackjack.view.DrawCommand; import blackjack.view.InputView; import blackjack.view.OutputView; public class Application { public static void main(final String[] args) { - final BlackJackController blackJackController = new BlackJackController(new InputView(), new OutputView()); - blackJackController.play(new ShuffledDeckFactory()); + final InputView inputView = new InputView(); + final OutputView outputView = new OutputView(); + final BlackJackGame blackJackGame = repeatUntilNoException( + () -> BlackJackGame.of( + inputView.inputPlayerNames(), + new ShuffledDeckFactory(), + new BlackJackRuleImpl()), + outputView::printError); + for (final String playerName : blackJackGame.getPlayerNames()) { + blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName, inputView)); + } + + blackJackGame.distributeInitialCard(); + outputView.printInitialCards( + convertCard(blackJackGame.getDealerFirstCard()), + getPlayerCards(blackJackGame.getPlayers())); + + for (final String playerName : blackJackGame.getPlayerNames()) { + DrawCommand playerChoice = DrawCommand.DRAW; + while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { + playerChoice = inputPlayerChoice(playerName, inputView); + if (playerChoice == DrawCommand.DRAW) { + blackJackGame.drawPlayerCard(playerName); + } + outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); + } + } + while (blackJackGame.isDealerDrawable()) { + blackJackGame.drawDealerCard(); + outputView.printDealerCardDrawMessage(); + } + + outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), + convertCards(blackJackGame.getDealerCards())); + outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), + blackJackGame.getPlayersScores()); + outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); + } + + private static DrawCommand inputPlayerChoice(final String playerName, final InputView inputView) { + return repeatUntilNoException( + () -> inputView.inputCommand(playerName), inputView::printInputError); + } + + private static int inputPlayerMoney(final String playerName, final InputView inputView) { + return repeatUntilNoException( + () -> inputView.inputPlayerMoney(playerName), inputView::printInputError); } } diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java deleted file mode 100644 index 150ccdd6a4..0000000000 --- a/src/main/java/blackjack/controller/BlackJackController.java +++ /dev/null @@ -1,127 +0,0 @@ -package blackjack.controller; - -import static blackjack.controller.DomainConverter.convertCard; -import static blackjack.controller.DomainConverter.convertCards; -import static blackjack.controller.DomainConverter.convertPlayersCards; -import static blackjack.controller.DomainConverter.getPlayerCards; -import static blackjack.util.Repeater.repeatUntilNoException; - -import blackjack.domain.BlackJackRuleImpl; -import blackjack.domain.card.DeckFactory; -import blackjack.service.BlackJackGame; -import blackjack.view.DrawCommand; -import blackjack.view.InputView; -import blackjack.view.OutputView; -import java.util.List; - -public class BlackJackController { - - private final InputView inputView; - private final OutputView outputView; - - public BlackJackController(final InputView inputView, final OutputView outputView) { - this.inputView = inputView; - this.outputView = outputView; - } - - //이 메서드는 10라인도 훨씬 넘었고, 되게 복잡하게 되어있는데, 이렇게 두는 것이 좋은가요? - //원래대로 돌렸을 경우에, 훨씬 간단해보였던 것 같아요 -// public void play(final DeckFactory deckFactory) { -// final BlackJackGame blackJackGame = repeatUntilNoException( -// () -> BlackJackGame.of( -// inputPlayerNames(), -// deckFactory, -// new BlackJackRuleImpl()), -// outputView::printError); -// -// for (final String playerName : blackJackGame.getPlayerNames()) { -// blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName)); -// } -// -// blackJackGame.distributeInitialCard(); -// -// outputView.printInitialCards( -// convertCard(blackJackGame.getDealerFirstCard()), -// getPlayerCards(blackJackGame.getPlayers())); -// -// for (final String playerName : blackJackGame.getPlayerNames()) { -// DrawCommand playerChoice = DrawCommand.DRAW; -// while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { -// playerChoice = inputPlayerChoice(playerName); -// if (playerChoice == DrawCommand.DRAW) { -// blackJackGame.drawPlayerCard(playerName); -// } -// outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); -// } -// } -// -// while (blackJackGame.isDealerDrawable()) { -// blackJackGame.drawDealerCard(); -// outputView.printDealerCardDrawMessage(); -// } -// -// outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), -// convertCards(blackJackGame.getDealerCards())); -// outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), -// blackJackGame.getPlayersScores()); -// -// outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); -// } - - //한 메서드가 너무 길어지는 느낌이 드는 것 같은데요 이것은 어떤가요? - public void play(final DeckFactory deckFactory) { - final BlackJackGame blackJackGame = repeatUntilNoException( - () -> BlackJackGame.of( - inputPlayerNames(), - deckFactory, - new BlackJackRuleImpl()), - outputView::printError); - for (final String playerName : blackJackGame.getPlayerNames()) { - blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName)); - } - - blackJackGame.distributeInitialCard(); - outputView.printInitialCards( - convertCard(blackJackGame.getDealerFirstCard()), - getPlayerCards(blackJackGame.getPlayers())); - - for (final String playerName : blackJackGame.getPlayerNames()) { - drawPlayerCard(blackJackGame, playerName); - } - while (blackJackGame.isDealerDrawable()) { - blackJackGame.drawDealerCard(); - outputView.printDealerCardDrawMessage(); - } - - outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), - convertCards(blackJackGame.getDealerCards())); - outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), - blackJackGame.getPlayersScores()); - outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); - } - - private void drawPlayerCard(final BlackJackGame blackJackGame, final String playerName) { - DrawCommand playerChoice = DrawCommand.DRAW; - while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { - playerChoice = inputPlayerChoice(playerName); - if (playerChoice == DrawCommand.DRAW) { - blackJackGame.drawPlayerCard(playerName); - } - outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); - } - } - - private int inputPlayerMoney(final String playerName) { - return repeatUntilNoException( - () -> inputView.inputPlayerMoney(playerName), outputView::printError); - } - - private DrawCommand inputPlayerChoice(final String playerName) { - return repeatUntilNoException( - () -> inputView.inputCommand(playerName), outputView::printError); - } - - private List inputPlayerNames() { - return inputView.inputPlayerNames(); - } -} diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java index e929baff13..cc3a46d71e 100644 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -13,22 +13,22 @@ //이 클래스는 controller 의 역할이지만, controller 에다가 두면, 너무 많은 역할을 하게 되는 것 같아서 분리하였습니다 //이 클래스가 단순하게 유틸리티 비슷한 클래스인데, 이대로 괜찮을지 여쭤보고 싶어요 -class DomainConverter { +public class DomainConverter { private DomainConverter() { } - static CardResponse convertCard(final Card card) { + public static CardResponse convertCard(final Card card) { return CardResponse.from(card); } - static List convertCards(final List cards) { + public static List convertCards(final List cards) { return cards.stream() .map(CardResponse::from) .collect(Collectors.toList()); } - static Map> getPlayerCards(final Players players) { + public static Map> getPlayerCards(final Players players) { return players.getPlayerNames().stream() .collect(toMap( Function.identity(), @@ -42,7 +42,7 @@ static List generateCardResponses(final List cards) { .collect(Collectors.toList()); } - static Map> convertPlayersCards(final Map> playersCards) { + public static Map> convertPlayersCards(final Map> playersCards) { return playersCards.keySet().stream() .collect(toMap( Function.identity(), diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index ebec12b02b..f6e9ec0716 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -36,4 +36,8 @@ public int inputPlayerMoney(final String playerName) { return inputPlayerMoney(playerName); } } + + public void printInputError(final Exception e) { + System.out.println(e.getMessage()); + } } From fe7fb38d6bdb0236d333c6f41e15d6552be24803 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 13:45:20 +0900 Subject: [PATCH 25/59] =?UTF-8?q?refactor:=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=EB=AA=A8=EB=93=A0=20=EC=98=88=EC=99=B8=EB=8A=94=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=97=90=EC=84=9C=20=EB=B0=9C=EC=83=9D=ED=95=98?= =?UTF-8?q?=EA=B8=B0=EC=97=90,=20inputView=20=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 2 +- src/main/java/blackjack/view/OutputView.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 01e74629b1..578c496c62 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -23,7 +23,7 @@ public static void main(final String[] args) { inputView.inputPlayerNames(), new ShuffledDeckFactory(), new BlackJackRuleImpl()), - outputView::printError); + inputView::printInputError); for (final String playerName : blackJackGame.getPlayerNames()) { blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName, inputView)); } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 3708f4cc45..b5f3ff7e71 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -93,10 +93,6 @@ private void printFinalPlayerScore(final int score) { System.out.println(RESULT + score); } - public void printError(final Exception exception) { - System.out.println(exception.getMessage()); - } - public void printFinalMoney(final Map calculatePlayersMoney) { System.out.println(); System.out.println("## 최종 수익"); From 680486e27e1f92c583aecd2ff7d58b1542b805be Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 14:12:58 +0900 Subject: [PATCH 26/59] =?UTF-8?q?refactor:=20=EC=BA=90=EC=8B=B1=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/CardPocket.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/blackjack/domain/card/CardPocket.java b/src/main/java/blackjack/domain/card/CardPocket.java index da23510c20..4af236aeb1 100644 --- a/src/main/java/blackjack/domain/card/CardPocket.java +++ b/src/main/java/blackjack/domain/card/CardPocket.java @@ -9,7 +9,6 @@ public class CardPocket { private static final int BLACKJACK_SCORE = 21; private static final int VALUE_ACE = 10; private final List cards; - private int cachedScore; private CardPocket(final List cards) { validateCardPocket(cards); @@ -31,20 +30,17 @@ public void addCard(final Card card) { calculateCurrentScore(); } - private void calculateCurrentScore() { + private int calculateCurrentScore() { final int countOfAce = countAce(); int scoreOfCards = calculateMinimumScore(); for (int i = 0; i < countOfAce; i++) { scoreOfCards = calculateAceScore(scoreOfCards); } - cachedScore = scoreOfCards; + return scoreOfCards; } public int calculateScore() { - // 캐싱된 값이 없는 경우에 계산 같은 작업이 없이, 그냥 반환하고 끝 처럼 보이는데요 메서드가 괜찮아보이시나요? - //아니면 계산하는 메서드를 호출하는 시늉이라도 주는게 좋을까요? - return cachedScore; - // return calculateCurrentScore(); 같은 느낌으로 주석을 남겨두는 느낌은 어떤가요? + return calculateCurrentScore(); } private int countAce() { From a6dd7acc4dc36f5f461565d58ea1ee21205bdc83 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 14:13:43 +0900 Subject: [PATCH 27/59] =?UTF-8?q?refactor:=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=82=B4=EB=B6=80=20=EB=B3=80=EC=88=98=20getValue=20=EB=A1=9C?= =?UTF-8?q?=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/controller/DomainConverter.java | 2 -- .../java/blackjack/domain/BlackJackRuleImpl.java | 2 -- .../java/blackjack/domain/participant/Name.java | 13 ++++++------- .../java/blackjack/domain/participant/Player.java | 4 ++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java index cc3a46d71e..0a079024fa 100644 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -11,8 +11,6 @@ import java.util.function.Function; import java.util.stream.Collectors; -//이 클래스는 controller 의 역할이지만, controller 에다가 두면, 너무 많은 역할을 하게 되는 것 같아서 분리하였습니다 -//이 클래스가 단순하게 유틸리티 비슷한 클래스인데, 이대로 괜찮을지 여쭤보고 싶어요 public class DomainConverter { private DomainConverter() { diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java index d310c99bff..15e2415cd6 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -14,8 +14,6 @@ public class BlackJackRuleImpl implements BlackJackRule { @Override public ResultType calculateDealerResult(final Dealer dealer, final Player player) { - //이 부분이 애매해서 리팩토링을 해보려고 했는데, 더 좋은 방법이 생각나지 않아서 일단 이렇게 구현했습니다. - //enum 클래스에 BiPredicate를 추가해서 구현해보려고 했는데, enum 클래스에 메서드를 추가하는 것이 맞는지 잘 모르겠습니다. if (dealer.hasBlackJack()) { return playWithBlackjack(player); } diff --git a/src/main/java/blackjack/domain/participant/Name.java b/src/main/java/blackjack/domain/participant/Name.java index 4d2b29d644..4c53b49bff 100644 --- a/src/main/java/blackjack/domain/participant/Name.java +++ b/src/main/java/blackjack/domain/participant/Name.java @@ -4,12 +4,11 @@ public class Name { private static final int MAX_NAME_LENGTH = 100; - //이 부분도 Name name 이런 네이밍은 어떻게 바꿔보는 게 좋을까요? getName.getName 같은 방식으로 호출될 것 같아서 애매했어요 - private final String name; + private final String value; - Name(final String name) { - validateName(name); - this.name = name; + Name(final String value) { + validateName(value); + this.value = value; } private void validateName(final String name) { @@ -29,7 +28,7 @@ private void validateLength(final String name) { } } - public String getName() { - return name; + public String getValue() { + return value; } } diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 0553ad3ff9..4418943f28 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -17,11 +17,11 @@ public boolean isDrawable() { } public String getName() { - return name.getName(); + return name.getValue(); } boolean hasName(final String playerName) { - return name.getName() + return name.getValue() .equals(playerName); } } From 7cc4e181d0168fe91bc77db7620050b803266e98 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 14:14:18 +0900 Subject: [PATCH 28/59] =?UTF-8?q?docs:=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/BlackJackRuleImpl.java | 5 ----- src/main/java/blackjack/domain/participant/Players.java | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/BlackJackRuleImpl.java index 15e2415cd6..ebeb9046a1 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/BlackJackRuleImpl.java @@ -3,11 +3,6 @@ import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; -/** - * 이 클래스가 룰이 자주 변경될 수 있기에, 인터페이스를 둔다는 점은 좋은데요 - *

- * 사실상 한 클래스만 존재하는 상황에서, 이를 interface로 빼는 것은 별로 의미가 없을 수 있어보이는데, 어떻게 생각하시나요? - */ public class BlackJackRuleImpl implements BlackJackRule { private static final int BUST_POINT = 21; diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 433ae07756..6e2d86b345 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -12,9 +12,6 @@ public class Players { private static final int MIN_PLAYER_COUNT = 1; private static final String OVER_RANGE_MESSAGE = "사용자 수는 " + MIN_PLAYER_COUNT + " 이상 " + MAX_PLAYER_COUNT + " 이하여야 합니다. 현재 : %s 명입니다"; - - //일급 컬렉션의 변수 네이밍이 고민이 되네요 ㅠㅠ Players라는 클래스가 있으니 players라는 변수명이 적절한지 모르겠습니다. - //Player 가 여러개 있으니, Players 가 되는 것이 당연한데 이런 경우에는 어떤 것을 두어야 하나요? private final List players; private Players(final List players) { From 35e55fb415e7ec6fe33457da10ab11eb8790c695 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 14:24:52 +0900 Subject: [PATCH 29/59] =?UTF-8?q?refactor:=20=EB=B8=94=EB=9E=99=EC=9E=AD?= =?UTF-8?q?=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=A7=8C=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EC=84=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 2 +- .../java/blackjack/domain/{ => blackjack}/BlackJackRule.java | 2 +- .../blackjack/domain/{ => blackjack}/BlackJackRuleImpl.java | 2 +- .../java/blackjack/domain/{ => blackjack}/ResultType.java | 2 +- src/main/java/blackjack/service/BlackJackGame.java | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/blackjack/domain/{ => blackjack}/BlackJackRule.java (84%) rename src/main/java/blackjack/domain/{ => blackjack}/BlackJackRuleImpl.java (97%) rename src/main/java/blackjack/domain/{ => blackjack}/ResultType.java (96%) diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 578c496c62..488af14a65 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -6,7 +6,7 @@ import static blackjack.controller.DomainConverter.getPlayerCards; import static blackjack.util.Repeater.repeatUntilNoException; -import blackjack.domain.BlackJackRuleImpl; +import blackjack.domain.blackjack.BlackJackRuleImpl; import blackjack.domain.card.ShuffledDeckFactory; import blackjack.service.BlackJackGame; import blackjack.view.DrawCommand; diff --git a/src/main/java/blackjack/domain/BlackJackRule.java b/src/main/java/blackjack/domain/blackjack/BlackJackRule.java similarity index 84% rename from src/main/java/blackjack/domain/BlackJackRule.java rename to src/main/java/blackjack/domain/blackjack/BlackJackRule.java index d85a0b014d..c1c25f0d19 100644 --- a/src/main/java/blackjack/domain/BlackJackRule.java +++ b/src/main/java/blackjack/domain/blackjack/BlackJackRule.java @@ -1,4 +1,4 @@ -package blackjack.domain; +package blackjack.domain.blackjack; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; diff --git a/src/main/java/blackjack/domain/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/blackjack/BlackJackRuleImpl.java similarity index 97% rename from src/main/java/blackjack/domain/BlackJackRuleImpl.java rename to src/main/java/blackjack/domain/blackjack/BlackJackRuleImpl.java index ebeb9046a1..954b89dc6a 100644 --- a/src/main/java/blackjack/domain/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/blackjack/BlackJackRuleImpl.java @@ -1,4 +1,4 @@ -package blackjack.domain; +package blackjack.domain.blackjack; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; diff --git a/src/main/java/blackjack/domain/ResultType.java b/src/main/java/blackjack/domain/blackjack/ResultType.java similarity index 96% rename from src/main/java/blackjack/domain/ResultType.java rename to src/main/java/blackjack/domain/blackjack/ResultType.java index e74ed7dcc8..4022a1c485 100644 --- a/src/main/java/blackjack/domain/ResultType.java +++ b/src/main/java/blackjack/domain/blackjack/ResultType.java @@ -1,4 +1,4 @@ -package blackjack.domain; +package blackjack.domain.blackjack; public enum ResultType { BLACKJACK_WIN(1.5) { diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 5345015835..4a69dbf7d9 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -1,7 +1,7 @@ package blackjack.service; -import blackjack.domain.BlackJackRule; -import blackjack.domain.ResultType; +import blackjack.domain.blackjack.BlackJackRule; +import blackjack.domain.blackjack.ResultType; import blackjack.domain.card.Card; import blackjack.domain.card.Deck; import blackjack.domain.card.DeckFactory; From 004805915808dab85be6bd150cc2d75ccf253107 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 21:15:53 +0900 Subject: [PATCH 30/59] =?UTF-8?q?feat:=20=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EA=B0=80=20=EA=B0=96=EA=B3=A0=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EB=B2=A0=ED=8C=85=20=EA=B8=88=EC=95=A1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/BettingMoney.java | 21 ++++++++++++++++ .../domain/participant/BettingMoneyTest.java | 24 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/main/java/blackjack/domain/participant/BettingMoney.java create mode 100644 src/test/java/blackjack/domain/participant/BettingMoneyTest.java diff --git a/src/main/java/blackjack/domain/participant/BettingMoney.java b/src/main/java/blackjack/domain/participant/BettingMoney.java new file mode 100644 index 0000000000..356e7a1cfd --- /dev/null +++ b/src/main/java/blackjack/domain/participant/BettingMoney.java @@ -0,0 +1,21 @@ +package blackjack.domain.participant; + +public class BettingMoney { + + private final int value; + + BettingMoney(final int value) { + if (value < 0) { + throw new IllegalArgumentException("베팅 금액은 0보다 작을 수 없습니다."); + } + this.value = value; + } + + public int value() { + return value; + } + + int profit(final double profit) { + return (int) (value * profit); + } +} diff --git a/src/test/java/blackjack/domain/participant/BettingMoneyTest.java b/src/test/java/blackjack/domain/participant/BettingMoneyTest.java new file mode 100644 index 0000000000..bad71c1b98 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/BettingMoneyTest.java @@ -0,0 +1,24 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.Test; + +class BettingMoneyTest { + + @Test + void 음수_금액이_입력될_수_없습니댜() { + assertThatThrownBy(() -> new BettingMoney(-1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("베팅 금액은 0보다 작을 수 없습니다."); + } + + @Test + void profit() { + final BettingMoney bettingMoney = new BettingMoney(1000); + final int result = bettingMoney.profit(1); + assertThat(result) + .isEqualTo(1000); + } +} From 359f18cf3b21de47c631f27182e8a7908ffbd654 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 21:16:56 +0900 Subject: [PATCH 31/59] =?UTF-8?q?feat:=20=EB=B8=94=EB=9E=99=EC=9E=AD=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=EC=97=90=20=EC=9E=88=EB=8D=98=20=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=EA=B3=84=EC=82=B0=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20?= =?UTF-8?q?players=20=EB=A1=9C=20=EC=98=AE=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/Participants.java | 5 +++++ .../blackjack/domain/participant/Players.java | 16 ++++++++++++++++ .../java/blackjack/service/BlackJackGame.java | 5 +---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index 77ae6a5b2e..b84a814b38 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -3,6 +3,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; import java.util.List; +import java.util.Map; public class Participants { @@ -50,4 +51,8 @@ public Players getPlayers() { public List getPlayerNames() { return players.getPlayerNames(); } + + public Map calculatePlayersScore() { + return players.calculatePlayersScore(); + } } diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 6e2d86b345..6bfa31d563 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -3,7 +3,9 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; import blackjack.domain.participant.exception.PlayerNotFoundException; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class Players { @@ -91,7 +93,21 @@ public Player findPlayerByName(final String name) { .orElseThrow(PlayerNotFoundException::new); } + public List getNames() { + return players.stream() + .map(Player::getName) + .collect(Collectors.toList()); + } + public List getPlayers() { return players; } + + public Map calculatePlayersScore() { + final Map playerScore = new LinkedHashMap<>(); + for (final Player player : players) { + playerScore.put(player.getName(), player.currentScore()); + } + return playerScore; + } } diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 4a69dbf7d9..2cc601d6f9 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -90,10 +90,7 @@ public Map> getPlayersCards() { } public Map getPlayersScores() { - final Map playerScores = new LinkedHashMap<>(); - participants.getPlayers().getPlayers() - .forEach(player -> playerScores.put(player.getName(), player.currentScore())); - return playerScores; + return participants.calculatePlayersScore(); } public void addPlayerMoney(final String playerName, final int inputPlayerMoney) { From e3750dcf07a2c7f85158d7de5277fb51f87cbab8 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 21:18:03 +0900 Subject: [PATCH 32/59] =?UTF-8?q?test:=20=EB=B9=A0=EC=A7=84=20displayGener?= =?UTF-8?q?ator=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/domain/participant/BettingMoneyTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/blackjack/domain/participant/BettingMoneyTest.java b/src/test/java/blackjack/domain/participant/BettingMoneyTest.java index bad71c1b98..e8be3937ab 100644 --- a/src/test/java/blackjack/domain/participant/BettingMoneyTest.java +++ b/src/test/java/blackjack/domain/participant/BettingMoneyTest.java @@ -3,8 +3,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; import org.junit.jupiter.api.Test; +@SuppressWarnings({"NonAsciiCharacters"}) +@DisplayNameGeneration(ReplaceUnderscores.class) class BettingMoneyTest { @Test From a6c01f03c3d9e434b4f387cb919a03d17384870e Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 21:24:39 +0900 Subject: [PATCH 33/59] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A6=84=EC=9D=84=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/participant/Names.java | 49 +++++++++++++++++++ .../domain/participant/NamesTest.java | 48 ++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/main/java/blackjack/domain/participant/Names.java create mode 100644 src/test/java/blackjack/domain/participant/NamesTest.java diff --git a/src/main/java/blackjack/domain/participant/Names.java b/src/main/java/blackjack/domain/participant/Names.java new file mode 100644 index 0000000000..f7b08a7ce3 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Names.java @@ -0,0 +1,49 @@ +package blackjack.domain.participant; + +import java.util.List; +import java.util.stream.Collectors; + +public class Names { + + private static final int MAX_PLAYER_COUNT = 5; + private static final int MIN_PLAYER_COUNT = 1; + private static final String OVER_RANGE_MESSAGE = + "사용자 수는 " + MIN_PLAYER_COUNT + " 이상 " + MAX_PLAYER_COUNT + " 이하여야 합니다. 현재 : %s 명입니다"; + + private final List names; + + public Names(final List names) { + validatePlayerNames(names); + this.names = List.copyOf(names.stream() + .map(Name::new) + .collect(Collectors.toList())); + } + + private static void validatePlayerNames(final List playerNames) { + validateNull(playerNames); + validatePlayerCount(playerNames); + validateDuplicate(playerNames); + } + + private static void validateNull(final List playerNames) { + if (playerNames == null) { + throw new IllegalArgumentException("사용자 이름이 입력되지 않았습니다"); + } + } + + private static void validatePlayerCount(final List playerNames) { + if (MIN_PLAYER_COUNT > playerNames.size() || playerNames.size() > MAX_PLAYER_COUNT) { + throw new IllegalArgumentException(String.format(OVER_RANGE_MESSAGE, playerNames.size())); + } + } + + private static void validateDuplicate(final List playerNames) { + if (playerNames.stream().distinct().count() != playerNames.size()) { + throw new IllegalArgumentException("사용자의 이름이 중복됩니다."); + } + } + + List getNames() { + return names; + } +} diff --git a/src/test/java/blackjack/domain/participant/NamesTest.java b/src/test/java/blackjack/domain/participant/NamesTest.java new file mode 100644 index 0000000000..98f61e5f42 --- /dev/null +++ b/src/test/java/blackjack/domain/participant/NamesTest.java @@ -0,0 +1,48 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +@SuppressWarnings({"NonAsciiCharacters", "SpellCheckingInspection"}) +@DisplayNameGeneration(ReplaceUnderscores.class) +class NamesTest { + + private static Stream provideNames() { + return Stream.of( + Arguments.of(List.of()), + Arguments.of(List.of("pobi", "crong", "honux", "wannte", "디디", "누누")) + ); + } + + @Test + void 이름이_목록이_null_이면_예외() { + assertThatThrownBy(() -> Players.from(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사용자 이름이 입력되지 않았습니다"); + } + + @ParameterizedTest + @MethodSource("provideNames") + void 이름의_수가_0부터_5까지만_가능하다(final List playerNames) { + assertThatThrownBy(() -> Players.from(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사용자 수는 1 이상 5 이하여야 합니다. 현재 : " + playerNames.size() + " 명입니다"); + } + + @Test + void 이름이_이름이_중복되면_예외() { + final List playerNames = List.of("pobi", "pobi", "honux", "wannte", "디디"); + + assertThatThrownBy(() -> Players.from(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("사용자의 이름이 중복됩니다."); + } +} From 0672801b379fd8f1828f38a9530d1c9096913e22 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 21:32:15 +0900 Subject: [PATCH 34/59] =?UTF-8?q?refactor:=20cardResponse=20=EB=A5=BC=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=EC=97=90=EC=84=9C=20=EC=A7=81?= =?UTF-8?q?=EC=A0=91=20=EC=9D=91=EB=8B=B5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 3 +-- .../blackjack/controller/DomainConverter.java | 15 ++------------- .../participant/dto}/CardResponse.java | 2 +- .../java/blackjack/service/BlackJackGame.java | 12 +++++++++--- src/main/java/blackjack/view/OutputView.java | 2 +- 5 files changed, 14 insertions(+), 20 deletions(-) rename src/main/java/blackjack/{response => domain/participant/dto}/CardResponse.java (92%) diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 488af14a65..2e1199027c 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -2,7 +2,6 @@ import static blackjack.controller.DomainConverter.convertCard; import static blackjack.controller.DomainConverter.convertCards; -import static blackjack.controller.DomainConverter.convertPlayersCards; import static blackjack.controller.DomainConverter.getPlayerCards; import static blackjack.util.Repeater.repeatUntilNoException; @@ -50,7 +49,7 @@ public static void main(final String[] args) { outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), convertCards(blackJackGame.getDealerCards())); - outputView.printFinalStatusOfPlayers(convertPlayersCards(blackJackGame.getPlayersCards()), + outputView.printFinalStatusOfPlayers(blackJackGame.getPlayersCards(), blackJackGame.getPlayersScores()); outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); } diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java index 0a079024fa..2fa0a17fff 100644 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ b/src/main/java/blackjack/controller/DomainConverter.java @@ -4,8 +4,7 @@ import blackjack.domain.card.Card; import blackjack.domain.participant.Players; -import blackjack.response.CardResponse; -import java.util.LinkedHashMap; +import blackjack.domain.participant.dto.CardResponse; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -34,19 +33,9 @@ public static Map> getPlayerCards(final Players playe )); } - static List generateCardResponses(final List cards) { + private static List generateCardResponses(final List cards) { return cards.stream() .map(CardResponse::from) .collect(Collectors.toList()); } - - public static Map> convertPlayersCards(final Map> playersCards) { - return playersCards.keySet().stream() - .collect(toMap( - Function.identity(), - name -> generateCardResponses(playersCards.get(name)), - (a, b) -> a, - LinkedHashMap::new - )); - } } diff --git a/src/main/java/blackjack/response/CardResponse.java b/src/main/java/blackjack/domain/participant/dto/CardResponse.java similarity index 92% rename from src/main/java/blackjack/response/CardResponse.java rename to src/main/java/blackjack/domain/participant/dto/CardResponse.java index fae1cda56c..10e258a77d 100644 --- a/src/main/java/blackjack/response/CardResponse.java +++ b/src/main/java/blackjack/domain/participant/dto/CardResponse.java @@ -1,4 +1,4 @@ -package blackjack.response; +package blackjack.domain.participant.dto; import blackjack.domain.card.Card; diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 2cc601d6f9..cf320dbe60 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -9,11 +9,13 @@ import blackjack.domain.participant.Participants; import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; +import blackjack.domain.participant.dto.CardResponse; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; +import java.util.stream.Collectors; public class BlackJackGame { @@ -83,9 +85,13 @@ public List getDealerCards() { .getCards(); } - public Map> getPlayersCards() { - final Map> playerCards = new HashMap<>(); - participants.getPlayers().getPlayers().forEach(player -> playerCards.put(player.getName(), player.getCards())); + public Map> getPlayersCards() { + final Map> playerCards = new HashMap<>(); + participants.getPlayers().getPlayers().forEach(player -> playerCards.put(player.getName(), + player.getCards() + .stream() + .map(CardResponse::from) + .collect(Collectors.toList()))); return playerCards; } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index b5f3ff7e71..21d0647e2b 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,6 +1,6 @@ package blackjack.view; -import blackjack.response.CardResponse; +import blackjack.domain.participant.dto.CardResponse; import java.text.MessageFormat; import java.util.List; import java.util.Map; From 0fa0ba991fc5cddf710a2b07fbd8019775bf95f6 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 21:35:38 +0900 Subject: [PATCH 35/59] =?UTF-8?q?refactor:=20=EC=B9=B4=EB=93=9C=EB=A5=BC?= =?UTF-8?q?=20=EC=A3=BC=EC=96=B4=EC=A7=84=20=ED=98=95=ED=83=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20players?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/participant/Participants.java | 5 +++++ .../java/blackjack/domain/participant/Players.java | 14 +++++++++++++- src/main/java/blackjack/service/BlackJackGame.java | 10 +--------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index b84a814b38..981b6a5f34 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -2,6 +2,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; +import blackjack.domain.participant.dto.CardResponse; import java.util.List; import java.util.Map; @@ -55,4 +56,8 @@ public List getPlayerNames() { public Map calculatePlayersScore() { return players.calculatePlayersScore(); } + + public Map> getPlayersCards() { + return players.getPlayersCards(); + } } diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 6bfa31d563..6af479684e 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -2,7 +2,9 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; +import blackjack.domain.participant.dto.CardResponse; import blackjack.domain.participant.exception.PlayerNotFoundException; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -103,11 +105,21 @@ public List getPlayers() { return players; } - public Map calculatePlayersScore() { + Map calculatePlayersScore() { final Map playerScore = new LinkedHashMap<>(); for (final Player player : players) { playerScore.put(player.getName(), player.currentScore()); } return playerScore; } + + public Map> getPlayersCards() { + final Map> playerCards = new HashMap<>(); + players.forEach(player -> playerCards.put(player.getName(), + player.getCards() + .stream() + .map(CardResponse::from) + .collect(Collectors.toList()))); + return playerCards; + } } diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index cf320dbe60..43aaaad146 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -10,12 +10,10 @@ import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; import blackjack.domain.participant.dto.CardResponse; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; -import java.util.stream.Collectors; public class BlackJackGame { @@ -86,13 +84,7 @@ public List getDealerCards() { } public Map> getPlayersCards() { - final Map> playerCards = new HashMap<>(); - participants.getPlayers().getPlayers().forEach(player -> playerCards.put(player.getName(), - player.getCards() - .stream() - .map(CardResponse::from) - .collect(Collectors.toList()))); - return playerCards; + return participants.getPlayersCards(); } public Map getPlayersScores() { From e621337011f1ecc929c6901e78c23813a5a7d662 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 22:05:12 +0900 Subject: [PATCH 36/59] =?UTF-8?q?docs:=20=EC=95=88=20=EC=93=B0=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/DeckFactory.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/blackjack/domain/card/DeckFactory.java b/src/main/java/blackjack/domain/card/DeckFactory.java index 2525be86b3..3ca5497cae 100644 --- a/src/main/java/blackjack/domain/card/DeckFactory.java +++ b/src/main/java/blackjack/domain/card/DeckFactory.java @@ -1,12 +1,5 @@ package blackjack.domain.card; -/** - * 엑을 생성하는 기능이 생각해보니, 팩토리로 구현될 이유가 있는지도 모르겠네요 - *

- * 그냥 Card 를 생성하는 기능을 가지고 있는 클래스로 만들어도 될 것 같아요 이렇게 바꿔보는 것은 어떻게 생각하시나요 - *

- * public interface CardFactory { Card generate(Shape shape, Symbol symbol); } - */ public interface DeckFactory { Deck generate(); From 8feda9976ed3d560acf05245f9a87dd1eb237918 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 22:45:10 +0900 Subject: [PATCH 37/59] =?UTF-8?q?test:=20cardFixture=20=EC=9D=84=20?= =?UTF-8?q?=ED=86=B5=ED=95=B4=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/card/CardFixture.java | 12 +++++++ .../blackjack/domain/card/CardPocketTest.java | 32 +++++++------------ .../domain/card/CardResponseFixture.java | 15 +++++++++ .../java/blackjack/domain/card/CardTest.java | 3 +- .../domain/participant/ParticipantTest.java | 13 ++++---- 5 files changed, 48 insertions(+), 27 deletions(-) create mode 100644 src/test/java/blackjack/domain/card/CardFixture.java create mode 100644 src/test/java/blackjack/domain/card/CardResponseFixture.java diff --git a/src/test/java/blackjack/domain/card/CardFixture.java b/src/test/java/blackjack/domain/card/CardFixture.java new file mode 100644 index 0000000000..df9cdf3e31 --- /dev/null +++ b/src/test/java/blackjack/domain/card/CardFixture.java @@ -0,0 +1,12 @@ +package blackjack.domain.card; + +public class CardFixture { + + public static final Card CLOVER_ACE = new Card(Shape.CLOVER, Symbol.ACE); + public static final Card SPADE_ACE = new Card(Shape.SPADE, Symbol.ACE); + public static final Card HEART_EIGHT = new Card(Shape.HEART, Symbol.EIGHT); + public static final Card DIAMOND_TEN = new Card(Shape.DIAMOND, Symbol.TEN); + public static final Card DIAMOND_EIGHT = new Card(Shape.DIAMOND, Symbol.EIGHT); + public static final Card CLOVER_TWO = new Card(Shape.CLOVER, Symbol.TWO); + public static final Card HEART_KING = new Card(Shape.HEART, Symbol.KING); +} diff --git a/src/test/java/blackjack/domain/card/CardPocketTest.java b/src/test/java/blackjack/domain/card/CardPocketTest.java index 48c6b83bc8..387a601354 100644 --- a/src/test/java/blackjack/domain/card/CardPocketTest.java +++ b/src/test/java/blackjack/domain/card/CardPocketTest.java @@ -1,5 +1,12 @@ package blackjack.domain.card; +import static blackjack.domain.card.CardFixture.CLOVER_ACE; +import static blackjack.domain.card.CardFixture.DIAMOND_EIGHT; +import static blackjack.domain.card.CardFixture.DIAMOND_TEN; +import static blackjack.domain.card.CardFixture.HEART_EIGHT; +import static blackjack.domain.card.CardFixture.SPADE_ACE; +import static blackjack.domain.card.CardResponseFixture.CLOVER_ACE_RESPONSE; +import static blackjack.domain.card.CardResponseFixture.HEART_EIGHT_RESPONSE; import static org.assertj.core.api.Assertions.assertThat; import java.util.List; @@ -14,8 +21,7 @@ @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class CardPocketTest { - private static final List cards = List.of(new Card(Shape.CLOVER, Symbol.ACE), - new Card(Shape.HEART, Symbol.EIGHT)); + private static final List cards = List.of(CLOVER_ACE, HEART_EIGHT); private CardPocket cardPocket; @@ -34,7 +40,7 @@ void setCardPocket() { @Test void 카드_포켓에_카드_추가한_후_카드의_점수_계산() { - cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.ACE)); + cardPocket.addCard(SPADE_ACE); assertThat(cardPocket.calculateScore()) .isEqualTo(20); @@ -43,8 +49,8 @@ void setCardPocket() { @Test void 카드_포켓에_카드_두번_추가한_후_카드의_점수_계산() { - cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.TEN)); - cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.EIGHT)); + cardPocket.addCard(DIAMOND_TEN); + cardPocket.addCard(DIAMOND_EIGHT); assertThat(cardPocket.calculateScore()) .isEqualTo(27); @@ -53,21 +59,7 @@ void setCardPocket() { @Test void 카드_포켓에서_카드_가져오는_기능_추가() { assertThat(cardPocket.getCards()) - .isEqualTo(cards); - } - - @Test - void 카드_포켓에서_Ace_의_점수_계산이_11_과_1로_잘_계산된다() { - final CardPocket cardPocket = CardPocket.empty(); - cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.ACE)); - cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.TEN)); - - assertThat(cardPocket.calculateScore()) - .isEqualTo(21); - - cardPocket.addCard(new Card(Shape.DIAMOND, Symbol.ACE)); - assertThat(cardPocket.calculateScore()) - .isEqualTo(12); + .containsExactly(CLOVER_ACE_RESPONSE, HEART_EIGHT_RESPONSE); } @ParameterizedTest diff --git a/src/test/java/blackjack/domain/card/CardResponseFixture.java b/src/test/java/blackjack/domain/card/CardResponseFixture.java new file mode 100644 index 0000000000..dcd9161988 --- /dev/null +++ b/src/test/java/blackjack/domain/card/CardResponseFixture.java @@ -0,0 +1,15 @@ +package blackjack.domain.card; + +import blackjack.domain.card.dto.CardResponse; + +public class CardResponseFixture { + + public static final CardResponse SPADE_ACE_RESPONSE = CardResponse.from( + new Card(Shape.SPADE, Symbol.ACE)); + public static final CardResponse CLOVER_ACE_RESPONSE = CardResponse.from( + new Card(Shape.CLOVER, Symbol.ACE)); + public static final CardResponse HEART_EIGHT_RESPONSE = CardResponse.from( + new Card(Shape.HEART, Symbol.EIGHT)); + public static final CardResponse DIAMOND_TEN_RESPONSE = CardResponse.from( + new Card(Shape.DIAMOND, Symbol.TEN)); +} diff --git a/src/test/java/blackjack/domain/card/CardTest.java b/src/test/java/blackjack/domain/card/CardTest.java index b853886a28..9ff4636524 100644 --- a/src/test/java/blackjack/domain/card/CardTest.java +++ b/src/test/java/blackjack/domain/card/CardTest.java @@ -1,5 +1,6 @@ package blackjack.domain.card; +import static blackjack.domain.card.CardFixture.CLOVER_ACE; import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.DisplayNameGeneration; @@ -12,7 +13,7 @@ class CardTest { private final Shape shape = Shape.CLOVER; private final Symbol symbol = Symbol.ACE; - private final Card card = new Card(shape, symbol); + private final Card card = CLOVER_ACE; @Test void 카드의_Symbol을_반환한다() { diff --git a/src/test/java/blackjack/domain/participant/ParticipantTest.java b/src/test/java/blackjack/domain/participant/ParticipantTest.java index 3080047c16..89163f5c22 100644 --- a/src/test/java/blackjack/domain/participant/ParticipantTest.java +++ b/src/test/java/blackjack/domain/participant/ParticipantTest.java @@ -1,5 +1,9 @@ package blackjack.domain.participant; +import static blackjack.domain.card.CardFixture.CLOVER_ACE; +import static blackjack.domain.card.CardFixture.SPADE_ACE; +import static blackjack.domain.card.CardResponseFixture.CLOVER_ACE_RESPONSE; +import static blackjack.domain.card.CardResponseFixture.SPADE_ACE_RESPONSE; import static org.assertj.core.api.Assertions.assertThat; import blackjack.domain.card.Card; @@ -14,10 +18,6 @@ @DisplayNameGeneration(ReplaceUnderscores.class) class ParticipantTest { - private final Card[] cards = new Card[]{ - new Card(Shape.CLOVER, Symbol.ACE), - new Card(Shape.CLOVER, Symbol.ACE) - }; private Participant participant; @BeforeEach @@ -28,7 +28,7 @@ public boolean isDrawable() { return true; } }; - participant.drawInitialCard(cards[0], cards[1]); + participant.drawInitialCard(SPADE_ACE, CLOVER_ACE); } @Test @@ -50,6 +50,7 @@ public boolean isDrawable() { @Test void 참가자는_자기가_가지고_있는_카드를_확인할_수_있다() { - assertThat(participant.getCards()).containsExactly(cards); + assertThat(participant.getCards()) + .containsExactly(SPADE_ACE_RESPONSE, CLOVER_ACE_RESPONSE); } } From ed4540be15442bd134d4032d834dbca5df623d38 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 23:49:50 +0900 Subject: [PATCH 38/59] =?UTF-8?q?refactor:=20blackJackRule=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/blackjack/BlackJackRule.java | 9 --------- .../BlackJackRule.java} | 11 ++++++++--- 2 files changed, 8 insertions(+), 12 deletions(-) delete mode 100644 src/main/java/blackjack/domain/blackjack/BlackJackRule.java rename src/main/java/blackjack/domain/{blackjack/BlackJackRuleImpl.java => service/BlackJackRule.java} (77%) diff --git a/src/main/java/blackjack/domain/blackjack/BlackJackRule.java b/src/main/java/blackjack/domain/blackjack/BlackJackRule.java deleted file mode 100644 index c1c25f0d19..0000000000 --- a/src/main/java/blackjack/domain/blackjack/BlackJackRule.java +++ /dev/null @@ -1,9 +0,0 @@ -package blackjack.domain.blackjack; - -import blackjack.domain.participant.Dealer; -import blackjack.domain.participant.Player; - -public interface BlackJackRule { - - ResultType calculateDealerResult(Dealer dealer, Player player); -} diff --git a/src/main/java/blackjack/domain/blackjack/BlackJackRuleImpl.java b/src/main/java/blackjack/domain/service/BlackJackRule.java similarity index 77% rename from src/main/java/blackjack/domain/blackjack/BlackJackRuleImpl.java rename to src/main/java/blackjack/domain/service/BlackJackRule.java index 954b89dc6a..ddf2cefd15 100644 --- a/src/main/java/blackjack/domain/blackjack/BlackJackRuleImpl.java +++ b/src/main/java/blackjack/domain/service/BlackJackRule.java @@ -1,13 +1,18 @@ -package blackjack.domain.blackjack; +package blackjack.domain.service; +import blackjack.domain.blackjack.ResultType; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; -public class BlackJackRuleImpl implements BlackJackRule { +public class BlackJackRule { private static final int BUST_POINT = 21; - @Override + public int calculatePlayerProfit(final Player player, final Dealer dealer) { + final ResultType result = calculateDealerResult(dealer, player); + return (int) (player.calculateProfit(result.getPlayerProfit()) * result.getPlayerProfit()); + } + public ResultType calculateDealerResult(final Dealer dealer, final Player player) { if (dealer.hasBlackJack()) { return playWithBlackjack(player); From b4ddb0f83d5c4e55ca911545ecaa941319b31ce9 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 23:51:15 +0900 Subject: [PATCH 39/59] =?UTF-8?q?feat:=20player=20=20=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B2=A0=ED=8C=85=20=EA=B8=88=EC=95=A1=EC=9D=84=20=EC=95=8C?= =?UTF-8?q?=EA=B3=A0=20=EC=9E=88=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/participant/Player.java | 8 ++++++- .../domain/participant/PlayerTest.java | 21 ++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 4418943f28..60f87b3c3c 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -3,11 +3,13 @@ public class Player extends Participant { private final int BUST_POINT = 21; + private final BettingMoney bettingMoney; private final Name name; - Player(final String name) { + Player(final String name, final int bettingMoney) { this.name = new Name(name); + this.bettingMoney = new BettingMoney(bettingMoney); } @Override @@ -24,4 +26,8 @@ boolean hasName(final String playerName) { return name.getValue() .equals(playerName); } + + public int calculateProfit(final double profit) { + return bettingMoney.profit(profit); + } } diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 35d2caaa3a..21a79deff3 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -1,10 +1,12 @@ package blackjack.domain.participant; +import static blackjack.domain.card.CardFixture.CLOVER_ACE; +import static blackjack.domain.card.CardFixture.CLOVER_TWO; +import static blackjack.domain.card.CardFixture.HEART_EIGHT; +import static blackjack.domain.card.CardFixture.HEART_KING; import static org.assertj.core.api.Assertions.assertThat; import blackjack.domain.card.Card; -import blackjack.domain.card.Shape; -import blackjack.domain.card.Symbol; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayNameGeneration; @@ -16,17 +18,17 @@ class PlayerTest { private static final List overDrawPointCards = List.of( - new Card(Shape.CLOVER, Symbol.ACE), - new Card(Shape.HEART, Symbol.KING)); + CLOVER_ACE, + HEART_KING); private static final List underDrawPointCards = List.of( - new Card(Shape.CLOVER, Symbol.TWO), - new Card(Shape.HEART, Symbol.EIGHT)); + CLOVER_TWO, + HEART_EIGHT); private Player player; @BeforeEach void setup() { - player = new Player("pobi"); + player = new Player("pobi", 10000); } @Test @@ -43,4 +45,9 @@ void setup() { .isFalse(); } + @Test + void 플레이어는_베팅_금액을_가진다() { + assertThat(player.calculateProfit(1)) + .isEqualTo(10000); + } } From 5a188972efc6b9f6f0a92ad0c944aba549d5aa6a Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 23:56:23 +0900 Subject: [PATCH 40/59] =?UTF-8?q?feat:=20=EB=B2=A0=ED=8C=85=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/participant/Players.java | 51 ++++++++----------- .../domain/participant/PlayersTest.java | 10 ++-- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 6af479684e..5dabdcbe3b 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -2,8 +2,9 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; -import blackjack.domain.participant.dto.CardResponse; +import blackjack.domain.card.dto.CardResponse; import blackjack.domain.participant.exception.PlayerNotFoundException; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -22,40 +23,29 @@ private Players(final List players) { this.players = players; } - public static Players from(final List playerNames) { + public static Players from(final List playerNames, final List bettingMoneys) { validatePlayerNames(playerNames); - final List players = createPlayers(playerNames); + validateSize(playerNames, bettingMoneys); + final List players = createPlayers(playerNames, bettingMoneys); return new Players(players); } - private static List createPlayers(final List playerNames) { - return playerNames.stream() - .map(Player::new) - .collect(Collectors.toList()); - } - - private static void validatePlayerNames(final List playerNames) { - validateNull(playerNames); - validatePlayerCount(playerNames); - validateDuplicate(playerNames); - } - - private static void validateNull(final List playerNames) { - if (playerNames == null) { - throw new IllegalArgumentException("사용자 이름이 입력되지 않았습니다"); + private static void validateSize(final List playerNames, final List bettingMoneys) { + if (playerNames.size() != bettingMoneys.size()) { + throw new IllegalArgumentException("플레이어 이름과 베팅 금액의 수가 일치하지 않습니다."); } } - private static void validatePlayerCount(final List playerNames) { - if (MIN_PLAYER_COUNT > playerNames.size() || playerNames.size() > MAX_PLAYER_COUNT) { - throw new IllegalArgumentException(String.format(OVER_RANGE_MESSAGE, playerNames.size())); + private static List createPlayers(final List playerNames, final List bettingMoneys) { + final List players = new ArrayList<>(); + for (int i = 0; i < playerNames.size(); i++) { + players.add(new Player(playerNames.get(i), bettingMoneys.get(i))); } + return players; } - private static void validateDuplicate(final List playerNames) { - if (playerNames.stream().distinct().count() != playerNames.size()) { - throw new IllegalArgumentException("사용자의 이름이 중복됩니다."); - } + public static void validatePlayerNames(final List playerNames) { + new Names(playerNames); } void distributeInitialCards(final Deck deck) { @@ -113,13 +103,12 @@ Map calculatePlayersScore() { return playerScore; } - public Map> getPlayersCards() { + Map> getPlayersCards() { final Map> playerCards = new HashMap<>(); - players.forEach(player -> playerCards.put(player.getName(), - player.getCards() - .stream() - .map(CardResponse::from) - .collect(Collectors.toList()))); + for (final Player player : players) { + playerCards.put(player.getName(), + player.getCards()); + } return playerCards; } } diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java index 94caf40244..64343a8258 100644 --- a/src/test/java/blackjack/domain/participant/PlayersTest.java +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -20,7 +20,7 @@ class PlayerInitiatorTest { @Test void 플레이어의_목록이_null_이면_예외() { - assertThatThrownBy(() -> Players.from(null)) + assertThatThrownBy(() -> Players.from(null, null)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("사용자 이름이 입력되지 않았습니다"); } @@ -29,7 +29,7 @@ class PlayerInitiatorTest { void 플레이어의_수가_0명이면_예외() { final List playerNames = new ArrayList<>(); - assertThatThrownBy(() -> Players.from(playerNames)) + assertThatThrownBy(() -> Players.from(playerNames, List.of())) .isInstanceOf(IllegalArgumentException.class) .hasMessage("사용자 수는 1 이상 5 이하여야 합니다. 현재 : 0 명입니다"); } @@ -38,7 +38,7 @@ class PlayerInitiatorTest { void 플레이어의_수가_5명초과면_예외() { final List playerNames = List.of("pobi", "crong", "honux", "wannte", "디디", "누누"); - assertThatThrownBy(() -> Players.from(playerNames)) + assertThatThrownBy(() -> Players.from(playerNames, List.of(1, 2, 3, 4, 5, 6))) .isInstanceOf(IllegalArgumentException.class) .hasMessage("사용자 수는 1 이상 5 이하여야 합니다. 현재 : 6 명입니다"); } @@ -47,11 +47,9 @@ class PlayerInitiatorTest { void 플레이어의_이름이_중복되면_예외() { final List playerNames = List.of("pobi", "pobi", "honux", "wannte", "디디"); - assertThatThrownBy(() -> Players.from(playerNames)) + assertThatThrownBy(() -> Players.from(playerNames, List.of(1, 2, 3, 4, 5))) .isInstanceOf(IllegalArgumentException.class) .hasMessage("사용자의 이름이 중복됩니다."); } } - - } From 5126cca93254b6802b520bfe2bf50c74154caac6 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sat, 11 Mar 2023 23:58:11 +0900 Subject: [PATCH 41/59] =?UTF-8?q?fix:=20names=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=97=90=EC=84=9C=20Players=20=EB=A5=BC=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=ED=95=98=EA=B3=A0=20=EC=9E=88=EB=8D=98=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/blackjack/domain/participant/NamesTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/blackjack/domain/participant/NamesTest.java b/src/test/java/blackjack/domain/participant/NamesTest.java index 98f61e5f42..2837149fcd 100644 --- a/src/test/java/blackjack/domain/participant/NamesTest.java +++ b/src/test/java/blackjack/domain/participant/NamesTest.java @@ -24,7 +24,7 @@ private static Stream provideNames() { @Test void 이름이_목록이_null_이면_예외() { - assertThatThrownBy(() -> Players.from(null)) + assertThatThrownBy(() -> new Names(null)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("사용자 이름이 입력되지 않았습니다"); } @@ -32,7 +32,7 @@ private static Stream provideNames() { @ParameterizedTest @MethodSource("provideNames") void 이름의_수가_0부터_5까지만_가능하다(final List playerNames) { - assertThatThrownBy(() -> Players.from(playerNames)) + assertThatThrownBy(() -> new Names(playerNames)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("사용자 수는 1 이상 5 이하여야 합니다. 현재 : " + playerNames.size() + " 명입니다"); } @@ -41,7 +41,7 @@ private static Stream provideNames() { void 이름이_이름이_중복되면_예외() { final List playerNames = List.of("pobi", "pobi", "honux", "wannte", "디디"); - assertThatThrownBy(() -> Players.from(playerNames)) + assertThatThrownBy(() -> new Names(playerNames)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("사용자의 이름이 중복됩니다."); } From dd80fd63e01ba9e0b4465d44b6e4fe6ab5a812e1 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 00:03:25 +0900 Subject: [PATCH 42/59] =?UTF-8?q?refactor:=20cardPocket=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=B0=94=EB=A1=9C=20CardResponse=20=EB=A1=9C=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 15 +++--- .../blackjack/controller/DomainConverter.java | 41 --------------- .../blackjack/domain/card/CardPocket.java | 8 ++- .../domain/card/dto/CardResponse.java | 52 +++++++++++++++++++ .../blackjack/domain/participant/Dealer.java | 4 +- .../domain/participant/Participant.java | 3 +- .../domain/participant/Participants.java | 12 ++++- .../domain/participant/dto/CardResponse.java | 26 ---------- .../java/blackjack/service/BlackJackGame.java | 13 +++-- src/main/java/blackjack/view/OutputView.java | 2 +- 10 files changed, 86 insertions(+), 90 deletions(-) delete mode 100644 src/main/java/blackjack/controller/DomainConverter.java create mode 100644 src/main/java/blackjack/domain/card/dto/CardResponse.java delete mode 100644 src/main/java/blackjack/domain/participant/dto/CardResponse.java diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 2e1199027c..8ff74116e4 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -1,12 +1,9 @@ package blackjack; -import static blackjack.controller.DomainConverter.convertCard; -import static blackjack.controller.DomainConverter.convertCards; -import static blackjack.controller.DomainConverter.getPlayerCards; import static blackjack.util.Repeater.repeatUntilNoException; -import blackjack.domain.blackjack.BlackJackRuleImpl; import blackjack.domain.card.ShuffledDeckFactory; +import blackjack.domain.service.BlackJackRule; import blackjack.service.BlackJackGame; import blackjack.view.DrawCommand; import blackjack.view.InputView; @@ -21,7 +18,7 @@ public static void main(final String[] args) { () -> BlackJackGame.of( inputView.inputPlayerNames(), new ShuffledDeckFactory(), - new BlackJackRuleImpl()), + new BlackJackRule()), inputView::printInputError); for (final String playerName : blackJackGame.getPlayerNames()) { blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName, inputView)); @@ -29,8 +26,8 @@ public static void main(final String[] args) { blackJackGame.distributeInitialCard(); outputView.printInitialCards( - convertCard(blackJackGame.getDealerFirstCard()), - getPlayerCards(blackJackGame.getPlayers())); + blackJackGame.getDealerFirstCard(), + blackJackGame.getPlayersCards()); for (final String playerName : blackJackGame.getPlayerNames()) { DrawCommand playerChoice = DrawCommand.DRAW; @@ -39,7 +36,7 @@ public static void main(final String[] args) { if (playerChoice == DrawCommand.DRAW) { blackJackGame.drawPlayerCard(playerName); } - outputView.printCardStatusOfPlayer(playerName, convertCards(blackJackGame.getPlayerCards(playerName))); + outputView.printCardStatusOfPlayer(playerName, blackJackGame.getPlayerCards(playerName)); } } while (blackJackGame.isDealerDrawable()) { @@ -48,7 +45,7 @@ public static void main(final String[] args) { } outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), - convertCards(blackJackGame.getDealerCards())); + blackJackGame.getDealerCards()); outputView.printFinalStatusOfPlayers(blackJackGame.getPlayersCards(), blackJackGame.getPlayersScores()); outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); diff --git a/src/main/java/blackjack/controller/DomainConverter.java b/src/main/java/blackjack/controller/DomainConverter.java deleted file mode 100644 index 2fa0a17fff..0000000000 --- a/src/main/java/blackjack/controller/DomainConverter.java +++ /dev/null @@ -1,41 +0,0 @@ -package blackjack.controller; - -import static java.util.stream.Collectors.toMap; - -import blackjack.domain.card.Card; -import blackjack.domain.participant.Players; -import blackjack.domain.participant.dto.CardResponse; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class DomainConverter { - - private DomainConverter() { - } - - public static CardResponse convertCard(final Card card) { - return CardResponse.from(card); - } - - public static List convertCards(final List cards) { - return cards.stream() - .map(CardResponse::from) - .collect(Collectors.toList()); - } - - public static Map> getPlayerCards(final Players players) { - return players.getPlayerNames().stream() - .collect(toMap( - Function.identity(), - name -> generateCardResponses(players.findPlayerByName(name).getCards()) - )); - } - - private static List generateCardResponses(final List cards) { - return cards.stream() - .map(CardResponse::from) - .collect(Collectors.toList()); - } -} diff --git a/src/main/java/blackjack/domain/card/CardPocket.java b/src/main/java/blackjack/domain/card/CardPocket.java index 4af236aeb1..ff40f3c504 100644 --- a/src/main/java/blackjack/domain/card/CardPocket.java +++ b/src/main/java/blackjack/domain/card/CardPocket.java @@ -1,7 +1,9 @@ package blackjack.domain.card; +import blackjack.domain.card.dto.CardResponse; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class CardPocket { @@ -62,8 +64,10 @@ private int calculateAceScore(final int score) { return score + VALUE_ACE; } - public List getCards() { - return List.copyOf(cards); + public List getCards() { + return cards.stream() + .map(CardResponse::from) + .collect(Collectors.toList()); } public boolean isBlackJack() { diff --git a/src/main/java/blackjack/domain/card/dto/CardResponse.java b/src/main/java/blackjack/domain/card/dto/CardResponse.java new file mode 100644 index 0000000000..eaacb09c2a --- /dev/null +++ b/src/main/java/blackjack/domain/card/dto/CardResponse.java @@ -0,0 +1,52 @@ +package blackjack.domain.card.dto; + +import blackjack.domain.card.Card; +import java.util.Objects; + +public class CardResponse { + + private final String symbol; + private final String shape; + + private CardResponse(final String symbol, final String shape) { + this.symbol = symbol; + this.shape = shape; + } + + public static CardResponse from(final Card card) { + return new CardResponse(card.getSymbol().getName(), card.getShape().getName()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final CardResponse that = (CardResponse) o; + return Objects.equals(symbol, that.symbol) && Objects.equals(shape, that.shape); + } + + @Override + public int hashCode() { + return Objects.hash(symbol, shape); + } + + @Override + public String toString() { + return "CardResponse{" + + "symbol='" + symbol + '\'' + + ", shape='" + shape + '\'' + + '}'; + } + + public String getSymbol() { + return symbol; + } + + public String getShape() { + return shape; + } +} diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 57428dbaa8..eeb69643c9 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -1,6 +1,6 @@ package blackjack.domain.participant; -import blackjack.domain.card.Card; +import blackjack.domain.card.dto.CardResponse; public class Dealer extends Participant { @@ -12,7 +12,7 @@ public boolean isDrawable() { return currentScore <= CARD_DRAW_POINT; } - public Card getFirstCard() { + public CardResponse getFirstCard() { return getCards().get(0); } } diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 60b2b9ab31..8bbeea8a3d 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -2,6 +2,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.CardPocket; +import blackjack.domain.card.dto.CardResponse; import java.util.List; public abstract class Participant { @@ -29,7 +30,7 @@ public int currentScore() { return cardPocket.calculateScore(); } - public List getCards() { + public List getCards() { return cardPocket.getCards(); } diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index 981b6a5f34..1ac906478d 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -2,7 +2,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; -import blackjack.domain.participant.dto.CardResponse; +import blackjack.domain.card.dto.CardResponse; import java.util.List; import java.util.Map; @@ -49,6 +49,16 @@ public Players getPlayers() { return players; } + //이런 방식으로 검증을 하게 되면, 생성자에서 검증을 하기에, 로직상은 문제가 없지만 + //new Names().validate()와 같이 호출하는 것이 직관적일 수도 있을 것 같은데 어떤 방향이 좋으신가요? + public void validatePlayerNames(final List playerNames) { + new Names(playerNames); + } + + public void validateBettingMoney(final int amount) { + new BettingMoney(amount); + } + public List getPlayerNames() { return players.getPlayerNames(); } diff --git a/src/main/java/blackjack/domain/participant/dto/CardResponse.java b/src/main/java/blackjack/domain/participant/dto/CardResponse.java deleted file mode 100644 index 10e258a77d..0000000000 --- a/src/main/java/blackjack/domain/participant/dto/CardResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package blackjack.domain.participant.dto; - -import blackjack.domain.card.Card; - -public class CardResponse { - - private final String symbol; - private final String shape; - - private CardResponse(final String symbol, final String shape) { - this.symbol = symbol; - this.shape = shape; - } - - public static CardResponse from(final Card card) { - return new CardResponse(card.getSymbol().getName(), card.getShape().getName()); - } - - public String getSymbol() { - return symbol; - } - - public String getShape() { - return shape; - } -} diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java index 43aaaad146..4f78bdff88 100644 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ b/src/main/java/blackjack/service/BlackJackGame.java @@ -1,15 +1,14 @@ package blackjack.service; -import blackjack.domain.blackjack.BlackJackRule; import blackjack.domain.blackjack.ResultType; -import blackjack.domain.card.Card; import blackjack.domain.card.Deck; import blackjack.domain.card.DeckFactory; +import blackjack.domain.card.dto.CardResponse; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Participants; import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; -import blackjack.domain.participant.dto.CardResponse; +import blackjack.domain.service.BlackJackRule; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,7 +31,7 @@ public static BlackJackGame of( final List playerNames, final DeckFactory deckFactory, final BlackJackRule blackJackRule) { - return new BlackJackGame(Players.from(playerNames), deckFactory, blackJackRule); + return new BlackJackGame(Players.from(playerNames, null), deckFactory, blackJackRule); } public void distributeInitialCard() { @@ -59,7 +58,7 @@ public List getPlayerNames() { return participants.getPlayerNames(); } - public Card getDealerFirstCard() { + public CardResponse getDealerFirstCard() { return participants.getDealer().getFirstCard(); } @@ -68,7 +67,7 @@ public Players getPlayers() { } - public List getPlayerCards(final String playerName) { + public List getPlayerCards(final String playerName) { return participants.findPlayerByName(playerName) .getCards(); } @@ -78,7 +77,7 @@ public int getDealerScore() { .currentScore(); } - public List getDealerCards() { + public List getDealerCards() { return participants.getDealer() .getCards(); } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 21d0647e2b..f44b1f08bc 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,6 +1,6 @@ package blackjack.view; -import blackjack.domain.participant.dto.CardResponse; +import blackjack.domain.card.dto.CardResponse; import java.text.MessageFormat; import java.util.List; import java.util.Map; From 6559e0a396617d998dbdb4740292d2cbbcbc4525 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 01:03:56 +0900 Subject: [PATCH 43/59] =?UTF-8?q?refactor:=20blackjackGame=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 74 +++++++---- .../domain/participant/Participants.java | 49 +++++--- .../blackjack/domain/participant/Players.java | 16 +++ .../domain/service/BlackJackRule.java | 2 +- .../java/blackjack/service/BlackJackGame.java | 119 ------------------ 5 files changed, 97 insertions(+), 163 deletions(-) delete mode 100644 src/main/java/blackjack/service/BlackJackGame.java diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 8ff74116e4..7c07cd6b8e 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -2,53 +2,77 @@ import static blackjack.util.Repeater.repeatUntilNoException; +import blackjack.domain.card.Deck; import blackjack.domain.card.ShuffledDeckFactory; +import blackjack.domain.participant.Participants; +import blackjack.domain.participant.Player; import blackjack.domain.service.BlackJackRule; -import blackjack.service.BlackJackGame; import blackjack.view.DrawCommand; import blackjack.view.InputView; import blackjack.view.OutputView; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; public class Application { public static void main(final String[] args) { final InputView inputView = new InputView(); final OutputView outputView = new OutputView(); - final BlackJackGame blackJackGame = repeatUntilNoException( - () -> BlackJackGame.of( - inputView.inputPlayerNames(), - new ShuffledDeckFactory(), - new BlackJackRule()), - inputView::printInputError); - for (final String playerName : blackJackGame.getPlayerNames()) { - blackJackGame.addPlayerMoney(playerName, inputPlayerMoney(playerName, inputView)); + final List playerNames = inputPlayerNames(inputView); + final List moneys = new ArrayList<>(); + for (final String playerName : playerNames) { + inputPlayerMoney(inputView, moneys, playerName); } + final Deck deck = new ShuffledDeckFactory().generate(); + final Participants participants = Participants.of(playerNames, moneys); + participants.distributeInitialCards(deck); + outputView.printInitialCards(participants.getDealer().getFirstCard(), participants.getPlayersCards()); - blackJackGame.distributeInitialCard(); - outputView.printInitialCards( - blackJackGame.getDealerFirstCard(), - blackJackGame.getPlayersCards()); - - for (final String playerName : blackJackGame.getPlayerNames()) { + for (final String playerName : participants.getPlayerNames()) { DrawCommand playerChoice = DrawCommand.DRAW; - while (blackJackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { + while (participants.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { playerChoice = inputPlayerChoice(playerName, inputView); if (playerChoice == DrawCommand.DRAW) { - blackJackGame.drawPlayerCard(playerName); + participants.drawPlayerCard(playerName, deck.popCard()); } - outputView.printCardStatusOfPlayer(playerName, blackJackGame.getPlayerCards(playerName)); + outputView.printCardStatusOfPlayer(playerName, participants.getPlayerCards(playerName)); } } - while (blackJackGame.isDealerDrawable()) { - blackJackGame.drawDealerCard(); + while (participants.isDealerDrawable()) { + participants.drawDealerCard(deck.popCard()); outputView.printDealerCardDrawMessage(); } - outputView.printFinalStatusOfDealer(blackJackGame.getDealerScore(), - blackJackGame.getDealerCards()); - outputView.printFinalStatusOfPlayers(blackJackGame.getPlayersCards(), - blackJackGame.getPlayersScores()); - outputView.printFinalMoney(blackJackGame.calculatePlayersMoney()); + outputView.printFinalStatusOfDealer(participants.getDealerScore(), + participants.getDealerCards()); + outputView.printFinalStatusOfPlayers(participants.getPlayersCards(), + participants.getPlayersScores()); + + final Map playerMoney = new LinkedHashMap<>(); + for (final Player player : participants.getPlayers()) { + final int resultMoney = new BlackJackRule().calculatePlayerProfit(player, participants.getDealer()); + playerMoney.put(player.getName(), resultMoney); + } + outputView.printFinalMoney(playerMoney); + } + + private static List inputPlayerNames(final InputView inputView) { + return repeatUntilNoException(() -> { + final List names = inputView.inputPlayerNames(); + Participants.validatePlayerNames(names); + return names; + }, + inputView::printInputError); + } + + private static void inputPlayerMoney(final InputView inputView, final List moneys, + final String playerName) { + + final int amount = inputPlayerMoney(playerName, inputView); + Participants.validateBettingMoney(amount); + moneys.add(amount); } private static DrawCommand inputPlayerChoice(final String playerName, final InputView inputView) { diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index 1ac906478d..974f225347 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -16,15 +16,26 @@ public Participants(final Players players, final Dealer dealer) { this.dealer = dealer; } + public static Participants of(final List playerNames, final List bettingMoneys) { + return new Participants(Players.from(playerNames, bettingMoneys), new Dealer()); + } + + //이런 방식으로 검증을 하게 되면, 생성자에서 검증을 하기에, 로직상은 문제가 없지만 + //new Names().validate()와 같이 호출하는 것이 직관적일 수도 있을 것 같은데 어떤 방향이 좋으신가요? + //애그리거트 루트로 생각하다보니, 여기에 검증하는 작업을 넣었는데, 생성하는 쪽에서 검증하는 것이 불가능하기에 static으로 작성하게 되었습니다 + public static void validatePlayerNames(final List playerNames) { + new Names(playerNames); + } + + public static void validateBettingMoney(final int amount) { + new BettingMoney(amount); + } + public void distributeInitialCards(final Deck deck) { players.distributeInitialCards(deck); dealer.drawInitialCard(deck.popCard(), deck.popCard()); } - public Player findPlayerByName(final String playerName) { - return players.findPlayerByName(playerName); - } - public boolean isPlayerDrawable(final String playerName) { return players.isDrawable(playerName); } @@ -45,29 +56,31 @@ public Dealer getDealer() { return dealer; } - public Players getPlayers() { - return players; - } - - //이런 방식으로 검증을 하게 되면, 생성자에서 검증을 하기에, 로직상은 문제가 없지만 - //new Names().validate()와 같이 호출하는 것이 직관적일 수도 있을 것 같은데 어떤 방향이 좋으신가요? - public void validatePlayerNames(final List playerNames) { - new Names(playerNames); - } - - public void validateBettingMoney(final int amount) { - new BettingMoney(amount); + public List getPlayers() { + return players.getPlayers(); } public List getPlayerNames() { return players.getPlayerNames(); } - public Map calculatePlayersScore() { - return players.calculatePlayersScore(); + public List getPlayerCards(final String playerName) { + return players.getPlayerCards(playerName); } public Map> getPlayersCards() { return players.getPlayersCards(); } + + public int getDealerScore() { + return dealer.currentScore(); + } + + public List getDealerCards() { + return dealer.getCards(); + } + + public Map getPlayersScores() { + return players.calculatePlayersScore(); + } } diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 5dabdcbe3b..5835c14388 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -91,10 +91,26 @@ public List getNames() { .collect(Collectors.toList()); } + public int getPlayerProfit(final String name, final double rate) { + return players.stream() + .filter(player -> player.hasName(name)) + .findFirst() + .map(player -> player.calculateProfit(rate)) + .orElseThrow(PlayerNotFoundException::new); + } + public List getPlayers() { return players; } + public List getPlayerCards(final String playerName) { + return players.stream() + .filter(player -> player.hasName(playerName)) + .findFirst() + .map(Player::getCards) + .orElseThrow(PlayerNotFoundException::new); + } + Map calculatePlayersScore() { final Map playerScore = new LinkedHashMap<>(); for (final Player player : players) { diff --git a/src/main/java/blackjack/domain/service/BlackJackRule.java b/src/main/java/blackjack/domain/service/BlackJackRule.java index ddf2cefd15..eab8442f2a 100644 --- a/src/main/java/blackjack/domain/service/BlackJackRule.java +++ b/src/main/java/blackjack/domain/service/BlackJackRule.java @@ -13,7 +13,7 @@ public int calculatePlayerProfit(final Player player, final Dealer dealer) { return (int) (player.calculateProfit(result.getPlayerProfit()) * result.getPlayerProfit()); } - public ResultType calculateDealerResult(final Dealer dealer, final Player player) { + private ResultType calculateDealerResult(final Dealer dealer, final Player player) { if (dealer.hasBlackJack()) { return playWithBlackjack(player); } diff --git a/src/main/java/blackjack/service/BlackJackGame.java b/src/main/java/blackjack/service/BlackJackGame.java deleted file mode 100644 index 4f78bdff88..0000000000 --- a/src/main/java/blackjack/service/BlackJackGame.java +++ /dev/null @@ -1,119 +0,0 @@ -package blackjack.service; - -import blackjack.domain.blackjack.ResultType; -import blackjack.domain.card.Deck; -import blackjack.domain.card.DeckFactory; -import blackjack.domain.card.dto.CardResponse; -import blackjack.domain.participant.Dealer; -import blackjack.domain.participant.Participants; -import blackjack.domain.participant.Player; -import blackjack.domain.participant.Players; -import blackjack.domain.service.BlackJackRule; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -public class BlackJackGame { - - private final Participants participants; - private final Deck deck; - private final BlackJackRule blackJackRule; - private final Map playerMoney = new LinkedHashMap<>(); - - private BlackJackGame(final Players players, final DeckFactory deckFactory, final BlackJackRule blackJackRule) { - participants = new Participants(players, new Dealer()); - deck = deckFactory.generate(); - this.blackJackRule = blackJackRule; - } - - public static BlackJackGame of( - final List playerNames, - final DeckFactory deckFactory, - final BlackJackRule blackJackRule) { - return new BlackJackGame(Players.from(playerNames, null), deckFactory, blackJackRule); - } - - public void distributeInitialCard() { - participants.distributeInitialCards(deck); - } - - public boolean isPlayerDrawable(final String playerName) { - return participants.isPlayerDrawable(playerName); - } - - public void drawPlayerCard(final String playerName) { - participants.drawPlayerCard(playerName, deck.popCard()); - } - - public void drawDealerCard() { - participants.drawDealerCard(deck.popCard()); - } - - public boolean isDealerDrawable() { - return participants.isDealerDrawable(); - } - - public List getPlayerNames() { - return participants.getPlayerNames(); - } - - public CardResponse getDealerFirstCard() { - return participants.getDealer().getFirstCard(); - } - - public Players getPlayers() { - return participants.getPlayers(); - } - - - public List getPlayerCards(final String playerName) { - return participants.findPlayerByName(playerName) - .getCards(); - } - - public int getDealerScore() { - return participants.getDealer() - .currentScore(); - } - - public List getDealerCards() { - return participants.getDealer() - .getCards(); - } - - public Map> getPlayersCards() { - return participants.getPlayersCards(); - } - - public Map getPlayersScores() { - return participants.calculatePlayersScore(); - } - - public void addPlayerMoney(final String playerName, final int inputPlayerMoney) { - playerMoney.put(playerName, inputPlayerMoney); - } - - public Map calculatePlayersMoney() { - final Map resultPlayersMoney = new LinkedHashMap<>(); - final Dealer dealer = participants.getDealer(); - participants.getPlayers() - .getPlayers() - .forEach(calculateWinningMoney(resultPlayersMoney, dealer)); - return resultPlayersMoney; - } - - private Consumer calculateWinningMoney(final Map resultPlayersMoney, final Dealer dealer) { - return player -> { - final ResultType playerResult = blackJackRule.calculateDealerResult(dealer, player) - .getOppositeResult(); - final int betMoney = playerMoney.get(player.getName()); - final int playerWinningMoney = calculatePlayerMoney(betMoney, playerResult); - resultPlayersMoney.put(player.getName(), playerWinningMoney); - }; - } - - private int calculatePlayerMoney(final int money, final ResultType resultType) { - return (int) (money * resultType.getPlayerProfit()); - } -} From 30fad821deccab47772080ec7980724cb5c58fe2 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 01:07:42 +0900 Subject: [PATCH 44/59] =?UTF-8?q?chore:=20=EC=95=88=20=EC=93=B0=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/blackjack/ResultType.java | 37 +++---------------- .../domain/participant/BettingMoney.java | 6 +-- .../blackjack/domain/participant/Names.java | 15 ++------ .../domain/participant/Participants.java | 4 +- .../blackjack/domain/participant/Players.java | 37 +++---------------- .../domain/card/CardResponseFixture.java | 4 +- 6 files changed, 18 insertions(+), 85 deletions(-) diff --git a/src/main/java/blackjack/domain/blackjack/ResultType.java b/src/main/java/blackjack/domain/blackjack/ResultType.java index 4022a1c485..8963151495 100644 --- a/src/main/java/blackjack/domain/blackjack/ResultType.java +++ b/src/main/java/blackjack/domain/blackjack/ResultType.java @@ -1,36 +1,11 @@ package blackjack.domain.blackjack; public enum ResultType { - BLACKJACK_WIN(1.5) { - @Override - public ResultType getOppositeResult() { - return BLACKJACK_LOSE; - } - }, - WIN(1) { - @Override - public ResultType getOppositeResult() { - return LOSE; - } - }, - TIE(0) { - @Override - public ResultType getOppositeResult() { - return TIE; - } - }, - LOSE(-1) { - @Override - public ResultType getOppositeResult() { - return WIN; - } - }, - BLACKJACK_LOSE(-1) { - @Override - public ResultType getOppositeResult() { - return BLACKJACK_WIN; - } - }; + BLACKJACK_WIN(1.5), + WIN(1), + TIE(0), + LOSE(-1), + BLACKJACK_LOSE(-1); private final double playerProfit; @@ -38,8 +13,6 @@ public ResultType getOppositeResult() { this.playerProfit = playerProfit; } - public abstract ResultType getOppositeResult(); - public double getPlayerProfit() { return playerProfit; } diff --git a/src/main/java/blackjack/domain/participant/BettingMoney.java b/src/main/java/blackjack/domain/participant/BettingMoney.java index 356e7a1cfd..6782e3fd84 100644 --- a/src/main/java/blackjack/domain/participant/BettingMoney.java +++ b/src/main/java/blackjack/domain/participant/BettingMoney.java @@ -1,6 +1,6 @@ package blackjack.domain.participant; -public class BettingMoney { +class BettingMoney { private final int value; @@ -11,10 +11,6 @@ public class BettingMoney { this.value = value; } - public int value() { - return value; - } - int profit(final double profit) { return (int) (value * profit); } diff --git a/src/main/java/blackjack/domain/participant/Names.java b/src/main/java/blackjack/domain/participant/Names.java index f7b08a7ce3..845c143756 100644 --- a/src/main/java/blackjack/domain/participant/Names.java +++ b/src/main/java/blackjack/domain/participant/Names.java @@ -1,22 +1,17 @@ package blackjack.domain.participant; import java.util.List; -import java.util.stream.Collectors; -public class Names { +class Names { private static final int MAX_PLAYER_COUNT = 5; private static final int MIN_PLAYER_COUNT = 1; private static final String OVER_RANGE_MESSAGE = "사용자 수는 " + MIN_PLAYER_COUNT + " 이상 " + MAX_PLAYER_COUNT + " 이하여야 합니다. 현재 : %s 명입니다"; - private final List names; - - public Names(final List names) { + Names(final List names) { validatePlayerNames(names); - this.names = List.copyOf(names.stream() - .map(Name::new) - .collect(Collectors.toList())); + names.forEach(Name::new); } private static void validatePlayerNames(final List playerNames) { @@ -42,8 +37,4 @@ private static void validateDuplicate(final List playerNames) { throw new IllegalArgumentException("사용자의 이름이 중복됩니다."); } } - - List getNames() { - return names; - } } diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index 974f225347..b7f71ad9ff 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -11,7 +11,7 @@ public class Participants { private final Players players; private final Dealer dealer; - public Participants(final Players players, final Dealer dealer) { + private Participants(final Players players, final Dealer dealer) { this.players = players; this.dealer = dealer; } @@ -22,7 +22,7 @@ public static Participants of(final List playerNames, final List playerNames) { new Names(playerNames); } diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 5835c14388..3b931a1cfe 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -11,19 +11,15 @@ import java.util.Map; import java.util.stream.Collectors; -public class Players { +class Players { - private static final int MAX_PLAYER_COUNT = 5; - private static final int MIN_PLAYER_COUNT = 1; - private static final String OVER_RANGE_MESSAGE = - "사용자 수는 " + MIN_PLAYER_COUNT + " 이상 " + MAX_PLAYER_COUNT + " 이하여야 합니다. 현재 : %s 명입니다"; private final List players; private Players(final List players) { this.players = players; } - public static Players from(final List playerNames, final List bettingMoneys) { + static Players from(final List playerNames, final List bettingMoneys) { validatePlayerNames(playerNames); validateSize(playerNames, bettingMoneys); final List players = createPlayers(playerNames, bettingMoneys); @@ -44,7 +40,7 @@ private static List createPlayers(final List playerNames, final return players; } - public static void validatePlayerNames(final List playerNames) { + private static void validatePlayerNames(final List playerNames) { new Names(playerNames); } @@ -56,7 +52,7 @@ void distributeInitialCards(final Deck deck) { } } - public List getPlayerNames() { + List getPlayerNames() { return players.stream() .map(Player::getName) .collect(Collectors.toList()); @@ -78,32 +74,11 @@ void draw(final String playerName, final Card card) { targetPlayer.drawCard(card); } - public Player findPlayerByName(final String name) { - return players.stream() - .filter(player -> player.hasName(name)) - .findFirst() - .orElseThrow(PlayerNotFoundException::new); - } - - public List getNames() { - return players.stream() - .map(Player::getName) - .collect(Collectors.toList()); - } - - public int getPlayerProfit(final String name, final double rate) { - return players.stream() - .filter(player -> player.hasName(name)) - .findFirst() - .map(player -> player.calculateProfit(rate)) - .orElseThrow(PlayerNotFoundException::new); - } - - public List getPlayers() { + List getPlayers() { return players; } - public List getPlayerCards(final String playerName) { + List getPlayerCards(final String playerName) { return players.stream() .filter(player -> player.hasName(playerName)) .findFirst() diff --git a/src/test/java/blackjack/domain/card/CardResponseFixture.java b/src/test/java/blackjack/domain/card/CardResponseFixture.java index dcd9161988..08c4b69bd7 100644 --- a/src/test/java/blackjack/domain/card/CardResponseFixture.java +++ b/src/test/java/blackjack/domain/card/CardResponseFixture.java @@ -8,8 +8,6 @@ public class CardResponseFixture { new Card(Shape.SPADE, Symbol.ACE)); public static final CardResponse CLOVER_ACE_RESPONSE = CardResponse.from( new Card(Shape.CLOVER, Symbol.ACE)); - public static final CardResponse HEART_EIGHT_RESPONSE = CardResponse.from( + static final CardResponse HEART_EIGHT_RESPONSE = CardResponse.from( new Card(Shape.HEART, Symbol.EIGHT)); - public static final CardResponse DIAMOND_TEN_RESPONSE = CardResponse.from( - new Card(Shape.DIAMOND, Symbol.TEN)); } From 21d84e07b45279e91d95ee9932fac45e93960c79 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 01:22:57 +0900 Subject: [PATCH 45/59] =?UTF-8?q?refactor:=20card=20=EB=8C=80=EC=8B=A0=20d?= =?UTF-8?q?eck=20=EC=9D=84=20=ED=86=B5=ED=95=B4=20=EC=B5=9C=EC=B4=88=20dra?= =?UTF-8?q?w=20=EB=A5=BC=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/Participants.java | 4 ++-- .../blackjack/domain/participant/Players.java | 6 ++--- .../domain/card/NotShuffledDeckFactory.java | 22 +++++++++++++++++++ .../domain/participant/ParticipantTest.java | 8 ++++--- 4 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 src/test/java/blackjack/domain/card/NotShuffledDeckFactory.java diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index b7f71ad9ff..da44278cb9 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -1,8 +1,8 @@ package blackjack.domain.participant; import blackjack.domain.card.Card; +import blackjack.domain.card.CardResponse; import blackjack.domain.card.Deck; -import blackjack.domain.card.dto.CardResponse; import java.util.List; import java.util.Map; @@ -33,7 +33,7 @@ public static void validateBettingMoney(final int amount) { public void distributeInitialCards(final Deck deck) { players.distributeInitialCards(deck); - dealer.drawInitialCard(deck.popCard(), deck.popCard()); + dealer.drawInitialCard(deck); } public boolean isPlayerDrawable(final String playerName) { diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 3b931a1cfe..8917718c01 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -1,8 +1,8 @@ package blackjack.domain.participant; import blackjack.domain.card.Card; +import blackjack.domain.card.CardResponse; import blackjack.domain.card.Deck; -import blackjack.domain.card.dto.CardResponse; import blackjack.domain.participant.exception.PlayerNotFoundException; import java.util.ArrayList; import java.util.HashMap; @@ -46,9 +46,7 @@ private static void validatePlayerNames(final List playerNames) { void distributeInitialCards(final Deck deck) { for (final Player player : players) { - final Card firstCard = deck.popCard(); - final Card secondCard = deck.popCard(); - player.drawInitialCard(firstCard, secondCard); + player.drawInitialCard(deck); } } diff --git a/src/test/java/blackjack/domain/card/NotShuffledDeckFactory.java b/src/test/java/blackjack/domain/card/NotShuffledDeckFactory.java new file mode 100644 index 0000000000..118af60681 --- /dev/null +++ b/src/test/java/blackjack/domain/card/NotShuffledDeckFactory.java @@ -0,0 +1,22 @@ +package blackjack.domain.card; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class NotShuffledDeckFactory implements DeckFactory { + + @Override + public Deck generate() { + final List cards = generateCards(); + return new Deck(new ArrayDeque<>(cards)); + } + + private List generateCards() { + return Arrays.stream(Shape.values()) + .flatMap(shape -> Arrays.stream(Symbol.values()) + .map(symbol -> new Card(shape, symbol))) + .collect(Collectors.toList()); + } +} diff --git a/src/test/java/blackjack/domain/participant/ParticipantTest.java b/src/test/java/blackjack/domain/participant/ParticipantTest.java index 89163f5c22..db12139e62 100644 --- a/src/test/java/blackjack/domain/participant/ParticipantTest.java +++ b/src/test/java/blackjack/domain/participant/ParticipantTest.java @@ -1,12 +1,12 @@ package blackjack.domain.participant; -import static blackjack.domain.card.CardFixture.CLOVER_ACE; -import static blackjack.domain.card.CardFixture.SPADE_ACE; import static blackjack.domain.card.CardResponseFixture.CLOVER_ACE_RESPONSE; import static blackjack.domain.card.CardResponseFixture.SPADE_ACE_RESPONSE; import static org.assertj.core.api.Assertions.assertThat; import blackjack.domain.card.Card; +import blackjack.domain.card.Deck; +import blackjack.domain.card.NotShuffledDeckFactory; import blackjack.domain.card.Shape; import blackjack.domain.card.Symbol; import org.junit.jupiter.api.BeforeEach; @@ -28,7 +28,9 @@ public boolean isDrawable() { return true; } }; - participant.drawInitialCard(SPADE_ACE, CLOVER_ACE); + final NotShuffledDeckFactory deckFactory = new NotShuffledDeckFactory(); + final Deck deck = deckFactory.generate(); + participant.drawInitialCard(deck); } @Test From 1dda7c03f5f2f1df722d7403e27db827f79f564f Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 01:25:28 +0900 Subject: [PATCH 46/59] =?UTF-8?q?refactor:=20deck=20=EC=9D=84=20=ED=86=B5?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20=EC=B5=9C=EC=B4=88=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20draw=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/domain/participant/Participant.java | 9 +++++---- .../java/blackjack/domain/participant/Participants.java | 2 +- src/main/java/blackjack/domain/participant/Players.java | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 8bbeea8a3d..e7f5c916fa 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -2,6 +2,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.CardPocket; +import blackjack.domain.card.Deck; import blackjack.domain.card.dto.CardResponse; import java.util.List; @@ -13,9 +14,9 @@ public abstract class Participant { cardPocket = CardPocket.empty(); } - void drawInitialCard(final Card first, final Card second) { - drawCard(first); - drawCard(second); + void drawInitialCard(final Deck deck) { + drawCard(deck.popCard()); + drawCard(deck.popCard()); } public boolean hasBlackJack() { @@ -30,7 +31,7 @@ public int currentScore() { return cardPocket.calculateScore(); } - public List getCards() { + List getCards() { return cardPocket.getCards(); } diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index da44278cb9..a72a009adf 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -1,8 +1,8 @@ package blackjack.domain.participant; import blackjack.domain.card.Card; -import blackjack.domain.card.CardResponse; import blackjack.domain.card.Deck; +import blackjack.domain.card.dto.CardResponse; import java.util.List; import java.util.Map; diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 8917718c01..f433024132 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -1,8 +1,8 @@ package blackjack.domain.participant; import blackjack.domain.card.Card; -import blackjack.domain.card.CardResponse; import blackjack.domain.card.Deck; +import blackjack.domain.card.dto.CardResponse; import blackjack.domain.participant.exception.PlayerNotFoundException; import java.util.ArrayList; import java.util.HashMap; From 291406098aef0f99a4e4cc37c860ac3ec0d34818 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 01:27:51 +0900 Subject: [PATCH 47/59] =?UTF-8?q?refactor:=20util=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EC=97=90=20=EC=9E=88=EB=8D=98=20repeat=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20main=20=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 15 +++++++++-- src/main/java/blackjack/util/Repeater.java | 29 ---------------------- 2 files changed, 13 insertions(+), 31 deletions(-) delete mode 100644 src/main/java/blackjack/util/Repeater.java diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 7c07cd6b8e..38a1b7ab43 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -1,7 +1,5 @@ package blackjack; -import static blackjack.util.Repeater.repeatUntilNoException; - import blackjack.domain.card.Deck; import blackjack.domain.card.ShuffledDeckFactory; import blackjack.domain.participant.Participants; @@ -14,6 +12,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; public class Application { @@ -84,4 +84,15 @@ private static int inputPlayerMoney(final String playerName, final InputView inp return repeatUntilNoException( () -> inputView.inputPlayerMoney(playerName), inputView::printInputError); } + + private static T repeatUntilNoException(final Supplier supplier, + final Consumer exceptionHandler) { + while (true) { + try { + return supplier.get(); + } catch (final IllegalArgumentException e) { + exceptionHandler.accept(e); + } + } + } } diff --git a/src/main/java/blackjack/util/Repeater.java b/src/main/java/blackjack/util/Repeater.java deleted file mode 100644 index 34d121f5c6..0000000000 --- a/src/main/java/blackjack/util/Repeater.java +++ /dev/null @@ -1,29 +0,0 @@ -package blackjack.util; - -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class Repeater { - - private Repeater() { - } - - public static T repeatUntilNoException(final Supplier supplier, - final Consumer exceptionHandler) { - T result = null; - while (result == null) { - result = createOutputOrNull(supplier, exceptionHandler); - } - return result; - } - - private static T createOutputOrNull(final Supplier inputSupplier, - final Consumer exceptionHandler) { - try { - return inputSupplier.get(); - } catch (final IllegalArgumentException e) { - exceptionHandler.accept(e); - return null; - } - } -} From 7d16dcfcbfa3d99d6a064c43c833ce3ad473390c Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 01:31:03 +0900 Subject: [PATCH 48/59] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=EA=B3=84=EC=82=B0=20=EC=9E=91=EC=97=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/service/BlackJackRule.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/blackjack/domain/service/BlackJackRule.java b/src/main/java/blackjack/domain/service/BlackJackRule.java index eab8442f2a..adca4986a8 100644 --- a/src/main/java/blackjack/domain/service/BlackJackRule.java +++ b/src/main/java/blackjack/domain/service/BlackJackRule.java @@ -9,11 +9,11 @@ public class BlackJackRule { private static final int BUST_POINT = 21; public int calculatePlayerProfit(final Player player, final Dealer dealer) { - final ResultType result = calculateDealerResult(dealer, player); + final ResultType result = calculatePlayerResult(dealer, player); return (int) (player.calculateProfit(result.getPlayerProfit()) * result.getPlayerProfit()); } - private ResultType calculateDealerResult(final Dealer dealer, final Player player) { + private ResultType calculatePlayerResult(final Dealer dealer, final Player player) { if (dealer.hasBlackJack()) { return playWithBlackjack(player); } @@ -27,7 +27,7 @@ private ResultType playWithBlackjack(final Player player) { if (player.hasBlackJack()) { return ResultType.TIE; } - return ResultType.BLACKJACK_WIN; + return ResultType.BLACKJACK_LOSE; } private ResultType playWithBust(final Player player) { @@ -35,18 +35,18 @@ private ResultType playWithBust(final Player player) { return ResultType.TIE; } if (player.hasBlackJack()) { - return ResultType.BLACKJACK_LOSE; + return ResultType.BLACKJACK_WIN; } - return ResultType.LOSE; + return ResultType.WIN; } private ResultType playWithScore(final Dealer dealer, final Player player) { if (player.hasBlackJack()) { - return ResultType.BLACKJACK_LOSE; + return ResultType.BLACKJACK_WIN; } if (player.currentScore() > BUST_POINT || dealer.currentScore() > player.currentScore()) { - return ResultType.WIN; + return ResultType.LOSE; } - return ResultType.LOSE; + return ResultType.WIN; } } From 805def5e13d44c6947fc61f87af058a5d57fdbbe Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 01:33:45 +0900 Subject: [PATCH 49/59] =?UTF-8?q?fix:=20=EA=B3=84=EC=82=B0=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=20=EB=90=98=EA=B3=A0=20=EC=9E=88=EB=8D=98=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/service/BlackJackRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/service/BlackJackRule.java b/src/main/java/blackjack/domain/service/BlackJackRule.java index adca4986a8..b94e53bfd4 100644 --- a/src/main/java/blackjack/domain/service/BlackJackRule.java +++ b/src/main/java/blackjack/domain/service/BlackJackRule.java @@ -10,7 +10,7 @@ public class BlackJackRule { public int calculatePlayerProfit(final Player player, final Dealer dealer) { final ResultType result = calculatePlayerResult(dealer, player); - return (int) (player.calculateProfit(result.getPlayerProfit()) * result.getPlayerProfit()); + return (int) (player.calculateProfit(result.getPlayerProfit())); } private ResultType calculatePlayerResult(final Dealer dealer, final Player player) { From f677e7e08ba86a90012fadff8a1dcdeca17eb088 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 09:40:07 +0900 Subject: [PATCH 50/59] =?UTF-8?q?refactor:=20=EC=95=88=20=EC=93=B0?= =?UTF-8?q?=EC=9D=B4=EB=8A=94=20=EC=BA=90=EC=8A=A4=ED=8C=85=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/service/BlackJackRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/service/BlackJackRule.java b/src/main/java/blackjack/domain/service/BlackJackRule.java index b94e53bfd4..33e534f52a 100644 --- a/src/main/java/blackjack/domain/service/BlackJackRule.java +++ b/src/main/java/blackjack/domain/service/BlackJackRule.java @@ -10,7 +10,7 @@ public class BlackJackRule { public int calculatePlayerProfit(final Player player, final Dealer dealer) { final ResultType result = calculatePlayerResult(dealer, player); - return (int) (player.calculateProfit(result.getPlayerProfit())); + return (player.calculateProfit(result.getPlayerProfit())); } private ResultType calculatePlayerResult(final Dealer dealer, final Player player) { From 6df66b3ad642ff56ccb3d2c5b339f7642583bb08 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 09:40:32 +0900 Subject: [PATCH 51/59] =?UTF-8?q?feat:=20=EB=8F=88=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=8B=9C=EC=97=90=EB=8F=84=20=EB=B0=98=EB=B3=B5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 38a1b7ab43..9db062a6ff 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -23,12 +23,12 @@ public static void main(final String[] args) { final List playerNames = inputPlayerNames(inputView); final List moneys = new ArrayList<>(); for (final String playerName : playerNames) { - inputPlayerMoney(inputView, moneys, playerName); + moneys.add(inputPlayerMoney(inputView, playerName)); } final Deck deck = new ShuffledDeckFactory().generate(); final Participants participants = Participants.of(playerNames, moneys); participants.distributeInitialCards(deck); - outputView.printInitialCards(participants.getDealer().getFirstCard(), participants.getPlayersCards()); + outputView.printInitialCards(participants.getDealerFirstCard(), participants.getPlayersCards()); for (final String playerName : participants.getPlayerNames()) { DrawCommand playerChoice = DrawCommand.DRAW; @@ -67,12 +67,14 @@ private static List inputPlayerNames(final InputView inputView) { inputView::printInputError); } - private static void inputPlayerMoney(final InputView inputView, final List moneys, + private static int inputPlayerMoney(final InputView inputView, final String playerName) { - - final int amount = inputPlayerMoney(playerName, inputView); - Participants.validateBettingMoney(amount); - moneys.add(amount); + return repeatUntilNoException(() -> { + final int amount = inputView.inputPlayerMoney(playerName); + Participants.validateBettingMoney(amount); + return amount; + }, + inputView::printInputError); } private static DrawCommand inputPlayerChoice(final String playerName, final InputView inputView) { @@ -80,11 +82,6 @@ private static DrawCommand inputPlayerChoice(final String playerName, final Inpu () -> inputView.inputCommand(playerName), inputView::printInputError); } - private static int inputPlayerMoney(final String playerName, final InputView inputView) { - return repeatUntilNoException( - () -> inputView.inputPlayerMoney(playerName), inputView::printInputError); - } - private static T repeatUntilNoException(final Supplier supplier, final Consumer exceptionHandler) { while (true) { From 948dea8c3b073432a52ffd4e8434511173003fd0 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 09:40:45 +0900 Subject: [PATCH 52/59] =?UTF-8?q?feat:=20=EB=94=9C=EB=9F=AC=EC=9D=98=20?= =?UTF-8?q?=EC=B2=AB=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20aggregate=20root=20?= =?UTF-8?q?=EB=A5=BC=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/domain/participant/Participants.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/participant/Participants.java b/src/main/java/blackjack/domain/participant/Participants.java index a72a009adf..7e09e27a17 100644 --- a/src/main/java/blackjack/domain/participant/Participants.java +++ b/src/main/java/blackjack/domain/participant/Participants.java @@ -22,7 +22,8 @@ public static Participants of(final List playerNames, final List playerNames) { new Names(playerNames); } @@ -64,6 +65,10 @@ public List getPlayerNames() { return players.getPlayerNames(); } + public CardResponse getDealerFirstCard() { + return dealer.getFirstCard(); + } + public List getPlayerCards(final String playerName) { return players.getPlayerCards(playerName); } From 1a1bef8f41c2ca6d956745279d43cabf6aa01f30 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 09:52:21 +0900 Subject: [PATCH 53/59] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c4ba7ce963..82fa370423 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,35 @@ Card --> Symbol ## UI +1. 입력 + - [x] 베팅 금액을 입력받는다 +2. 출력 + - [x] 최종 수익을 출력한다 + +## 도메인 + +1. BettingMoney + - [x] 사용자에 베팅 금액을 받는다 + - [예외처리] 0 이상의 숫자인지 확인한다 + - [x] 베팅 금액에 대한 수익률을 계산한다 +2. CardPocket + - Card 와 관련된 도메인에 대한 애그리거트 루트입니다 + - 도메인 외부로 조회된 결과를 반환할 때 CardResponse 형태로 바꾸어 반환합니다 +3. Participants + - 플레이어와 딜러에 대한 애그리거트 루트입니다 + - 외부에서 발생하는 모든 조회는 Participant 를 통해 조회해야합니다 +4. ResultType + - 블랙잭 게임과 관련된 결과를 담당하는 클래스 입니다 +5. BLackjackRule + - 블랙잭 게임의 결과를 계산하는 도메인 서비스입니다 + - Player 와, Dealer 를 받아서 수익률을 계산합니다 + +## UI + 1. 입력 - 참여할 사람을 입력한다 - List으로 변환 및 반환한다 -- ## 도메인 From dbf6028a58a6c84f20ebec22f82d09b73e5e3667 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 10:07:05 +0900 Subject: [PATCH 54/59] =?UTF-8?q?chore:=20=EC=83=81=EC=88=98=EC=99=80,=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=82=AC=EC=9D=B4=EC=97=90=20=EB=B9=88?= =?UTF-8?q?=EC=B9=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/CardPocket.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/blackjack/domain/card/CardPocket.java b/src/main/java/blackjack/domain/card/CardPocket.java index ff40f3c504..f266827ef1 100644 --- a/src/main/java/blackjack/domain/card/CardPocket.java +++ b/src/main/java/blackjack/domain/card/CardPocket.java @@ -10,6 +10,7 @@ public class CardPocket { private static final int BUST_SCORE = 21; private static final int BLACKJACK_SCORE = 21; private static final int VALUE_ACE = 10; + private final List cards; private CardPocket(final List cards) { From 87d1212a3b7720887f358791a74d7dcf809287c4 Mon Sep 17 00:00:00 2001 From: Be-student Date: Sun, 12 Mar 2023 10:08:10 +0900 Subject: [PATCH 55/59] =?UTF-8?q?chore:=20=EC=83=81=EC=88=98=EC=97=90=20st?= =?UTF-8?q?atic=20keyword=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/participant/Player.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 60f87b3c3c..61cb94e0bf 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -2,7 +2,7 @@ public class Player extends Participant { - private final int BUST_POINT = 21; + private static final int BLACKJACK_SCORE = 21; private final BettingMoney bettingMoney; private final Name name; @@ -15,7 +15,7 @@ public class Player extends Participant { @Override public boolean isDrawable() { final int currentScore = currentScore(); - return currentScore < BUST_POINT; + return currentScore < BLACKJACK_SCORE; } public String getName() { From 68fa3ab1eb9a19e2f67c141dacded1c5dd32bb55 Mon Sep 17 00:00:00 2001 From: Be-student Date: Mon, 13 Mar 2023 23:24:55 +0900 Subject: [PATCH 56/59] =?UTF-8?q?feat:=20inputOutput=20=EC=97=90=EA=B2=8C?= =?UTF-8?q?=20=EC=A0=84=EB=8B=AC=ED=95=B4=EC=A3=BC=EB=8A=94=20IOView=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 예외는 여기서 출력하도록 설정했습니다 --- src/main/java/blackjack/view/IOView.java | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/java/blackjack/view/IOView.java diff --git a/src/main/java/blackjack/view/IOView.java b/src/main/java/blackjack/view/IOView.java new file mode 100644 index 0000000000..a1cda051aa --- /dev/null +++ b/src/main/java/blackjack/view/IOView.java @@ -0,0 +1,60 @@ +package blackjack.view; + +import blackjack.domain.card.dto.CardResponse; +import java.util.List; +import java.util.Map; + +public class IOView { + + private final InputView inputView; + private final OutputView outputView; + + public IOView(final InputView inputView, final OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public List inputPlayerNames() { + return inputView.inputPlayerNames(); + } + + public DrawCommand inputCommand(final String playerName) { + return inputView.inputCommand(playerName); + } + + public int inputPlayerMoney(final String playerName) { + return inputView.inputPlayerMoney(playerName); + } + + public void printInitialCards( + final CardResponse dealerCard, + final Map> playerNameToCards) { + outputView.printInitialCards(dealerCard, playerNameToCards); + } + + public void printCardStatusOfPlayer(final String planerName, final List playerCardsResponse) { + outputView.printCardStatusOfPlayer(planerName, playerCardsResponse); + } + + public void printDealerCardDrawMessage() { + outputView.printDealerCardDrawMessage(); + } + + public void printFinalStatusOfDealer(final int score, final List dealerCards) { + outputView.printFinalStatusOfDealer(score, dealerCards); + } + + public void printFinalStatusOfPlayers( + final Map> playersCardsResponse, + final Map playersScore) { + outputView.printFinalStatusOfPlayers(playersCardsResponse, playersScore); + } + + public void printFinalMoney(final Map calculatePlayersMoney) { + outputView.printFinalMoney(calculatePlayersMoney); + } + + public void printError(final Exception e) { + System.err.println(e.getMessage()); + } +} From 165c3407ac9eddf906250f8a0329a03b4a2e5a33 Mon Sep 17 00:00:00 2001 From: Be-student Date: Tue, 14 Mar 2023 00:07:33 +0900 Subject: [PATCH 57/59] =?UTF-8?q?feat:=20controller,=20game=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/Application.java | 92 ++---------------- .../controller/BlackjackController.java | 96 +++++++++++++++++++ .../{service => blackjack}/BlackJackRule.java | 9 +- .../domain/blackjack/BlackjackGame.java | 82 ++++++++++++++++ 4 files changed, 189 insertions(+), 90 deletions(-) create mode 100644 src/main/java/blackjack/controller/BlackjackController.java rename src/main/java/blackjack/domain/{service => blackjack}/BlackJackRule.java (84%) create mode 100644 src/main/java/blackjack/domain/blackjack/BlackjackGame.java diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java index 9db062a6ff..57ab2e6205 100644 --- a/src/main/java/blackjack/Application.java +++ b/src/main/java/blackjack/Application.java @@ -1,95 +1,17 @@ package blackjack; -import blackjack.domain.card.Deck; -import blackjack.domain.card.ShuffledDeckFactory; -import blackjack.domain.participant.Participants; -import blackjack.domain.participant.Player; -import blackjack.domain.service.BlackJackRule; -import blackjack.view.DrawCommand; +import blackjack.controller.BlackjackController; +import blackjack.view.IOView; import blackjack.view.InputView; import blackjack.view.OutputView; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Supplier; public class Application { public static void main(final String[] args) { - final InputView inputView = new InputView(); - final OutputView outputView = new OutputView(); - final List playerNames = inputPlayerNames(inputView); - final List moneys = new ArrayList<>(); - for (final String playerName : playerNames) { - moneys.add(inputPlayerMoney(inputView, playerName)); - } - final Deck deck = new ShuffledDeckFactory().generate(); - final Participants participants = Participants.of(playerNames, moneys); - participants.distributeInitialCards(deck); - outputView.printInitialCards(participants.getDealerFirstCard(), participants.getPlayersCards()); - - for (final String playerName : participants.getPlayerNames()) { - DrawCommand playerChoice = DrawCommand.DRAW; - while (participants.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { - playerChoice = inputPlayerChoice(playerName, inputView); - if (playerChoice == DrawCommand.DRAW) { - participants.drawPlayerCard(playerName, deck.popCard()); - } - outputView.printCardStatusOfPlayer(playerName, participants.getPlayerCards(playerName)); - } - } - while (participants.isDealerDrawable()) { - participants.drawDealerCard(deck.popCard()); - outputView.printDealerCardDrawMessage(); - } - - outputView.printFinalStatusOfDealer(participants.getDealerScore(), - participants.getDealerCards()); - outputView.printFinalStatusOfPlayers(participants.getPlayersCards(), - participants.getPlayersScores()); - - final Map playerMoney = new LinkedHashMap<>(); - for (final Player player : participants.getPlayers()) { - final int resultMoney = new BlackJackRule().calculatePlayerProfit(player, participants.getDealer()); - playerMoney.put(player.getName(), resultMoney); - } - outputView.printFinalMoney(playerMoney); - } - - private static List inputPlayerNames(final InputView inputView) { - return repeatUntilNoException(() -> { - final List names = inputView.inputPlayerNames(); - Participants.validatePlayerNames(names); - return names; - }, - inputView::printInputError); - } - - private static int inputPlayerMoney(final InputView inputView, - final String playerName) { - return repeatUntilNoException(() -> { - final int amount = inputView.inputPlayerMoney(playerName); - Participants.validateBettingMoney(amount); - return amount; - }, - inputView::printInputError); - } - - private static DrawCommand inputPlayerChoice(final String playerName, final InputView inputView) { - return repeatUntilNoException( - () -> inputView.inputCommand(playerName), inputView::printInputError); - } - - private static T repeatUntilNoException(final Supplier supplier, - final Consumer exceptionHandler) { - while (true) { - try { - return supplier.get(); - } catch (final IllegalArgumentException e) { - exceptionHandler.accept(e); - } - } + final IOView ioView = new IOView(new InputView(), new OutputView()); + final BlackjackController blackjackController = new BlackjackController(ioView); + blackjackController.init(); + blackjackController.play(); + blackjackController.calculateResult(); } } diff --git a/src/main/java/blackjack/controller/BlackjackController.java b/src/main/java/blackjack/controller/BlackjackController.java new file mode 100644 index 0000000000..625f452357 --- /dev/null +++ b/src/main/java/blackjack/controller/BlackjackController.java @@ -0,0 +1,96 @@ +package blackjack.controller; + +import blackjack.domain.blackjack.BlackjackGame; +import blackjack.domain.card.ShuffledDeckFactory; +import blackjack.domain.participant.Participants; +import blackjack.view.DrawCommand; +import blackjack.view.IOView; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class BlackjackController { + + private final IOView ioView; + private BlackjackGame blackjackGame; + + public BlackjackController(final IOView ioView) { + this.ioView = ioView; + } + + public void init() { + final List playerNames = inputPlayerNames(); + final List moneys = new ArrayList<>(); + for (final String playerName : playerNames) { + moneys.add(inputPlayerMoney(playerName)); + } + blackjackGame = BlackjackGame.of(playerNames, moneys, new ShuffledDeckFactory().generate()); + blackjackGame.distributeInitialCards(); + ioView.printInitialCards(blackjackGame.getDealerFirstCard(), blackjackGame.getPlayersCards()); + } + + public void play() { + for (final String playerName : blackjackGame.getPlayerNames()) { + drawPlayerCards(playerName); + } + while (blackjackGame.isDealerDrawable()) { + blackjackGame.drawDealerCard(); + ioView.printDealerCardDrawMessage(); + } + } + + public void calculateResult() { + ioView.printFinalStatusOfDealer(blackjackGame.getDealerScore(), blackjackGame.getDealerCards()); + ioView.printFinalStatusOfPlayers(blackjackGame.getPlayersCards(), blackjackGame.getPlayersScores()); + ioView.printFinalMoney(blackjackGame.calculateMoney()); + } + + private void drawPlayerCards(final String playerName) { + DrawCommand playerChoice = DrawCommand.DRAW; + while (blackjackGame.isPlayerDrawable(playerName) && playerChoice != DrawCommand.STAY) { + playerChoice = inputPlayerChoice(playerName); + drawPlayerCard(playerName, playerChoice); + ioView.printCardStatusOfPlayer(playerName, blackjackGame.getPlayerCards(playerName)); + } + } + + private void drawPlayerCard(final String playerName, final DrawCommand playerChoice) { + if (playerChoice == DrawCommand.DRAW) { + blackjackGame.drawPlayerCard(playerName); + } + } + + private List inputPlayerNames() { + return repeatUntilNoException(() -> { + final List names = ioView.inputPlayerNames(); + Participants.validatePlayerNames(names); + return names; + }, + ioView::printError); + } + + private int inputPlayerMoney(final String playerName) { + return repeatUntilNoException(() -> { + final int amount = ioView.inputPlayerMoney(playerName); + Participants.validateBettingMoney(amount); + return amount; + }, + ioView::printError); + } + + private DrawCommand inputPlayerChoice(final String playerName) { + return repeatUntilNoException(() -> ioView.inputCommand(playerName), ioView::printError); + } + + private T repeatUntilNoException(final Supplier supplier, + final Consumer exceptionHandler) { + while (true) { + try { + return supplier.get(); + } catch (final IllegalArgumentException e) { + exceptionHandler.accept(e); + } + } + } +} diff --git a/src/main/java/blackjack/domain/service/BlackJackRule.java b/src/main/java/blackjack/domain/blackjack/BlackJackRule.java similarity index 84% rename from src/main/java/blackjack/domain/service/BlackJackRule.java rename to src/main/java/blackjack/domain/blackjack/BlackJackRule.java index 33e534f52a..5030b0b2a5 100644 --- a/src/main/java/blackjack/domain/service/BlackJackRule.java +++ b/src/main/java/blackjack/domain/blackjack/BlackJackRule.java @@ -1,16 +1,15 @@ -package blackjack.domain.service; +package blackjack.domain.blackjack; -import blackjack.domain.blackjack.ResultType; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; -public class BlackJackRule { +class BlackJackRule { private static final int BUST_POINT = 21; - public int calculatePlayerProfit(final Player player, final Dealer dealer) { + int calculatePlayerProfit(final Player player, final Dealer dealer) { final ResultType result = calculatePlayerResult(dealer, player); - return (player.calculateProfit(result.getPlayerProfit())); + return player.calculateProfit(result.getPlayerProfit()); } private ResultType calculatePlayerResult(final Dealer dealer, final Player player) { diff --git a/src/main/java/blackjack/domain/blackjack/BlackjackGame.java b/src/main/java/blackjack/domain/blackjack/BlackjackGame.java new file mode 100644 index 0000000000..0dbc4fd94e --- /dev/null +++ b/src/main/java/blackjack/domain/blackjack/BlackjackGame.java @@ -0,0 +1,82 @@ +package blackjack.domain.blackjack; + +import blackjack.domain.card.Deck; +import blackjack.domain.card.dto.CardResponse; +import blackjack.domain.participant.Participants; +import blackjack.domain.participant.Player; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class BlackjackGame { + + private final Participants participants; + private final Deck deck; + + private BlackjackGame(final Participants participants, final Deck deck) { + this.participants = participants; + this.deck = deck; + } + + public static BlackjackGame of(final List playerNames, final List bettingMoneys, final Deck deck) { + return new BlackjackGame(Participants.of(playerNames, bettingMoneys), deck); + } + + public void distributeInitialCards() { + participants.distributeInitialCards(deck); + } + + public CardResponse getDealerFirstCard() { + return participants.getDealerFirstCard(); + } + + public Map> getPlayersCards() { + return participants.getPlayersCards(); + } + + public List getPlayerNames() { + return participants.getPlayerNames(); + } + + public boolean isDealerDrawable() { + return participants.isDealerDrawable(); + } + + public void drawDealerCard() { + participants.drawDealerCard(deck.popCard()); + } + + public boolean isPlayerDrawable(final String playerName) { + return participants.isPlayerDrawable(playerName); + } + + public List getPlayerCards(final String playerName) { + return participants.getPlayerCards(playerName); + } + + public void drawPlayerCard(final String playerName) { + participants.drawPlayerCard(playerName, deck.popCard()); + } + + public int getDealerScore() { + return participants.getDealerScore(); + } + + public List getDealerCards() { + return participants.getDealerCards(); + } + + public Map getPlayersScores() { + return participants.getPlayersScores(); + } + + public Map calculateMoney() { + final Map playerMoney = new LinkedHashMap<>(); + final BlackJackRule blackJackRule = new BlackJackRule(); + for (final Player player : participants.getPlayers()) { + final int resultMoney = blackJackRule.calculatePlayerProfit(player, participants.getDealer()); + playerMoney.put(player.getName(), resultMoney); + } + return playerMoney; + } +} From 28d1fb87748cd881f18e0477642c37bea699484e Mon Sep 17 00:00:00 2001 From: Be-student Date: Tue, 14 Mar 2023 00:15:58 +0900 Subject: [PATCH 58/59] =?UTF-8?q?chore:=20=EC=A4=84=EB=B0=94=EA=BF=88=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/participant/Player.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 61cb94e0bf..61ef2fb9f9 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -3,8 +3,8 @@ public class Player extends Participant { private static final int BLACKJACK_SCORE = 21; + private final BettingMoney bettingMoney; - private final Name name; Player(final String name, final int bettingMoney) { From 40d04b286862ccf44cb137e48a890c9140569fc8 Mon Sep 17 00:00:00 2001 From: Be-student Date: Tue, 14 Mar 2023 00:23:23 +0900 Subject: [PATCH 59/59] =?UTF-8?q?feat:=20player=EC=A0=95=EB=B3=B4=EB=A5=BC?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/participant/Player.java | 14 ++++++------- .../domain/participant/PlayerInfo.java | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 src/main/java/blackjack/domain/participant/PlayerInfo.java diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 61ef2fb9f9..f3a137180a 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -3,13 +3,11 @@ public class Player extends Participant { private static final int BLACKJACK_SCORE = 21; - - private final BettingMoney bettingMoney; - private final Name name; + + private final PlayerInfo playerInfo; Player(final String name, final int bettingMoney) { - this.name = new Name(name); - this.bettingMoney = new BettingMoney(bettingMoney); + playerInfo = new PlayerInfo(name, bettingMoney); } @Override @@ -19,15 +17,15 @@ public boolean isDrawable() { } public String getName() { - return name.getValue(); + return playerInfo.getName().getValue(); } boolean hasName(final String playerName) { - return name.getValue() + return playerInfo.getName().getValue() .equals(playerName); } public int calculateProfit(final double profit) { - return bettingMoney.profit(profit); + return playerInfo.getBettingMoney().profit(profit); } } diff --git a/src/main/java/blackjack/domain/participant/PlayerInfo.java b/src/main/java/blackjack/domain/participant/PlayerInfo.java new file mode 100644 index 0000000000..8ad7c6426c --- /dev/null +++ b/src/main/java/blackjack/domain/participant/PlayerInfo.java @@ -0,0 +1,20 @@ +package blackjack.domain.participant; + +public class PlayerInfo { + + private final Name name; + private final BettingMoney bettingMoney; + + public PlayerInfo(final String name, final int bettingMoney) { + this.name = new Name(name); + this.bettingMoney = new BettingMoney(bettingMoney); + } + + public Name getName() { + return name; + } + + public BettingMoney getBettingMoney() { + return bettingMoney; + } +}