From 87b8cad10a3689640df2cf2c5c4ab6800db7770b Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 08:45:17 +0900 Subject: [PATCH 01/98] =?UTF-8?q?refactor(Hand):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/card/Hand.java | 30 ++++++++++++------- .../java/domain/participant/Participant.java | 2 +- src/test/java/domain/card/HandTest.java | 6 ++-- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/main/java/domain/card/Hand.java b/src/main/java/domain/card/Hand.java index bfdc980476..4888c5019f 100644 --- a/src/main/java/domain/card/Hand.java +++ b/src/main/java/domain/card/Hand.java @@ -17,19 +17,27 @@ public void addCard(Card card) { cards.add(card); } - public int calculateScore() { - int score = cards.stream() - .map(Card::getScore) - .reduce(0, Integer::sum); - int aceCount = cards.stream() - .filter(Card::isAce) - .toList() - .size(); + public int calculateTotalScore() { + int baseScore = calculateBaseScore(); + int aceCount = calculateAceCount(); - return calculateScoreWithBestAce(score, aceCount); + return calculateTotalScoreWithAceCalculation(baseScore, aceCount); } - private int calculateScoreWithBestAce(int score, int aceCount) { + private int calculateAceCount() { + return cards.stream() + .filter(Card::isAce) + .toList() + .size(); + } + + private Integer calculateBaseScore() { + return cards.stream() + .map(Card::getScore) + .reduce(0, Integer::sum); + } + + private int calculateTotalScoreWithAceCalculation(int score, int aceCount) { while (score > BLACKJACK_SCORE && aceCount > 0) { score -= 10; aceCount--; @@ -39,7 +47,7 @@ private int calculateScoreWithBestAce(int score, int aceCount) { } public boolean isBust() { - return calculateScore() > BLACKJACK_SCORE; + return calculateTotalScore() > BLACKJACK_SCORE; } public Card getFirstCard() { diff --git a/src/main/java/domain/participant/Participant.java b/src/main/java/domain/participant/Participant.java index d658225560..23d3a8f296 100644 --- a/src/main/java/domain/participant/Participant.java +++ b/src/main/java/domain/participant/Participant.java @@ -21,7 +21,7 @@ public boolean isBust() { } public int calculateScore() { - return hand.calculateScore(); + return hand.calculateTotalScore(); } public List getHand() { diff --git a/src/test/java/domain/card/HandTest.java b/src/test/java/domain/card/HandTest.java index 20506b4c07..6422145a9a 100644 --- a/src/test/java/domain/card/HandTest.java +++ b/src/test/java/domain/card/HandTest.java @@ -64,7 +64,7 @@ class Success { hand.addCard(new Card(Rank.THREE, Suit.SPADE)); // when - int actual = hand.calculateScore(); + int actual = hand.calculateTotalScore(); // then assertThat(actual).isEqualTo(13); @@ -80,7 +80,7 @@ class Success { hand.addCard(new Card(Rank.THREE, Suit.DIAMOND)); // when - int actual = hand.calculateScore(); + int actual = hand.calculateTotalScore(); // then assertThat(actual).isEqualTo(14); @@ -96,7 +96,7 @@ class Success { hand.addCard(new Card(Rank.NINE, Suit.DIAMOND)); // when - int actual = hand.calculateScore(); + int actual = hand.calculateTotalScore(); // then assertThat(actual).isEqualTo(21); From 1b1c96612daebb4f67fb612363973aa8e5cdaf6d Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 08:46:11 +0900 Subject: [PATCH 02/98] =?UTF-8?q?refactor(HitOrStand):=20domain.game=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=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/controller/BlackjackController.java | 2 +- src/main/java/domain/game/BlackjackGameManager.java | 1 - src/main/java/{constant => domain/game}/HitOrStand.java | 2 +- src/test/java/constant/HitOrStandTest.java | 1 + src/test/java/domain/game/BlackjackGameManagerTest.java | 1 - 5 files changed, 3 insertions(+), 4 deletions(-) rename src/main/java/{constant => domain/game}/HitOrStand.java (97%) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index 9a53ca385a..885c202f05 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -1,6 +1,6 @@ package controller; -import constant.HitOrStand; +import domain.game.HitOrStand; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 58c67dc814..297eefe6f7 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -1,6 +1,5 @@ package domain.game; -import constant.HitOrStand; import constant.Result; import domain.card.Card; import domain.card.CardMachine; diff --git a/src/main/java/constant/HitOrStand.java b/src/main/java/domain/game/HitOrStand.java similarity index 97% rename from src/main/java/constant/HitOrStand.java rename to src/main/java/domain/game/HitOrStand.java index 50502f919e..5334c894e4 100644 --- a/src/main/java/constant/HitOrStand.java +++ b/src/main/java/domain/game/HitOrStand.java @@ -1,4 +1,4 @@ -package constant; +package domain.game; import exception.BlackjackException; import java.util.Arrays; diff --git a/src/test/java/constant/HitOrStandTest.java b/src/test/java/constant/HitOrStandTest.java index 8b8f50a7dd..1228ae2c1d 100644 --- a/src/test/java/constant/HitOrStandTest.java +++ b/src/test/java/constant/HitOrStandTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; +import domain.game.HitOrStand; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; diff --git a/src/test/java/domain/game/BlackjackGameManagerTest.java b/src/test/java/domain/game/BlackjackGameManagerTest.java index 1e5983b022..5065f0a569 100644 --- a/src/test/java/domain/game/BlackjackGameManagerTest.java +++ b/src/test/java/domain/game/BlackjackGameManagerTest.java @@ -4,7 +4,6 @@ import dto.BlackjackResultDto; import factory.BlackjackControllerFactory; -import constant.HitOrStand; import domain.card.Rank; import constant.Result; import domain.card.Suit; From a7aa54b717138a9d6354ecc70abd3eec3e7994f9 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 08:46:35 +0900 Subject: [PATCH 03/98] =?UTF-8?q?refactor(Result):=20domain.game=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=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/domain/game/BlackjackGameManager.java | 1 - src/main/java/{constant => domain/game}/Result.java | 2 +- src/main/java/dto/PlayerStatisticDto.java | 2 +- src/main/java/view/OutputView.java | 2 +- src/test/java/domain/game/BlackjackGameManagerTest.java | 1 - 5 files changed, 3 insertions(+), 5 deletions(-) rename src/main/java/{constant => domain/game}/Result.java (91%) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 297eefe6f7..10d304edc6 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -1,6 +1,5 @@ package domain.game; -import constant.Result; import domain.card.Card; import domain.card.CardMachine; import domain.participant.Dealer; diff --git a/src/main/java/constant/Result.java b/src/main/java/domain/game/Result.java similarity index 91% rename from src/main/java/constant/Result.java rename to src/main/java/domain/game/Result.java index 087eca88b0..6947e3adac 100644 --- a/src/main/java/constant/Result.java +++ b/src/main/java/domain/game/Result.java @@ -1,4 +1,4 @@ -package constant; +package domain.game; public enum Result { WIN("승"), diff --git a/src/main/java/dto/PlayerStatisticDto.java b/src/main/java/dto/PlayerStatisticDto.java index 0e1019725e..7b58c5c6ab 100644 --- a/src/main/java/dto/PlayerStatisticDto.java +++ b/src/main/java/dto/PlayerStatisticDto.java @@ -1,6 +1,6 @@ package dto; -import constant.Result; +import domain.game.Result; import domain.participant.Player; public record PlayerStatisticDto( diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 8e06f12872..e43f9af667 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,6 +1,6 @@ package view; -import constant.Result; +import domain.game.Result; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.DealerStatisticDto; diff --git a/src/test/java/domain/game/BlackjackGameManagerTest.java b/src/test/java/domain/game/BlackjackGameManagerTest.java index 5065f0a569..4c431d8ff5 100644 --- a/src/test/java/domain/game/BlackjackGameManagerTest.java +++ b/src/test/java/domain/game/BlackjackGameManagerTest.java @@ -5,7 +5,6 @@ import dto.BlackjackResultDto; import factory.BlackjackControllerFactory; import domain.card.Rank; -import constant.Result; import domain.card.Suit; import domain.card.Card; import dto.BlackjackStatisticsDto; From a6539dcfbb45ee7f3691bfb6c5af7a09e86d44a7 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 09:01:42 +0900 Subject: [PATCH 04/98] =?UTF-8?q?refactor(Hand):=20REDUCED=5FSCORE=5FFROM?= =?UTF-8?q?=5FACE=20=EC=83=81=EC=88=98=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/domain/card/Hand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/card/Hand.java b/src/main/java/domain/card/Hand.java index 4888c5019f..3a28afdd70 100644 --- a/src/main/java/domain/card/Hand.java +++ b/src/main/java/domain/card/Hand.java @@ -6,6 +6,7 @@ public class Hand { private static final int BLACKJACK_SCORE = 21; + private static final int REDUCED_SCORE_FROM_ACE = 10; private final List cards; @@ -39,7 +40,7 @@ private Integer calculateBaseScore() { private int calculateTotalScoreWithAceCalculation(int score, int aceCount) { while (score > BLACKJACK_SCORE && aceCount > 0) { - score -= 10; + score -= REDUCED_SCORE_FROM_ACE; aceCount--; } From caba72c7f25278abe4700386754b759295444535 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 15:00:02 +0900 Subject: [PATCH 05/98] =?UTF-8?q?refactor(BlackjackGameManager):=20Dealer?= =?UTF-8?q?=EB=A5=BC=20=EA=B0=80=EC=A0=B8=EC=98=A4=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EA=B3=A0=20Participants=EC=9D=98=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=ED=98=B8=EC=B6=9C=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/BlackjackController.java | 2 +- .../domain/game/BlackjackGameManager.java | 31 ++++++------------- .../java/domain/participant/Participants.java | 29 +++++++++++++++++ src/main/java/domain/participant/Players.java | 17 +++++++++- .../domain/game/BlackjackGameManagerTest.java | 22 ++++++------- 5 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index 885c202f05..96aaaf8a8a 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -46,7 +46,7 @@ private void initializeGame() { private void inputPlayers() { List input = Parser.parseInput(inputView.inputPlayers()); - blackjackGameManager.createPlayers(input); + blackjackGameManager.createParticipants(input); } private void inputHitOrStandOnPlayer() { diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 10d304edc6..7f5e489bcd 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -5,7 +5,6 @@ import domain.participant.Dealer; import domain.participant.Participants; import domain.participant.Player; -import domain.participant.Players; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.DealerStatisticDto; @@ -23,25 +22,17 @@ public BlackjackGameManager() { this.cardMachine = new CardMachine(); } - public void createPlayers(List names) { - Dealer dealer = new Dealer(); - Players players = new Players(names); - participants = new Participants(dealer, players); + public void createParticipants(List names) { + participants = Participants.from(names); } public void drawInitialCards() { - participants.dealer().addCard(drawCard()); - participants.dealer().addCard(drawCard()); - for (Player player : participants.players().getPlayers()) { - player.addCard(drawCard()); - player.addCard(drawCard()); - } + participants.drawInitialCards(this::drawCard); } public boolean drawDealerCard() { - Dealer dealer = participants.dealer(); - if (dealer.shouldHit()) { - dealer.addCard(drawCard()); + if (participants.dealerShouldHit()) { + participants.drawCardsByDealer(this::drawCard); return true; } @@ -53,13 +44,11 @@ public Card drawCard() { } public ParticipantDto generateInitialDealerDto() { - Dealer dealer = participants.dealer(); - return ParticipantDto.from(dealer, true); + return ParticipantDto.from(participants.dealer(), true); } public ParticipantDto generateDealerDto() { - Dealer dealer = participants.dealer(); - return ParticipantDto.from(dealer); + return ParticipantDto.from(participants.dealer()); } public List generatePlayerDtoList() { @@ -90,10 +79,9 @@ public BlackjackStatisticsDto getBlackjackStatistics() { } public List calculatePlayerResults() { - Dealer dealer = participants.dealer(); List playerStatisticDtoList = new ArrayList<>(); for (Player player : participants.players().getPlayers()) { - Result result = calculatePlayerResult(dealer, player); + Result result = calculatePlayerResult(participants.dealer(), player); playerStatisticDtoList.add(PlayerStatisticDto.of(player, result)); } return playerStatisticDtoList; @@ -123,8 +111,7 @@ private int judgeResult(Result result, Result playerResult) { } public ParticipantDto updatePlayer(String name) { - Player player = participants.getPlayer(name); - player.addCard(drawCard()); + Player player = participants.drawCardsByPlayer(name, this::drawCard); return ParticipantDto.from(player); } diff --git a/src/main/java/domain/participant/Participants.java b/src/main/java/domain/participant/Participants.java index 7147bb8f4a..ac79813dfd 100644 --- a/src/main/java/domain/participant/Participants.java +++ b/src/main/java/domain/participant/Participants.java @@ -1,7 +1,36 @@ package domain.participant; +import domain.card.Card; +import java.util.List; +import java.util.function.Supplier; + public record Participants(Dealer dealer, Players players) { + public static Participants from(List names) { + Dealer dealer = new Dealer(); + Players players = new Players(names); + return new Participants(dealer, players); + } + + public boolean dealerShouldHit() { + return dealer.shouldHit(); + } + + public void drawInitialCards(Supplier cardSupplier) { + dealer.addCard(cardSupplier.get()); + dealer.addCard(cardSupplier.get()); + players.drawInitialCards(cardSupplier); + } + + public void drawCardsByDealer(Supplier cardSupplier) { + dealer.addCard(cardSupplier.get()); + } + + public Player drawCardsByPlayer(String name, Supplier cardSupplier) { + players.addCard(name, cardSupplier.get()); + return players.getPlayer(name); + } + public Player getPlayer(String name) { return players.getPlayer(name); } diff --git a/src/main/java/domain/participant/Players.java b/src/main/java/domain/participant/Players.java index c8a280f203..0cbd3ce9ba 100644 --- a/src/main/java/domain/participant/Players.java +++ b/src/main/java/domain/participant/Players.java @@ -5,6 +5,8 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.function.Supplier; +import domain.card.Card; public class Players { @@ -13,6 +15,7 @@ public class Players { public static final String PLAYER_DUPLICATED = "게임 참가자의 이름은 중복 되어선 안됩니다."; public static final String PLAYER_COUNT_OUT_OF_RANGE = String.format("게임 참가자의 수는 %d~%d명 사이여야 합니다.", PLAYER_MIN_COUNT, PLAYER_MAX_COUNT); + public static final String NOT_FOUND_PLAYER = "플레이어를 찾을 수 없습니다."; private final List players; @@ -46,10 +49,22 @@ public Player getPlayer(String name) { return players.stream() .filter(player -> player.getName().equals(name)) .findFirst() - .orElse(null); + .orElseThrow(() -> new BlackjackException(NOT_FOUND_PLAYER)); } public List getPlayers() { return Collections.unmodifiableList(players); } + + public void drawInitialCards(Supplier cardSupplier) { + for (Player player : players) { + player.addCard(cardSupplier.get()); + player.addCard(cardSupplier.get()); + } + } + + public void addCard(String name, Card card) { + Player player = getPlayer(name); + player.addCard(card); + } } diff --git a/src/test/java/domain/game/BlackjackGameManagerTest.java b/src/test/java/domain/game/BlackjackGameManagerTest.java index 4c431d8ff5..d7ce90b8a9 100644 --- a/src/test/java/domain/game/BlackjackGameManagerTest.java +++ b/src/test/java/domain/game/BlackjackGameManagerTest.java @@ -36,7 +36,7 @@ class Success { void 게임_참가자_조건이_맞으면_정상_작동_해야한다(List input) { // when & then - blackjackGameManager.createPlayers(input); + blackjackGameManager.createParticipants(input); } static Stream successCases() { @@ -58,7 +58,7 @@ class Success { void 초기_카드_분배시_최종_결과에는_모두_2장씩_있어야_한다() { // given - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); // when blackjackGameManager.drawInitialCards(); @@ -86,7 +86,7 @@ class Success { card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); // when @@ -114,7 +114,7 @@ class Success { card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); // when @@ -142,7 +142,7 @@ class Success { card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); // when @@ -172,7 +172,7 @@ class Success { card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), card(Rank.NINE, Suit.CLOVER) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); // when @@ -194,7 +194,7 @@ class Success { card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), card(Rank.NINE, Suit.CLOVER) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); // when @@ -258,7 +258,7 @@ class Success { card(Rank.TEN, Suit.DIAMOND), card(Rank.SEVEN, Suit.HEART), card(Rank.NINE, Suit.CLOVER), card(Rank.SEVEN, Suit.DIAMOND) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye", "brown")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye", "brown")); blackjackGameManager.drawInitialCards(); // when @@ -290,7 +290,7 @@ class Success { card(Rank.TEN, Suit.DIAMOND), card(Rank.SEVEN, Suit.HEART), card(Rank.NINE, Suit.CLOVER), card(Rank.SEVEN, Suit.DIAMOND) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye", "brown")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye", "brown")); blackjackGameManager.drawInitialCards(); // when @@ -320,7 +320,7 @@ class Success { card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), card(Rank.ACE, Suit.CLOVER) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); blackjackGameManager.updatePlayer("jacob"); @@ -353,7 +353,7 @@ class Success { card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), card(Rank.ACE, Suit.CLOVER) )); - blackjackGameManager.createPlayers(List.of("jacob", "seoye")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); // when From 7035b92debb308a7781bff666da7ddfb34979caf Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 16:08:27 +0900 Subject: [PATCH 06/98] =?UTF-8?q?refactor(BlackjackGameManager):=20generat?= =?UTF-8?q?ePlayerDtoList()=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20=EC=8A=A4=ED=8A=B8=EB=A6=BC=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/game/BlackjackGameManager.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 7f5e489bcd..492181e46c 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -52,11 +52,9 @@ public ParticipantDto generateDealerDto() { } public List generatePlayerDtoList() { - List playersDto = new ArrayList<>(); - for (Player player : participants.players().getPlayers()) { - playersDto.add(ParticipantDto.from(player)); - } - return playersDto; + return participants.players().getPlayers().stream() + .map(ParticipantDto::from) + .toList(); } public BlackjackResultDto getBlackjackResult() { From 640c510a2e7e9d6e66d078b5c0342730371cf17d Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 16:38:23 +0900 Subject: [PATCH 07/98] =?UTF-8?q?refactor(BlackjackGameManager):=20getBlac?= =?UTF-8?q?kjackStatistics()=20=EB=A9=94=EC=84=9C=EB=93=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 --- .../java/domain/game/BlackjackGameManager.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 492181e46c..cc17b1009f 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -65,24 +65,16 @@ public BlackjackResultDto getBlackjackResult() { } public BlackjackStatisticsDto getBlackjackStatistics() { - List playerStatisticDtoList = calculatePlayerResults(); + List playerStatisticDtoList = new ArrayList<>(); int win = 0, draw = 0, lose = 0; - for (PlayerStatisticDto playerStatisticDto : playerStatisticDtoList) { - Result result = playerStatisticDto.result(); + for (Player player : participants.players().getPlayers()) { + Result result = calculatePlayerResult(participants.dealer(), player); win += judgeResult(result, Result.LOSE); draw += judgeResult(result, Result.DRAW); lose += judgeResult(result, Result.WIN); - } - return BlackjackStatisticsDto.of(DealerStatisticDto.of(win, draw, lose), playerStatisticDtoList); - } - - public List calculatePlayerResults() { - List playerStatisticDtoList = new ArrayList<>(); - for (Player player : participants.players().getPlayers()) { - Result result = calculatePlayerResult(participants.dealer(), player); playerStatisticDtoList.add(PlayerStatisticDto.of(player, result)); } - return playerStatisticDtoList; + return BlackjackStatisticsDto.of(DealerStatisticDto.of(win, draw, lose), playerStatisticDtoList); } private Result calculatePlayerResult(Dealer dealer, Player player) { From 28f5d228774f12b51dde574c44257eb97057083f Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 16:38:51 +0900 Subject: [PATCH 08/98] =?UTF-8?q?test(BlackjackGameManager):=20calculatePl?= =?UTF-8?q?ayerResults()=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/game/BlackjackGameManagerTest.java | 39 ++----------------- 1 file changed, 3 insertions(+), 36 deletions(-) diff --git a/src/test/java/domain/game/BlackjackGameManagerTest.java b/src/test/java/domain/game/BlackjackGameManagerTest.java index d7ce90b8a9..ba730233d2 100644 --- a/src/test/java/domain/game/BlackjackGameManagerTest.java +++ b/src/test/java/domain/game/BlackjackGameManagerTest.java @@ -2,14 +2,13 @@ import static org.assertj.core.api.Assertions.assertThat; -import dto.BlackjackResultDto; -import factory.BlackjackControllerFactory; +import domain.card.Card; import domain.card.Rank; import domain.card.Suit; -import domain.card.Card; +import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; -import dto.PlayerStatisticDto; +import factory.BlackjackControllerFactory; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; @@ -242,38 +241,6 @@ class Success { } } - @Nested - class CalculatePlayerResultsTest { - - @Nested - class Success { - - @Test - void 플레이어별_결과를_승무패로_계산해야_한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.SPADE), - card(Rank.TEN, Suit.CLOVER), card(Rank.EIGHT, Suit.DIAMOND), - card(Rank.TEN, Suit.DIAMOND), card(Rank.SEVEN, Suit.HEART), - card(Rank.NINE, Suit.CLOVER), card(Rank.SEVEN, Suit.DIAMOND) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye", "brown")); - blackjackGameManager.drawInitialCards(); - - // when - List actual = blackjackGameManager.calculatePlayerResults(); - - // then - assertThat(actual).containsExactly( - new PlayerStatisticDto("jacob", Result.WIN), - new PlayerStatisticDto("seoye", Result.DRAW), - new PlayerStatisticDto("brown", Result.LOSE) - ); - } - } - } - @Nested class CalculateDealerResultTest { From 51c80beead1afb111a8c08b29aa3c12f6db1e997 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 16:48:19 +0900 Subject: [PATCH 09/98] =?UTF-8?q?docs(README):=20=EB=B0=B0=ED=8C=85=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=B6=94=EA=B0=80=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 768c170647..82d669290a 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,20 @@ pobi,jason ``` +☑️ 카드 수령 여부 입력 뷰 +```text +pobi의 배팅 금액은? +10000 +``` + + --- ✅ 카드 수령 여부 입력 뷰 ```text -pobi는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)y +pobi는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n) +y ``` # 출력 @@ -63,13 +71,13 @@ jason카드: 7클로버, K스페이드 - 결과: 17 --- -✅ 최종 승패 출력 뷰 +✅ 최종 수익 출력 뷰 ```text -## 최종 승패 -딜러: 1승 1패 -pobi: 승 -jason: 패 +## 최종 수익 +딜러: 10000 +pobi: 10000 +jason: -20000 ``` # 핵심 기능 @@ -143,13 +151,15 @@ jason: 패 --- -✅ 최종 승패 계산 기능 - -- 게임 참가자의 승패 여부를 계산한다. +✅ 최종 수익 계산 기능 +- 딜러와 게임 참가자의 최종 수익을 계산한다. - 딜러가 버스트인 경우에는 아래의 규칙을 따른다. - - 버스트가 아닌 모든 참가자는 승이다. - - 버스트인 모든 참가자는 패다. + - 버스트가 아닌 모든 참가자는 배팅한 금액을 수익으로 가져간다. + - 만약 참가자가 블랙잭이면(처음 받은 카드 2장의 합이 21이면) 배팅한 금액의 1.5배를 수익으로 가져간다. + - 버스트인 모든 참가자는 배팅한 금액을 잃는다. - 딜러가 버스트가 아닌 경우에는 아래의 규칙을 따른다. - - 딜러의 점수보다 낮거나 버스트인 참가자들은 패다. - - 딜러의 점수와 같은 참가자들은 무다. - - 딜러의 점수보다 높음 참가자들은 승이다. + - 딜러의 점수보다 낮거나 버스트인 참가자들은 배팅한 금액만큼 잃는다. + - 딜러의 점수와 같은 참가자들은 수익이 0이다. + - 딜러의 점수보다 높음 참가자들은 배팅한 금액을 수익으로 가져간다. + - 만약 참가자가 블랙잭이면(처음 받은 카드 2장의 합이 21이면) 배팅한 금액의 1.5배를 수익으로 가져간다. + From b78f443b5b2e252a2691b3cd105c329e0d6fb752 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 16:50:17 +0900 Subject: [PATCH 10/98] =?UTF-8?q?feat(BlackjackController):=20inputBetAmou?= =?UTF-8?q?nts=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/BlackjackController.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index 96aaaf8a8a..ea1dff640b 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -35,6 +35,7 @@ public void start() { private void initializeGame() { inputPlayers(); + inputBetAmounts(); blackjackGameManager.drawInitialCards(); List playerDtoList = blackjackGameManager.generatePlayerDtoList(); @@ -44,6 +45,14 @@ private void initializeGame() { outputView.printHandList(dealerDto, playerDtoList); } + private void inputBetAmounts() { + List playerDtoList = blackjackService.getPlayerDtoList(); + for (ParticipantDto participantDto : playerDtoList) { + String betAmountInput = inputView.inputBetAmount(participantDto.name()); + blackjackService.setBetAmount(participantDto.name(), new BetAmount(betAmountInput)); + } + } + private void inputPlayers() { List input = Parser.parseInput(inputView.inputPlayers()); blackjackGameManager.createParticipants(input); From 7f3f8519faa6d62f8ac6b08a6447029d8a316952 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 16:54:38 +0900 Subject: [PATCH 11/98] =?UTF-8?q?feat(BetAmount):=20=EB=B0=B0=ED=8C=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=EC=9D=84=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=20BetAmount=20=ED=8B=80?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/participant/BetAmount.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/domain/participant/BetAmount.java diff --git a/src/main/java/domain/participant/BetAmount.java b/src/main/java/domain/participant/BetAmount.java new file mode 100644 index 0000000000..3a23606ff5 --- /dev/null +++ b/src/main/java/domain/participant/BetAmount.java @@ -0,0 +1,43 @@ +package domain.participant; + +public class BetAmount { + + public static final String INVALID_BET_AMOUNT_NUMBER = "배팅 금액은 숫자여야 합니다."; + public static final String INVALID_BET_AMOUNT_POSITIVE = "배팅 금액은 양수여야 합니다."; + + private final int betAmount; + + public BetAmount(String betAmountInput) { + validate(betAmountInput); + this.betAmount = Integer.parseInt(betAmountInput); + } + + private void validate(String betAmountInput) { + validateNumber(betAmountInput); + validatePositive(betAmountInput); + } + + private void validateNumber(String betAmountInput) { + if (isNotNumber(betAmountInput)) { + throw new IllegalArgumentException(INVALID_BET_AMOUNT_NUMBER); + } + } + + private static boolean isNotNumber(String betAmountInput) { + return !betAmountInput.matches("-*\\d+"); + } + + private void validatePositive(String betAmountInput) { + if (isPositive(betAmountInput)) { + throw new IllegalArgumentException(INVALID_BET_AMOUNT_POSITIVE); + } + } + + private static boolean isPositive(String betAmountInput) { + return Integer.parseInt(betAmountInput) <= 0; + } + + public int getBetAmount() { + return betAmount; + } +} From c3004ea9e3dcebb06eb018bb50574a89df8e58b1 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 17:05:22 +0900 Subject: [PATCH 12/98] =?UTF-8?q?feat(BlackjackController):=20inputBetAmou?= =?UTF-8?q?nts=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/BlackjackController.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index ea1dff640b..2e8c7c67ca 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -1,11 +1,12 @@ package controller; +import domain.game.BlackjackGameManager; import domain.game.HitOrStand; +import domain.participant.BetAmount; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; import java.util.List; -import domain.game.BlackjackGameManager; import util.Parser; import view.InputView; import view.OutputView; @@ -46,10 +47,10 @@ private void initializeGame() { } private void inputBetAmounts() { - List playerDtoList = blackjackService.getPlayerDtoList(); + List playerDtoList = blackjackGameManager.getPlayerDtoList(); for (ParticipantDto participantDto : playerDtoList) { String betAmountInput = inputView.inputBetAmount(participantDto.name()); - blackjackService.setBetAmount(participantDto.name(), new BetAmount(betAmountInput)); + blackjackGameManager.setBetAmount(participantDto.name(), new BetAmount(betAmountInput)); } } From 7431a4e4f3f67f3b4e3259740de60b6ee77fda2d Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 17:06:04 +0900 Subject: [PATCH 13/98] =?UTF-8?q?feat(BlackjackGameManager):=20getPlayerDt?= =?UTF-8?q?oList=20=EB=B0=8F=20setBetAmount=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/game/BlackjackGameManager.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index cc17b1009f..0ba84f1e2d 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -2,6 +2,7 @@ import domain.card.Card; import domain.card.CardMachine; +import domain.participant.BetAmount; import domain.participant.Dealer; import domain.participant.Participants; import domain.participant.Player; @@ -112,4 +113,13 @@ public boolean isHit(HitOrStand hitOrStand) { public boolean isStand(HitOrStand hitOrStand) { return hitOrStand.isStand(); } + + public List getPlayerDtoList() { + return ParticipantDto.from(participants.players()); + } + + public void setBetAmount(String name, BetAmount betAmount) { + Player player = participants.getPlayer(name); + player.setBetAmount(betAmount); + } } From 7c75ff378edead8f4b831ba1aa7114e967a4d1c0 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 17:07:10 +0900 Subject: [PATCH 14/98] =?UTF-8?q?feat(InputView):=20inputBetAmount=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/InputView.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 136242d3cf..e074db01a8 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -6,6 +6,7 @@ public class InputView { private static final String INPUT_PLAYERS_MESSAGE = "게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"; private static final String INPUT_HIT_OR_STAND = "%s는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)\n"; + private static final String INPUT_BET_AMOUNT = "%s의 배팅 금액은?\n"; private final Scanner scanner = new Scanner(System.in); @@ -18,4 +19,9 @@ public String inputHitOrStand(String name) { System.out.printf(INPUT_HIT_OR_STAND, name); return scanner.nextLine(); } + + public String inputBetAmount(String name) { + System.out.printf(INPUT_BET_AMOUNT, name); + return scanner.nextLine(); + } } From 59130bb60c06f3aa53408e7d7d0c025135e8f71a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 17:07:28 +0900 Subject: [PATCH 15/98] =?UTF-8?q?feat(ParticipantDto):=20from=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/dto/ParticipantDto.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/dto/ParticipantDto.java b/src/main/java/dto/ParticipantDto.java index be55391988..36c85e0070 100644 --- a/src/main/java/dto/ParticipantDto.java +++ b/src/main/java/dto/ParticipantDto.java @@ -3,6 +3,8 @@ import domain.card.Card; import domain.participant.Dealer; import domain.participant.Player; +import domain.participant.Players; +import java.util.ArrayList; import java.util.List; public record ParticipantDto( @@ -27,6 +29,15 @@ public static ParticipantDto from(Player player) { return new ParticipantDto(player.getName(), convertHandString(player.getHand()), player.calculateScore()); } + public static List from(Players players) { + List playersDto = new ArrayList<>(); + for (Player player : players.getPlayers()) { + List hand = convertHandString(player.getHand()); + playersDto.add(new ParticipantDto(player.getName(), hand, player.calculateScore())); + } + return playersDto; + } + private static List convertHandString(List cards) { return cards.stream() .map(card -> card.rank().getRank() + card.suit().getSuit()) From eb50b4138bf49cf53ac44d8abac8b42fa52f24e7 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 17:07:40 +0900 Subject: [PATCH 16/98] =?UTF-8?q?feat(Player):=20setBetAmount=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Player.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/domain/participant/Player.java b/src/main/java/domain/participant/Player.java index 2c7eccbb5d..b0d2f41f99 100644 --- a/src/main/java/domain/participant/Player.java +++ b/src/main/java/domain/participant/Player.java @@ -3,6 +3,7 @@ public class Player extends Participant { private final PlayerName playerName; + private BetAmount betAmount; public Player(String name) { super(); @@ -12,4 +13,8 @@ public Player(String name) { public String getName() { return playerName.name(); } + + public void setBetAmount(BetAmount betAmount) { + this.betAmount = betAmount; + } } From cd807d355ccb4ad0400eacb505286029e2ea9205 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 18:46:24 +0900 Subject: [PATCH 17/98] =?UTF-8?q?feat(DealerStatisticDto):=20DealerStatist?= =?UTF-8?q?icDto=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/dto/DealerStatisticDto.java | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/main/java/dto/DealerStatisticDto.java diff --git a/src/main/java/dto/DealerStatisticDto.java b/src/main/java/dto/DealerStatisticDto.java deleted file mode 100644 index 2e2a414094..0000000000 --- a/src/main/java/dto/DealerStatisticDto.java +++ /dev/null @@ -1,12 +0,0 @@ -package dto; - -public record DealerStatisticDto( - int win, - int draw, - int lose -) { - - public static DealerStatisticDto of(int win, int draw, int lose) { - return new DealerStatisticDto(win, draw, lose); - } -} From 841c634365f4e096336d3e74332bf73c41d70c1f Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 18:47:29 +0900 Subject: [PATCH 18/98] =?UTF-8?q?feat(BlackjackStatisticsDto):=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=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/dto/BlackjackStatisticsDto.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/dto/BlackjackStatisticsDto.java b/src/main/java/dto/BlackjackStatisticsDto.java index 3566999171..be4dacbd54 100644 --- a/src/main/java/dto/BlackjackStatisticsDto.java +++ b/src/main/java/dto/BlackjackStatisticsDto.java @@ -3,11 +3,11 @@ import java.util.List; public record BlackjackStatisticsDto( - DealerStatisticDto dealerStatisticDto, + int dealerProfit, List playerStatisticDtoList ) { - public static BlackjackStatisticsDto of(DealerStatisticDto dealerStatisticDto, List playerStatisticDtoList) { - return new BlackjackStatisticsDto(dealerStatisticDto, playerStatisticDtoList); + public static BlackjackStatisticsDto of(int dealerProfit, List playerStatisticDtoList) { + return new BlackjackStatisticsDto(dealerProfit, playerStatisticDtoList); } } From fbf79e0e6dc2d496a023b43831a7372df1bc3f15 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 18:49:38 +0900 Subject: [PATCH 19/98] =?UTF-8?q?feat(Hand):=20calculateInitialBaseScore()?= =?UTF-8?q?,=20isBlackjack(),=20calculateInitialScore()=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/card/Hand.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/domain/card/Hand.java b/src/main/java/domain/card/Hand.java index 3a28afdd70..b98c576804 100644 --- a/src/main/java/domain/card/Hand.java +++ b/src/main/java/domain/card/Hand.java @@ -38,6 +38,12 @@ private Integer calculateBaseScore() { .reduce(0, Integer::sum); } + private Integer calculateInitialBaseScore() { + return cards.subList(0, 2).stream() + .map(Card::getScore) + .reduce(0, Integer::sum); + } + private int calculateTotalScoreWithAceCalculation(int score, int aceCount) { while (score > BLACKJACK_SCORE && aceCount > 0) { score -= REDUCED_SCORE_FROM_ACE; @@ -59,4 +65,15 @@ public List getCard() { return cards.stream() .toList(); } + + public boolean isBlackjack() { + return calculateInitialScore() == BLACKJACK_SCORE; + } + + private int calculateInitialScore() { + int baseScore = calculateInitialBaseScore(); + int aceCount = calculateAceCount(); + + return calculateTotalScoreWithAceCalculation(baseScore, aceCount); + } } From 1b369edb013235d2a6d1b0f9c240682eeffa714a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 18:55:45 +0900 Subject: [PATCH 20/98] =?UTF-8?q?feat(Hand):=20getBlackjackStatistics(),?= =?UTF-8?q?=20calculatePlayerProfit()=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/game/BlackjackGameManager.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 0ba84f1e2d..85be20c661 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -8,7 +8,6 @@ import domain.participant.Player; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; -import dto.DealerStatisticDto; import dto.ParticipantDto; import dto.PlayerStatisticDto; import java.util.ArrayList; @@ -67,18 +66,18 @@ public BlackjackResultDto getBlackjackResult() { public BlackjackStatisticsDto getBlackjackStatistics() { List playerStatisticDtoList = new ArrayList<>(); - int win = 0, draw = 0, lose = 0; + int dealerProfit = 0; for (Player player : participants.players().getPlayers()) { - Result result = calculatePlayerResult(participants.dealer(), player); - win += judgeResult(result, Result.LOSE); - draw += judgeResult(result, Result.DRAW); - lose += judgeResult(result, Result.WIN); - playerStatisticDtoList.add(PlayerStatisticDto.of(player, result)); + Result result = judgePlayerResult(participants.dealer(), player); + int playerProfit = calculatePlayerProfit(player, result); + dealerProfit += playerProfit * -1; + playerStatisticDtoList.add(PlayerStatisticDto.of(player, playerProfit)); } - return BlackjackStatisticsDto.of(DealerStatisticDto.of(win, draw, lose), playerStatisticDtoList); + + return BlackjackStatisticsDto.of(dealerProfit, playerStatisticDtoList); } - private Result calculatePlayerResult(Dealer dealer, Player player) { + private Result judgePlayerResult(Dealer dealer, Player player) { if (player.isBust()) { return Result.LOSE; } @@ -94,9 +93,15 @@ private Result calculatePlayerResult(Dealer dealer, Player player) { return Result.LOSE; } - private int judgeResult(Result result, Result playerResult) { - if (result.equals(playerResult)) { - return 1; + private int calculatePlayerProfit(Player player, Result result) { + if (result.equals(Result.WIN) && player.isBlackjack()) { + return player.getBetAmount() + player.getBetAmount() / 2; + } + if (result.equals(Result.WIN)) { + return player.getBetAmount(); + } + if (result.equals(Result.LOSE)) { + return player.getBetAmount() * -1; } return 0; } From 6c2486f544754bbf8693f5e9635afb40cff9340a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 18:56:13 +0900 Subject: [PATCH 21/98] =?UTF-8?q?feat(OutputView):=20=EC=B5=9C=EC=A2=85=20?= =?UTF-8?q?=EC=88=98=EC=9D=B5=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/OutputView.java | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index e43f9af667..1845ddadf6 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,9 +1,7 @@ package view; -import domain.game.Result; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; -import dto.DealerStatisticDto; import dto.ParticipantDto; import dto.PlayerStatisticDto; import java.util.List; @@ -15,14 +13,14 @@ public class OutputView { private static final String PRINT_HAND_MESSAGE = "%s카드: %s"; private static final String PRINT_DEALER_HIT = "\n딜러는 16이하라 한장의 카드를 더 받았습니다."; private static final String PRINT_BLACKJACK_RESULT_MESSAGE = " - 결과: %d\n"; - private static final String PRINT_BLACKJACK_STATISTICS_HEADER_MESSAGE = "## 최종 승패"; - private static final String PRINT_BLACKJACK_STATISTICS_DEALER_MESSAGE = "딜러:%s%s%s\n"; - private static final String PRINT_BLACKJACK_STATISTICS_PLAYER_MESSAGE = "%s: %s\n"; + private static final String PRINT_BLACKJACK_STATISTICS_HEADER_MESSAGE = "## 최종 수익"; + private static final String PRINT_BLACKJACK_STATISTICS_DEALER_MESSAGE = "딜러: %d\n"; + private static final String PRINT_BLACKJACK_STATISTICS_PLAYER_MESSAGE = "%s: %d\n"; public void printPlayers(List playerDtoList) { List names = playerDtoList.stream() - .map(ParticipantDto::name) - .toList(); + .map(ParticipantDto::name) + .toList(); System.out.printf(PRINT_PLAYERS_MESSAGE, String.join(DELIMITER, names)); } @@ -61,16 +59,11 @@ public void printBlackjackResult(BlackjackResultDto blackjackResult) { } public void printBlackjackStatistics(BlackjackStatisticsDto blackjackStatistics) { - DealerStatisticDto dealerStatisticDto = blackjackStatistics.dealerStatisticDto(); - List playerStatisticDtoList = blackjackStatistics.playerStatisticDtoList(); System.out.println(PRINT_BLACKJACK_STATISTICS_HEADER_MESSAGE); - System.out.printf(PRINT_BLACKJACK_STATISTICS_DEALER_MESSAGE, - printResult(dealerStatisticDto.win(), Result.WIN.getResult()), - printResult(dealerStatisticDto.draw(), Result.DRAW.getResult()), - printResult(dealerStatisticDto.lose(), Result.LOSE.getResult())); - for (PlayerStatisticDto playerStatisticDto : playerStatisticDtoList) { - System.out.printf(PRINT_BLACKJACK_STATISTICS_PLAYER_MESSAGE, playerStatisticDto.name(), - playerStatisticDto.result().getResult()); + System.out.printf(PRINT_BLACKJACK_STATISTICS_DEALER_MESSAGE, blackjackStatistics.dealerProfit()); + for (PlayerStatisticDto playerStatisticDto : blackjackStatistics.playerStatisticDtoList()) { + System.out.printf(PRINT_BLACKJACK_STATISTICS_PLAYER_MESSAGE, + playerStatisticDto.name(), playerStatisticDto.profit()); } } From 91e304cc103eccaee332c6ac98b2f3a47fc0b745 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 18:56:33 +0900 Subject: [PATCH 22/98] =?UTF-8?q?feat(Player):=20isBlack(),=20getBetAmount?= =?UTF-8?q?()=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Player.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/domain/participant/Player.java b/src/main/java/domain/participant/Player.java index b0d2f41f99..65e4c7f3fe 100644 --- a/src/main/java/domain/participant/Player.java +++ b/src/main/java/domain/participant/Player.java @@ -17,4 +17,12 @@ public String getName() { public void setBetAmount(BetAmount betAmount) { this.betAmount = betAmount; } + + public boolean isBlackjack() { + return hand.isBlackjack(); + } + + public int getBetAmount() { + return betAmount.getBetAmount(); + } } From 0f4bfaf75b882ea1118e79b261e3f0f8434becfc Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 18:57:10 +0900 Subject: [PATCH 23/98] =?UTF-8?q?feat(PlayerStatisticDto):=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=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/dto/PlayerStatisticDto.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/dto/PlayerStatisticDto.java b/src/main/java/dto/PlayerStatisticDto.java index 7b58c5c6ab..1deb8bb312 100644 --- a/src/main/java/dto/PlayerStatisticDto.java +++ b/src/main/java/dto/PlayerStatisticDto.java @@ -1,14 +1,13 @@ package dto; -import domain.game.Result; import domain.participant.Player; public record PlayerStatisticDto( String name, - Result result + int profit ) { - public static PlayerStatisticDto of(Player player, Result result) { - return new PlayerStatisticDto(player.getName(), result); + public static PlayerStatisticDto of(Player player, int profit) { + return new PlayerStatisticDto(player.getName(), profit); } } From 3e0ec19fc05669327bc30e4df5fc29fc5570c964 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 19:05:29 +0900 Subject: [PATCH 24/98] =?UTF-8?q?docs(README):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=ED=95=9C=20=ED=95=AD=EB=AA=A9=20=EC=B2=B4?= =?UTF-8?q?=ED=81=AC=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 82d669290a..35bf53825e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ pobi,jason ``` -☑️ 카드 수령 여부 입력 뷰 +✅️ 카드 수령 여부 입력 뷰 ```text pobi의 배팅 금액은? 10000 From 7872210a9bd9fa3c3b759a394ac498d9242d2d63 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 19:12:55 +0900 Subject: [PATCH 25/98] =?UTF-8?q?refactor(CardMachine):=20addRepeatDeckCou?= =?UTF-8?q?nt=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=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/domain/card/CardMachine.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/card/CardMachine.java b/src/main/java/domain/card/CardMachine.java index 60753805ed..4d5a2eb7e0 100644 --- a/src/main/java/domain/card/CardMachine.java +++ b/src/main/java/domain/card/CardMachine.java @@ -33,11 +33,11 @@ private void setRanksAndSuits(List decks) { private void setSuits(List decks, Rank rank) { for (Suit suit : Suit.values()) { - addRepeatSix(decks, rank, suit); + addRepeatDeckCount(decks, rank, suit); } } - private void addRepeatSix(List decks, Rank rank, Suit suit) { + private void addRepeatDeckCount(List decks, Rank rank, Suit suit) { for (int i = 0; i < DECK_COUNT; i++) { decks.add(new Card(rank, suit)); } From e06ffda0abd844d327e20989624cb36204dafe61 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 19:13:55 +0900 Subject: [PATCH 26/98] =?UTF-8?q?refactor(Hand):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=9C=84=EC=B9=98=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/domain/card/Hand.java | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/domain/card/Hand.java b/src/main/java/domain/card/Hand.java index b98c576804..05f0bba4cf 100644 --- a/src/main/java/domain/card/Hand.java +++ b/src/main/java/domain/card/Hand.java @@ -25,11 +25,11 @@ public int calculateTotalScore() { return calculateTotalScoreWithAceCalculation(baseScore, aceCount); } - private int calculateAceCount() { - return cards.stream() - .filter(Card::isAce) - .toList() - .size(); + private int calculateInitialScore() { + int baseScore = calculateInitialBaseScore(); + int aceCount = calculateAceCount(); + + return calculateTotalScoreWithAceCalculation(baseScore, aceCount); } private Integer calculateBaseScore() { @@ -44,6 +44,13 @@ private Integer calculateInitialBaseScore() { .reduce(0, Integer::sum); } + private int calculateAceCount() { + return cards.stream() + .filter(Card::isAce) + .toList() + .size(); + } + private int calculateTotalScoreWithAceCalculation(int score, int aceCount) { while (score > BLACKJACK_SCORE && aceCount > 0) { score -= REDUCED_SCORE_FROM_ACE; @@ -69,11 +76,4 @@ public List getCard() { public boolean isBlackjack() { return calculateInitialScore() == BLACKJACK_SCORE; } - - private int calculateInitialScore() { - int baseScore = calculateInitialBaseScore(); - int aceCount = calculateAceCount(); - - return calculateTotalScoreWithAceCalculation(baseScore, aceCount); - } } From 927179b85627c8ee1b8b4ef4c339dc28dae83e59 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 19:14:15 +0900 Subject: [PATCH 27/98] =?UTF-8?q?refactor(Rank):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=9C=84=EC=B9=98=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/domain/card/Rank.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/card/Rank.java b/src/main/java/domain/card/Rank.java index 116f3952cb..1a30296467 100644 --- a/src/main/java/domain/card/Rank.java +++ b/src/main/java/domain/card/Rank.java @@ -24,10 +24,6 @@ public enum Rank { this.score = score; } - public boolean isAce() { - return this.equals(Rank.ACE); - } - public String getRank() { return rank; } @@ -35,4 +31,8 @@ public String getRank() { public int getScore() { return score; } + + public boolean isAce() { + return this.equals(Rank.ACE); + } } From 0990745bb353bf2d5ba12651ac9b6421d97aaf18 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 19:24:25 +0900 Subject: [PATCH 28/98] =?UTF-8?q?refactor(BlackjackGameManager):=20getPlay?= =?UTF-8?q?erDtoList()=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/BlackjackController.java | 2 +- .../java/domain/game/BlackjackGameManager.java | 14 +++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index 2e8c7c67ca..f93a05efdf 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -47,7 +47,7 @@ private void initializeGame() { } private void inputBetAmounts() { - List playerDtoList = blackjackGameManager.getPlayerDtoList(); + List playerDtoList = blackjackGameManager.generatePlayerDtoList(); for (ParticipantDto participantDto : playerDtoList) { String betAmountInput = inputView.inputBetAmount(participantDto.name()); blackjackGameManager.setBetAmount(participantDto.name(), new BetAmount(betAmountInput)); diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 85be20c661..b5717e5e6a 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -43,6 +43,11 @@ public Card drawCard() { return cardMachine.drawCard(); } + public ParticipantDto updatePlayer(String name) { + Player player = participants.drawCardsByPlayer(name, this::drawCard); + return ParticipantDto.from(player); + } + public ParticipantDto generateInitialDealerDto() { return ParticipantDto.from(participants.dealer(), true); } @@ -106,11 +111,6 @@ private int calculatePlayerProfit(Player player, Result result) { return 0; } - public ParticipantDto updatePlayer(String name) { - Player player = participants.drawCardsByPlayer(name, this::drawCard); - return ParticipantDto.from(player); - } - public boolean isHit(HitOrStand hitOrStand) { return hitOrStand.isHit(); } @@ -119,10 +119,6 @@ public boolean isStand(HitOrStand hitOrStand) { return hitOrStand.isStand(); } - public List getPlayerDtoList() { - return ParticipantDto.from(participants.players()); - } - public void setBetAmount(String name, BetAmount betAmount) { Player player = participants.getPlayer(name); player.setBetAmount(betAmount); From 83da4c2baf2949f28a79c89552a8fb6a66d2a747 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 19:25:15 +0900 Subject: [PATCH 29/98] =?UTF-8?q?refactor(ParticipantDto):=20Players?= =?UTF-8?q?=EB=A5=BC=20=EC=9D=B8=EC=88=98=EB=A1=9C=20=EA=B0=80=EC=A7=80?= =?UTF-8?q?=EB=8A=94=20from=20=EB=A9=94=EC=84=9C=EB=93=9C=201=EA=B0=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/dto/ParticipantDto.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/dto/ParticipantDto.java b/src/main/java/dto/ParticipantDto.java index 36c85e0070..be55391988 100644 --- a/src/main/java/dto/ParticipantDto.java +++ b/src/main/java/dto/ParticipantDto.java @@ -3,8 +3,6 @@ import domain.card.Card; import domain.participant.Dealer; import domain.participant.Player; -import domain.participant.Players; -import java.util.ArrayList; import java.util.List; public record ParticipantDto( @@ -29,15 +27,6 @@ public static ParticipantDto from(Player player) { return new ParticipantDto(player.getName(), convertHandString(player.getHand()), player.calculateScore()); } - public static List from(Players players) { - List playersDto = new ArrayList<>(); - for (Player player : players.getPlayers()) { - List hand = convertHandString(player.getHand()); - playersDto.add(new ParticipantDto(player.getName(), hand, player.calculateScore())); - } - return playersDto; - } - private static List convertHandString(List cards) { return cards.stream() .map(card -> card.rank().getRank() + card.suit().getSuit()) From fc36d0feb291f68e688403d6c4c84786394f13f4 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 20:20:10 +0900 Subject: [PATCH 30/98] =?UTF-8?q?refactor(BlackjackControllerFactory):=20b?= =?UTF-8?q?lackjackService=20->=20blackjackGameManager=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=AA=85=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/factory/BlackjackControllerFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/factory/BlackjackControllerFactory.java b/src/main/java/factory/BlackjackControllerFactory.java index eae653e0c4..9407966787 100644 --- a/src/main/java/factory/BlackjackControllerFactory.java +++ b/src/main/java/factory/BlackjackControllerFactory.java @@ -8,10 +8,10 @@ public class BlackjackControllerFactory { public BlackjackController blackjackController() { - return new BlackjackController(inputView(), outputView(), blackjackService()); + return new BlackjackController(inputView(), outputView(), blackjackGameManager()); } - public BlackjackGameManager blackjackService() { + public BlackjackGameManager blackjackGameManager() { return new BlackjackGameManager(); } From 595d088c7ef1756e9e287fe9bfdb1437cf3fe3ac Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 20:26:14 +0900 Subject: [PATCH 31/98] =?UTF-8?q?refactor(Hand):=20INITIAL=5FCARD=5FCOUNT?= =?UTF-8?q?=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/card/Hand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/card/Hand.java b/src/main/java/domain/card/Hand.java index 05f0bba4cf..350aebff24 100644 --- a/src/main/java/domain/card/Hand.java +++ b/src/main/java/domain/card/Hand.java @@ -7,6 +7,7 @@ public class Hand { private static final int BLACKJACK_SCORE = 21; private static final int REDUCED_SCORE_FROM_ACE = 10; + private static final int INITIAL_CARD_COUNT = 2; private final List cards; @@ -39,7 +40,7 @@ private Integer calculateBaseScore() { } private Integer calculateInitialBaseScore() { - return cards.subList(0, 2).stream() + return cards.subList(0, INITIAL_CARD_COUNT).stream() .map(Card::getScore) .reduce(0, Integer::sum); } From 3919a6323d2221eb605ad56fb27099a5f94371c9 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Fri, 13 Mar 2026 21:01:40 +0900 Subject: [PATCH 32/98] =?UTF-8?q?refactor(Result):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=95=84=EB=93=9C=20=EB=B0=8F=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=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 --- src/main/java/domain/game/Result.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/main/java/domain/game/Result.java b/src/main/java/domain/game/Result.java index 6947e3adac..5b601a3f69 100644 --- a/src/main/java/domain/game/Result.java +++ b/src/main/java/domain/game/Result.java @@ -1,18 +1,8 @@ package domain.game; public enum Result { - WIN("승"), - DRAW("무"), - LOSE("패"), + WIN, + DRAW, + LOSE, ; - - private final String result; - - Result(String result) { - this.result = result; - } - - public String getResult() { - return result; - } } From 1dcc127d8d9f88d68db037195d165abeda9f678a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:15:31 +0900 Subject: [PATCH 33/98] =?UTF-8?q?remove(CardTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=ED=95=A0=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=A1=B4?= =?UTF-8?q?=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9C=BC=EB=AF=80?= =?UTF-8?q?=EB=A1=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/card/CardTest.java | 144 ------------------------ 1 file changed, 144 deletions(-) delete mode 100644 src/test/java/domain/card/CardTest.java diff --git a/src/test/java/domain/card/CardTest.java b/src/test/java/domain/card/CardTest.java deleted file mode 100644 index 82bbe45f30..0000000000 --- a/src/test/java/domain/card/CardTest.java +++ /dev/null @@ -1,144 +0,0 @@ -package domain.card; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.stream.Stream; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Nested; -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; - -public class CardTest { - - @Nested - class CalculateScoreTest { - - @Nested - class Success { - - @Test - void J_Q_K_이면_10을_반환_해야_한다() { - - // given - Card card1 = new Card(Rank.J, Suit.HEART); - Card card2 = new Card(Rank.Q, Suit.HEART); - Card card3 = new Card(Rank.K, Suit.HEART); - - // when - int actual1 = card1.getScore(); - int actual2 = card2.getScore(); - int actual3 = card3.getScore(); - - // then - int expected = 10; - Assertions.assertEquals(10, actual1); - Assertions.assertEquals(10, actual2); - Assertions.assertEquals(10, actual3); - } - - @Test - void 에이스_이면_11을_반환_해야_한다() { - - // given - Card card = new Card(Rank.ACE, Suit.CLOVER); - - // when - int actual = card.getScore(); - - // then - Assertions.assertEquals(11, actual); - } - - @ParameterizedTest - @MethodSource("cardProvider") - void 숫자라면_숫자를_반환_해야_한다(Card card, int expected) { - - // when - int actual = card.getScore(); - - // then - Assertions.assertEquals(expected, actual); - } - - static Stream cardProvider() { - return Stream.of( - Arguments.of(new Card(Rank.FIVE, Suit.CLOVER), 5), - Arguments.of(new Card(Rank.TWO, Suit.CLOVER), 2), - Arguments.of(new Card(Rank.TEN, Suit.CLOVER), 10) - ); - } - } - } - - @Nested - class IsAceTest { - - @Nested - class Success { - - @Test - void 에이스_카드는_true를_반환해야_한다() { - - // given - Card card = new Card(Rank.ACE, Suit.HEART); - - // when - boolean actual = card.isAce(); - - // then - assertThat(actual).isTrue(); - } - - @Test - void 에이스가_아닌_카드는_false를_반환해야_한다() { - - // given - Card card = new Card(Rank.TEN, Suit.HEART); - - // when - boolean actual = card.isAce(); - - // then - assertThat(actual).isFalse(); - } - } - } - - @Nested - class EqualsAndHashCodeTest { - - @Nested - class Success { - - @Test - void 랭크와_무늬가_같으면_equals는_true다() { - - // given - Card card = new Card(Rank.TEN, Suit.HEART); - Card other = new Card(Rank.TEN, Suit.HEART); - - // when - boolean actual = card.equals(other); - - // then - assertThat(actual).isTrue(); - } - - @Test - void 랭크와_무늬가_같으면_hashCode도_같다() { - - // given - Card card = new Card(Rank.TEN, Suit.HEART); - Card other = new Card(Rank.TEN, Suit.HEART); - - // when - int actual = card.hashCode(); - - // then - assertThat(actual).isEqualTo(other.hashCode()); - } - } - } -} From 653e765ec9268a1c833e1dc3e4b9635939ed5eee Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:21:52 +0900 Subject: [PATCH 34/98] =?UTF-8?q?remove(ParticipantTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=ED=95=A0=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9C=BC?= =?UTF-8?q?=EB=AF=80=EB=A1=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/ParticipantTest.java | 138 ------------------ 1 file changed, 138 deletions(-) delete mode 100644 src/test/java/domain/participant/ParticipantTest.java diff --git a/src/test/java/domain/participant/ParticipantTest.java b/src/test/java/domain/participant/ParticipantTest.java deleted file mode 100644 index e76a102dc7..0000000000 --- a/src/test/java/domain/participant/ParticipantTest.java +++ /dev/null @@ -1,138 +0,0 @@ -package domain.participant; - -import static org.assertj.core.api.Assertions.assertThat; - -import domain.card.Card; -import domain.card.Rank; -import domain.card.Suit; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -class ParticipantTest { - - @Nested - class AddCardTest { - - @Nested - class Success { - - @Test - void 카드를_추가하면_손패에_저장되어야_한다() { - - // given - Participant participant = new Participant(); - Card card = new Card(Rank.ACE, Suit.HEART); - - // when - participant.addCard(card); - - // then - assertThat(participant.getHand()) - .hasSize(1) - .containsExactly(card); - } - } - } - - @Nested - class GetHandTest { - - @Nested - class Success { - - @Test - void 손패가_비어있으면_빈_리스트를_반환해야_한다() { - - // given - Participant participant = new Participant(); - - // when - var actual = participant.getHand(); - - // then - assertThat(actual).isEmpty(); - } - - @Test - void 손패의_카드_이름을_추가한_순서대로_반환해야_한다() { - - // given - Participant participant = new Participant(); - Card firstCard = new Card(Rank.FIVE, Suit.HEART); - Card secondCard = new Card(Rank.J, Suit.SPADE); - participant.addCard(firstCard); - participant.addCard(secondCard); - - // when - var actual = participant.getHand(); - - // then - assertThat(actual) - .hasSize(2) - .containsExactly(firstCard, secondCard); - } - } - } - - @Nested - class CalculateScoreTest { - - @Nested - class Success { - - @Test - void 현재_손패_점수를_계산해_반환해야_한다() { - - // given - Participant participant = new Participant(); - participant.addCard(new Card(Rank.TEN, Suit.HEART)); - participant.addCard(new Card(Rank.THREE, Suit.SPADE)); - - // when - int actual = participant.calculateScore(); - - // then - assertThat(actual).isEqualTo(13); - } - } - } - - @Nested - class IsBustTest { - - @Nested - class Success { - - @Test - void 점수가_21을_초과하면_true를_반환해야_한다() { - - // given - Participant participant = new Participant(); - participant.addCard(new Card(Rank.TEN, Suit.HEART)); - participant.addCard(new Card(Rank.K, Suit.SPADE)); - participant.addCard(new Card(Rank.TWO, Suit.CLOVER)); - - // when - boolean actual = participant.isBust(); - - // then - assertThat(actual).isTrue(); - } - - @Test - void 점수가_21_이하면_false를_반환해야_한다() { - - // given - Participant participant = new Participant(); - participant.addCard(new Card(Rank.TEN, Suit.HEART)); - participant.addCard(new Card(Rank.ACE, Suit.SPADE)); - - // when - boolean actual = participant.isBust(); - - // then - assertThat(actual).isFalse(); - } - } - } -} From 2f578fed3b34372dabcc44aed6b0bca1f1571d69 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:13 +0900 Subject: [PATCH 35/98] =?UTF-8?q?test(BetAmountTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/BetAmountTest.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/test/java/domain/participant/BetAmountTest.java diff --git a/src/test/java/domain/participant/BetAmountTest.java b/src/test/java/domain/participant/BetAmountTest.java new file mode 100644 index 0000000000..7fa1fdc2cf --- /dev/null +++ b/src/test/java/domain/participant/BetAmountTest.java @@ -0,0 +1,65 @@ +package domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +class BetAmountTest { + + @Nested + class ConstructorTest { + + @Nested + class Success { + + @ParameterizedTest + @MethodSource("successCases") + void 양수_숫자면_배팅_금액이_정상_생성된다(String input, int expected) { + + // when + BetAmount actual = new BetAmount(input); + + // then + assertThat(actual.getBetAmount()).isEqualTo(expected); + } + + static Stream successCases() { + return Stream.of( + Arguments.of("1", 1), + Arguments.of("1000", 1000), + Arguments.of("50000", 50000) + ); + } + } + + @Nested + class Fail { + + @ParameterizedTest + @ValueSource(strings = {"abc", "1a", "12 3", "1.5"}) + void 숫자가_아니면_예외가_발생한다(String input) { + + // when & then + assertThatThrownBy(() -> new BetAmount(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(BetAmount.INVALID_BET_AMOUNT_NUMBER); + } + + @ParameterizedTest + @ValueSource(strings = {"0", "-1", "-1000"}) + void 제로_이하이면_예외가_발생한다(String input) { + + // when & then + assertThatThrownBy(() -> new BetAmount(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(BetAmount.INVALID_BET_AMOUNT_POSITIVE); + } + } + } +} From edf3ee01cabacb457718c276f3dabe02fba2770b Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:21 +0900 Subject: [PATCH 36/98] =?UTF-8?q?test(BlackjackGameManagerTest):=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=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 --- .../domain/game/BlackjackGameManagerTest.java | 237 ++++++++---------- 1 file changed, 104 insertions(+), 133 deletions(-) diff --git a/src/test/java/domain/game/BlackjackGameManagerTest.java b/src/test/java/domain/game/BlackjackGameManagerTest.java index ba730233d2..24d2792913 100644 --- a/src/test/java/domain/game/BlackjackGameManagerTest.java +++ b/src/test/java/domain/game/BlackjackGameManagerTest.java @@ -5,6 +5,7 @@ import domain.card.Card; import domain.card.Rank; import domain.card.Suit; +import domain.participant.BetAmount; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; @@ -12,60 +13,92 @@ import java.util.ArrayDeque; import java.util.Deque; import java.util.List; -import java.util.stream.Stream; import org.junit.jupiter.api.Nested; 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; class BlackjackGameManagerTest { private final BlackjackControllerFactory blackjackControllerFactory = new BlackjackControllerFactory(); - private final BlackjackGameManager blackjackGameManager = blackjackControllerFactory.blackjackService(); + private final BlackjackGameManager blackjackGameManager = blackjackControllerFactory.blackjackGameManager(); @Nested - class CreatePlayersTest { + class DrawDealerCardTest { @Nested class Success { - @ParameterizedTest - @MethodSource("successCases") - void 게임_참가자_조건이_맞으면_정상_작동_해야한다(List input) { + @Test + void 딜러_점수가_16_이하면_카드를_추가로_뽑아야_한다() { - // when & then - blackjackGameManager.createParticipants(input); + // given + BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), + card(Rank.NINE, Suit.CLOVER) + )); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); + blackjackGameManager.drawInitialCards(); + + // when + boolean actual = blackjackGameManager.drawDealerCard(); + + // then + BlackjackResultDto result = blackjackGameManager.getBlackjackResult(); + assertThat(actual).isTrue(); + assertThat(result.playerResultDtoList().getFirst().hand()).hasSize(2); } - static Stream successCases() { - return Stream.of( - Arguments.of(List.of("jacob", "seoye")), - Arguments.of(List.of("aa aa", "성 열")) - ); + @Test + void 딜러_점수가_17_이상이면_카드를_추가로_뽑지_않아야_한다() { + + // given + BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), + card(Rank.NINE, Suit.CLOVER) + )); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); + blackjackGameManager.drawInitialCards(); + + // when + boolean actual = blackjackGameManager.drawDealerCard(); + + // then + BlackjackResultDto result = blackjackGameManager.getBlackjackResult(); + assertThat(actual).isFalse(); + assertThat(result.playerResultDtoList().getFirst().hand()).hasSize(2); } + } } @Nested - class DrawInitialCardsTest { + class UpdatePlayerTest { @Nested class Success { @Test - void 초기_카드_분배시_최종_결과에는_모두_2장씩_있어야_한다() { + void 플레이어_카드를_추가하고_업데이트된_Dto를_반환한다() { // given + BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER) + )); blackjackGameManager.createParticipants(List.of("jacob", "seoye")); + blackjackGameManager.drawInitialCards(); // when - blackjackGameManager.drawInitialCards(); - BlackjackResultDto actual = blackjackGameManager.getBlackjackResult(); + ParticipantDto actual = blackjackGameManager.updatePlayer("jacob"); // then - assertThat(actual.playerResultDtoList().get(0).hand()).hasSize(2); - assertThat(actual.playerResultDtoList().get(1).hand()).hasSize(2); + assertThat(actual.name()).isEqualTo("jacob"); + assertThat(actual.hand()).hasSize(3); } } } @@ -156,179 +189,117 @@ class Success { } @Nested - class DrawDealerCardTest { + class getBlackjackResultTest { @Nested class Success { @Test - void 딜러_점수가_16_이하면_카드를_추가로_뽑아야_한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), - card(Rank.NINE, Suit.CLOVER) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - - // when - boolean actual = blackjackGameManager.drawDealerCard(); - - // then - BlackjackResultDto result = blackjackGameManager.getBlackjackResult(); - assertThat(actual).isTrue(); - assertThat(result.playerResultDtoList().getFirst().hand()).hasSize(2); - } - - @Test - void 딜러_점수가_17_이상이면_카드를_추가로_뽑지_않아야_한다() { + void 플레이어가_카드를_추가로_받으면_최종_결과에_반영되어야_한다() { // given BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), - card(Rank.NINE, Suit.CLOVER) + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER) )); blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); + blackjackGameManager.updatePlayer("jacob"); // when - boolean actual = blackjackGameManager.drawDealerCard(); - - // then - BlackjackResultDto result = blackjackGameManager.getBlackjackResult(); - assertThat(actual).isFalse(); - assertThat(result.playerResultDtoList().getFirst().hand()).hasSize(2); - } - - } - } - - @Nested - class DrawCardTest { - - @Nested - class Success { - - @Test - void 카드를_뽑으면_null이_아닌_카드를_반환해야_한다() { - - // when - Card actual = blackjackGameManager.drawCard(); - - // then - assertThat(actual).isNotNull(); - } - - @Test - void 카드가_소진되기_전까지는_카드를_반환해야_한다() { - - // given - Card actual = null; - - // when - for (int i = 0; i < 312; i++) { - actual = blackjackGameManager.drawCard(); - } + BlackjackResultDto actual = blackjackGameManager.getBlackjackResult(); // then - assertThat(actual).isNotNull(); + assertThat(actual.playerResultDtoList().get(0).name()).isEqualTo("jacob"); + assertThat(actual.playerResultDtoList().get(0).hand()).hasSize(3); + assertThat(actual.playerResultDtoList().get(0).hand()).contains("A클로버"); + assertThat(actual.playerResultDtoList().get(1).name()).isEqualTo("seoye"); + assertThat(actual.playerResultDtoList().get(1).hand()).hasSize(2); } } } @Nested - class CalculateDealerResultTest { + class GetBlackjackStatisticsTest { @Nested class Success { @Test - void 딜러_승무패_통계를_플레이어_결과로부터_계산해야_한다() { + void 블랙잭_승리와_패배를_반영해_수익을_계산한다() { // given BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.SPADE), - card(Rank.TEN, Suit.CLOVER), card(Rank.EIGHT, Suit.DIAMOND), - card(Rank.TEN, Suit.DIAMOND), card(Rank.SEVEN, Suit.HEART), - card(Rank.NINE, Suit.CLOVER), card(Rank.SEVEN, Suit.DIAMOND) + card(Rank.TEN, Suit.HEART), card(Rank.NINE, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER), card(Rank.K, Suit.DIAMOND), + card(Rank.TEN, Suit.CLOVER), card(Rank.SEVEN, Suit.DIAMOND) )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye", "brown")); + blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); + blackjackGameManager.setBetAmount("jacob", new BetAmount("1000")); + blackjackGameManager.setBetAmount("seoye", new BetAmount("500")); // when BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); // then - assertThat(actual.dealerStatisticDto().win()).isEqualTo(1); - assertThat(actual.dealerStatisticDto().draw()).isEqualTo(1); - assertThat(actual.dealerStatisticDto().lose()).isEqualTo(1); + assertThat(actual.dealerProfit()).isEqualTo(-1000); + assertThat(actual.playerStatisticDtoList()).hasSize(2); + assertThat(actual.playerStatisticDtoList().get(0).name()).isEqualTo("jacob"); + assertThat(actual.playerStatisticDtoList().get(0).profit()).isEqualTo(1500); + assertThat(actual.playerStatisticDtoList().get(1).name()).isEqualTo("seoye"); + assertThat(actual.playerStatisticDtoList().get(1).profit()).isEqualTo(-500); } - } - } - - @Nested - class generateBlackjackResultDto { - - @Nested - class Success { @Test - void 플레이어가_카드를_추가로_받으면_최종_결과에_반영되어야_한다() { + void 무승부일_때_플레이어_수익은_0이고_딜러_수익에_반영되지_않는다() { // given BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), - card(Rank.ACE, Suit.CLOVER) + card(Rank.TEN, Suit.HEART), card(Rank.EIGHT, Suit.SPADE), + card(Rank.NINE, Suit.CLOVER), card(Rank.NINE, Suit.DIAMOND), + card(Rank.TEN, Suit.CLOVER), card(Rank.SIX, Suit.DIAMOND) )); blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); - blackjackGameManager.updatePlayer("jacob"); + blackjackGameManager.setBetAmount("jacob", new BetAmount("500")); + blackjackGameManager.setBetAmount("seoye", new BetAmount("700")); // when - BlackjackResultDto actual = blackjackGameManager.getBlackjackResult(); + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); // then - assertThat(actual.playerResultDtoList().get(0).name()).isEqualTo("jacob"); - assertThat(actual.playerResultDtoList().get(0).hand()).hasSize(3); - assertThat(actual.playerResultDtoList().get(0).hand()).contains("A클로버"); - assertThat(actual.playerResultDtoList().get(1).name()).isEqualTo("seoye"); - assertThat(actual.playerResultDtoList().get(1).hand()).hasSize(2); + assertThat(actual.dealerProfit()).isEqualTo(700); + assertThat(actual.playerStatisticDtoList().get(0).profit()).isEqualTo(0); + assertThat(actual.playerStatisticDtoList().get(1).profit()).isEqualTo(-700); } - } - } - - @Nested - class UpdatePlayerTest { - - @Nested - class Success { @Test - void 플레이어_카드를_추가하고_업데이트된_Dto를_반환한다() { + void 플레이어가_버스트면_딜러가_버스트여도_패배로_처리한다() { // given BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), - card(Rank.ACE, Suit.CLOVER) + card(Rank.TEN, Suit.CLOVER), card(Rank.EIGHT, Suit.DIAMOND), + card(Rank.NINE, Suit.HEART), card(Rank.SEVEN, Suit.CLOVER), + card(Rank.K, Suit.SPADE), card(Rank.Q, Suit.DIAMOND) )); blackjackGameManager.createParticipants(List.of("jacob", "seoye")); blackjackGameManager.drawInitialCards(); + blackjackGameManager.setBetAmount("jacob", new BetAmount("1000")); + blackjackGameManager.setBetAmount("seoye", new BetAmount("500")); + blackjackGameManager.updatePlayer("seoye"); + blackjackGameManager.drawDealerCard(); // when - ParticipantDto actual = blackjackGameManager.updatePlayer("jacob"); + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); // then - assertThat(actual.name()).isEqualTo("jacob"); - assertThat(actual.hand()).hasSize(3); + assertThat(actual.dealerProfit()).isEqualTo(-500); + assertThat(actual.playerStatisticDtoList().get(0).profit()).isEqualTo(1000); + assertThat(actual.playerStatisticDtoList().get(1).profit()).isEqualTo(-500); } } } From 98f6661d92391ff781449fb9ef456c1d135be4c0 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:27 +0900 Subject: [PATCH 37/98] =?UTF-8?q?test(BlackjackResultDtoTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/dto/BlackjackResultDtoTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/dto/BlackjackResultDtoTest.java diff --git a/src/test/java/dto/BlackjackResultDtoTest.java b/src/test/java/dto/BlackjackResultDtoTest.java new file mode 100644 index 0000000000..c45791c2ce --- /dev/null +++ b/src/test/java/dto/BlackjackResultDtoTest.java @@ -0,0 +1,26 @@ +package dto; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class BlackjackResultDtoTest { + + @Test + void of로_생성하면_딜러와_플레이어_결과를_포함한다() { + // given + ParticipantDto dealerResult = new ParticipantDto("딜러", List.of("10하트", "7스페이드"), 17); + List playerResults = List.of( + new ParticipantDto("jacob", List.of("A클로버", "K다이아몬드"), 21), + new ParticipantDto("seoye", List.of("9하트", "7클로버"), 16) + ); + + // when + BlackjackResultDto actual = BlackjackResultDto.of(dealerResult, playerResults); + + // then + assertThat(actual.dealerResultDto()).isEqualTo(dealerResult); + assertThat(actual.playerResultDtoList()).containsExactlyElementsOf(playerResults); + } +} From a4ea9eb7ccb097f0c6aec04ac9f705896b848035 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:31 +0900 Subject: [PATCH 38/98] =?UTF-8?q?test(BlackjackStatisticsDtoTest):=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=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 --- .../java/dto/BlackjackStatisticsDtoTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/dto/BlackjackStatisticsDtoTest.java diff --git a/src/test/java/dto/BlackjackStatisticsDtoTest.java b/src/test/java/dto/BlackjackStatisticsDtoTest.java new file mode 100644 index 0000000000..e1b64f781e --- /dev/null +++ b/src/test/java/dto/BlackjackStatisticsDtoTest.java @@ -0,0 +1,26 @@ +package dto; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class BlackjackStatisticsDtoTest { + + @Test + void of로_생성하면_딜러_수익과_플레이어_통계를_포함한다() { + // given + int dealerProfit = -500; + List playerStatistics = List.of( + new PlayerStatisticDto("jacob", 1000), + new PlayerStatisticDto("seoye", -500) + ); + + // when + BlackjackStatisticsDto actual = BlackjackStatisticsDto.of(dealerProfit, playerStatistics); + + // then + assertThat(actual.dealerProfit()).isEqualTo(dealerProfit); + assertThat(actual.playerStatisticDtoList()).containsExactlyElementsOf(playerStatistics); + } +} From f2b48ac4f4cb07297968fa352ee4c00c249fc02a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:37 +0900 Subject: [PATCH 39/98] =?UTF-8?q?test(CardMachineTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/card/CardMachineTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/domain/card/CardMachineTest.java b/src/test/java/domain/card/CardMachineTest.java index e38beace06..3301f4fc1e 100644 --- a/src/test/java/domain/card/CardMachineTest.java +++ b/src/test/java/domain/card/CardMachineTest.java @@ -19,13 +19,13 @@ class DrawCardTest { class Success { @Test - void 카드를_뽑으면_null이_아닌_Card를_반환해야_한다() { + void 카드를_정상적으로_뽑으면_Card를_반환해야_한다() { // when Card actual = cardMachine.drawCard(); // then - assertThat(actual).isNotNull(); + assertThat(actual).isInstanceOf(Card.class); } @Test @@ -42,7 +42,6 @@ class Success { // then assertThat(counts).hasSize(52); - assertThat(counts.values()).allMatch(count -> count <= 6); assertThat(counts.values()).allMatch(count -> count == 6); } } From c779f8c9b55e75e70f2dbded53264c0eb75c9a58 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:42 +0900 Subject: [PATCH 40/98] =?UTF-8?q?test(DealerTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/participant/DealerTest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/test/java/domain/participant/DealerTest.java b/src/test/java/domain/participant/DealerTest.java index fb5fb6a1c2..de964478c4 100644 --- a/src/test/java/domain/participant/DealerTest.java +++ b/src/test/java/domain/participant/DealerTest.java @@ -36,4 +36,58 @@ class Success { } } } + + @Nested + class ShouldHitTest { + + @Nested + class Success { + + @Test + void 딜러_점수가_16_이하면_카드를_더_뽑는다() { + + // given + Dealer dealer = new Dealer(); + dealer.addCard(new Card(Rank.TEN, Suit.HEART)); + dealer.addCard(new Card(Rank.SIX, Suit.SPADE)); + + // when + boolean actual = dealer.shouldHit(); + + // then + assertThat(actual).isTrue(); + } + + @Test + void 딜러_점수가_17이면_카드를_더_뽑지_않는다() { + + // given + Dealer dealer = new Dealer(); + dealer.addCard(new Card(Rank.TEN, Suit.HEART)); + dealer.addCard(new Card(Rank.SEVEN, Suit.SPADE)); + + // when + boolean actual = dealer.shouldHit(); + + // then + assertThat(actual).isFalse(); + } + + @Test + void 딜러_점수가_21_초과면_카드를_더_뽑지_않는다() { + + // given + Dealer dealer = new Dealer(); + dealer.addCard(new Card(Rank.TEN, Suit.HEART)); + dealer.addCard(new Card(Rank.NINE, Suit.SPADE)); + dealer.addCard(new Card(Rank.THREE, Suit.CLOVER)); + + // when + boolean actual = dealer.shouldHit(); + + // then + assertThat(actual).isFalse(); + } + } + } } From 92b7197dabed0a0e3f63d2368f511b4cb126b871 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:47 +0900 Subject: [PATCH 41/98] =?UTF-8?q?test(HandTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/card/HandTest.java | 68 ++++++++++++++++++++----- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/src/test/java/domain/card/HandTest.java b/src/test/java/domain/card/HandTest.java index 6422145a9a..1e3860dfa7 100644 --- a/src/test/java/domain/card/HandTest.java +++ b/src/test/java/domain/card/HandTest.java @@ -50,7 +50,7 @@ class Success { } @Nested - class CalculateScoreTest { + class CalculateTotalScoreTest { @Nested class Success { @@ -105,41 +105,81 @@ class Success { } @Nested - class GetCardTest { + class IsBustTest { @Nested class Success { @Test - void 손패가_비어있다면_빈_목록을_반환해야_한다() { + void 최종_점수가_21_초과이면_버스트이다() { // given Hand hand = new Hand(); + hand.addCard(new Card(Rank.THREE, Suit.HEART)); + hand.addCard(new Card(Rank.K, Suit.SPADE)); + hand.addCard(new Card(Rank.NINE, Suit.DIAMOND)); // when - var actual = hand.getCard(); + boolean actual = hand.isBust(); // then - assertThat(actual).isEmpty(); + assertThat(actual).isTrue(); } @Test - void 손패의_카드들을_이름_목록으로_반환해야_한다() { + void 최종_점수가_21_이하이면_버스트가_아니다() { // given Hand hand = new Hand(); - Card firstCard = new Card(Rank.FIVE, Suit.HEART); - Card secondCard = new Card(Rank.J, Suit.DIAMOND); - hand.addCard(firstCard); - hand.addCard(secondCard); + hand.addCard(new Card(Rank.TWO, Suit.HEART)); + hand.addCard(new Card(Rank.K, Suit.SPADE)); + hand.addCard(new Card(Rank.NINE, Suit.DIAMOND)); // when - var actual = hand.getCard(); + boolean actual = hand.isBust(); // then - assertThat(actual) - .hasSize(2) - .containsExactly(firstCard, secondCard); + assertThat(actual).isFalse(); + } + } + } + + @Nested + class IsBlackjackTest { + + @Nested + class Success { + + @Test + void 처음_받은_2장_카드의_최종_점수가_21이면_블랙잭이다() { + + // given + Hand hand = new Hand(); + hand.addCard(new Card(Rank.ACE, Suit.HEART)); + hand.addCard(new Card(Rank.K, Suit.SPADE)); + + // when + boolean actual = hand.isBlackjack(); + + // then + assertThat(actual).isTrue(); + } + + @Test + void 세장_이상을_받아서_최종_점수가_21이면_블랙잭이_아니다() { + + // given + Hand hand = new Hand(); + hand.addCard(new Card(Rank.TEN, Suit.HEART)); + hand.addCard(new Card(Rank.K, Suit.SPADE)); + hand.addCard(new Card(Rank.ACE, Suit.SPADE)); + hand.addCard(new Card(Rank.ACE, Suit.SPADE)); + + // when + boolean actual = hand.isBlackjack(); + + // then + assertThat(actual).isFalse(); } } } From 0583a0f62272e9ab58d723e018379bf35ddb0c72 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:51 +0900 Subject: [PATCH 42/98] =?UTF-8?q?test(HitOrStandTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/game/HitOrStandTest.java | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/test/java/domain/game/HitOrStandTest.java diff --git a/src/test/java/domain/game/HitOrStandTest.java b/src/test/java/domain/game/HitOrStandTest.java new file mode 100644 index 0000000000..69a5f721db --- /dev/null +++ b/src/test/java/domain/game/HitOrStandTest.java @@ -0,0 +1,125 @@ +package domain.game; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class HitOrStandTest { + + @Nested + class FromTest { + + @Nested + class Success { + + @Test + void y를_입력하면_HIT을_반환한다() { + // given + String input = "y"; + + // when + HitOrStand actual = HitOrStand.from(input); + + // then + assertThat(actual).isEqualTo(HitOrStand.HIT); + } + + @Test + void n을_입력하면_STAND를_반환한다() { + // given + String input = "n"; + + // when + HitOrStand actual = HitOrStand.from(input); + + // then + assertThat(actual).isEqualTo(HitOrStand.STAND); + } + + @Test + void 앞뒤_공백이_있어도_정상_처리한다() { + // given + String input = " y "; + + // when + HitOrStand actual = HitOrStand.from(input); + + // then + assertThat(actual).isEqualTo(HitOrStand.HIT); + } + } + + @Nested + class Fail { + + @Test + void y_또는_n가_아니면_예외를_던진다() { + // given + String input = "a"; + + // when & then + assertThatThrownBy(() -> HitOrStand.from(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(HitOrStand.INVALID_YES_NO_INPUT); + } + } + } + + @Nested + class IsHitTest { + + @Test + void HIT이면_true를_반환한다() { + // given + HitOrStand hitOrStand = HitOrStand.HIT; + + // when + boolean actual = hitOrStand.isHit(); + + // then + assertThat(actual).isTrue(); + } + + @Test + void STAND이면_false를_반환한다() { + // given + HitOrStand hitOrStand = HitOrStand.STAND; + + // when + boolean actual = hitOrStand.isHit(); + + // then + assertThat(actual).isFalse(); + } + } + + @Nested + class IsStandTest { + + @Test + void STAND이면_true를_반환한다() { + // given + HitOrStand hitOrStand = HitOrStand.STAND; + + // when + boolean actual = hitOrStand.isStand(); + + // then + assertThat(actual).isTrue(); + } + + @Test + void HIT이면_false를_반환한다() { + // given + HitOrStand hitOrStand = HitOrStand.HIT; + + // when + boolean actual = hitOrStand.isStand(); + + // then + assertThat(actual).isFalse(); + } + } +} From 519dd99862880be7c397580b6fc783b28c40cf61 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:22:56 +0900 Subject: [PATCH 43/98] =?UTF-8?q?test(ParserTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/util/ParserTest.java | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/test/java/util/ParserTest.java b/src/test/java/util/ParserTest.java index 9e5d8a5f73..c323b883ad 100644 --- a/src/test/java/util/ParserTest.java +++ b/src/test/java/util/ParserTest.java @@ -15,15 +15,14 @@ class ParseInputTest { // given String input = "a,b,c"; - String delimiter = ","; // when - List actuals = Parser.parseInput(input); + List actual = Parser.parseInput(input); // then - List expecteds = List.of("a", "b", "c"); + List expected = List.of("a", "b", "c"); for (int i = 0; i < 3; i++) { - Assertions.assertEquals(expecteds.get(i), actuals.get(i)); + Assertions.assertEquals(expected.get(i), actual.get(i)); } } @@ -32,15 +31,14 @@ class ParseInputTest { // given String input = " a ,b ,c "; - String delimiter = ","; // when - List actuals = Parser.parseInput(input); + List actual = Parser.parseInput(input); // then - List expecteds = List.of("a", "b", "c"); + List expected = List.of("a", "b", "c"); for (int i = 0; i < 3; i++) { - Assertions.assertEquals(expecteds.get(i), actuals.get(i)); + Assertions.assertEquals(expected.get(i), actual.get(i)); } } @@ -49,15 +47,14 @@ class ParseInputTest { // given String input = " a b ,b c ,c d "; - String delimiter = ","; // when - List actuals = Parser.parseInput(input); + List actual = Parser.parseInput(input); // then - List expecteds = List.of("a b", "b c", "c d"); + List expected = List.of("a b", "b c", "c d"); for (int i = 0; i < 3; i++) { - Assertions.assertEquals(expecteds.get(i), actuals.get(i)); + Assertions.assertEquals(expected.get(i), actual.get(i)); } } } From 9cb7d691a66cc7c7c636f7a97c5497db34a2eff4 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:23:00 +0900 Subject: [PATCH 44/98] =?UTF-8?q?test(ParticipantDtoTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/dto/ParticipantDtoTest.java | 74 +++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/test/java/dto/ParticipantDtoTest.java diff --git a/src/test/java/dto/ParticipantDtoTest.java b/src/test/java/dto/ParticipantDtoTest.java new file mode 100644 index 0000000000..6a015b29ed --- /dev/null +++ b/src/test/java/dto/ParticipantDtoTest.java @@ -0,0 +1,74 @@ +package dto; + +import static org.assertj.core.api.Assertions.assertThat; + +import domain.card.Card; +import domain.card.Rank; +import domain.card.Suit; +import domain.participant.Dealer; +import domain.participant.Player; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class ParticipantDtoTest { + + @Nested + class FromDealerTest { + + @Test + void 딜러_정보를_모든_패와_점수로_생성한다() { + // given + Dealer dealer = new Dealer(); + dealer.addCard(card(Rank.TEN, Suit.HEART)); + dealer.addCard(card(Rank.SEVEN, Suit.SPADE)); + + // when + ParticipantDto actual = ParticipantDto.from(dealer); + + // then + assertThat(actual.name()).isEqualTo("딜러"); + assertThat(actual.hand()).containsExactly("10하트", "7스페이드"); + assertThat(actual.score()).isEqualTo(17); + } + + @Test + void 딜러_초기_공개_정보를_생성하면_첫_번째_카드만_노출한다() { + // given + Dealer dealer = new Dealer(); + dealer.addCard(card(Rank.ACE, Suit.CLOVER)); + dealer.addCard(card(Rank.K, Suit.DIAMOND)); + + // when + ParticipantDto actual = ParticipantDto.from(dealer, true); + + // then + assertThat(actual.name()).isEqualTo("딜러"); + assertThat(actual.hand()).containsExactly("A클로버"); + assertThat(actual.score()).isEqualTo(21); + } + } + + @Nested + class FromPlayerTest { + + @Test + void 플레이어_정보를_패와_점수로_생성한다() { + // given + Player player = new Player("jacob"); + player.addCard(card(Rank.NINE, Suit.HEART)); + player.addCard(card(Rank.EIGHT, Suit.CLOVER)); + + // when + ParticipantDto actual = ParticipantDto.from(player); + + // then + assertThat(actual.name()).isEqualTo("jacob"); + assertThat(actual.hand()).containsExactly("9하트", "8클로버"); + assertThat(actual.score()).isEqualTo(17); + } + } + + private static Card card(Rank rank, Suit suit) { + return new Card(rank, suit); + } +} From 25891758b9a9cb8411e046e1895c24c2c6003c80 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:23:06 +0900 Subject: [PATCH 45/98] =?UTF-8?q?test(ParticipantsTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/ParticipantsTest.java | 161 +++++++++++++++--- 1 file changed, 135 insertions(+), 26 deletions(-) diff --git a/src/test/java/domain/participant/ParticipantsTest.java b/src/test/java/domain/participant/ParticipantsTest.java index 80e2a83122..ca305db436 100644 --- a/src/test/java/domain/participant/ParticipantsTest.java +++ b/src/test/java/domain/participant/ParticipantsTest.java @@ -2,50 +2,159 @@ import static org.assertj.core.api.Assertions.assertThat; +import domain.card.Card; +import domain.card.Rank; +import domain.card.Suit; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.List; +import java.util.function.Supplier; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; class ParticipantsTest { @Nested - class GetPlayerTest { + class FromTest { + + @Test + void 참가자_이름으로_딜러와_플레이어_묶음을_생성한다() { + // given + List names = List.of("jacob", "seoye"); + + // when + Participants actual = Participants.from(names); + + // then + assertThat(actual.dealer()).isNotNull(); + assertThat(actual.players().getPlayers()).hasSize(2); + assertThat(actual.players().getPlayers().get(0).getName()).isEqualTo("jacob"); + assertThat(actual.players().getPlayers().get(1).getName()).isEqualTo("seoye"); + } + } + + @Nested + class DealerShouldHitTest { + + @Test + void 딜러_점수가_16_이하면_true를_반환한다() { + // given + Participants participants = Participants.from(List.of("jacob", "seoye")); + participants.dealer().addCard(card(Rank.TEN, Suit.HEART)); + participants.dealer().addCard(card(Rank.SIX, Suit.SPADE)); + + // when + boolean actual = participants.dealerShouldHit(); + + // then + assertThat(actual).isTrue(); + } + + @Test + void 딜러_점수가_17_이상이면_false를_반환한다() { + // given + Participants participants = Participants.from(List.of("jacob", "seoye")); + participants.dealer().addCard(card(Rank.TEN, Suit.HEART)); + participants.dealer().addCard(card(Rank.SEVEN, Suit.SPADE)); + + // when + boolean actual = participants.dealerShouldHit(); + + // then + assertThat(actual).isFalse(); + } + } + + @Nested + class DrawInitialCardsTest { - @Nested - class Success { + @Test + void 딜러는_2장_모든_플레이어도_각각_2장을_받는다() { + // given + Participants participants = Participants.from(List.of("jacob", "seoye")); + Supplier supplier = fixedCardSupplier(List.of( + card(Rank.TEN, Suit.HEART), + card(Rank.SIX, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER), + card(Rank.K, Suit.DIAMOND), + card(Rank.NINE, Suit.HEART), + card(Rank.THREE, Suit.CLOVER) + )); - @Test - void 이름에_해당하는_플레이어를_반환해야_한다() { + // when + participants.drawInitialCards(supplier); - // given - Participants participants = createParticipants(); - Player expected = participants.players().getPlayer("jacob"); + // then + assertThat(participants.dealer().getHand()).hasSize(2); + assertThat(participants.players().getPlayer("jacob").getHand()).hasSize(2); + assertThat(participants.players().getPlayer("seoye").getHand()).hasSize(2); + assertThat(participants.dealer().getHand()).containsExactly( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE) + ); + } + } + + @Nested + class DrawCardsByDealerTest { + + @Test + void 딜러에게_카드를_한_장_추가한다() { + // given + Participants participants = Participants.from(List.of("jacob", "seoye")); + participants.dealer().addCard(card(Rank.TEN, Suit.HEART)); + participants.dealer().addCard(card(Rank.SIX, Suit.SPADE)); + Supplier supplier = fixedCardSupplier(List.of(card(Rank.ACE, Suit.CLOVER))); - // when - Player actual = participants.getPlayer("jacob"); + // when + participants.drawCardsByDealer(supplier); - // then - assertThat(actual).isSameAs(expected); - } + // then + assertThat(participants.dealer().getHand()).hasSize(3); + assertThat(participants.dealer().getHand().get(2)).isEqualTo(card(Rank.ACE, Suit.CLOVER)); + } + } - @Test - void 해당_이름의_플레이어가_없으면_null을_반환해야_한다() { + @Nested + class DrawCardsByPlayerTest { - // given - Participants participants = createParticipants(); + @Test + void 이름으로_찾은_플레이어에게_카드를_추가하고_플레이어를_반환한다() { + // given + Participants participants = Participants.from(List.of("jacob", "seoye")); + Supplier supplier = fixedCardSupplier(List.of(card(Rank.FOUR, Suit.DIAMOND))); - // when - Player actual = participants.getPlayer("brown"); + // when + Player actual = participants.drawCardsByPlayer("jacob", supplier); - // then - assertThat(actual).isNull(); - } + // then + assertThat(actual.getName()).isEqualTo("jacob"); + assertThat(actual.getHand()).containsExactly(card(Rank.FOUR, Suit.DIAMOND)); } } - private Participants createParticipants() { - Dealer dealer = new Dealer(); - Players players = new Players(List.of("jacob", "seoye")); - return new Participants(dealer, players); + @Nested + class GetPlayerTest { + + @Test + void 이름으로_플레이어를_조회한다() { + // given + Participants participants = Participants.from(List.of("jacob", "seoye")); + + // when + Player actual = participants.getPlayer("seoye"); + + // then + assertThat(actual.getName()).isEqualTo("seoye"); + } } + + private static Supplier fixedCardSupplier(List cards) { + Deque deque = new ArrayDeque<>(cards); + return deque::removeFirst; + } + + private static Card card(Rank rank, Suit suit) { + return new Card(rank, suit); + } + } From 7da70e22fbc9f0414b235207495afa75061563d0 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:23:10 +0900 Subject: [PATCH 46/98] =?UTF-8?q?test(PlayerNameTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/participant/PlayerNameTest.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/test/java/domain/participant/PlayerNameTest.java b/src/test/java/domain/participant/PlayerNameTest.java index d2c22c5256..e6873e08d6 100644 --- a/src/test/java/domain/participant/PlayerNameTest.java +++ b/src/test/java/domain/participant/PlayerNameTest.java @@ -1,7 +1,7 @@ package domain.participant; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import exception.BlackjackException; import java.util.stream.Stream; @@ -21,8 +21,7 @@ class Success { @ParameterizedTest @MethodSource("successCases") - void 이름이_2글자_이상_5글자_이하면_정상_생성된다(String input) { - + void 이름이_2글자_이상_5글자_이하면_생성된다(String input) { // when PlayerName actual = new PlayerName(input); @@ -34,7 +33,7 @@ static Stream successCases() { return Stream.of( Arguments.of("ab"), Arguments.of("abcde"), - Arguments.of("성 열") + Arguments.of("성열") ); } } @@ -43,9 +42,8 @@ static Stream successCases() { class Fail { @ParameterizedTest - @ValueSource(strings = {"a", "abcdef", "aa aaa"}) - void 이름_길이가_2글자_미만_또는_5글자_초과면_예외가_발생한다(String input) { - + @ValueSource(strings = {"a", "abcdef"}) + void 이름_길이가_범위를_벗어나면_예외가_발생한다(String input) { // when & then assertThatThrownBy(() -> new PlayerName(input)) .isInstanceOf(IllegalArgumentException.class) @@ -55,7 +53,6 @@ class Fail { @ParameterizedTest @ValueSource(strings = {"", " ", " "}) void 이름이_공백이면_예외가_발생한다(String input) { - // when & then assertThatThrownBy(() -> new PlayerName(input)) .isInstanceOf(IllegalArgumentException.class) From 94613d9269482504630d3cba1071f35b3b238789 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:23:14 +0900 Subject: [PATCH 47/98] =?UTF-8?q?test(PlayerStatisticDtoTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/dto/PlayerStatisticDtoTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/java/dto/PlayerStatisticDtoTest.java diff --git a/src/test/java/dto/PlayerStatisticDtoTest.java b/src/test/java/dto/PlayerStatisticDtoTest.java new file mode 100644 index 0000000000..18311339b9 --- /dev/null +++ b/src/test/java/dto/PlayerStatisticDtoTest.java @@ -0,0 +1,23 @@ +package dto; + +import static org.assertj.core.api.Assertions.assertThat; + +import domain.participant.Player; +import org.junit.jupiter.api.Test; + +class PlayerStatisticDtoTest { + + @Test + void of로_생성하면_플레이어_이름과_수익을_반환한다() { + // given + Player player = new Player("jacob"); + int profit = 1200; + + // when + PlayerStatisticDto actual = PlayerStatisticDto.of(player, profit); + + // then + assertThat(actual.name()).isEqualTo("jacob"); + assertThat(actual.profit()).isEqualTo(profit); + } +} From 5ca14ad7fe0c3423345ccdefd1b26c1d8dd773b1 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:23:18 +0900 Subject: [PATCH 48/98] =?UTF-8?q?test(PlayersTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/participant/PlayersTest.java | 224 +++++++++++++----- 1 file changed, 164 insertions(+), 60 deletions(-) diff --git a/src/test/java/domain/participant/PlayersTest.java b/src/test/java/domain/participant/PlayersTest.java index 16b13805bb..c4655c3cf0 100644 --- a/src/test/java/domain/participant/PlayersTest.java +++ b/src/test/java/domain/participant/PlayersTest.java @@ -1,16 +1,22 @@ package domain.participant; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import domain.card.Card; +import domain.card.Rank; +import domain.card.Suit; import exception.BlackjackException; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.List; +import java.util.function.Supplier; import java.util.stream.Stream; import org.junit.jupiter.api.Nested; -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; +import org.junit.jupiter.params.provider.ValueSource; class PlayersTest { @@ -20,108 +26,206 @@ class ConstructorTest { @Nested class Success { - @Test - void 플레이어_이름_목록으로_Players를_생성한다() { - - // given - List input = List.of("jacob", "seoye"); - + @ParameterizedTest + @MethodSource("successCases") + void 인원수와_이름이_유효하면_생성된다(List names, int expectedSize) { // when - Players players = new Players(input); + Players actual = new Players(names); // then - assertThat(players.getPlayers()).hasSize(2); - assertThat(players.getPlayers()) - .extracting(Player::getName) - .containsExactly("jacob", "seoye"); + assertThat(actual.getPlayers()).hasSize(expectedSize); + } + + static Stream successCases() { + return Stream.of( + Arguments.of(List.of("aa", "bb"), 2), + Arguments.of(List.of("a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1"), 8) + ); } } @Nested class Fail { - @Test - void 플레이어_이름이_중복되면_예외가_발생한다() { - + @ParameterizedTest + @ValueSource(ints = {1, 9}) + void 인원수가_범위를_벗어나면_예외가_발생한다(int size) { // given - List input = List.of("jacob", "jacob"); + List names = java.util.stream.IntStream.range(0, size) + .mapToObj(i -> String.format("p%d", i)) + .toList(); // when & then - assertThatThrownBy(() -> new Players(input)) + assertThatThrownBy(() -> new Players(names)) .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_DUPLICATED); + .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_COUNT_OUT_OF_RANGE); } @ParameterizedTest - @MethodSource("playerCountOutOfRangeCases") - void 플레이어_수가_2명_미만_또는_8명_초과면_예외가_발생한다(List input) { - + @MethodSource("duplicatedCases") + void 이름이_중복되면_예외가_발생한다(List names) { // when & then - assertThatThrownBy(() -> new Players(input)) + assertThatThrownBy(() -> new Players(names)) .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_COUNT_OUT_OF_RANGE); + .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_DUPLICATED); } - static Stream playerCountOutOfRangeCases() { + static Stream duplicatedCases() { return Stream.of( - Arguments.of(List.of("a1")), - Arguments.of(List.of("a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9")) + Arguments.of(List.of("aa", "aa")), + Arguments.of(List.of("aa", "bb", "aa")) ); } } } @Nested - class GetPlayersTest { + class GetPlayerTest { - @Nested - class Success { + @ParameterizedTest + @MethodSource("successCases") + void 이름으로_플레이어를_조회한다(String targetName) { + // given + Players players = new Players(List.of("jacob", "seoye")); - @Test - void 플레이어_목록은_수정_불가능한_리스트여야_한다() { + // when + Player actual = players.getPlayer(targetName); - // given - Players players = new Players(List.of("jacob", "seoye")); + // then + assertThat(actual.getName()).isEqualTo(targetName); + } - // when & then - assertThatThrownBy(() -> players.getPlayers().add(new Player("brown"))) - .isInstanceOf(UnsupportedOperationException.class); - } + static Stream successCases() { + return Stream.of( + Arguments.of("jacob"), + Arguments.of("seoye") + ); + } + + @ParameterizedTest + @ValueSource(strings = {"brown", "jason"}) + void 없는_이름이면_예외가_발생한다(String targetName) { + // given + Players players = new Players(List.of("jacob", "seoye")); + + // when & then + assertThatThrownBy(() -> players.getPlayer(targetName)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.NOT_FOUND_PLAYER); } } @Nested - class GetPlayerTest { + class GetPlayersTest { - @Nested - class Success { + @ParameterizedTest + @MethodSource("sizeCases") + void 전체_플레이어_목록을_조회한다(List names, int expectedSize) { + // when + Players actual = new Players(names); - @Test - void 이름으로_플레이어를_조회한다() { + // then + assertThat(actual.getPlayers()).hasSize(expectedSize); + } - // given - Players players = new Players(List.of("jacob", "seoye")); + static Stream sizeCases() { + return Stream.of( + Arguments.of(List.of("aa", "bb"), 2), + Arguments.of(List.of("aa", "bb", "cc"), 3) + ); + } - // when - Player actual = players.getPlayer("jacob"); + @ParameterizedTest + @ValueSource(strings = {"zz"}) + void 반환_목록은_수정할_수_없다(String newPlayerName) { + // given + Players players = new Players(List.of("aa", "bb")); + Player newPlayer = new Player(newPlayerName + "1"); - // then - assertThat(actual).isNotNull(); - assertThat(actual.getName()).isEqualTo("jacob"); - } + // when & then + assertThatThrownBy(() -> players.getPlayers().add(newPlayer)) + .isInstanceOf(UnsupportedOperationException.class); + } + } - @Test - void 없는_이름을_조회하면_null을_반환한다() { + @Nested + class DrawInitialCardsTest { + + @ParameterizedTest + @MethodSource("drawCases") + void 모든_플레이어는_초기_카드를_2장씩_받는다(List names) { + // given + Players players = new Players(names); + Supplier supplier = fixedCardSupplier(List.of( + card(Rank.TEN, Suit.HEART), + card(Rank.SIX, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER), + card(Rank.K, Suit.DIAMOND), + card(Rank.TWO, Suit.HEART), + card(Rank.THREE, Suit.SPADE), + card(Rank.FOUR, Suit.CLOVER), + card(Rank.FIVE, Suit.DIAMOND) + )); + + // when + players.drawInitialCards(supplier); + + // then + assertThat(players.getPlayers()) + .allSatisfy(player -> assertThat(player.getHand()).hasSize(2)); + } - // given - Players players = new Players(List.of("jacob", "seoye")); + static Stream drawCases() { + return Stream.of( + Arguments.of(List.of("aa", "bb")), + Arguments.of(List.of("aa", "bb", "cc", "dd")) + ); + } + } - // when - Player actual = players.getPlayer("brown"); + @Nested + class AddCardTest { - // then - assertThat(actual).isNull(); - } + @ParameterizedTest + @MethodSource("successCases") + void 이름으로_찾은_플레이어에게_카드를_추가한다(String targetName) { + // given + Players players = new Players(List.of("jacob", "seoye")); + Card card = card(Rank.NINE, Suit.HEART); + + // when + players.addCard(targetName, card); + + // then + assertThat(players.getPlayer(targetName).getHand()).containsExactly(card); + } + + static Stream successCases() { + return Stream.of( + Arguments.of("jacob"), + Arguments.of("seoye") + ); } + + @ParameterizedTest + @ValueSource(strings = {"brown"}) + void 없는_플레이어에게_추가하면_예외가_발생한다(String targetName) { + // given + Players players = new Players(List.of("jacob", "seoye")); + + // when & then + assertThatThrownBy(() -> players.addCard(targetName, card(Rank.NINE, Suit.HEART))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.NOT_FOUND_PLAYER); + } + } + + private static Supplier fixedCardSupplier(List cards) { + Deque deque = new ArrayDeque<>(cards); + return deque::removeFirst; + } + + private static Card card(Rank rank, Suit suit) { + return new Card(rank, suit); } } From bd95be88e638e22404ba0c66d1577a9f6f85b6ab Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 13:23:24 +0900 Subject: [PATCH 49/98] =?UTF-8?q?test(PlayerTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/participant/PlayerTest.java | 126 ++++++------------ 1 file changed, 42 insertions(+), 84 deletions(-) diff --git a/src/test/java/domain/participant/PlayerTest.java b/src/test/java/domain/participant/PlayerTest.java index 2e0b4c0ef5..4c160a204f 100644 --- a/src/test/java/domain/participant/PlayerTest.java +++ b/src/test/java/domain/participant/PlayerTest.java @@ -5,7 +5,6 @@ import domain.card.Card; import domain.card.Rank; import domain.card.Suit; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -14,110 +13,69 @@ class PlayerTest { @Nested class ConstructorTest { - @Nested - class Success { + @Test + void 생성하면_이름을_반환할_수_있다() { + // given + String name = "jacob"; - @Test - void 게임_참가자_조건이_맞으면_성공_이다() { + // when + Player actual = new Player(name); - // given - String name = "jacob"; - - // when - Player player = new Player(name); - String actual = player.getName(); - - // then - String expected = "jacob"; - Assertions.assertEquals(expected, actual); - } + // then + assertThat(actual.getName()).isEqualTo(name); } } @Nested - class AddCardTest { - - @Nested - class Success { - - @Test - void 카드를_추가하면_손패에_카드가_저장되어야_한다() { + class SetBetAmountTest { - // given - Player player = new Player("jacob"); - Card card = new Card(Rank.ACE, Suit.HEART); + @Test + void 배팅_금액을_설정하면_조회할_수_있다() { + // given + Player player = new Player("jacob"); + BetAmount betAmount = new BetAmount("2000"); - // when - player.addCard(card); + // when + player.setBetAmount(betAmount); - // then - assertThat(player.getHand().size()).isEqualTo(1); - } + // then + assertThat(player.getBetAmount()).isEqualTo(2000); } } @Nested - class IsBustTest { + class IsBlackjackTest { - @Nested - class Success { + @Test + void 처음_두_장이_21점이면_블랙잭이다() { + // given + Player player = new Player("jacob"); + player.addCard(card(Rank.ACE, Suit.HEART)); + player.addCard(card(Rank.K, Suit.SPADE)); - @Test - void 플레이어의_점수가_21_초과이면_버스트이다() { + // when + boolean actual = player.isBlackjack(); - // given - Player player = new Player("jacob"); - Card card1 = new Card(Rank.TEN, Suit.HEART); - Card card2 = new Card(Rank.TEN, Suit.HEART); - Card card3 = new Card(Rank.TEN, Suit.HEART); - - // when - player.addCard(card1); - player.addCard(card2); - player.addCard(card3); - - // then - assertThat(player.isBust()).isTrue(); - } - - @Test - void 플레이어의_점수가_21_이하이면_버스트가_아니다() { + // then + assertThat(actual).isTrue(); + } - // given - Player player = new Player("jacob"); - Card card1 = new Card(Rank.TEN, Suit.HEART); - Card card2 = new Card(Rank.ACE, Suit.HEART); + @Test + void 처음_두_장이_21점이_아니면_블랙잭이_아니다() { + // given + Player player = new Player("jacob"); + player.addCard(card(Rank.TEN, Suit.HEART)); + player.addCard(card(Rank.NINE, Suit.SPADE)); - // when - player.addCard(card1); - player.addCard(card2); + // when + boolean actual = player.isBlackjack(); - // then - assertThat(player.isBust()).isFalse(); - } + // then + assertThat(actual).isFalse(); } } - @Nested - class CalculateScoreTest { - - @Nested - class Success { - - @Test - void 플레이어의_현재_점수를_반환해야_한다() { - - // given - Player player = new Player("jacob"); - player.addCard(new Card(Rank.TEN, Suit.HEART)); - player.addCard(new Card(Rank.THREE, Suit.SPADE)); - - // when - int actual = player.calculateScore(); - - // then - assertThat(actual).isEqualTo(13); - } - } + private static Card card(Rank rank, Suit suit) { + return new Card(rank, suit); } } From fcb8756998afb7bd5a4db0078c2231772743cb5d Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 21:48:26 +0900 Subject: [PATCH 50/98] =?UTF-8?q?refactor(Player):=20isBlackjack=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20Participant=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Player.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/domain/participant/Player.java b/src/main/java/domain/participant/Player.java index 65e4c7f3fe..e556de54d4 100644 --- a/src/main/java/domain/participant/Player.java +++ b/src/main/java/domain/participant/Player.java @@ -18,10 +18,6 @@ public void setBetAmount(BetAmount betAmount) { this.betAmount = betAmount; } - public boolean isBlackjack() { - return hand.isBlackjack(); - } - public int getBetAmount() { return betAmount.getBetAmount(); } From 7bb91ad687265c12a4667a3e6c543b82ca588a20 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 21:48:35 +0900 Subject: [PATCH 51/98] =?UTF-8?q?refactor(Participant):=20isBlackjack=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20Participant=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Participant.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/domain/participant/Participant.java b/src/main/java/domain/participant/Participant.java index 23d3a8f296..f17a776c92 100644 --- a/src/main/java/domain/participant/Participant.java +++ b/src/main/java/domain/participant/Participant.java @@ -24,6 +24,10 @@ public int calculateScore() { return hand.calculateTotalScore(); } + public boolean isBlackjack() { + return hand.isBlackjack(); + } + public List getHand() { return hand.getCard(); } From 2544ed370c2d78f00ea57cc2a1f77072d245beee Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 21:49:19 +0900 Subject: [PATCH 52/98] =?UTF-8?q?feat(Participant):=20=EB=94=9C=EB=9F=AC?= =?UTF-8?q?=EA=B0=80=20=EB=B8=94=EB=9E=99=EC=9E=AD=EC=9D=B8=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EA=B3=A0=EB=A0=A4=ED=95=B4=EC=84=9C=20judgePlayerR?= =?UTF-8?q?esult=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B0=8F=20calculatePlay?= =?UTF-8?q?erProfit=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/game/BlackjackGameManager.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index b5717e5e6a..775a6d9d9d 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -87,10 +87,16 @@ private Result judgePlayerResult(Dealer dealer, Player player) { return Result.LOSE; } if (dealer.isBust()) { - return Result.WIN; + return Result.BLACKJACK_WIN; + } + if (player.isBlackjack() && dealer.isBlackjack()) { + return Result.DRAW; + } + if (player.isBlackjack()) { + return Result.BLACKJACK_WIN; } if (player.calculateScore() > dealer.calculateScore()) { - return Result.WIN; + return Result.BLACKJACK_WIN; } if (player.calculateScore() == dealer.calculateScore()) { return Result.DRAW; @@ -99,7 +105,7 @@ private Result judgePlayerResult(Dealer dealer, Player player) { } private int calculatePlayerProfit(Player player, Result result) { - if (result.equals(Result.WIN) && player.isBlackjack()) { + if (result.equals(Result.BLACKJACK_WIN)) { return player.getBetAmount() + player.getBetAmount() / 2; } if (result.equals(Result.WIN)) { From 10b0abf7ce22f04fa3e4354bb275285a617db1e6 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 21:50:48 +0900 Subject: [PATCH 53/98] =?UTF-8?q?feat(Result):=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EA=B0=80=20=EB=B8=94=EB=9E=99=EC=9E=AD?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EA=B8=B4=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=EB=A5=BC=20=EB=94=B0=EB=A1=9C=20=EB=B6=84=EB=A6=AC=ED=95=B4?= =?UTF-8?q?=EC=84=9C=20=EA=B5=AC=ED=98=84=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B0=9D=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/domain/game/Result.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/domain/game/Result.java b/src/main/java/domain/game/Result.java index 5b601a3f69..853b16d8ca 100644 --- a/src/main/java/domain/game/Result.java +++ b/src/main/java/domain/game/Result.java @@ -1,6 +1,7 @@ package domain.game; public enum Result { + BLACKJACK_WIN, WIN, DRAW, LOSE, From f6e8e9a8c24d6e2f51125c36a6316fad1834c8ac Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 21:56:23 +0900 Subject: [PATCH 54/98] =?UTF-8?q?refactor(Participant):=20getName=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EC=83=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Participant.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/participant/Participant.java b/src/main/java/domain/participant/Participant.java index f17a776c92..705b3b60a6 100644 --- a/src/main/java/domain/participant/Participant.java +++ b/src/main/java/domain/participant/Participant.java @@ -4,7 +4,7 @@ import domain.card.Hand; import java.util.List; -public class Participant { +public abstract class Participant { protected final Hand hand; @@ -31,4 +31,6 @@ public boolean isBlackjack() { public List getHand() { return hand.getCard(); } + + public abstract String getName(); } From 121e289b097ec83dcd17aa3fd7f6325d9d8a7329 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 21:56:44 +0900 Subject: [PATCH 55/98] =?UTF-8?q?refactor(Dealer):=20getName=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=9C=84=EC=B9=98=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/domain/participant/Dealer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/participant/Dealer.java b/src/main/java/domain/participant/Dealer.java index b3bb6f59c6..04d90246fe 100644 --- a/src/main/java/domain/participant/Dealer.java +++ b/src/main/java/domain/participant/Dealer.java @@ -19,11 +19,11 @@ public List getOnlyFirstHand() { return newHand; } - public String getName() { - return DEALER_NAME; - } - public boolean shouldHit() { return this.calculateScore() <= DEALER_HIT_MAX_SCORE; } + + public String getName() { + return DEALER_NAME; + } } From dda1d77d26bf53a0a9bbb051c578e91e33abf27e Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 21:56:53 +0900 Subject: [PATCH 56/98] =?UTF-8?q?refactor(Player):=20getName=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=9C=84=EC=B9=98=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/domain/participant/Player.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/participant/Player.java b/src/main/java/domain/participant/Player.java index e556de54d4..b55fff4394 100644 --- a/src/main/java/domain/participant/Player.java +++ b/src/main/java/domain/participant/Player.java @@ -10,10 +10,6 @@ public Player(String name) { this.playerName = new PlayerName(name); } - public String getName() { - return playerName.name(); - } - public void setBetAmount(BetAmount betAmount) { this.betAmount = betAmount; } @@ -21,4 +17,8 @@ public void setBetAmount(BetAmount betAmount) { public int getBetAmount() { return betAmount.getBetAmount(); } + + public String getName() { + return playerName.name(); + } } From 06892b36e4da3281acd97121a13cfe73de3e052e Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:10:20 +0900 Subject: [PATCH 57/98] =?UTF-8?q?refactor(BlackjackController):=20?= =?UTF-8?q?=EB=B2=A0=ED=8C=85=20=EA=B8=88=EC=95=A1=EC=9D=84=20=EB=AA=A8?= =?UTF-8?q?=EB=91=90=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EC=9D=80=20=EB=92=A4=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98=EB=8A=94=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=A5=BC=20=ED=98=B8=EC=B6=9C=ED=95=98?= =?UTF-8?q?=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 --- .../java/controller/BlackjackController.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index f93a05efdf..791eb89b20 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -6,6 +6,7 @@ import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; +import java.util.ArrayList; import java.util.List; import util.Parser; import view.InputView; @@ -35,8 +36,8 @@ public void start() { } private void initializeGame() { - inputPlayers(); - inputBetAmounts(); + List playerNames = inputPlayerNames(); + inputBetAmounts(playerNames); blackjackGameManager.drawInitialCards(); List playerDtoList = blackjackGameManager.generatePlayerDtoList(); @@ -46,17 +47,17 @@ private void initializeGame() { outputView.printHandList(dealerDto, playerDtoList); } - private void inputBetAmounts() { - List playerDtoList = blackjackGameManager.generatePlayerDtoList(); - for (ParticipantDto participantDto : playerDtoList) { - String betAmountInput = inputView.inputBetAmount(participantDto.name()); - blackjackGameManager.setBetAmount(participantDto.name(), new BetAmount(betAmountInput)); + private void inputBetAmounts(List playerNames) { + List betAmounts = new ArrayList<>(); + for (String playerName : playerNames) { + String betAmountInput = inputView.inputBetAmount(playerName); + betAmounts.add(new BetAmount(betAmountInput)); } + blackjackGameManager.createParticipants(playerNames, betAmounts); } - private void inputPlayers() { - List input = Parser.parseInput(inputView.inputPlayers()); - blackjackGameManager.createParticipants(input); + private List inputPlayerNames() { + return Parser.parseInput(inputView.inputPlayers()); } private void inputHitOrStandOnPlayer() { From d8a5c956d8f892d1027044effc3f3c3ef962cce6 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:11:22 +0900 Subject: [PATCH 58/98] =?UTF-8?q?refactor(BlackjackGameManager):=20?= =?UTF-8?q?=EB=B2=A0=ED=8C=85=EA=B8=88=EC=95=A1=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9D=B8=EC=88=98?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EC=95=84=20=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A5=BC=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20createParticipants=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=A5=BC=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/domain/game/BlackjackGameManager.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 775a6d9d9d..7bd90198ea 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -22,8 +22,8 @@ public BlackjackGameManager() { this.cardMachine = new CardMachine(); } - public void createParticipants(List names) { - participants = Participants.from(names); + public void createParticipants(List playerNames, List betAmounts) { + participants = Participants.of(playerNames, betAmounts); } public void drawInitialCards() { @@ -124,9 +124,4 @@ public boolean isHit(HitOrStand hitOrStand) { public boolean isStand(HitOrStand hitOrStand) { return hitOrStand.isStand(); } - - public void setBetAmount(String name, BetAmount betAmount) { - Player player = participants.getPlayer(name); - player.setBetAmount(betAmount); - } } From 59b88167ed064f75aa1a4e254f9226cbfec2ea19 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:15:05 +0900 Subject: [PATCH 59/98] =?UTF-8?q?refactor(Participants):=20=EB=B2=A0?= =?UTF-8?q?=ED=8C=85=EA=B8=88=EC=95=A1=20=EA=B0=9D=EC=B2=B4=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9D=B8=EC=88=98=EB=A1=9C=20?= =?UTF-8?q?=EB=B0=9B=EC=95=84=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=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/domain/participant/Participants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/participant/Participants.java b/src/main/java/domain/participant/Participants.java index ac79813dfd..79a1e0cc1c 100644 --- a/src/main/java/domain/participant/Participants.java +++ b/src/main/java/domain/participant/Participants.java @@ -6,9 +6,9 @@ public record Participants(Dealer dealer, Players players) { - public static Participants from(List names) { + public static Participants of(List names, List betAmounts) { Dealer dealer = new Dealer(); - Players players = new Players(names); + Players players = new Players(names, betAmounts); return new Participants(dealer, players); } From a34b82ef34c07e498141b7ae5da57954ef7d1e6c Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:15:24 +0900 Subject: [PATCH 60/98] =?UTF-8?q?refactor(Players):=20=EB=B2=A0=ED=8C=85?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EA=B0=9D=EC=B2=B4=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=9D=B8=EC=88=98=EB=A1=9C=20=EB=B0=9B?= =?UTF-8?q?=EC=95=84=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EB=A5=BC=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=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 --- src/main/java/domain/participant/Players.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/participant/Players.java b/src/main/java/domain/participant/Players.java index 0cbd3ce9ba..a36072ad0e 100644 --- a/src/main/java/domain/participant/Players.java +++ b/src/main/java/domain/participant/Players.java @@ -19,11 +19,11 @@ public class Players { private final List players; - public Players(List names) { + public Players(List names, List betAmounts) { validatePlayerNames(names); List players = new ArrayList<>(); - for (String name : names) { - players.add(new Player(name)); + for (int i = 0; i < names.size(); i++) { + players.add(new Player(names.get(i), betAmounts.get(i))); } this.players = players; } From a290e93d7337f42e5bdc6e4b07bc5561b60dae97 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:16:09 +0900 Subject: [PATCH 61/98] =?UTF-8?q?refactor(Player):=20BetAmount=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=EB=A5=BC=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EC=95=84=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EB=A5=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20setBetAmount=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Player.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/participant/Player.java b/src/main/java/domain/participant/Player.java index b55fff4394..dd0b95bf08 100644 --- a/src/main/java/domain/participant/Player.java +++ b/src/main/java/domain/participant/Player.java @@ -3,14 +3,11 @@ public class Player extends Participant { private final PlayerName playerName; - private BetAmount betAmount; + private final BetAmount betAmount; - public Player(String name) { + public Player(String name, BetAmount betAmount) { super(); this.playerName = new PlayerName(name); - } - - public void setBetAmount(BetAmount betAmount) { this.betAmount = betAmount; } From 5131913413ee01f4ef605995f42d7dafa5b6a388 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:31:38 +0900 Subject: [PATCH 62/98] =?UTF-8?q?refactor(BlackjackController):=20PlayerNa?= =?UTF-8?q?me=EC=9D=84=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=83=9D=EC=84=B1=ED=95=B4=EC=84=9C=20BlackjackGam?= =?UTF-8?q?eManager=EB=A1=9C=20=EB=84=98=EA=B2=A8=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98?= =?UTF-8?q?=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 --- .../java/controller/BlackjackController.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index 791eb89b20..f1aa7b8624 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -3,6 +3,7 @@ import domain.game.BlackjackGameManager; import domain.game.HitOrStand; import domain.participant.BetAmount; +import domain.participant.PlayerName; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; @@ -36,8 +37,10 @@ public void start() { } private void initializeGame() { - List playerNames = inputPlayerNames(); - inputBetAmounts(playerNames); + List playerNames = inputPlayerNames(); + List betAmounts = inputBetAmounts(playerNames); + blackjackGameManager.createParticipants(playerNames, betAmounts); + blackjackGameManager.drawInitialCards(); List playerDtoList = blackjackGameManager.generatePlayerDtoList(); @@ -47,17 +50,22 @@ private void initializeGame() { outputView.printHandList(dealerDto, playerDtoList); } - private void inputBetAmounts(List playerNames) { + private List inputBetAmounts(List playerNames) { List betAmounts = new ArrayList<>(); - for (String playerName : playerNames) { - String betAmountInput = inputView.inputBetAmount(playerName); + for (PlayerName playerName : playerNames) { + String betAmountInput = inputView.inputBetAmount(playerName.name()); betAmounts.add(new BetAmount(betAmountInput)); } - blackjackGameManager.createParticipants(playerNames, betAmounts); + return betAmounts; } - private List inputPlayerNames() { - return Parser.parseInput(inputView.inputPlayers()); + private List inputPlayerNames() { + List names = Parser.parseInput(inputView.inputPlayers()); + List playerNames = new ArrayList<>(); + for (String name : names) { + playerNames.add(new PlayerName(name)); + } + return playerNames; } private void inputHitOrStandOnPlayer() { From e13c47b5c086f089e505181b434d5a59e591435e Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:33:11 +0900 Subject: [PATCH 63/98] =?UTF-8?q?refactor(BlackjackGameManager):=20PlayerN?= =?UTF-8?q?ame=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EB=84=98=EA=B2=A8?= =?UTF-8?q?=EB=B0=9B=EC=95=84=20Participants=EB=A5=BC=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=ED=95=98=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 --- src/main/java/domain/game/BlackjackGameManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 7bd90198ea..ce2d00d581 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -6,6 +6,7 @@ import domain.participant.Dealer; import domain.participant.Participants; import domain.participant.Player; +import domain.participant.PlayerName; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; @@ -22,7 +23,7 @@ public BlackjackGameManager() { this.cardMachine = new CardMachine(); } - public void createParticipants(List playerNames, List betAmounts) { + public void createParticipants(List playerNames, List betAmounts) { participants = Participants.of(playerNames, betAmounts); } From f98a848949ef3ae03a89bb7b189982cbcb04ff3a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:33:31 +0900 Subject: [PATCH 64/98] =?UTF-8?q?refactor(Participants):=20PlayerName=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EB=84=98=EA=B2=A8?= =?UTF-8?q?=EB=B0=9B=EC=95=84=20Players=EB=A5=BC=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=ED=95=98=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 --- src/main/java/domain/participant/Participants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/participant/Participants.java b/src/main/java/domain/participant/Participants.java index 79a1e0cc1c..7d4283d2da 100644 --- a/src/main/java/domain/participant/Participants.java +++ b/src/main/java/domain/participant/Participants.java @@ -6,9 +6,9 @@ public record Participants(Dealer dealer, Players players) { - public static Participants of(List names, List betAmounts) { + public static Participants of(List playerNames, List betAmounts) { Dealer dealer = new Dealer(); - Players players = new Players(names, betAmounts); + Players players = new Players(playerNames, betAmounts); return new Participants(dealer, players); } From 368f1bb7fcf6d1d5e186d25606fc4e46472acfad Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:33:53 +0900 Subject: [PATCH 65/98] =?UTF-8?q?refactor(Players):=20PlayerName=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EB=84=98=EA=B2=A8?= =?UTF-8?q?=EB=B0=9B=EC=95=84=20Player=EB=A5=BC=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=ED=95=98=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 --- src/main/java/domain/participant/Players.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/participant/Players.java b/src/main/java/domain/participant/Players.java index a36072ad0e..afd300b009 100644 --- a/src/main/java/domain/participant/Players.java +++ b/src/main/java/domain/participant/Players.java @@ -19,7 +19,7 @@ public class Players { private final List players; - public Players(List names, List betAmounts) { + public Players(List names, List betAmounts) { validatePlayerNames(names); List players = new ArrayList<>(); for (int i = 0; i < names.size(); i++) { @@ -28,12 +28,12 @@ public Players(List names, List betAmounts) { this.players = players; } - private void validatePlayerNames(List names) { + private void validatePlayerNames(List names) { validatePlayerDuplication(names); validatePlayerCount(names.size()); } - private void validatePlayerDuplication(List names) { + private void validatePlayerDuplication(List names) { if (new HashSet<>(names).size() != names.size()) { throw new BlackjackException(PLAYER_DUPLICATED); } From 145bbc200ce2bafb1a54feec1dab5d000fd186e2 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:35:00 +0900 Subject: [PATCH 66/98] =?UTF-8?q?feat(PlayerName):=20Players=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EB=82=B4=20=EA=B2=80=EC=A6=9D=20=EA=B3=BC=EC=A0=95?= =?UTF-8?q?=EC=97=90=EC=84=9C=20PlayerName=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EC=8B=9C=20=EC=9D=B4=EB=A6=84=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B9=84=EA=B5=90=20=EA=B0=80=EB=8A=A5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20equals=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/PlayerName.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/domain/participant/PlayerName.java b/src/main/java/domain/participant/PlayerName.java index 898a3fce40..e8c1204290 100644 --- a/src/main/java/domain/participant/PlayerName.java +++ b/src/main/java/domain/participant/PlayerName.java @@ -1,6 +1,7 @@ package domain.participant; import exception.BlackjackException; +import java.util.Objects; public record PlayerName(String name) { @@ -30,4 +31,13 @@ private void validateNotBlank(String name) { throw new BlackjackException(PLAYER_NAME_BLANK); } } + + @Override + public boolean equals(Object object) { + if (object == null || getClass() != object.getClass()) { + return false; + } + PlayerName that = (PlayerName) object; + return Objects.equals(name, that.name); + } } From ca54fc8a3101076a5ec0dca4496adea47723b0b4 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:35:29 +0900 Subject: [PATCH 67/98] =?UTF-8?q?refactor(Player):=20PlayerName=EC=9D=84?= =?UTF-8?q?=20=EB=84=98=EA=B2=A8=EB=B0=9B=EC=95=84=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=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 --- src/main/java/domain/participant/Player.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/participant/Player.java b/src/main/java/domain/participant/Player.java index dd0b95bf08..a877f9b20a 100644 --- a/src/main/java/domain/participant/Player.java +++ b/src/main/java/domain/participant/Player.java @@ -5,9 +5,9 @@ public class Player extends Participant { private final PlayerName playerName; private final BetAmount betAmount; - public Player(String name, BetAmount betAmount) { + public Player(PlayerName playerName, BetAmount betAmount) { super(); - this.playerName = new PlayerName(name); + this.playerName = playerName; this.betAmount = betAmount; } From 276d6ff501aef54acbb615a4859f292979347c5a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:36:42 +0900 Subject: [PATCH 68/98] =?UTF-8?q?feat(PlayerName):=20hashCode=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/PlayerName.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/domain/participant/PlayerName.java b/src/main/java/domain/participant/PlayerName.java index e8c1204290..1d28a7a032 100644 --- a/src/main/java/domain/participant/PlayerName.java +++ b/src/main/java/domain/participant/PlayerName.java @@ -40,4 +40,9 @@ public boolean equals(Object object) { PlayerName that = (PlayerName) object; return Objects.equals(name, that.name); } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } } From 214ee2d2a1dd6287d97c39822a6929131ea4aeca Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:41:50 +0900 Subject: [PATCH 69/98] =?UTF-8?q?refactor(PlayerName):=20isPositive?= =?UTF-8?q?=EB=A5=BC=20isNotPositive=EB=A1=9C=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20NUMBER=5F?= =?UTF-8?q?FORMAT=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/BetAmount.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/participant/BetAmount.java b/src/main/java/domain/participant/BetAmount.java index 3a23606ff5..6dfa4fa4a3 100644 --- a/src/main/java/domain/participant/BetAmount.java +++ b/src/main/java/domain/participant/BetAmount.java @@ -2,8 +2,9 @@ public class BetAmount { - public static final String INVALID_BET_AMOUNT_NUMBER = "배팅 금액은 숫자여야 합니다."; - public static final String INVALID_BET_AMOUNT_POSITIVE = "배팅 금액은 양수여야 합니다."; + private static final String INVALID_BET_AMOUNT_NUMBER = "배팅 금액은 숫자여야 합니다."; + private static final String INVALID_BET_AMOUNT_POSITIVE = "배팅 금액은 양수여야 합니다."; + private static final String NUMBER_FORMAT = "-?\\d+"; private final int betAmount; @@ -24,16 +25,16 @@ private void validateNumber(String betAmountInput) { } private static boolean isNotNumber(String betAmountInput) { - return !betAmountInput.matches("-*\\d+"); + return !betAmountInput.matches(NUMBER_FORMAT); } private void validatePositive(String betAmountInput) { - if (isPositive(betAmountInput)) { + if (isNotPositive(betAmountInput)) { throw new IllegalArgumentException(INVALID_BET_AMOUNT_POSITIVE); } } - private static boolean isPositive(String betAmountInput) { + private static boolean isNotPositive(String betAmountInput) { return Integer.parseInt(betAmountInput) <= 0; } From a1c6f29710fd47e9cc6d38f2ce8a186c6cc2bf0a Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:58:23 +0900 Subject: [PATCH 70/98] =?UTF-8?q?refactor(Hand):=20calculateAceCount=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=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/domain/card/Hand.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/card/Hand.java b/src/main/java/domain/card/Hand.java index 350aebff24..9c6b48035a 100644 --- a/src/main/java/domain/card/Hand.java +++ b/src/main/java/domain/card/Hand.java @@ -46,10 +46,9 @@ private Integer calculateInitialBaseScore() { } private int calculateAceCount() { - return cards.stream() + return (int) cards.stream() .filter(Card::isAce) - .toList() - .size(); + .count(); } private int calculateTotalScoreWithAceCalculation(int score, int aceCount) { From 2757c76647a3af8a2cb26cbd9fb7c619f544e7f7 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sat, 14 Mar 2026 22:58:45 +0900 Subject: [PATCH 71/98] =?UTF-8?q?refactor(OutputView):=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20printResult?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/OutputView.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 1845ddadf6..ee8f9b223f 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -66,11 +66,4 @@ public void printBlackjackStatistics(BlackjackStatisticsDto blackjackStatistics) playerStatisticDto.name(), playerStatisticDto.profit()); } } - - private String printResult(int result, String name) { - if (result == 0) { - return ""; - } - return " " + result + name; - } } From eee034c65a90d9b1ac01511b1221a1c824092cdb Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:20:09 +0900 Subject: [PATCH 72/98] =?UTF-8?q?refactor(BlackjackJudge):=20BlackjackGame?= =?UTF-8?q?Manager=EC=9D=98=20judgePlayerResult()=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B0=8F=20calculatePlayerProfit()=EB=A5=BC=20Blac?= =?UTF-8?q?kjackJudge=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/domain/game/BlackjackJudge.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/java/domain/game/BlackjackJudge.java diff --git a/src/main/java/domain/game/BlackjackJudge.java b/src/main/java/domain/game/BlackjackJudge.java new file mode 100644 index 0000000000..02d0473733 --- /dev/null +++ b/src/main/java/domain/game/BlackjackJudge.java @@ -0,0 +1,33 @@ +package domain.game; + +import domain.participant.Dealer; +import domain.participant.Player; + +public record BlackjackJudge() { + + public Result judgePlayerResult(Dealer dealer, Player player) { + if (player.isBust()) { + return Result.LOSE; + } + if (dealer.isBust()) { + return Result.BLACKJACK_WIN; + } + if (player.isBlackjack() && dealer.isBlackjack()) { + return Result.DRAW; + } + if (player.isBlackjack()) { + return Result.BLACKJACK_WIN; + } + if (player.calculateScore() > dealer.calculateScore()) { + return Result.BLACKJACK_WIN; + } + if (player.calculateScore() == dealer.calculateScore()) { + return Result.DRAW; + } + return Result.LOSE; + } + + public int calculatePlayerProfit(Player player, Result result) { + return result.getProfit(player.getBetAmount()); + } +} From 14cfcc15ccbc058f8bca2f75f7478fb5ef191910 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:20:58 +0900 Subject: [PATCH 73/98] =?UTF-8?q?refactor(BlackjackGameManager):=20Blackja?= =?UTF-8?q?ckJudge=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20judgePlayerResult(),=20calculatePlayerProfit()=EB=A5=BC=20Bl?= =?UTF-8?q?ackjackJudge=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 --- .../domain/game/BlackjackGameManager.java | 42 ++----------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index ce2d00d581..5d0fac1569 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -3,7 +3,6 @@ import domain.card.Card; import domain.card.CardMachine; import domain.participant.BetAmount; -import domain.participant.Dealer; import domain.participant.Participants; import domain.participant.Player; import domain.participant.PlayerName; @@ -17,10 +16,12 @@ public class BlackjackGameManager { private final CardMachine cardMachine; + private final BlackjackJudge blackjackJudge; private Participants participants; public BlackjackGameManager() { this.cardMachine = new CardMachine(); + this.blackjackJudge = new BlackjackJudge(); } public void createParticipants(List playerNames, List betAmounts) { @@ -74,8 +75,8 @@ public BlackjackStatisticsDto getBlackjackStatistics() { List playerStatisticDtoList = new ArrayList<>(); int dealerProfit = 0; for (Player player : participants.players().getPlayers()) { - Result result = judgePlayerResult(participants.dealer(), player); - int playerProfit = calculatePlayerProfit(player, result); + Result result = blackjackJudge.judgePlayerResult(participants.dealer(), player); + int playerProfit = blackjackJudge.calculatePlayerProfit(player, result); dealerProfit += playerProfit * -1; playerStatisticDtoList.add(PlayerStatisticDto.of(player, playerProfit)); } @@ -83,41 +84,6 @@ public BlackjackStatisticsDto getBlackjackStatistics() { return BlackjackStatisticsDto.of(dealerProfit, playerStatisticDtoList); } - private Result judgePlayerResult(Dealer dealer, Player player) { - if (player.isBust()) { - return Result.LOSE; - } - if (dealer.isBust()) { - return Result.BLACKJACK_WIN; - } - if (player.isBlackjack() && dealer.isBlackjack()) { - return Result.DRAW; - } - if (player.isBlackjack()) { - return Result.BLACKJACK_WIN; - } - if (player.calculateScore() > dealer.calculateScore()) { - return Result.BLACKJACK_WIN; - } - if (player.calculateScore() == dealer.calculateScore()) { - return Result.DRAW; - } - return Result.LOSE; - } - - private int calculatePlayerProfit(Player player, Result result) { - if (result.equals(Result.BLACKJACK_WIN)) { - return player.getBetAmount() + player.getBetAmount() / 2; - } - if (result.equals(Result.WIN)) { - return player.getBetAmount(); - } - if (result.equals(Result.LOSE)) { - return player.getBetAmount() * -1; - } - return 0; - } - public boolean isHit(HitOrStand hitOrStand) { return hitOrStand.isHit(); } From afb17615a1ae0900d412bea1af442e5145236265 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:22:56 +0900 Subject: [PATCH 74/98] =?UTF-8?q?refactor(Result):=20BlackjackJudge?= =?UTF-8?q?=EC=9D=98=20calculatePlayerProfit()=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=82=B4=EC=9A=A9=EC=9D=84=20Result=EA=B0=80=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=EC=A7=80=EB=8F=84=EB=A1=9D=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 --- src/main/java/domain/game/Result.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/game/Result.java b/src/main/java/domain/game/Result.java index 853b16d8ca..ed18480f8d 100644 --- a/src/main/java/domain/game/Result.java +++ b/src/main/java/domain/game/Result.java @@ -1,9 +1,19 @@ package domain.game; public enum Result { - BLACKJACK_WIN, - WIN, - DRAW, - LOSE, + BLACKJACK_WIN(1.5), + WIN(1), + DRAW(0), + LOSE(-1), ; + + private final double multiple; + + Result(double multiple) { + this.multiple = multiple; + } + + public int getProfit(int betAmount) { + return (int) this.multiple * betAmount; + } } From 0df7db2ef9ea306f3e4cbdb6c10a267ace2ced98 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:23:47 +0900 Subject: [PATCH 75/98] =?UTF-8?q?refactor(BlackjackJudge):=20=ED=94=8C?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=96=B4=EA=B0=80=20=EB=B8=94=EB=9E=99?= =?UTF-8?q?=EC=9E=AD=EC=9D=B4=20=EC=95=84=EB=8B=8C=20=EC=A0=90=EC=88=98?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EA=B2=BC=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?WIN=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=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/domain/game/BlackjackJudge.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/domain/game/BlackjackJudge.java b/src/main/java/domain/game/BlackjackJudge.java index 02d0473733..e89d67f799 100644 --- a/src/main/java/domain/game/BlackjackJudge.java +++ b/src/main/java/domain/game/BlackjackJudge.java @@ -19,7 +19,7 @@ public Result judgePlayerResult(Dealer dealer, Player player) { return Result.BLACKJACK_WIN; } if (player.calculateScore() > dealer.calculateScore()) { - return Result.BLACKJACK_WIN; + return Result.WIN; } if (player.calculateScore() == dealer.calculateScore()) { return Result.DRAW; From 529ca7c2c5c1e0fb4f33ea997ddce9aaf5f7fa5f Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:42:17 +0900 Subject: [PATCH 76/98] =?UTF-8?q?refactor(BlackjackJudge):=20calculatePlay?= =?UTF-8?q?erProfit=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/game/BlackjackJudge.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/domain/game/BlackjackJudge.java b/src/main/java/domain/game/BlackjackJudge.java index e89d67f799..47ce3463d9 100644 --- a/src/main/java/domain/game/BlackjackJudge.java +++ b/src/main/java/domain/game/BlackjackJudge.java @@ -26,8 +26,4 @@ public Result judgePlayerResult(Dealer dealer, Player player) { } return Result.LOSE; } - - public int calculatePlayerProfit(Player player, Result result) { - return result.getProfit(player.getBetAmount()); - } } From cd917e1e1431a552ec49d21b9dae0c508d5f4091 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:42:35 +0900 Subject: [PATCH 77/98] =?UTF-8?q?refactor(BetAmount):=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20public=EC=9C=BC=EB=A1=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/domain/participant/BetAmount.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/participant/BetAmount.java b/src/main/java/domain/participant/BetAmount.java index 6dfa4fa4a3..6dc072846b 100644 --- a/src/main/java/domain/participant/BetAmount.java +++ b/src/main/java/domain/participant/BetAmount.java @@ -2,8 +2,8 @@ public class BetAmount { - private static final String INVALID_BET_AMOUNT_NUMBER = "배팅 금액은 숫자여야 합니다."; - private static final String INVALID_BET_AMOUNT_POSITIVE = "배팅 금액은 양수여야 합니다."; + public static final String INVALID_BET_AMOUNT_NUMBER = "배팅 금액은 숫자여야 합니다."; + public static final String INVALID_BET_AMOUNT_POSITIVE = "배팅 금액은 양수여야 합니다."; private static final String NUMBER_FORMAT = "-?\\d+"; private final int betAmount; From ae02ed2094a2254b4cc838a3038526dceb2bf8b3 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:43:07 +0900 Subject: [PATCH 78/98] =?UTF-8?q?refactor(BlackjackController):=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EA=B0=80=20=EB=B2=84?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=9D=B4=EB=A9=B4=20=EB=8D=94=EC=9D=B4?= =?UTF-8?q?=EC=83=81=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EB=BD=91=EC=A7=80=20?= =?UTF-8?q?=EB=AA=BB=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/BlackjackController.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index f1aa7b8624..d421cbe09f 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -77,7 +77,7 @@ private void inputHitOrStandOnPlayer() { private void inputHitOrStand(String name, List hand) { HitOrStand hitOrStand = HitOrStand.from(inputView.inputHitOrStand(name)); - if (blackjackGameManager.isStand(hitOrStand)) { + if (hitOrStand.isStand()) { outputView.printlnHand(name, hand); return; } @@ -86,13 +86,17 @@ private void inputHitOrStand(String name, List hand) { } private void drawCardOnPlayer(String name, HitOrStand hitOrStand) { - while (blackjackGameManager.isHit(hitOrStand)) { + while (canDrawContinue(name, hitOrStand)) { ParticipantDto playerDto = blackjackGameManager.updatePlayer(name); outputView.printlnHand(name, playerDto.hand()); hitOrStand = HitOrStand.from(inputView.inputHitOrStand(name)); } } + private boolean canDrawContinue(String name, HitOrStand hitOrStand) { + return hitOrStand.isHit() && !blackjackGameManager.playerIsBust(name); + } + private void printBlackjackResult() { BlackjackResultDto blackjackResultDto = blackjackGameManager.getBlackjackResult(); outputView.printBlackjackResult(blackjackResultDto); From 1bb8255941981fcbc3b397ec07b69144ec7899c5 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:43:39 +0900 Subject: [PATCH 79/98] =?UTF-8?q?refactor(BlackjackGameManager):=20isHit,?= =?UTF-8?q?=20isStand=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20=EB=B0=8F=20playerIsBust=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/game/BlackjackGameManager.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/domain/game/BlackjackGameManager.java b/src/main/java/domain/game/BlackjackGameManager.java index 5d0fac1569..6daf67fda7 100644 --- a/src/main/java/domain/game/BlackjackGameManager.java +++ b/src/main/java/domain/game/BlackjackGameManager.java @@ -76,7 +76,7 @@ public BlackjackStatisticsDto getBlackjackStatistics() { int dealerProfit = 0; for (Player player : participants.players().getPlayers()) { Result result = blackjackJudge.judgePlayerResult(participants.dealer(), player); - int playerProfit = blackjackJudge.calculatePlayerProfit(player, result); + int playerProfit = result.getProfit(player.getBetAmount()); dealerProfit += playerProfit * -1; playerStatisticDtoList.add(PlayerStatisticDto.of(player, playerProfit)); } @@ -84,11 +84,7 @@ public BlackjackStatisticsDto getBlackjackStatistics() { return BlackjackStatisticsDto.of(dealerProfit, playerStatisticDtoList); } - public boolean isHit(HitOrStand hitOrStand) { - return hitOrStand.isHit(); - } - - public boolean isStand(HitOrStand hitOrStand) { - return hitOrStand.isStand(); + public boolean playerIsBust(String name) { + return participants.playerIsBust(name); } } From 4c28283efb871dfc8d2c6da66f793d615641a6fa Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:43:55 +0900 Subject: [PATCH 80/98] =?UTF-8?q?refactor(Participants):=20playerIsBust=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Participants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/participant/Participants.java b/src/main/java/domain/participant/Participants.java index 7d4283d2da..7db7e9fbcc 100644 --- a/src/main/java/domain/participant/Participants.java +++ b/src/main/java/domain/participant/Participants.java @@ -31,7 +31,7 @@ public Player drawCardsByPlayer(String name, Supplier cardSupplier) { return players.getPlayer(name); } - public Player getPlayer(String name) { - return players.getPlayer(name); + public boolean playerIsBust(String name) { + return players.playerIsBust(name); } } From 3da7d09e48f9e953caa62d76542fc522e048a3f8 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:44:03 +0900 Subject: [PATCH 81/98] =?UTF-8?q?refactor(Players):=20playerIsBust=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/Players.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/domain/participant/Players.java b/src/main/java/domain/participant/Players.java index afd300b009..6daec7e6a6 100644 --- a/src/main/java/domain/participant/Players.java +++ b/src/main/java/domain/participant/Players.java @@ -67,4 +67,8 @@ public void addCard(String name, Card card) { Player player = getPlayer(name); player.addCard(card); } + + public boolean playerIsBust(String name) { + return getPlayer(name).isBust(); + } } From 7650a5af58247aba141a64ba9e391e6d2fb36d7b Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 16:51:55 +0900 Subject: [PATCH 82/98] =?UTF-8?q?refactor(Players):=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EA=B0=80=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EB=A1=9C=20=EB=BD=91=EC=95=98=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EB=B2=84=EC=8A=A4=ED=8A=B8=EC=9D=B4=EB=A9=B4=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EB=BD=91=EC=9D=84=EC=A7=80=20?= =?UTF-8?q?=EB=AC=BC=EC=96=B4=EB=B3=B4=EC=A7=80=20=EC=95=8A=EA=B3=A0=20?= =?UTF-8?q?=EB=8B=A4=EC=9D=8C=20=EC=B0=A8=EB=A1=80=EB=A1=9C=20=EB=84=98?= =?UTF-8?q?=EC=96=B4=EA=B0=80=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/BlackjackController.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index d421cbe09f..f4f8906b3f 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -86,15 +86,14 @@ private void inputHitOrStand(String name, List hand) { } private void drawCardOnPlayer(String name, HitOrStand hitOrStand) { - while (canDrawContinue(name, hitOrStand)) { + do { ParticipantDto playerDto = blackjackGameManager.updatePlayer(name); outputView.printlnHand(name, playerDto.hand()); - hitOrStand = HitOrStand.from(inputView.inputHitOrStand(name)); - } + } while (canDrawContinue(name)); } - private boolean canDrawContinue(String name, HitOrStand hitOrStand) { - return hitOrStand.isHit() && !blackjackGameManager.playerIsBust(name); + private boolean canDrawContinue(String name) { + return !blackjackGameManager.playerIsBust(name) && HitOrStand.from(inputView.inputHitOrStand(name)).isHit(); } private void printBlackjackResult() { From 38c446b244cb90ccaf1355a4bf9a409e158d7008 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 17:00:58 +0900 Subject: [PATCH 83/98] =?UTF-8?q?refactor(BlackjackController):=20drawCard?= =?UTF-8?q?OnPlayer=20=EB=A9=94=EC=84=9C=EB=93=9C=20hitOrStand=20=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=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/controller/BlackjackController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/controller/BlackjackController.java b/src/main/java/controller/BlackjackController.java index f4f8906b3f..3d9cccfd47 100644 --- a/src/main/java/controller/BlackjackController.java +++ b/src/main/java/controller/BlackjackController.java @@ -82,10 +82,10 @@ private void inputHitOrStand(String name, List hand) { return; } - drawCardOnPlayer(name, hitOrStand); + drawCardOnPlayer(name); } - private void drawCardOnPlayer(String name, HitOrStand hitOrStand) { + private void drawCardOnPlayer(String name) { do { ParticipantDto playerDto = blackjackGameManager.updatePlayer(name); outputView.printlnHand(name, playerDto.hand()); From ecaf295a94a6275d9c6467e85749c2d4f52e9c0c Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 17:56:51 +0900 Subject: [PATCH 84/98] =?UTF-8?q?refactor(Card):=20equals=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/card/Card.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/domain/card/Card.java b/src/main/java/domain/card/Card.java index 303921458c..e472792276 100644 --- a/src/main/java/domain/card/Card.java +++ b/src/main/java/domain/card/Card.java @@ -9,14 +9,4 @@ public int getScore() { public boolean isAce() { return rank.isAce(); } - - @Override - public boolean equals(Object o) { - if (o == null || getClass() != o.getClass()) { - return false; - } - Card card = (Card) o; - return rank == card.rank && suit == card.suit; - } - } From 8549a01700e17b6a8632f54cce7b69ee2085f26b Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 17:59:04 +0900 Subject: [PATCH 85/98] =?UTF-8?q?refactor(BlackjackJudge):=20=EC=8A=B9?= =?UTF-8?q?=ED=8C=A8=20=ED=8C=90=EB=8B=A8=20=EB=A9=94=EC=84=9C=EB=93=9C=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/domain/game/BlackjackJudge.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/game/BlackjackJudge.java b/src/main/java/domain/game/BlackjackJudge.java index 47ce3463d9..82247916a3 100644 --- a/src/main/java/domain/game/BlackjackJudge.java +++ b/src/main/java/domain/game/BlackjackJudge.java @@ -9,15 +9,15 @@ public Result judgePlayerResult(Dealer dealer, Player player) { if (player.isBust()) { return Result.LOSE; } - if (dealer.isBust()) { - return Result.BLACKJACK_WIN; - } if (player.isBlackjack() && dealer.isBlackjack()) { return Result.DRAW; } if (player.isBlackjack()) { return Result.BLACKJACK_WIN; } + if (dealer.isBust()) { + return Result.WIN; + } if (player.calculateScore() > dealer.calculateScore()) { return Result.WIN; } From 22d2ee1eed30bb9a87420c1eee55220db6ed2a29 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 17:59:49 +0900 Subject: [PATCH 86/98] =?UTF-8?q?fix(Result):=20=EC=8B=A4=EC=88=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=B2=84=EA=B7=B8=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/domain/game/Result.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/domain/game/Result.java b/src/main/java/domain/game/Result.java index ed18480f8d..9aecb8afd9 100644 --- a/src/main/java/domain/game/Result.java +++ b/src/main/java/domain/game/Result.java @@ -14,6 +14,6 @@ public enum Result { } public int getProfit(int betAmount) { - return (int) this.multiple * betAmount; + return (int) (betAmount * this.multiple); } } From 09a2d3d0a967d5ea550b5dd3ad5a908367b04731 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:00:21 +0900 Subject: [PATCH 87/98] =?UTF-8?q?refactor(BetAmount):=20BlackjackException?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=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 --- src/main/java/domain/participant/BetAmount.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/participant/BetAmount.java b/src/main/java/domain/participant/BetAmount.java index 6dc072846b..4c414d1198 100644 --- a/src/main/java/domain/participant/BetAmount.java +++ b/src/main/java/domain/participant/BetAmount.java @@ -1,5 +1,7 @@ package domain.participant; +import exception.BlackjackException; + public class BetAmount { public static final String INVALID_BET_AMOUNT_NUMBER = "배팅 금액은 숫자여야 합니다."; @@ -20,7 +22,7 @@ private void validate(String betAmountInput) { private void validateNumber(String betAmountInput) { if (isNotNumber(betAmountInput)) { - throw new IllegalArgumentException(INVALID_BET_AMOUNT_NUMBER); + throw new BlackjackException(INVALID_BET_AMOUNT_NUMBER); } } @@ -30,7 +32,7 @@ private static boolean isNotNumber(String betAmountInput) { private void validatePositive(String betAmountInput) { if (isNotPositive(betAmountInput)) { - throw new IllegalArgumentException(INVALID_BET_AMOUNT_POSITIVE); + throw new BlackjackException(INVALID_BET_AMOUNT_POSITIVE); } } From 522fad1fb43c605579e90741926e7377283b99a2 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:17:37 +0900 Subject: [PATCH 88/98] =?UTF-8?q?test(HandTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/card/HandTest.java | 66 +++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/test/java/domain/card/HandTest.java b/src/test/java/domain/card/HandTest.java index 1e3860dfa7..3bd0b346b1 100644 --- a/src/test/java/domain/card/HandTest.java +++ b/src/test/java/domain/card/HandTest.java @@ -1,6 +1,7 @@ package domain.card; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -144,6 +145,71 @@ class Success { } } + @Nested + class GetFirstCardTest { + + @Nested + class Success { + + @Test + void 첫번째_카드를_반환한다() { + + // given + Hand hand = new Hand(); + Card firstCard = new Card(Rank.ACE, Suit.HEART); + Card secondCard = new Card(Rank.K, Suit.SPADE); + hand.addCard(firstCard); + hand.addCard(secondCard); + + // when + Card actual = hand.getFirstCard(); + + // then + assertThat(actual).isEqualTo(firstCard); + } + } + } + + @Nested + class GetCardTest { + + @Nested + class Success { + + @Test + void 손패의_전체_카드를_순서대로_반환한다() { + + // given + Hand hand = new Hand(); + Card firstCard = new Card(Rank.ACE, Suit.HEART); + Card secondCard = new Card(Rank.K, Suit.SPADE); + hand.addCard(firstCard); + hand.addCard(secondCard); + + // when + var actual = hand.getCard(); + + // then + assertThat(actual) + .hasSize(2) + .containsExactly(firstCard, secondCard); + } + + @Test + void 반환한_목록은_외부에서_수정할_수_없다() { + + // given + Hand hand = new Hand(); + hand.addCard(new Card(Rank.ACE, Suit.HEART)); + var cards = hand.getCard(); + + // when & then + assertThatThrownBy(() -> cards.add(new Card(Rank.K, Suit.SPADE))) + .isInstanceOf(UnsupportedOperationException.class); + } + } + } + @Nested class IsBlackjackTest { From f712103e30d2eea80ed18d1425765aaeb3bbe010 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:19:31 +0900 Subject: [PATCH 89/98] =?UTF-8?q?test(BlackjackGameManagerTest):=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=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 --- .../domain/game/BlackjackGameManagerTest.java | 574 +++++++++--------- 1 file changed, 287 insertions(+), 287 deletions(-) diff --git a/src/test/java/domain/game/BlackjackGameManagerTest.java b/src/test/java/domain/game/BlackjackGameManagerTest.java index 24d2792913..bee9a88fa3 100644 --- a/src/test/java/domain/game/BlackjackGameManagerTest.java +++ b/src/test/java/domain/game/BlackjackGameManagerTest.java @@ -6,10 +6,10 @@ import domain.card.Rank; import domain.card.Suit; import domain.participant.BetAmount; +import domain.participant.PlayerName; import dto.BlackjackResultDto; import dto.BlackjackStatisticsDto; import dto.ParticipantDto; -import factory.BlackjackControllerFactory; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; @@ -18,356 +18,359 @@ class BlackjackGameManagerTest { - private final BlackjackControllerFactory blackjackControllerFactory = new BlackjackControllerFactory(); - private final BlackjackGameManager blackjackGameManager = blackjackControllerFactory.blackjackGameManager(); - @Nested class DrawDealerCardTest { - @Nested - class Success { - - @Test - void 딜러_점수가_16_이하면_카드를_추가로_뽑아야_한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), - card(Rank.NINE, Suit.CLOVER) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - - // when - boolean actual = blackjackGameManager.drawDealerCard(); - - // then - BlackjackResultDto result = blackjackGameManager.getBlackjackResult(); - assertThat(actual).isTrue(); - assertThat(result.playerResultDtoList().getFirst().hand()).hasSize(2); - } - - @Test - void 딜러_점수가_17_이상이면_카드를_추가로_뽑지_않아야_한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), - card(Rank.NINE, Suit.CLOVER) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - - // when - boolean actual = blackjackGameManager.drawDealerCard(); - - // then - BlackjackResultDto result = blackjackGameManager.getBlackjackResult(); - assertThat(actual).isFalse(); - assertThat(result.playerResultDtoList().getFirst().hand()).hasSize(2); - } + @Test + void 딜러_점수가_16_이하면_카드를_한장_추가한다() { + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), + card(Rank.NINE, Suit.CLOVER) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + + // when + boolean actual = blackjackGameManager.drawDealerCard(); + + // then + ParticipantDto dealerDto = blackjackGameManager.generateDealerDto(); + assertThat(actual).isTrue(); + assertThat(dealerDto.hand()).containsExactly("10하트", "6스페이드", "9클로버"); } - } - @Nested - class UpdatePlayerTest { + @Test + void 딜러_점수가_17_이상이면_카드를_추가하지_않는다() { - @Nested - class Success { - - @Test - void 플레이어_카드를_추가하고_업데이트된_Dto를_반환한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), - card(Rank.ACE, Suit.CLOVER) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - - // when - ParticipantDto actual = blackjackGameManager.updatePlayer("jacob"); - - // then - assertThat(actual.name()).isEqualTo("jacob"); - assertThat(actual.hand()).hasSize(3); - } + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + + // when + boolean actual = blackjackGameManager.drawDealerCard(); + + // then + ParticipantDto dealerDto = blackjackGameManager.generateDealerDto(); + assertThat(actual).isFalse(); + assertThat(dealerDto.hand()).containsExactly("10하트", "7스페이드"); } } @Nested - class GenerateInitialDealerDtoTest { - - @Nested - class Success { + class UpdatePlayerTest { - @Test - void 딜러의_초기_공개_Dto를_생성해야_한다() { + @Test + void 플레이어에게_카드를_추가하고_업데이트된_Dto를_반환한다() { - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); - // when - ParticipantDto actual = blackjackGameManager.generateInitialDealerDto(); + // when + ParticipantDto actual = blackjackGameManager.updatePlayer("jacob"); - // then - assertThat(actual.name()).isEqualTo("딜러"); - assertThat(actual.hand()).hasSize(1); - } + // then + assertThat(actual.name()).isEqualTo("jacob"); + assertThat(actual.hand()).containsExactly("2클로버", "3다이아몬드", "A클로버"); + assertThat(actual.score()).isEqualTo(16); } } @Nested - class GenerateDealerDtoTest { + class GenerateInitialDealerDtoTest { - @Nested - class Success { + @Test + void 딜러의_초기_공개_Dto를_생성한다() { - @Test - void 딜러의_최종_Dto를_생성해야_한다() { + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + + // when + ParticipantDto actual = blackjackGameManager.generateInitialDealerDto(); + + // then + assertThat(actual.name()).isEqualTo("딜러"); + assertThat(actual.hand()).containsExactly("10하트"); + assertThat(actual.score()).isEqualTo(16); + } + } - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); + @Nested + class GenerateDealerDtoTest { - // when - ParticipantDto actual = blackjackGameManager.generateDealerDto(); + @Test + void 딜러의_전체_손패_Dto를_생성한다() { - // then - assertThat(actual.name()).isEqualTo("딜러"); - assertThat(actual.hand()).hasSize(2); - } + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + + // when + ParticipantDto actual = blackjackGameManager.generateDealerDto(); + + // then + assertThat(actual.name()).isEqualTo("딜러"); + assertThat(actual.hand()).containsExactly("10하트", "6스페이드"); + assertThat(actual.score()).isEqualTo(16); } } @Nested class GeneratePlayersDtoTest { - @Nested - class Success { - - @Test - void 플레이어_Dto_목록을_생성해야_한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), - card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - - // when - List actual = blackjackGameManager.generatePlayerDtoList(); - - // then - assertThat(actual).hasSize(2); - assertThat(actual.get(0).name()).isEqualTo("jacob"); - assertThat(actual.get(1).name()).isEqualTo("seoye"); - } + @Test + void 플레이어_Dto_목록을_생성한다() { + + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.NINE, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER), card(Rank.K, Suit.DIAMOND), + card(Rank.NINE, Suit.HEART), card(Rank.SEVEN, Suit.CLOVER) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + + // when + List actual = blackjackGameManager.generatePlayerDtoList(); + + // then + assertThat(actual).hasSize(2); + assertThat(actual.get(0).name()).isEqualTo("jacob"); + assertThat(actual.get(0).hand()).containsExactly("A클로버", "K다이아몬드"); + assertThat(actual.get(1).name()).isEqualTo("seoye"); + assertThat(actual.get(1).hand()).containsExactly("9하트", "7클로버"); } } @Nested class getBlackjackResultTest { - @Nested - class Success { + @Test + void 플레이어가_카드를_추가로_받으면_최종_결과에_반영된다() { - @Test - void 플레이어가_카드를_추가로_받으면_최종_결과에_반영되어야_한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TWO, Suit.CLOVER), card(Rank.THREE, Suit.DIAMOND), + card(Rank.TEN, Suit.CLOVER), card(Rank.NINE, Suit.DIAMOND), card(Rank.FOUR, Suit.HEART), card(Rank.FIVE, Suit.SPADE), card(Rank.ACE, Suit.CLOVER) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - blackjackGameManager.updatePlayer("jacob"); - - // when - BlackjackResultDto actual = blackjackGameManager.getBlackjackResult(); - - // then - assertThat(actual.playerResultDtoList().get(0).name()).isEqualTo("jacob"); - assertThat(actual.playerResultDtoList().get(0).hand()).hasSize(3); - assertThat(actual.playerResultDtoList().get(0).hand()).contains("A클로버"); - assertThat(actual.playerResultDtoList().get(1).name()).isEqualTo("seoye"); - assertThat(actual.playerResultDtoList().get(1).hand()).hasSize(2); - } + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + blackjackGameManager.updatePlayer("jacob"); + + // when + BlackjackResultDto actual = blackjackGameManager.getBlackjackResult(); + + // then + assertThat(actual.playerResultDtoList()).hasSize(2); + assertThat(actual.playerResultDtoList().get(0).name()).isEqualTo("jacob"); + assertThat(actual.playerResultDtoList().get(0).hand()).containsExactly("10클로버", "9다이아몬드", "A클로버"); + assertThat(actual.playerResultDtoList().get(1).name()).isEqualTo("seoye"); + assertThat(actual.playerResultDtoList().get(1).hand()).containsExactly("4하트", "5스페이드"); } } @Nested class GetBlackjackStatisticsTest { - @Nested - class Success { - - @Test - void 블랙잭_승리와_패배를_반영해_수익을_계산한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.NINE, Suit.SPADE), - card(Rank.ACE, Suit.CLOVER), card(Rank.K, Suit.DIAMOND), - card(Rank.TEN, Suit.CLOVER), card(Rank.SEVEN, Suit.DIAMOND) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - blackjackGameManager.setBetAmount("jacob", new BetAmount("1000")); - blackjackGameManager.setBetAmount("seoye", new BetAmount("500")); - - // when - BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); - - // then - assertThat(actual.dealerProfit()).isEqualTo(-1000); - assertThat(actual.playerStatisticDtoList()).hasSize(2); - assertThat(actual.playerStatisticDtoList().get(0).name()).isEqualTo("jacob"); - assertThat(actual.playerStatisticDtoList().get(0).profit()).isEqualTo(1500); - assertThat(actual.playerStatisticDtoList().get(1).name()).isEqualTo("seoye"); - assertThat(actual.playerStatisticDtoList().get(1).profit()).isEqualTo(-500); - } - - @Test - void 무승부일_때_플레이어_수익은_0이고_딜러_수익에_반영되지_않는다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.EIGHT, Suit.SPADE), - card(Rank.NINE, Suit.CLOVER), card(Rank.NINE, Suit.DIAMOND), - card(Rank.TEN, Suit.CLOVER), card(Rank.SIX, Suit.DIAMOND) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - blackjackGameManager.setBetAmount("jacob", new BetAmount("500")); - blackjackGameManager.setBetAmount("seoye", new BetAmount("700")); - - // when - BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); - - // then - assertThat(actual.dealerProfit()).isEqualTo(700); - assertThat(actual.playerStatisticDtoList().get(0).profit()).isEqualTo(0); - assertThat(actual.playerStatisticDtoList().get(1).profit()).isEqualTo(-700); - } - - @Test - void 플레이어가_버스트면_딜러가_버스트여도_패배로_처리한다() { - - // given - BlackjackGameManager blackjackGameManager = new FixedDeckBlackjackGameManager(List.of( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), - card(Rank.TEN, Suit.CLOVER), card(Rank.EIGHT, Suit.DIAMOND), - card(Rank.NINE, Suit.HEART), card(Rank.SEVEN, Suit.CLOVER), - card(Rank.K, Suit.SPADE), card(Rank.Q, Suit.DIAMOND) - )); - blackjackGameManager.createParticipants(List.of("jacob", "seoye")); - blackjackGameManager.drawInitialCards(); - blackjackGameManager.setBetAmount("jacob", new BetAmount("1000")); - blackjackGameManager.setBetAmount("seoye", new BetAmount("500")); - blackjackGameManager.updatePlayer("seoye"); - blackjackGameManager.drawDealerCard(); - - // when - BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); - - // then - assertThat(actual.dealerProfit()).isEqualTo(-500); - assertThat(actual.playerStatisticDtoList().get(0).profit()).isEqualTo(1000); - assertThat(actual.playerStatisticDtoList().get(1).profit()).isEqualTo(-500); - } + @Test + void 플레이어가_버스트면_패배한다() { + + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.SPADE), + card(Rank.K, Suit.CLOVER), card(Rank.NINE, Suit.DIAMOND), + card(Rank.TEN, Suit.CLOVER), card(Rank.EIGHT, Suit.DIAMOND), + card(Rank.K, Suit.HEART) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + blackjackGameManager.updatePlayer("seoye"); + + // when + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); + + // then + assertThat(profitOf(actual, "seoye")).isEqualTo(-500); + assertThat(actual.dealerProfit()).isEqualTo(-500); } - } - @Nested - class IsHitTest { + @Test + void 플레이어와_딜러가_모두_블랙잭이면_무승부다() { - @Nested - class Success { + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.ACE, Suit.HEART), card(Rank.K, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER), card(Rank.Q, Suit.DIAMOND), + card(Rank.TEN, Suit.CLOVER), card(Rank.NINE, Suit.DIAMOND) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); - @Test - void y를_입력하면_true_를_반환한다() { - // given - HitOrStand hitOrStand = HitOrStand.from(" y "); + // when + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); - // when - boolean actual = blackjackGameManager.isHit(hitOrStand); + // then + assertThat(profitOf(actual, "jacob")).isEqualTo(0); + assertThat(actual.dealerProfit()).isEqualTo(500); + } - // then - assertThat(actual).isTrue(); - } + @Test + void 플레이어만_블랙잭이면_배팅_금액의_1_5배를_번다() { - @Test - void n을_입력하면_false를_반환한다() { - // given - HitOrStand hitOrStand = HitOrStand.from(" n "); + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.NINE, Suit.SPADE), + card(Rank.ACE, Suit.CLOVER), card(Rank.K, Suit.DIAMOND), + card(Rank.EIGHT, Suit.HEART), card(Rank.SEVEN, Suit.CLOVER) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); - // when - boolean actual = blackjackGameManager.isHit(hitOrStand); + // when + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); - // then - assertThat(actual).isFalse(); - } + // then + assertThat(profitOf(actual, "jacob")).isEqualTo(1500); + assertThat(actual.dealerProfit()).isEqualTo(-1000); } - } - @Nested - class IsStandTest { + @Test + void 딜러가_버스트면_살아있는_플레이어는_승리한다() { + + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), + card(Rank.TEN, Suit.CLOVER), card(Rank.SEVEN, Suit.DIAMOND), + card(Rank.NINE, Suit.HEART), card(Rank.EIGHT, Suit.CLOVER), + card(Rank.NINE, Suit.DIAMOND) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + blackjackGameManager.drawDealerCard(); + + // when + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); + + // then + assertThat(profitOf(actual, "jacob")).isEqualTo(1000); + assertThat(profitOf(actual, "seoye")).isEqualTo(500); + assertThat(actual.dealerProfit()).isEqualTo(-1500); + } + + @Test + void 플레이어_점수가_딜러보다_크면_승리한다() { + + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.EIGHT, Suit.SPADE), + card(Rank.TEN, Suit.CLOVER), card(Rank.NINE, Suit.DIAMOND), + card(Rank.EIGHT, Suit.HEART), card(Rank.SEVEN, Suit.CLOVER) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); - @Nested - class Success { + // when + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); - @Test - void n을_입력하면_true를_반환한다() { - // given - HitOrStand hitOrStand = HitOrStand.from(" n "); + // then + assertThat(profitOf(actual, "jacob")).isEqualTo(1000); + assertThat(actual.dealerProfit()).isEqualTo(-500); + } - // when - boolean actual = blackjackGameManager.isStand(hitOrStand); + @Test + void 플레이어_점수가_딜러와_같으면_무승부다() { - // then - assertThat(actual).isTrue(); - } + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.EIGHT, Suit.SPADE), + card(Rank.NINE, Suit.CLOVER), card(Rank.NINE, Suit.DIAMOND), + card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.CLOVER) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); - @Test - void y를_입력하면_false를_반환한다() { - // given - HitOrStand hitOrStand = HitOrStand.from(" y "); + // when + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); - // when - boolean actual = blackjackGameManager.isStand(hitOrStand); + // then + assertThat(profitOf(actual, "jacob")).isEqualTo(0); + assertThat(actual.dealerProfit()).isEqualTo(500); + } - // then - assertThat(actual).isFalse(); - } + @Test + void 플레이어_점수가_딜러보다_작으면_패배한다() { + + // given + BlackjackGameManager blackjackGameManager = fixedDeckBlackjackGameManager(List.of( + card(Rank.TEN, Suit.HEART), card(Rank.EIGHT, Suit.SPADE), + card(Rank.NINE, Suit.CLOVER), card(Rank.EIGHT, Suit.DIAMOND), + card(Rank.TEN, Suit.HEART), card(Rank.SEVEN, Suit.CLOVER) + )); + createParticipants(blackjackGameManager, betAmounts("1000", "500")); + blackjackGameManager.drawInitialCards(); + + // when + BlackjackStatisticsDto actual = blackjackGameManager.getBlackjackStatistics(); + + // then + assertThat(profitOf(actual, "jacob")).isEqualTo(-1000); + assertThat(profitOf(actual, "seoye")).isEqualTo(-500); + assertThat(actual.dealerProfit()).isEqualTo(1500); } } + private static int profitOf(BlackjackStatisticsDto blackjackStatisticsDto, String name) { + return blackjackStatisticsDto.playerStatisticDtoList().stream() + .filter(player -> player.name().equals(name)) + .findFirst() + .orElseThrow() + .profit(); + } + + private static BlackjackGameManager fixedDeckBlackjackGameManager(List cards) { + return new FixedDeckBlackjackGameManager(cards); + } + + private static void createParticipants(BlackjackGameManager blackjackGameManager, List betAmounts) { + blackjackGameManager.createParticipants(playerNames(), betAmounts); + } + + private static List playerNames() { + return List.of(new PlayerName("jacob"), new PlayerName("seoye")); + } + + private static List betAmounts(String first, String second) { + return List.of(new BetAmount(first), new BetAmount(second)); + } + private static Card card(Rank rank, Suit suit) { return new Card(rank, suit); } @@ -382,9 +385,6 @@ private FixedDeckBlackjackGameManager(List cards) { @Override public Card drawCard() { - if (cards.isEmpty()) { - return null; - } return cards.removeFirst(); } } From 3dc17b8f633ce000d58851f36ccaa7acae88724f Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:22:26 +0900 Subject: [PATCH 90/98] =?UTF-8?q?test(BlackjackJudgeTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/game/BlackjackJudgeTest.java | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 src/test/java/domain/game/BlackjackJudgeTest.java diff --git a/src/test/java/domain/game/BlackjackJudgeTest.java b/src/test/java/domain/game/BlackjackJudgeTest.java new file mode 100644 index 0000000000..6cfd700302 --- /dev/null +++ b/src/test/java/domain/game/BlackjackJudgeTest.java @@ -0,0 +1,197 @@ +package domain.game; + +import static org.assertj.core.api.Assertions.assertThat; + +import domain.card.Card; +import domain.card.Rank; +import domain.card.Suit; +import domain.participant.BetAmount; +import domain.participant.Dealer; +import domain.participant.Player; +import domain.participant.PlayerName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BlackjackJudgeTest { + + private final BlackjackJudge blackjackJudge = new BlackjackJudge(); + + @Nested + class JudgePlayerResultTest { + + @Test + void 플레이어가_버스트면_패배를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.TEN, Suit.HEART), + card(Rank.SIX, Suit.SPADE) + ); + Player player = player( + card(Rank.K, Suit.CLOVER), + card(Rank.NINE, Suit.DIAMOND), + card(Rank.FIVE, Suit.HEART) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.LOSE); + } + + @Test + void 플레이어와_딜러가_모두_블랙잭이면_무승부를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.ACE, Suit.HEART), + card(Rank.K, Suit.SPADE) + ); + Player player = player( + card(Rank.ACE, Suit.CLOVER), + card(Rank.Q, Suit.DIAMOND) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.DRAW); + } + + @Test + void 플레이어만_블랙잭이면_블랙잭_승리를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.TEN, Suit.HEART), + card(Rank.NINE, Suit.SPADE) + ); + Player player = player( + card(Rank.ACE, Suit.CLOVER), + card(Rank.K, Suit.DIAMOND) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.BLACKJACK_WIN); + } + + @Test + void 플레이어가_블랙잭이고_딜러가_버스트여도_블랙잭_승리를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.K, Suit.HEART), + card(Rank.NINE, Suit.SPADE), + card(Rank.FIVE, Suit.DIAMOND) + ); + Player player = player( + card(Rank.ACE, Suit.CLOVER), + card(Rank.Q, Suit.HEART) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.BLACKJACK_WIN); + } + + @Test + void 딜러가_버스트면_승리를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.K, Suit.HEART), + card(Rank.NINE, Suit.SPADE), + card(Rank.THREE, Suit.DIAMOND) + ); + Player player = player( + card(Rank.TEN, Suit.CLOVER), + card(Rank.SEVEN, Suit.HEART) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.WIN); + } + + @Test + void 플레이어_점수가_딜러보다_크면_승리를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.TEN, Suit.HEART), + card(Rank.EIGHT, Suit.SPADE) + ); + Player player = player( + card(Rank.TEN, Suit.CLOVER), + card(Rank.NINE, Suit.DIAMOND) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.WIN); + } + + @Test + void 플레이어_점수가_딜러와_같으면_무승부를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.TEN, Suit.HEART), + card(Rank.EIGHT, Suit.SPADE) + ); + Player player = player( + card(Rank.NINE, Suit.CLOVER), + card(Rank.NINE, Suit.DIAMOND) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.DRAW); + } + + @Test + void 모든_우선_조건에_해당하지_않으면_패배를_반환한다() { + // given + Dealer dealer = dealer( + card(Rank.TEN, Suit.HEART), + card(Rank.NINE, Suit.SPADE) + ); + Player player = player( + card(Rank.NINE, Suit.CLOVER), + card(Rank.EIGHT, Suit.DIAMOND) + ); + + // when + Result actual = blackjackJudge.judgePlayerResult(dealer, player); + + // then + assertThat(actual).isEqualTo(Result.LOSE); + } + } + + private static Dealer dealer(Card... cards) { + Dealer dealer = new Dealer(); + for (Card card : cards) { + dealer.addCard(card); + } + return dealer; + } + + private static Player player(Card... cards) { + Player player = new Player(new PlayerName("jacob"), new BetAmount("1000")); + for (Card card : cards) { + player.addCard(card); + } + return player; + } + + private static Card card(Rank rank, Suit suit) { + return new Card(rank, suit); + } +} From 2578a5fb23e3565bb1e51b506aee70b3e7dca59d Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:25:03 +0900 Subject: [PATCH 91/98] =?UTF-8?q?remove(HitOrStandTest):=20constant=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B0=8F=20=ED=95=98=EC=9C=84=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20HitOrStandTest=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/constant/HitOrStandTest.java | 29 ---------------------- 1 file changed, 29 deletions(-) delete mode 100644 src/test/java/constant/HitOrStandTest.java diff --git a/src/test/java/constant/HitOrStandTest.java b/src/test/java/constant/HitOrStandTest.java deleted file mode 100644 index 1228ae2c1d..0000000000 --- a/src/test/java/constant/HitOrStandTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package constant; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import domain.game.HitOrStand; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -class HitOrStandTest { - - @Nested - class From { - - @Nested - class Fail { - - @Test - void y_또는_n가_아니면_예외가_발생한다() { - // given - String input = "a"; - - // when & then - assertThatThrownBy(() -> HitOrStand.from(input)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining(HitOrStand.INVALID_YES_NO_INPUT); - } - } - } -} \ No newline at end of file From e244b53342f52263700b6d428ff37879066d8f9e Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:26:17 +0900 Subject: [PATCH 92/98] =?UTF-8?q?test(ResultTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/game/ResultTest.java | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/test/java/domain/game/ResultTest.java diff --git a/src/test/java/domain/game/ResultTest.java b/src/test/java/domain/game/ResultTest.java new file mode 100644 index 0000000000..0caf008368 --- /dev/null +++ b/src/test/java/domain/game/ResultTest.java @@ -0,0 +1,61 @@ +package domain.game; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class ResultTest { + + @Nested + class GetProfitTest { + + @Test + void 블랙잭_승리면_배팅_금액의_1_5배를_반환한다() { + // given + int betAmount = 1000; + + // when + int actual = Result.BLACKJACK_WIN.getProfit(betAmount); + + // then + assertThat(actual).isEqualTo(1500); + } + + @Test + void 일반_승리면_배팅_금액과_같은_수익을_반환한다() { + // given + int betAmount = 1000; + + // when + int actual = Result.WIN.getProfit(betAmount); + + // then + assertThat(actual).isEqualTo(1000); + } + + @Test + void 무승부면_수익은_0이다() { + // given + int betAmount = 1000; + + // when + int actual = Result.DRAW.getProfit(betAmount); + + // then + assertThat(actual).isEqualTo(0); + } + + @Test + void 패배면_배팅_금액만큼_음수_수익을_반환한다() { + // given + int betAmount = 1000; + + // when + int actual = Result.LOSE.getProfit(betAmount); + + // then + assertThat(actual).isEqualTo(-1000); + } + } +} From f961d9842ddc018fc39562f165864ef34642f900 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:31:57 +0900 Subject: [PATCH 93/98] =?UTF-8?q?refactor(PlayerName):=20equals=20?= =?UTF-8?q?=EB=B0=8F=20hashCode=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/participant/PlayerName.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/main/java/domain/participant/PlayerName.java b/src/main/java/domain/participant/PlayerName.java index 1d28a7a032..898a3fce40 100644 --- a/src/main/java/domain/participant/PlayerName.java +++ b/src/main/java/domain/participant/PlayerName.java @@ -1,7 +1,6 @@ package domain.participant; import exception.BlackjackException; -import java.util.Objects; public record PlayerName(String name) { @@ -31,18 +30,4 @@ private void validateNotBlank(String name) { throw new BlackjackException(PLAYER_NAME_BLANK); } } - - @Override - public boolean equals(Object object) { - if (object == null || getClass() != object.getClass()) { - return false; - } - PlayerName that = (PlayerName) object; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() { - return Objects.hashCode(name); - } } From db6bbc3a6f5c1b0d3d7ccddff8b112f5b803b701 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:33:41 +0900 Subject: [PATCH 94/98] =?UTF-8?q?test(ParticipantsTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/participant/ParticipantsTest.java | 109 +++++++----------- 1 file changed, 43 insertions(+), 66 deletions(-) diff --git a/src/test/java/domain/participant/ParticipantsTest.java b/src/test/java/domain/participant/ParticipantsTest.java index ca305db436..358e4cc86b 100644 --- a/src/test/java/domain/participant/ParticipantsTest.java +++ b/src/test/java/domain/participant/ParticipantsTest.java @@ -1,6 +1,7 @@ package domain.participant; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import domain.card.Card; import domain.card.Rank; @@ -15,15 +16,16 @@ class ParticipantsTest { @Nested - class FromTest { + class OfTest { @Test - void 참가자_이름으로_딜러와_플레이어_묶음을_생성한다() { + void 플레이어_이름과_배팅_금액으로_참가자를_생성한다() { // given - List names = List.of("jacob", "seoye"); + List playerNames = playerNames(); + List betAmounts = betAmounts("1000", "500"); // when - Participants actual = Participants.from(names); + Participants actual = Participants.of(playerNames, betAmounts); // then assertThat(actual.dealer()).isNotNull(); @@ -33,46 +35,14 @@ class FromTest { } } - @Nested - class DealerShouldHitTest { - - @Test - void 딜러_점수가_16_이하면_true를_반환한다() { - // given - Participants participants = Participants.from(List.of("jacob", "seoye")); - participants.dealer().addCard(card(Rank.TEN, Suit.HEART)); - participants.dealer().addCard(card(Rank.SIX, Suit.SPADE)); - - // when - boolean actual = participants.dealerShouldHit(); - - // then - assertThat(actual).isTrue(); - } - - @Test - void 딜러_점수가_17_이상이면_false를_반환한다() { - // given - Participants participants = Participants.from(List.of("jacob", "seoye")); - participants.dealer().addCard(card(Rank.TEN, Suit.HEART)); - participants.dealer().addCard(card(Rank.SEVEN, Suit.SPADE)); - - // when - boolean actual = participants.dealerShouldHit(); - - // then - assertThat(actual).isFalse(); - } - } - @Nested class DrawInitialCardsTest { @Test - void 딜러는_2장_모든_플레이어도_각각_2장을_받는다() { + void 딜러는_2장_모든_플레이어는_각각_2장을_받는다() { // given - Participants participants = Participants.from(List.of("jacob", "seoye")); - Supplier supplier = fixedCardSupplier(List.of( + Participants participants = participants(); + Supplier cardSupplier = fixedCardSupplier(List.of( card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), card(Rank.ACE, Suit.CLOVER), @@ -82,15 +52,15 @@ class DrawInitialCardsTest { )); // when - participants.drawInitialCards(supplier); + participants.drawInitialCards(cardSupplier); // then - assertThat(participants.dealer().getHand()).hasSize(2); - assertThat(participants.players().getPlayer("jacob").getHand()).hasSize(2); - assertThat(participants.players().getPlayer("seoye").getHand()).hasSize(2); - assertThat(participants.dealer().getHand()).containsExactly( - card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE) - ); + assertThat(participants.dealer().getHand()) + .containsExactly(card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE)); + assertThat(participants.players().getPlayer("jacob").getHand()) + .containsExactly(card(Rank.ACE, Suit.CLOVER), card(Rank.K, Suit.DIAMOND)); + assertThat(participants.players().getPlayer("seoye").getHand()) + .containsExactly(card(Rank.NINE, Suit.HEART), card(Rank.THREE, Suit.CLOVER)); } } @@ -100,17 +70,17 @@ class DrawCardsByDealerTest { @Test void 딜러에게_카드를_한_장_추가한다() { // given - Participants participants = Participants.from(List.of("jacob", "seoye")); + Participants participants = participants(); participants.dealer().addCard(card(Rank.TEN, Suit.HEART)); participants.dealer().addCard(card(Rank.SIX, Suit.SPADE)); - Supplier supplier = fixedCardSupplier(List.of(card(Rank.ACE, Suit.CLOVER))); + Supplier cardSupplier = fixedCardSupplier(List.of(card(Rank.ACE, Suit.CLOVER))); // when - participants.drawCardsByDealer(supplier); + participants.drawCardsByDealer(cardSupplier); // then - assertThat(participants.dealer().getHand()).hasSize(3); - assertThat(participants.dealer().getHand().get(2)).isEqualTo(card(Rank.ACE, Suit.CLOVER)); + assertThat(participants.dealer().getHand()) + .containsExactly(card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), card(Rank.ACE, Suit.CLOVER)); } } @@ -120,34 +90,42 @@ class DrawCardsByPlayerTest { @Test void 이름으로_찾은_플레이어에게_카드를_추가하고_플레이어를_반환한다() { // given - Participants participants = Participants.from(List.of("jacob", "seoye")); - Supplier supplier = fixedCardSupplier(List.of(card(Rank.FOUR, Suit.DIAMOND))); + Participants participants = participants(); + Supplier cardSupplier = fixedCardSupplier(List.of(card(Rank.FOUR, Suit.DIAMOND))); // when - Player actual = participants.drawCardsByPlayer("jacob", supplier); + Player actual = participants.drawCardsByPlayer("jacob", cardSupplier); // then assertThat(actual.getName()).isEqualTo("jacob"); assertThat(actual.getHand()).containsExactly(card(Rank.FOUR, Suit.DIAMOND)); } - } - - @Nested - class GetPlayerTest { @Test - void 이름으로_플레이어를_조회한다() { + void 존재하지_않는_플레이어_이름이면_예외를_던진다() { // given - Participants participants = Participants.from(List.of("jacob", "seoye")); - - // when - Player actual = participants.getPlayer("seoye"); + Participants participants = participants(); + Supplier cardSupplier = fixedCardSupplier(List.of(card(Rank.FOUR, Suit.DIAMOND))); - // then - assertThat(actual.getName()).isEqualTo("seoye"); + // when & then + assertThatThrownBy(() -> participants.drawCardsByPlayer("brown", cardSupplier)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(Players.NOT_FOUND_PLAYER); } } + private static Participants participants() { + return Participants.of(playerNames(), betAmounts("1000", "500")); + } + + private static List playerNames() { + return List.of(new PlayerName("jacob"), new PlayerName("seoye")); + } + + private static List betAmounts(String first, String second) { + return List.of(new BetAmount(first), new BetAmount(second)); + } + private static Supplier fixedCardSupplier(List cards) { Deque deque = new ArrayDeque<>(cards); return deque::removeFirst; @@ -156,5 +134,4 @@ private static Supplier fixedCardSupplier(List cards) { private static Card card(Rank rank, Suit suit) { return new Card(rank, suit); } - } From f9c39d13855f9de17ef6204a6fd17023e0dfb925 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:38:41 +0900 Subject: [PATCH 95/98] =?UTF-8?q?test(PlayersTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/participant/PlayersTest.java | 292 ++++++++++-------- 1 file changed, 162 insertions(+), 130 deletions(-) diff --git a/src/test/java/domain/participant/PlayersTest.java b/src/test/java/domain/participant/PlayersTest.java index c4655c3cf0..bbebadfe2b 100644 --- a/src/test/java/domain/participant/PlayersTest.java +++ b/src/test/java/domain/participant/PlayersTest.java @@ -11,105 +11,91 @@ import java.util.Deque; import java.util.List; import java.util.function.Supplier; -import java.util.stream.Stream; import org.junit.jupiter.api.Nested; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; +import org.junit.jupiter.api.Test; class PlayersTest { @Nested class ConstructorTest { - @Nested - class Success { - - @ParameterizedTest - @MethodSource("successCases") - void 인원수와_이름이_유효하면_생성된다(List names, int expectedSize) { - // when - Players actual = new Players(names); - - // then - assertThat(actual.getPlayers()).hasSize(expectedSize); - } - - static Stream successCases() { - return Stream.of( - Arguments.of(List.of("aa", "bb"), 2), - Arguments.of(List.of("a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1"), 8) - ); - } + @Test + void 유효한_이름과_배팅_금액이면_플레이어_목록을_생성한다() { + // when + Players actual = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); + + // then + assertThat(actual.getPlayers()).hasSize(2); + assertThat(actual.getPlayers().get(0).getName()).isEqualTo("jacob"); + assertThat(actual.getPlayers().get(1).getName()).isEqualTo("seoye"); } - @Nested - class Fail { - - @ParameterizedTest - @ValueSource(ints = {1, 9}) - void 인원수가_범위를_벗어나면_예외가_발생한다(int size) { - // given - List names = java.util.stream.IntStream.range(0, size) - .mapToObj(i -> String.format("p%d", i)) - .toList(); - - // when & then - assertThatThrownBy(() -> new Players(names)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_COUNT_OUT_OF_RANGE); - } - - @ParameterizedTest - @MethodSource("duplicatedCases") - void 이름이_중복되면_예외가_발생한다(List names) { - // when & then - assertThatThrownBy(() -> new Players(names)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_DUPLICATED); - } - - static Stream duplicatedCases() { - return Stream.of( - Arguments.of(List.of("aa", "aa")), - Arguments.of(List.of("aa", "bb", "aa")) - ); - } + @Test + void 플레이어_수가_2명_미만이면_예외가_발생한다() { + // when & then + assertThatThrownBy(() -> players( + List.of("jacob"), + List.of("1000") + )) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_COUNT_OUT_OF_RANGE); + } + + @Test + void 플레이어_수가_8명_초과이면_예외가_발생한다() { + // when & then + assertThatThrownBy(() -> players( + List.of("aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii"), + List.of("100", "100", "100", "100", "100", "100", "100", "100", "100") + )) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_COUNT_OUT_OF_RANGE); + } + + @Test + void 플레이어_이름이_중복되면_예외가_발생한다() { + // when & then + assertThatThrownBy(() -> players( + List.of("jacob", "jacob"), + List.of("1000", "500") + )) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.PLAYER_DUPLICATED); } } @Nested class GetPlayerTest { - @ParameterizedTest - @MethodSource("successCases") - void 이름으로_플레이어를_조회한다(String targetName) { + @Test + void 이름으로_플레이어를_조회한다() { // given - Players players = new Players(List.of("jacob", "seoye")); + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); // when - Player actual = players.getPlayer(targetName); + Player actual = players.getPlayer("seoye"); // then - assertThat(actual.getName()).isEqualTo(targetName); + assertThat(actual.getName()).isEqualTo("seoye"); + assertThat(actual.getBetAmount()).isEqualTo(500); } - static Stream successCases() { - return Stream.of( - Arguments.of("jacob"), - Arguments.of("seoye") - ); - } - - @ParameterizedTest - @ValueSource(strings = {"brown", "jason"}) - void 없는_이름이면_예외가_발생한다(String targetName) { + @Test + void 존재하지_않는_이름이면_예외가_발생한다() { // given - Players players = new Players(List.of("jacob", "seoye")); + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); // when & then - assertThatThrownBy(() -> players.getPlayer(targetName)) + assertThatThrownBy(() -> players.getPlayer("brown")) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.NOT_FOUND_PLAYER); } @@ -118,32 +104,33 @@ static Stream successCases() { @Nested class GetPlayersTest { - @ParameterizedTest - @MethodSource("sizeCases") - void 전체_플레이어_목록을_조회한다(List names, int expectedSize) { + @Test + void 전체_플레이어_목록을_조회한다() { + // given + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); + // when - Players actual = new Players(names); + List actual = players.getPlayers(); // then - assertThat(actual.getPlayers()).hasSize(expectedSize); + assertThat(actual).hasSize(2); + assertThat(actual.get(0).getName()).isEqualTo("jacob"); + assertThat(actual.get(1).getName()).isEqualTo("seoye"); } - static Stream sizeCases() { - return Stream.of( - Arguments.of(List.of("aa", "bb"), 2), - Arguments.of(List.of("aa", "bb", "cc"), 3) - ); - } - - @ParameterizedTest - @ValueSource(strings = {"zz"}) - void 반환_목록은_수정할_수_없다(String newPlayerName) { + @Test + void 반환_목록은_수정할_수_없다() { // given - Players players = new Players(List.of("aa", "bb")); - Player newPlayer = new Player(newPlayerName + "1"); + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); // when & then - assertThatThrownBy(() -> players.getPlayers().add(newPlayer)) + assertThatThrownBy(() -> players.getPlayers().add(new Player(new PlayerName("brown"), new BetAmount("700")))) .isInstanceOf(UnsupportedOperationException.class); } } @@ -151,75 +138,120 @@ static Stream sizeCases() { @Nested class DrawInitialCardsTest { - @ParameterizedTest - @MethodSource("drawCases") - void 모든_플레이어는_초기_카드를_2장씩_받는다(List names) { + @Test + void 모든_플레이어는_초기_카드를_2장씩_받는다() { // given - Players players = new Players(names); - Supplier supplier = fixedCardSupplier(List.of( + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); + Supplier cardSupplier = fixedCardSupplier(List.of( card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE), card(Rank.ACE, Suit.CLOVER), - card(Rank.K, Suit.DIAMOND), - card(Rank.TWO, Suit.HEART), - card(Rank.THREE, Suit.SPADE), - card(Rank.FOUR, Suit.CLOVER), - card(Rank.FIVE, Suit.DIAMOND) + card(Rank.K, Suit.DIAMOND) )); // when - players.drawInitialCards(supplier); + players.drawInitialCards(cardSupplier); // then - assertThat(players.getPlayers()) - .allSatisfy(player -> assertThat(player.getHand()).hasSize(2)); - } - - static Stream drawCases() { - return Stream.of( - Arguments.of(List.of("aa", "bb")), - Arguments.of(List.of("aa", "bb", "cc", "dd")) - ); + assertThat(players.getPlayer("jacob").getHand()) + .containsExactly(card(Rank.TEN, Suit.HEART), card(Rank.SIX, Suit.SPADE)); + assertThat(players.getPlayer("seoye").getHand()) + .containsExactly(card(Rank.ACE, Suit.CLOVER), card(Rank.K, Suit.DIAMOND)); } } @Nested class AddCardTest { - @ParameterizedTest - @MethodSource("successCases") - void 이름으로_찾은_플레이어에게_카드를_추가한다(String targetName) { + @Test + void 이름으로_찾은_플레이어에게_카드를_추가한다() { // given - Players players = new Players(List.of("jacob", "seoye")); + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); Card card = card(Rank.NINE, Suit.HEART); // when - players.addCard(targetName, card); + players.addCard("jacob", card); // then - assertThat(players.getPlayer(targetName).getHand()).containsExactly(card); - } - - static Stream successCases() { - return Stream.of( - Arguments.of("jacob"), - Arguments.of("seoye") - ); + assertThat(players.getPlayer("jacob").getHand()).containsExactly(card); } - @ParameterizedTest - @ValueSource(strings = {"brown"}) - void 없는_플레이어에게_추가하면_예외가_발생한다(String targetName) { + @Test + void 없는_플레이어에게_카드를_추가하면_예외가_발생한다() { // given - Players players = new Players(List.of("jacob", "seoye")); + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); // when & then - assertThatThrownBy(() -> players.addCard(targetName, card(Rank.NINE, Suit.HEART))) + assertThatThrownBy(() -> players.addCard("brown", card(Rank.NINE, Suit.HEART))) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining(BlackjackException.ERROR_PREFIX + Players.NOT_FOUND_PLAYER); } } + @Nested + class PlayerIsBustTest { + + @Test + void 플레이어_점수가_21_초과면_true를_반환한다() { + // given + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); + players.addCard("jacob", card(Rank.TEN, Suit.HEART)); + players.addCard("jacob", card(Rank.NINE, Suit.SPADE)); + players.addCard("jacob", card(Rank.THREE, Suit.CLOVER)); + + // when + boolean actual = players.playerIsBust("jacob"); + + // then + assertThat(actual).isTrue(); + } + + @Test + void 플레이어_점수가_21_이하면_false를_반환한다() { + // given + Players players = players( + List.of("jacob", "seoye"), + List.of("1000", "500") + ); + players.addCard("jacob", card(Rank.TEN, Suit.HEART)); + players.addCard("jacob", card(Rank.SEVEN, Suit.SPADE)); + + // when + boolean actual = players.playerIsBust("jacob"); + + // then + assertThat(actual).isFalse(); + } + } + + private static Players players(List names, List betAmounts) { + return new Players(toPlayerNames(names), toBetAmounts(betAmounts)); + } + + private static List toPlayerNames(List names) { + return names.stream() + .map(PlayerName::new) + .toList(); + } + + private static List toBetAmounts(List betAmounts) { + return betAmounts.stream() + .map(BetAmount::new) + .toList(); + } + private static Supplier fixedCardSupplier(List cards) { Deque deque = new ArrayDeque<>(cards); return deque::removeFirst; From b252768e5b44162082535ba808acad0cc9986c67 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:39:01 +0900 Subject: [PATCH 96/98] =?UTF-8?q?remove(PlayerTest):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=98=EB=AF=80=EB=A1=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/domain/participant/PlayerTest.java | 81 ------------------- 1 file changed, 81 deletions(-) delete mode 100644 src/test/java/domain/participant/PlayerTest.java diff --git a/src/test/java/domain/participant/PlayerTest.java b/src/test/java/domain/participant/PlayerTest.java deleted file mode 100644 index 4c160a204f..0000000000 --- a/src/test/java/domain/participant/PlayerTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package domain.participant; - -import static org.assertj.core.api.Assertions.assertThat; - -import domain.card.Card; -import domain.card.Rank; -import domain.card.Suit; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -class PlayerTest { - - @Nested - class ConstructorTest { - - @Test - void 생성하면_이름을_반환할_수_있다() { - // given - String name = "jacob"; - - // when - Player actual = new Player(name); - - // then - assertThat(actual.getName()).isEqualTo(name); - } - } - - @Nested - class SetBetAmountTest { - - @Test - void 배팅_금액을_설정하면_조회할_수_있다() { - // given - Player player = new Player("jacob"); - BetAmount betAmount = new BetAmount("2000"); - - // when - player.setBetAmount(betAmount); - - // then - assertThat(player.getBetAmount()).isEqualTo(2000); - } - } - - @Nested - class IsBlackjackTest { - - @Test - void 처음_두_장이_21점이면_블랙잭이다() { - // given - Player player = new Player("jacob"); - player.addCard(card(Rank.ACE, Suit.HEART)); - player.addCard(card(Rank.K, Suit.SPADE)); - - // when - boolean actual = player.isBlackjack(); - - // then - assertThat(actual).isTrue(); - } - - @Test - void 처음_두_장이_21점이_아니면_블랙잭이_아니다() { - // given - Player player = new Player("jacob"); - player.addCard(card(Rank.TEN, Suit.HEART)); - player.addCard(card(Rank.NINE, Suit.SPADE)); - - // when - boolean actual = player.isBlackjack(); - - // then - assertThat(actual).isFalse(); - } - } - - private static Card card(Rank rank, Suit suit) { - return new Card(rank, suit); - } -} From 133cb901dd6c30a10515167fb6613261442f7f12 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:41:35 +0900 Subject: [PATCH 97/98] =?UTF-8?q?test(ParticipantDtoTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/dto/ParticipantDtoTest.java | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/test/java/dto/ParticipantDtoTest.java b/src/test/java/dto/ParticipantDtoTest.java index 6a015b29ed..e80ffaf409 100644 --- a/src/test/java/dto/ParticipantDtoTest.java +++ b/src/test/java/dto/ParticipantDtoTest.java @@ -5,8 +5,10 @@ import domain.card.Card; import domain.card.Rank; import domain.card.Suit; +import domain.participant.BetAmount; import domain.participant.Dealer; import domain.participant.Player; +import domain.participant.PlayerName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -46,6 +48,22 @@ class FromDealerTest { assertThat(actual.hand()).containsExactly("A클로버"); assertThat(actual.score()).isEqualTo(21); } + + @Test + void 딜러_초기_공개_여부가_false면_모든_카드를_노출한다() { + // given + Dealer dealer = new Dealer(); + dealer.addCard(card(Rank.TEN, Suit.HEART)); + dealer.addCard(card(Rank.SEVEN, Suit.SPADE)); + + // when + ParticipantDto actual = ParticipantDto.from(dealer, false); + + // then + assertThat(actual.name()).isEqualTo("딜러"); + assertThat(actual.hand()).containsExactly("10하트", "7스페이드"); + assertThat(actual.score()).isEqualTo(17); + } } @Nested @@ -54,7 +72,7 @@ class FromPlayerTest { @Test void 플레이어_정보를_패와_점수로_생성한다() { // given - Player player = new Player("jacob"); + Player player = new Player(new PlayerName("jacob"), new BetAmount("1000")); player.addCard(card(Rank.NINE, Suit.HEART)); player.addCard(card(Rank.EIGHT, Suit.CLOVER)); From 55e5d337779597f91a6e3bbebb22ec03a6f9f8f2 Mon Sep 17 00:00:00 2001 From: khcho96 Date: Sun, 15 Mar 2026 18:41:43 +0900 Subject: [PATCH 98/98] =?UTF-8?q?test(PlayerStatisticDtoTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/dto/PlayerStatisticDtoTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/dto/PlayerStatisticDtoTest.java b/src/test/java/dto/PlayerStatisticDtoTest.java index 18311339b9..de4cc285bd 100644 --- a/src/test/java/dto/PlayerStatisticDtoTest.java +++ b/src/test/java/dto/PlayerStatisticDtoTest.java @@ -2,7 +2,9 @@ import static org.assertj.core.api.Assertions.assertThat; +import domain.participant.BetAmount; import domain.participant.Player; +import domain.participant.PlayerName; import org.junit.jupiter.api.Test; class PlayerStatisticDtoTest { @@ -10,7 +12,7 @@ class PlayerStatisticDtoTest { @Test void of로_생성하면_플레이어_이름과_수익을_반환한다() { // given - Player player = new Player("jacob"); + Player player = new Player(new PlayerName("jacob"), new BetAmount("1000")); int profit = 1200; // when