diff --git a/README.md b/README.md index 2f845848790..d15a1adcd08 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # java-blackjack -블랙잭 미션 저장소 +## 블랙잭 미션 저장소 +### 구현 기능 목록 - [x] 카드 점수 계산 (숫자는 그대로, J,Q,K는 10으로 계산) - [x] 카드 합계 계산 - [x] Ace 개수 계산 @@ -27,10 +28,32 @@ - [x] 마지막 참가자가 버스트가 되거나 카드를 안받을 경우 게임 종료 - [x] 전체 플레이어 승패 결과 계산 --[x] 입력 +- [x] 입력 - [x] 게임 참가자 이름 입력 - [x] 카드 더받기 유무 입력 + - [x] 출력 - [x] 분배 받은 카드 목록 출력 - [x] 딜러와 참가자 카드 합계 결과 출력 - - [x] 최종 승패 결과 출력 \ No newline at end of file + - [x] 최종 승패 결과 출력 + +### 추가 기능 구현 목록 +- [x] 입력 + - [x] 참여하는 Player의 배팅 금액을 입력받는다. + +- [x] 배팅 금액 + - [x] 플레이어와 딜러는 배팅 금액을 가진다. + +- [x] Player & Dealer 블랙잭 판단 + - [x] 플레이어와 딜러의 초기 카드 2장의 합이 21인지 판단한다. + - [x] 플레이어에게 1.5배 지급하는 겅우 + - [x] 플레이어의 초기 카드 2장이 21인 경우 + - [x] 플레이어가 배팅 금액을 모두 잃는 경우 + - [x] 딜러의 초기 카드 2장이 21인 경우 + - [x] 플레이어가 버스트인 경우 + - [x] 플레이어가 배팅한 금액을 그대로 받는 경우 + - [x] 딜러와 플레이어 모두 초기 카드 합이 21인 경우 + - [x] 플레이어가 카드를 계속 뽑아서 딜러보다 카드 합이 높은 경우 + +- [x] 출력 + - [x] 딜러와 참가자의 최종 수익을 출력한다. diff --git a/src/main/java/blackjack/controller/BlackjackController.java b/src/main/java/blackjack/controller/BlackjackController.java index 0a07577ad84..d1bb0dbbb0d 100644 --- a/src/main/java/blackjack/controller/BlackjackController.java +++ b/src/main/java/blackjack/controller/BlackjackController.java @@ -5,11 +5,8 @@ import blackjack.service.Game; import blackjack.utils.InputParser; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; +import java.util.*; +import java.util.stream.Collectors; import blackjack.view.InputView; import blackjack.view.OutputView; @@ -23,8 +20,7 @@ public BlackjackController(CardDistributor cardDistributor) { public void startGame() { List playerNames = getPlayerNames(); - List players = getPlayers(playerNames); - + List players = createPlayers(playerNames); Participant dealer = Participant.createDealer(); setupInitialHand(players, dealer, playerNames); @@ -32,18 +28,20 @@ public void startGame() { playDealerTurn(dealer); calculateFinalScore(players, dealer); - calculateFinalGameResult(players, dealer); + calculateFinalGameProfit(players, dealer); } - private static List getPlayerNames() { - String playerNamesStr = InputView.askPlayerNames(); - return InputParser.splitPlayerNames(playerNamesStr); + private List getPlayerNames() { + String names = InputView.askPlayerNames(); + return InputParser.splitPlayerNames(names); } - private List getPlayers(List playerNames) { + private List createPlayers(List playerNames) { List players = new ArrayList<>(); for (String playerName : playerNames) { - players.add(Participant.createPlayer(playerName)); + String amountStr = InputView.askPlayerBettingAmount(playerName); + long amount = InputParser.convertNumber(amountStr); + players.add(Participant.createPlayer(playerName, Money.fromBettingAmount(amount))); } return players; } @@ -78,7 +76,9 @@ private void drawUntilPlayerStand(Participant player) { private void playDealerTurn(Participant dealer) { int additionalCount = game.dealerDrawsCardsUntilDone(dealer); - OutputView.printDealerCardDrawnResult(additionalCount); + if (additionalCount > 0) { + OutputView.printDealerCardDrawnResult(additionalCount); + } } private boolean isHit(Participant player) { @@ -93,26 +93,38 @@ private boolean isHit(Participant player) { } private void calculateFinalScore(List players, Participant dealer) { - List playerResults = new ArrayList<>(); - for (Participant player : players) { - ParticipantResult participantResult = new ParticipantResult(player.getName(), player.getCardNames(), player.calculateTotalScore()); - playerResults.add(participantResult); - } + List playerResults = players.stream() + .map(player -> new ParticipantResult(player.getName(), player.getCardNames(), player.calculateTotalScore())) + .collect(Collectors.toList()); ParticipantResult dealerResult = new ParticipantResult(dealer.getName(), dealer.getCardNames(), dealer.calculateTotalScore()); OutputView.printFinalCardScores(playerResults, dealerResult); } - private void calculateFinalGameResult(List players, Participant dealer) { - GameResult gameResult = dealer.judgeResult(players, dealer); - Map dealerResult = gameResult.dealerResult(); - Map playerResult = gameResult.playerResults(); - HashMap playerNameResult = new HashMap<>(); + private void calculateFinalGameProfit(List players, Participant dealer) { + Map playersProfit = calculatePlayersProfit(players, (Dealer) dealer); + long dealerProfit = calculateDealerProfit(playersProfit); + OutputView.printFinalProfit(dealerProfit, playersProfit); + } + + private Map calculatePlayersProfit(List players, Dealer dealer) { + GameResult gameResult = dealer.judgeResult(players); + Map results = gameResult.playerResults(); + Map playersProfit = new LinkedHashMap<>(); + for (Participant participant : players) { + Player player = (Player) participant; - for (Entry entry : playerResult.entrySet()) { - playerNameResult.put(entry.getKey().getName(), entry.getValue()); + ScoreCompareResult result = results.get(player); + Money profit = player.calculateFinalProfit(result); + playersProfit.put(player.getName(), profit.getBettingMoney()); } - OutputView.printFinalResult(dealerResult, playerNameResult); + return playersProfit; } + private long calculateDealerProfit(Map playersProfit) { + long totalPlayersProfit = playersProfit.values().stream() + .mapToLong(Long::longValue) + .sum(); + return -totalPlayersProfit; + } } diff --git a/src/main/java/blackjack/domain/Cards.java b/src/main/java/blackjack/domain/Cards.java index 189eee5ccea..25896a47502 100644 --- a/src/main/java/blackjack/domain/Cards.java +++ b/src/main/java/blackjack/domain/Cards.java @@ -2,8 +2,12 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class Cards { + private static final int BLACKJACK_SCORE = 21; + private static final int BLACKJACK_SIZE = 2; + private static final int ACE_SCORE = 10; private final List cards; @@ -21,24 +25,32 @@ public int sumScore() { totalScore += card.getScore(); } int aceCount = (int) cards.stream().filter(Card::isAce).count(); - - while (totalScore > 21 && aceCount > 0) { - totalScore -= 10; + while (totalScore > BLACKJACK_SCORE && aceCount > 0) { + totalScore -= ACE_SCORE; aceCount--; } return totalScore; } + public boolean isBust() { + return sumScore() > BLACKJACK_SCORE; + } + + public boolean isBlackjack() { + return sumScore() == BLACKJACK_SCORE && cards.size() == BLACKJACK_SIZE; + } + public void addCard(Card card) { + if (card == null || sumScore() > BLACKJACK_SCORE) { + throw new IllegalArgumentException("[ERROR] 카드를 추가할 수 없습니다."); + } cards.add(card); } public List getCardNames() { - List cardNames = new ArrayList<>(); - for (Card card : cards) { - String cardName = card.getCardName(); - cardNames.add(cardName); - } - return cardNames; + return cards.stream() + .map(Card::getCardName) + .collect(Collectors.toList()); } + } \ No newline at end of file diff --git a/src/main/java/blackjack/domain/Dealer.java b/src/main/java/blackjack/domain/Dealer.java index cbeef3b0862..9a933c50259 100644 --- a/src/main/java/blackjack/domain/Dealer.java +++ b/src/main/java/blackjack/domain/Dealer.java @@ -5,21 +5,24 @@ import java.util.Map; public class Dealer extends Participant{ + + private static final int DEALER_HIT_LIMIT = 17; + public Dealer() { super("딜러"); } public boolean isDealerNotDone() { - return calculateTotalScore() < 17; + return calculateTotalScore() < DEALER_HIT_LIMIT; } - @Override - public GameResult judgeResult(List players, Participant dealer) { + + public GameResult judgeResult(List players) { Map dealerResult = new HashMap<>(); Map playerResults = new HashMap<>(); for (Participant player : players) { - ScoreCompareResult result = compareScore(player, dealer); + ScoreCompareResult result = compareScore(player, this); playerResults.put(player, toPlayerResult(result)); dealerResult.merge(toDealerKey(result), 1, Integer::sum); } diff --git a/src/main/java/blackjack/domain/Money.java b/src/main/java/blackjack/domain/Money.java new file mode 100644 index 00000000000..0b6840c33aa --- /dev/null +++ b/src/main/java/blackjack/domain/Money.java @@ -0,0 +1,37 @@ +package blackjack.domain; + +public class Money { + + private final long bettingMoney; + + public Money(long bettingMoney) { + this.bettingMoney = bettingMoney; + } + + public static Money fromBettingAmount(long bettingMoney) { + validateMoney(bettingMoney); + return new Money(bettingMoney); + } + + public Money multiplyBettingAmount(double bonusAmount) { + return new Money((long) (bettingMoney * bonusAmount)); + } + + public Money lossBettingAmount() { + return new Money(-this.bettingMoney); + } + + public Money keepBettingAmount() { + return this; + } + + public long getBettingMoney() { + return bettingMoney; + } + + private static void validateMoney(long bettingMoney) { + if (bettingMoney <= 0) { + throw new IllegalArgumentException("[ERROR] 배팅 금액을 정확하게 입력해 주세요."); + } + } +} diff --git a/src/main/java/blackjack/domain/Name.java b/src/main/java/blackjack/domain/Name.java new file mode 100644 index 00000000000..fff65b05904 --- /dev/null +++ b/src/main/java/blackjack/domain/Name.java @@ -0,0 +1,20 @@ +package blackjack.domain; + +public class Name { + private final String name; + + public Name(String name) { + validate(name); + this.name = name; + } + + private void validate(String name) { + if (name == null || name.trim().isEmpty()) { + throw new IllegalArgumentException("[ERROR] 이름을 정확하게 입력해주세요."); + } + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/blackjack/domain/Participant.java b/src/main/java/blackjack/domain/Participant.java index 9ec2827e48b..aa01595040e 100644 --- a/src/main/java/blackjack/domain/Participant.java +++ b/src/main/java/blackjack/domain/Participant.java @@ -1,28 +1,19 @@ package blackjack.domain; -import java.util.HashMap; import java.util.List; public abstract class Participant { - protected final String name; + protected final Name name; protected final Cards drawnCards; protected Participant(String name) { - this.name = name; + this.name = new Name(name); this.drawnCards = new Cards(); } - public String getName() { - return name; - } - - public boolean isDealerNotDone() { - return false; - } - - public static Participant createPlayer(String name) { - return new Player(name); + public static Participant createPlayer(String name, Money money) { + return new Player(name, money); } public static Participant createDealer() { @@ -33,19 +24,27 @@ public void receiveOneCard(Card card) { drawnCards.addCard(card); } - public List getCardNames() { - return drawnCards.getCardNames(); + public boolean isDealerNotDone() { + return false; } public boolean isBust() { - return drawnCards.sumScore() > 21; + return drawnCards.isBust(); + } + + public boolean isBlackjack() { + return drawnCards.isBlackjack(); } public int calculateTotalScore() { return drawnCards.sumScore(); } - public GameResult judgeResult(List players, Participant dealer) { - return new GameResult(new HashMap<>(), new HashMap<>()); + public String getName() { + return name.getName(); + } + + public List getCardNames() { + return drawnCards.getCardNames(); } } diff --git a/src/main/java/blackjack/domain/Player.java b/src/main/java/blackjack/domain/Player.java index 9c86f4bc61a..d3bf544674e 100644 --- a/src/main/java/blackjack/domain/Player.java +++ b/src/main/java/blackjack/domain/Player.java @@ -1,14 +1,21 @@ package blackjack.domain; public class Player extends Participant { - private final String name; + private static final double BONUS_AMOUNT = 1.5; + private final Money money; - public Player(String name) { + public Player(String name, Money money) { super(name); - this.name = name; + this.money = money; } - public String getName() { - return name; + public Money calculateFinalProfit(ScoreCompareResult result) { + if (isBlackjack() && result == ScoreCompareResult.PLAYER_WIN) { + return money.multiplyBettingAmount(BONUS_AMOUNT); + } + if (result == ScoreCompareResult.PLAYER_LOSS) { + return money.lossBettingAmount(); + } + return money.keepBettingAmount(); } } diff --git a/src/main/java/blackjack/domain/Rank.java b/src/main/java/blackjack/domain/Rank.java index 7b87657fb6c..39d75a0bd25 100644 --- a/src/main/java/blackjack/domain/Rank.java +++ b/src/main/java/blackjack/domain/Rank.java @@ -35,10 +35,4 @@ public boolean isAce() { return this == ACE; } - public static Rank from(String name) { - return java.util.Arrays.stream(values()) - .filter(r -> r.getName().equals(name)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Rank입니다: " + name)); - } } diff --git a/src/main/java/blackjack/domain/Shape.java b/src/main/java/blackjack/domain/Shape.java index b010d2a5e93..23cc6e0130d 100644 --- a/src/main/java/blackjack/domain/Shape.java +++ b/src/main/java/blackjack/domain/Shape.java @@ -16,10 +16,4 @@ public String getName() { return name; } - public static Shape from(String name) { - return java.util.Arrays.stream(values()) - .filter(s -> s.getName().equals(name)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 Shape입니다: " + name)); - } } diff --git a/src/main/java/blackjack/service/Game.java b/src/main/java/blackjack/service/Game.java index 616e3e5bf98..6f05b1be763 100644 --- a/src/main/java/blackjack/service/Game.java +++ b/src/main/java/blackjack/service/Game.java @@ -1,12 +1,7 @@ package blackjack.service; import blackjack.domain.*; -import blackjack.view.InputView; -import blackjack.view.OutputView; - -import java.util.HashMap; import java.util.List; -import java.util.Map; public class Game { diff --git a/src/main/java/blackjack/service/RandomCardPicker.java b/src/main/java/blackjack/service/RandomCardPicker.java index 62d1c4a7ee3..086323220d5 100644 --- a/src/main/java/blackjack/service/RandomCardPicker.java +++ b/src/main/java/blackjack/service/RandomCardPicker.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Random; public class RandomCardPicker implements CardPicker { private final NumberGenerator numberGenerator; diff --git a/src/main/java/blackjack/utils/InputParser.java b/src/main/java/blackjack/utils/InputParser.java index b9a482fb86f..5a3c5843590 100644 --- a/src/main/java/blackjack/utils/InputParser.java +++ b/src/main/java/blackjack/utils/InputParser.java @@ -1,25 +1,25 @@ package blackjack.utils; import java.util.List; +import java.util.stream.Stream; public class InputParser { public static List splitPlayerNames(String input) { if (input == null || input.trim().isEmpty()) { - throw new IllegalArgumentException("[ERROR] 플레이어 이름을 입력해주세요."); + throw new IllegalArgumentException("[ERROR] 이름을 정확하게 입력해주세요."); } String[] names = input.split(","); - for (String name : names) { - validateNameEmpty(name); - } - return List.of(names).stream() + return Stream.of(names) .map(String::trim) .toList(); } - private static void validateNameEmpty(String name) { - if (name.trim().isEmpty()) { - throw new IllegalArgumentException("[ERROR] 플레이어 이름은 공백이 될 수 없습니다."); + public static long convertNumber(String input) { + try { + return Long.parseLong(input); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] 숫자 이외의 값은 입력할 수 없습니다."); } } } diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index fad744f5fd1..e41d88c1dc6 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -17,4 +17,9 @@ public static String askHitOrStand(String playerName) { System.out.printf(ASK_HIT_OR_STAND, playerName); return scanner.nextLine(); } + + public static String askPlayerBettingAmount(String playerName) { + System.out.printf("%n%s의 배팅 금액은?%n", playerName); + return scanner.nextLine(); + } } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 758f388c3f8..768110051a7 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,7 +1,7 @@ package blackjack.view; +import blackjack.domain.Money; import blackjack.domain.ParticipantResult; -import blackjack.domain.ScoreCompareResult; import java.util.List; import java.util.Map; @@ -30,7 +30,7 @@ private static void printFinalDrawnCards(String playerName, List cardNam public static void printDealerCardDrawnResult(int cardCount) { System.out.println(); - System.out.println("딜러는 " + cardCount + "장의 카드를 더 뽑았습니다."); + System.out.println("딜러는 16이하라 " + cardCount + "장의 카드를 더 뽑았습니다."); } public static void printFinalCardScores(List playerResult, ParticipantResult dealerResult) { @@ -45,30 +45,11 @@ public static void printFinalCardScores(List playerResult, Pa } } - public static void printFinalResult( - Map dealerResult, - Map playerResults) { - System.out.println(); - System.out.println("## 최종 승패"); - int wins = dealerResult.getOrDefault(ScoreCompareResult.DEALER_WIN, 0); - int losses = dealerResult.getOrDefault(ScoreCompareResult.DEALER_LOSS, 0); - int pushes = dealerResult.getOrDefault(ScoreCompareResult.PUSH, 0); - System.out.printf("딜러: %d승 %d무 %d패%n", wins, pushes, losses); - - for (Map.Entry entry : playerResults.entrySet()) { - System.out.println(entry.getKey() + ": " + toKorean(entry.getValue())); - } - } - - private static String toKorean(ScoreCompareResult result) { - if (result == ScoreCompareResult.PLAYER_WIN) { - return "승"; - } - if (result == ScoreCompareResult.PLAYER_LOSS) { - return "패"; + public static void printFinalProfit(long dealerProfit, Map playersProfit) { + System.out.println("\n## 최종 수익"); + System.out.println("딜러: " + dealerProfit); + for (Map.Entry entry : playersProfit.entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue()); } - return "무"; } - - } diff --git a/src/test/java/blackjackTest/domain/BustTest.java b/src/test/java/blackjackTest/domain/BustTest.java index 15624908661..b7ac2b14ae0 100644 --- a/src/test/java/blackjackTest/domain/BustTest.java +++ b/src/test/java/blackjackTest/domain/BustTest.java @@ -9,7 +9,7 @@ public class BustTest { @Test void player_busts_when_sum_exceeds_21() { - Player player = new Player("Alice"); + Player player = new Player("Alice", new Money(10000)); player.receiveOneCard(new Card(Rank.TWO, Shape.HEART)); player.receiveOneCard(new Card(Rank.QUEEN, Shape.SPADE)); player.receiveOneCard(new Card(Rank.TEN, Shape.CLOVER)); @@ -29,7 +29,7 @@ void dealer_busts_when_sum_exceeds_21() { @Test void player_not_busts_when_sum_21_or_less() { - Player player = new Player("Alice"); + Player player = new Player("Alice", new Money(10000)); player.receiveOneCard(new Card(Rank.ACE, Shape.HEART)); player.receiveOneCard(new Card(Rank.QUEEN, Shape.SPADE)); player.receiveOneCard(new Card(Rank.TEN, Shape.CLOVER)); diff --git a/src/test/java/blackjackTest/domain/CardTest.java b/src/test/java/blackjackTest/domain/CardTest.java index 05c9d4930eb..c26b0b10f09 100644 --- a/src/test/java/blackjackTest/domain/CardTest.java +++ b/src/test/java/blackjackTest/domain/CardTest.java @@ -1,7 +1,6 @@ package blackjackTest.domain; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import blackjack.domain.Card; import blackjack.domain.Rank; diff --git a/src/test/java/blackjackTest/domain/PlayerTest.java b/src/test/java/blackjackTest/domain/PlayerTest.java index 12af26cf9a2..b545d4f5db7 100644 --- a/src/test/java/blackjackTest/domain/PlayerTest.java +++ b/src/test/java/blackjackTest/domain/PlayerTest.java @@ -2,16 +2,13 @@ import static org.assertj.core.api.Assertions.assertThat; -import blackjack.domain.Card; -import blackjack.domain.Player; -import blackjack.domain.Rank; -import blackjack.domain.Shape; +import blackjack.domain.*; import org.junit.jupiter.api.Test; public class PlayerTest { @Test void player_total_score_blackJack() { - Player player = new Player("player1"); + Player player = new Player("player1", new Money(10000)); player.receiveOneCard(new Card(Rank.ACE, Shape.HEART)); player.receiveOneCard(new Card(Rank.QUEEN, Shape.SPADE)); assertThat(player.calculateTotalScore()).isEqualTo(21); @@ -19,7 +16,7 @@ void player_total_score_blackJack() { @Test void player_total_score_not_blackjack() { - Player player = new Player("player2"); + Player player = new Player("player2", new Money(10000)); player.receiveOneCard(new Card(Rank.THREE, Shape.HEART)); player.receiveOneCard(new Card(Rank.TEN, Shape.SPADE)); assertThat(player.calculateTotalScore()).isEqualTo(13); diff --git a/src/test/java/blackjackTest/service/BlackjackTest.java b/src/test/java/blackjackTest/service/BlackjackTest.java new file mode 100644 index 00000000000..8278a7613c9 --- /dev/null +++ b/src/test/java/blackjackTest/service/BlackjackTest.java @@ -0,0 +1,196 @@ +package blackjackTest.service; + +import blackjack.domain.*; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class BlackjackTest { + + private ScoreCompareResult getPlayerResult(Dealer dealer, Player player) { + GameResult gameResult = dealer.judgeResult(List.of(player)); + return gameResult.playerResults().get(player); + } + @Test + void 플레이어_초기카드_합_21인지_확인() { + Player pobi = new Player("pobi", new Money(10000)); + pobi.receiveOneCard(new Card(Rank.ACE, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TEN, Shape.SPADE)); + + assertThat(pobi.isBlackjack()).isEqualTo(true); + } + + @Test + void 플레이어_초기카드_합_21_아닌경우_1() { + Player pobi = new Player("pobi", new Money(10000)); + pobi.receiveOneCard(new Card(Rank.TWO, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TEN, Shape.SPADE)); + + assertThat(pobi.isBlackjack()).isEqualTo(false); + } + + @Test + void 플레이어_초기카드_합_21_아닌경우_2() { + Player pobi = new Player("pobi", new Money(10000)); + pobi.receiveOneCard(new Card(Rank.TWO, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TEN, Shape.SPADE)); + pobi.receiveOneCard(new Card(Rank.NINE, Shape.SPADE)); + + assertThat(pobi.isBlackjack()).isEqualTo(false); + } + + @Test + void 플레이어_초기카드_합_21이면_배팅금액의_1_5배_지급() { + int bettingAmountValue = 10000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.ACE, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TEN, Shape.SPADE)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + long expectedAmount = (long) (bettingAmountValue * 1.5); + assertThat(profit.getBettingMoney()).isEqualTo(expectedAmount); + } + + @Test + void 플레이어_카드합_21_넘으면_배팅금액_모두_잃음() { + long bettingAmountValue = 10000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TEN, Shape.SPADE)); + pobi.receiveOneCard(new Card(Rank.TWO, Shape.CLOVER)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + long expectedAmount = -bettingAmountValue; + assertThat(profit.getBettingMoney()).isEqualTo(expectedAmount); + } + + @Test + void 딜러_초기카드_합_21이면_배팅금액_모두_잃음() { + long bettingAmountValue = 10000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TEN, Shape.SPADE)); + dealer.receiveOneCard(new Card(Rank.ACE, Shape.CLOVER)); + dealer.receiveOneCard(new Card(Rank.QUEEN, Shape.SPADE)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + long expectedAmount = -bettingAmountValue; + assertThat(profit.getBettingMoney()).isEqualTo(expectedAmount); + } + + @Test + void 딜러와_플레이어_모두_초기카드_합_21이면_배팅금액_돌려받음() { + long bettingAmountValue = 10000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.ACE, Shape.SPADE)); + dealer.receiveOneCard(new Card(Rank.ACE, Shape.CLOVER)); + dealer.receiveOneCard(new Card(Rank.QUEEN, Shape.SPADE)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + assertThat(profit.getBettingMoney()).isEqualTo(bettingAmountValue); + } + + @Test + void 플레이어가_딜러보다_점수가_높으면_배팅금액_돌려받음() { + long bettingAmountValue = 10000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TWO, Shape.SPADE)); + pobi.receiveOneCard(new Card(Rank.EIGHT, Shape.CLOVER)); + + dealer.receiveOneCard(new Card(Rank.EIGHT, Shape.CLOVER)); + dealer.receiveOneCard(new Card(Rank.QUEEN, Shape.SPADE)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + + assertThat(profit.getBettingMoney()).isEqualTo(bettingAmountValue); + } + + @Test + void 딜러가_버스트일때_플레이어가_이기면_배팅금액_돌려받음() { + long bettingAmountValue = 10000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TWO, Shape.SPADE)); + pobi.receiveOneCard(new Card(Rank.EIGHT, Shape.CLOVER)); + + dealer.receiveOneCard(new Card(Rank.EIGHT, Shape.CLOVER)); + dealer.receiveOneCard(new Card(Rank.QUEEN, Shape.SPADE)); + dealer.receiveOneCard(new Card(Rank.NINE, Shape.CLOVER)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + + assertThat(profit.getBettingMoney()).isEqualTo(bettingAmountValue); + } + + @Test + void 딜러와_플레이어_점수가_같으면_배팅금액_돌려받음() { + long bettingAmountValue = 20000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TWO, Shape.SPADE)); + pobi.receiveOneCard(new Card(Rank.EIGHT, Shape.CLOVER)); + + dealer.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + dealer.receiveOneCard(new Card(Rank.TWO, Shape.SPADE)); + dealer.receiveOneCard(new Card(Rank.EIGHT, Shape.CLOVER)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + + assertThat(profit.getBettingMoney()).isEqualTo(bettingAmountValue); + } + + @Test + void 플레이어_점수가_딜러보다_낮으면_배팅금액_잃음() { + long bettingAmountValue = 20000; + Money bettingAmount = new Money(bettingAmountValue); + Player pobi = new Player("pobi", bettingAmount); + Dealer dealer = new Dealer(); + + pobi.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + pobi.receiveOneCard(new Card(Rank.TWO, Shape.SPADE)); + + dealer.receiveOneCard(new Card(Rank.TEN, Shape.HEART)); + dealer.receiveOneCard(new Card(Rank.TWO, Shape.SPADE)); + dealer.receiveOneCard(new Card(Rank.EIGHT, Shape.CLOVER)); + + ScoreCompareResult playerResult = getPlayerResult(dealer, pobi); + Money profit = pobi.calculateFinalProfit(playerResult); + long expectedAmount = -bettingAmountValue; + + assertThat(profit.getBettingMoney()).isEqualTo(expectedAmount); + } + + +} diff --git a/src/test/java/blackjackTest/service/GameTest.java b/src/test/java/blackjackTest/service/GameTest.java index 5e0663228cf..3a413fdae57 100644 --- a/src/test/java/blackjackTest/service/GameTest.java +++ b/src/test/java/blackjackTest/service/GameTest.java @@ -33,10 +33,20 @@ void dealer_should_draw_card_until_score_at_least_17() { @Test void judge_total_winner_result() { - Player pobi = createPlayer("pobi", "2:하트", "8:스페이드", "A:클로버"); - Player jason = createPlayer("jason", "7:클로버", "K:스페이드"); - Player brown = createPlayer("brown", "10:하트", "10:클로버"); - Dealer dealer = createDealer("3:다이아몬드", "9:클로버", "8:다이아몬드"); + Player pobi = createPlayer("pobi", + new Card(Rank.TWO, Shape.HEART), + new Card(Rank.EIGHT, Shape.SPADE), + new Card(Rank.ACE, Shape.CLOVER)); + Player jason = createPlayer("jason", + new Card(Rank.SEVEN, Shape.CLOVER), + new Card(Rank.KING, Shape.SPADE)); + Player brown = createPlayer("brown", + new Card(Rank.TEN, Shape.HEART), + new Card(Rank.TEN, Shape.CLOVER)); + + Dealer dealer = createDealer(new Card(Rank.THREE, Shape.DIAMOND), + new Card(Rank.NINE, Shape.CLOVER), + new Card(Rank.EIGHT, Shape.DIAMOND)); GameResult expected = new GameResult( Map.of( @@ -49,31 +59,23 @@ void judge_total_winner_result() { brown, ScoreCompareResult.PUSH) ); - GameResult actual = dealer.judgeResult(List.of(pobi, jason, brown), dealer); + GameResult actual = dealer.judgeResult(List.of(pobi, jason, brown)); assertThat(actual).usingRecursiveComparison().isEqualTo(expected); } - private Player createPlayer(String name, String... cards) { - Player player = new Player(name); - for (String card : cards) { - String[] parts = card.split(":"); - Rank rank = Rank.from(parts[0]); - Shape shape = Shape.from(parts[1]); - - player.receiveOneCard(new Card(rank, shape)); + private Player createPlayer(String name, Card... cards) { + Player player = new Player(name, new Money(10000)); + for (Card card : cards) { + player.receiveOneCard(card); } return player; } - private Dealer createDealer(String... cards) { + private Dealer createDealer(Card... cards) { Dealer dealer = new Dealer(); - for (String card : cards) { - String[] parts = card.split(":"); - Rank rank = Rank.from(parts[0]); - Shape shape = Shape.from(parts[1]); - - dealer.receiveOneCard(new Card(rank, shape)); + for (Card card : cards) { + dealer.receiveOneCard(card); } return dealer; }