diff --git a/README.md b/README.md index 745d1dcd2d5..97b6c8da327 100644 --- a/README.md +++ b/README.md @@ -5,22 +5,29 @@ ### 입력 - [x] "게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리) " 를 출력한다. - [x] 게임에 참여하는 참가자의 이름을 쉼표 기준으로 나누는 문자열을 하나 입력받는다. +- [x] 참가자 별로 베팅할 금액을 입력 - [x] 게임을 계속 진행할 지 결정하는 (y/n) 는 y, n를 입력한다. ### 입력 예외 - [x] 이름은 쉼표 기준으로 분리되어 1개 이상이어야 한다. - [x] 이름은 영어로 2~10자 사이여야 한다. -- [x] 이름은 영어로만 엊루이한야 져어루다한야. +- [x] 이름은 영어로만 이루어져야 한다. - [x] 이름은 소문자 기준으로 중복되지 않는다. +- [x] 베팅할 금액은 10 이상의 양수여야 한다. - [x] 게임을 계속 진행할 지 결정하는 y, n만 입력할 수 있다. ### 기능 1. 입력 처리 -- [x] 입력받은 문자열을 ‘,’를 기준으로 파싱한다. -- [x] 파싱한 이름을 검증한다. + 1-1. 참가자 이름 입력 + - [x] 입력받은 문자열을 ‘,’를 기준으로 파싱한다. + - [x] 파싱한 이름을 검증한다. + + 1-2. 베팅 금액 입력 + - [x] 참가자 별로 베팅할 금액을 입력받는다. + - [x] 베팅한 금액을 검증한다. 2. 게임 진행 @@ -37,11 +44,14 @@ 3. 결과 처리 -- [X] 덱은 한 덱(52장)으로 고정한다(이때 하드코딩하지 않는다) - [x] 딜러와 각 참가자들의 카드 합을 구한다. -- [x] 참가자 승 : 딜러보다 합이 21에 더 가까운 경우 or 딜러가 버스트인 경우(참가자 버스트 X) -- [x] 참가자 무승부: 참가자와 딜러의 합이 같음(버스트 X) -- [x] 참가자 패 : 참가자 버스트 or 딜러보다 합이 적음(딜러가 버스트 X) +- [x] 딜러와 참가자 수익 계산 초기값은 '0'으로 수익, 손해는 이 값을 기준으로 계산한다. +- [x] 처음 두 장의 카드 합이 21이면 블랙잭으로, 베팅 금액의 1.5배를 딜러에게 받는다. +- [x] 딜러와 플레이어가 모두 동시에 블랙잭인 경우 플레이어는 베팅한 금액을 돌려받는다.(수익: 0) +- [x] 카드를 추가로 뽑아 21을 초과할 경우 베팅 금액을 모두 잃게 된다. (수익: -베팅 금액) +- [x] 딜러가 21을 초과하면 그 시점까지 남아 있던 플레이어들은 가지고 있는 패에 상관 없이 승리해 베팅 금액을 받는다. (수익: 베팅 금액) +- [x] 딜러가 21을 초과하더라도 플레이어가 21을 초과해 이미 베팅 금액을 잃었다면 베팅 금액을 받지 않는다. (수익: -베팅 금액) +- [x] 딜러가 21을 초과할 때 플레이어가 이미 블랙잭으로 1.5배를 받았다면 추가로 금액을 받지 않는다. ### 출력 @@ -51,4 +61,4 @@ - [x] 참가자가 추가로 받은 카드들을“ [참가자]카드: 7클로버, K스페이드 ” 의 형태로 출력한다. - [x] 딜러가 받은 추가 카드를 “딜러는 16이하라 한장의 카드를 더 받았습니다.” 의 형태로 출력한다. - [x] 딜러, 참가자들의 카드 목록과 카드 합 결과를 “딜러카드: 3다이아몬드, 9클로버, 8다이아몬드 - 결과: 20” 의 형태로 출력한다. -- [x] 딜러, 참가자들의 최종 승패를 “## 최종 승패 딜러: 1승 1패 [참가자]: 승 [참가자]: 패” 의 형태로 출력한다. +- [x] 딜러, 참가자들의 수익을 ## 최종 수익 딜러 : xxxx [참가자]: xxxx [참가자]: xxxx” 의 형태로 출력한다. \ No newline at end of file diff --git a/src/main/java/Application.java b/src/main/java/Application.java index 487e5ef19b6..84db4a518eb 100644 --- a/src/main/java/Application.java +++ b/src/main/java/Application.java @@ -3,6 +3,7 @@ import view.OutputView; public class Application { + public static void main(String[] args) { InputView inputView = new InputView(); OutputView outputView = new OutputView(); diff --git a/src/main/java/controller/BlackJackController.java b/src/main/java/controller/BlackJackController.java index 6cb515e20b4..89909b497f3 100644 --- a/src/main/java/controller/BlackJackController.java +++ b/src/main/java/controller/BlackJackController.java @@ -1,25 +1,25 @@ package controller; -import static util.Constants.COMMA_DELIMITER; -import static util.Constants.DEALER_NAME; -import static util.Constants.DEFAULT_CARD_SET; -import static util.Constants.HIT; -import static util.Constants.STAND; - +import domain.betting.Betting; +import domain.betting.BettingAmount; +import domain.card.GameCards; import domain.game.GamblersGameResult; import domain.game.Game; +import domain.player.Dealer; import domain.player.Gambler; -import dto.AgreementRequestDto; -import dto.DealerResultDto; -import dto.ParticipantHandResponseDto; -import dto.ParticipantsGameInfoDto; -import dto.ParticipantsHandResponseDto; +import view.requestDto.AgreementRequestDto; +import view.requestDto.BettingAmountRequestDto; +import view.responseDto.DealerResultDto; +import view.responseDto.ParticipantHandResponseDto; +import view.responseDto.ParticipantsGameInfoDto; +import view.responseDto.ParticipantsHandResponseDto; import java.util.List; -import util.Parser; +import java.util.Map; import view.InputView; import view.OutputView; public class BlackJackController { + private final InputView inputView; private final OutputView outputView; @@ -30,49 +30,62 @@ public BlackJackController(InputView inputView, OutputView outputView) { public void run() { List names = inputGamblersInfo(); - Game game = initializeGame(names); + Map gamblerNameAndBettingInfo = betByName(names); + Game game = initializeGame(gamblerNameAndBettingInfo); playGame(game); checkDealerHand(game); printParticipantsResult(game); - determineFinalGameResult(game.getResult()); + determineFinalGameProfit(game.getResult()); } private List inputGamblersInfo() { - String name = inputView.askGamblerNames().name(); - return Parser.parse(name, COMMA_DELIMITER); + return inputView.askGamblerNames().names(); } - private Game initializeGame(List names) { - Game game = new Game(DEALER_NAME, names, DEFAULT_CARD_SET); + private Map betByName(List names) { + Betting betting = new Betting(names); + for (String name : names) { + BettingAmountRequestDto bettingAmountRequestDto = inputView.askBettingAmount(name); + betting.betBettingAmount(name, + new BettingAmount(bettingAmountRequestDto.getBettingAmount())); + } + return betting.getBettingAmounts(); + } - outputView.printInitialDeal(names); + private Game initializeGame(Map gamblerNameAndBettingInfo) { + Game game = new Game(Dealer.DEALER_NAME, gamblerNameAndBettingInfo, + GameCards.DEFAULT_CARD_SET); + + outputView.printInitialDeal(gamblerNameAndBettingInfo.keySet().stream().toList()); game.initializeGame(); outputView.printParticipantsInfo( - new ParticipantsHandResponseDto(game.getInitialParticipantsHandInfo()) - ); - + new ParticipantsHandResponseDto(game.getInitialParticipantsHandInfo())); return game; } private void playGame(Game game) { List gamblers = game.getGamblersList(); - for(Gambler gambler : gamblers) { + for (Gambler gambler : gamblers) { + if (gambler.isBlackJack()) { + outputView.printBlackJackMessage(gambler.getName()); + continue; + } playTurn(game, gambler); } } private void playTurn(Game game, Gambler gambler) { - while(!gambler.isBust()) { + while (!gambler.isBust()) { AgreementRequestDto agreementRequestDto = inputView.askHitOrStand(gambler.getName()); - if (agreementRequestDto.agreement().equals(HIT)) { - gambler.addCard(game.pickCard()); + if (agreementRequestDto.agreement().equals(InputView.HIT)) { + game.drawCardTo(gambler); outputView.printParticipantInfo( new ParticipantHandResponseDto(gambler.getName(), gambler.getHandInfo())); } - if (agreementRequestDto.agreement().equals(STAND)) { + if (agreementRequestDto.agreement().equals(InputView.STAND)) { break; } } @@ -80,24 +93,19 @@ private void playTurn(Game game, Gambler gambler) { private void checkDealerHand(Game game) { if (game.shouldDealerDraw()) { - outputView.printDealerCardIsUnder16(); - game.addDealerCard(); + outputView.printDealerCardIsBelowDrawThreshold(); + game.drawCardTo(game.getDealer()); } } private void printParticipantsResult(Game game) { - outputView.printParticipantsGameInfo(new ParticipantsGameInfoDto( - game.getParticipantGameInfos() - )); + outputView.printParticipantsGameInfo( + new ParticipantsGameInfoDto(game.getParticipantGameInfos())); } - private void determineFinalGameResult(GamblersGameResult gamblersGameResult) { + private void determineFinalGameProfit(GamblersGameResult gamblersGameResult) { outputView.printDealerResult( - new DealerResultDto(gamblersGameResult.countDealerWin(), - gamblersGameResult.countDealerLose(), - gamblersGameResult.countDealerDraw())); - outputView.printGamblerResult( - gamblersGameResult.getResultInfo() - ); + new DealerResultDto(gamblersGameResult.getDealerProfit().getProfit())); + outputView.printGamblerResult(gamblersGameResult.getParticipantProfits()); } } diff --git a/src/main/java/domain/betting/Betting.java b/src/main/java/domain/betting/Betting.java new file mode 100644 index 00000000000..76b36fca034 --- /dev/null +++ b/src/main/java/domain/betting/Betting.java @@ -0,0 +1,38 @@ +package domain.betting; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class Betting { + + private final Map values = new LinkedHashMap<>(); + + public Betting(List names) { + validateDuplicateNames(names); + for (String name : names) { + values.put(name, null); + } + } + + public void betBettingAmount(String name, BettingAmount bettingAmount) { + values.put(name, bettingAmount); + } + + public BettingAmount getBettingAmountByName(String name) { + return values.get(name); + } + + public Map getBettingAmounts() { + return values; + } + + public void validateDuplicateNames(List names) { + List distinctNamesCount = names.stream(). + distinct().collect(Collectors.toList()); + if (distinctNamesCount.size() != names.size()) { + throw new IllegalArgumentException("중복된 이름이 입력됩니다."); + } + } +} diff --git a/src/main/java/domain/betting/BettingAmount.java b/src/main/java/domain/betting/BettingAmount.java new file mode 100644 index 00000000000..c9869de3653 --- /dev/null +++ b/src/main/java/domain/betting/BettingAmount.java @@ -0,0 +1,33 @@ +package domain.betting; + +import java.util.Objects; + +public class BettingAmount { + + private final int bettingAmount; + + public BettingAmount(int bettingAmount) { + this.bettingAmount = bettingAmount; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BettingAmount that = (BettingAmount) o; + return bettingAmount == that.bettingAmount; + } + + @Override + public int hashCode() { + return Objects.hash(bettingAmount); + } + + public int getBettingAmount() { + return bettingAmount; + } +} diff --git a/src/main/java/domain/card/Card.java b/src/main/java/domain/card/Card.java index b602d883aeb..e48b28b22b3 100644 --- a/src/main/java/domain/card/Card.java +++ b/src/main/java/domain/card/Card.java @@ -1,6 +1,7 @@ package domain.card; public class Card { + private final CardScore score; private final CardKind kind; diff --git a/src/main/java/domain/card/CardKind.java b/src/main/java/domain/card/CardKind.java index e4aadc66dcd..6fef5943e86 100644 --- a/src/main/java/domain/card/CardKind.java +++ b/src/main/java/domain/card/CardKind.java @@ -5,7 +5,7 @@ public enum CardKind { CLOVER("클로버"), HEART("하트"), - DIAMOND ("다이아몬드"), + DIAMOND("다이아몬드"), SPADES("스페이드"); private final String kind; @@ -18,7 +18,7 @@ public String getKind() { return kind; } - public static CardKind of(final String kind){ + public static CardKind of(final String kind) { return Arrays.stream(values()) .filter(val -> val.kind.equals(kind)) .findFirst() diff --git a/src/main/java/domain/card/CardScore.java b/src/main/java/domain/card/CardScore.java index fc3d11ee3b2..3333c7a5621 100644 --- a/src/main/java/domain/card/CardScore.java +++ b/src/main/java/domain/card/CardScore.java @@ -33,7 +33,7 @@ public String getScore() { return this.score; } - public static CardScore of(final String score){ + public static CardScore of(final String score) { return Arrays.stream(values()) .filter(val -> val.score.equals(score)) .findFirst() diff --git a/src/main/java/domain/card/GameCards.java b/src/main/java/domain/card/GameCards.java index 36af9465472..e4066ccbf53 100644 --- a/src/main/java/domain/card/GameCards.java +++ b/src/main/java/domain/card/GameCards.java @@ -9,13 +9,16 @@ public class GameCards { + public static final int DEFAULT_CARD_SET = 1; + public static final int DEFAULT_START_CARD_COUNT = 2; + private List cards; - public GameCards(int amount) { + public GameCards(int DEFAULT_CARD_SET) { this.cards = Arrays.stream(CardKind.values()) .flatMap(cardKind -> Arrays.stream(CardScore.values()) .flatMap(cardScore -> - IntStream.range(0, amount) + IntStream.range(0, DEFAULT_CARD_SET) .mapToObj(card -> new Card(cardScore.getScore(), cardKind.getKind())) )) diff --git a/src/main/java/domain/game/GamblersGameResult.java b/src/main/java/domain/game/GamblersGameResult.java index d37c6490c11..8913efcc1c2 100644 --- a/src/main/java/domain/game/GamblersGameResult.java +++ b/src/main/java/domain/game/GamblersGameResult.java @@ -1,55 +1,42 @@ package domain.game; +import domain.player.Gambler; +import domain.player.Gamblers; +import domain.player.Participant; import java.util.LinkedHashMap; import java.util.Map; -import java.util.stream.Collectors; public class GamblersGameResult { - private Map gamblersResult; + public static final int REVERSE_SIGN = -1; - public GamblersGameResult(int dealerScore, Map gameResults) { - this.gamblersResult = gameResults.entrySet() - .stream() - .collect(Collectors.toMap(Map.Entry::getKey, - entry -> GameResult.determine( - dealerScore, - entry.getValue()), - (a, b) -> a, LinkedHashMap::new)); - } + private Map participantProfits; - public GameResult getMatchResult(String name) { - return gamblersResult.get(name); + public GamblersGameResult(Participant dealer, Gamblers gamblers) { + this.participantProfits = new LinkedHashMap<>(); + calculateProfits(dealer, gamblers); } - public int countDealerWin() { - return (int) gamblersResult.values() - .stream() - .filter(result -> result == GameResult.LOSE) - .count(); + private void calculateProfits(Participant dealer, Gamblers gamblers) { + for (Gambler gambler : gamblers.getGamblers()) { + GameResult result = GameResult.determine(dealer, gambler); + Profit profit = result.calculateProfit(gambler.getBettingAmount()); + participantProfits.put(gambler.getName(), profit); + } } - public int countDealerLose() { - return (int) gamblersResult.values() - .stream() - .filter(result -> result == GameResult.WIN) - .count(); + public Profit getMatchProfits(String name) { + return participantProfits.get(name); } - public int countDealerDraw() { - return (int) gamblersResult - .values() - .stream() - .filter(result -> result == GameResult.DRAW) - .count(); + public Map getParticipantProfits() { + return participantProfits; } - public Map getResultInfo() { - return gamblersResult.entrySet() - .stream() - .collect(Collectors.toMap(Map.Entry::getKey, - entry -> entry.getValue().getGameResult(), - (a, b) -> a, LinkedHashMap::new - )); + public Profit getDealerProfit() { + int totalProfit = participantProfits.values().stream() + .mapToInt(Profit::getProfit) + .sum(); + return new Profit(totalProfit * REVERSE_SIGN); } } diff --git a/src/main/java/domain/game/Game.java b/src/main/java/domain/game/Game.java index fd6f85c1a24..d26e5599d91 100644 --- a/src/main/java/domain/game/Game.java +++ b/src/main/java/domain/game/Game.java @@ -1,12 +1,12 @@ package domain.game; -import static util.Constants.DEFAULT_START_CARD_COUNT; - +import domain.betting.BettingAmount; import domain.card.Card; import domain.card.GameCards; import domain.player.Dealer; import domain.player.Gambler; import domain.player.Gamblers; +import domain.player.Participant; import domain.player.ParticipantGameInfo; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -19,14 +19,15 @@ public class Game { private final Gamblers gamblers; private final GameCards gameCards; - public Game(String dealerName, List names, int amount) { + public Game(String dealerName, Map gamblersNameAndBettingInfo, + int DEFAULT_CARD_SET) { this.dealer = new Dealer(dealerName); - this.gamblers = new Gamblers(names); - this.gameCards = new GameCards(amount); + this.gamblers = new Gamblers(gamblersNameAndBettingInfo); + this.gameCards = new GameCards(DEFAULT_CARD_SET); } public void initializeGame() { - for (int i = 0; i < DEFAULT_START_CARD_COUNT; i++) { + for (int i = 0; i < GameCards.DEFAULT_START_CARD_COUNT; i++) { dealer.addCard(gameCards.drawCard()); gamblers.receiveCards(gameCards); } @@ -39,18 +40,21 @@ public Map> getInitialParticipantsHandInfo() { return info; } + public Dealer getDealer() { + return dealer; + } public boolean shouldDealerDraw() { return dealer.isBelowDrawThreshold(); } - public void addDealerCard() { - dealer.addCard(pickCard()); - } - public Card pickCard() { return gameCards.drawCard(); } + public void drawCardTo(Participant participant) { + participant.addCard(pickCard()); + } + public List getGamblersList() { return gamblers.getGamblers(); } @@ -70,7 +74,7 @@ public List getGamblersHandSize() { return gamblers.getHandSize(); } - public GamblersGameResult getResult(){ - return new GamblersGameResult(dealer.getTotalScore(), gamblers.getParticipantTotalScore()); + public GamblersGameResult getResult() { + return new GamblersGameResult(dealer, gamblers); } } diff --git a/src/main/java/domain/game/GameResult.java b/src/main/java/domain/game/GameResult.java index 9ff5145c8aa..4fec26afaee 100644 --- a/src/main/java/domain/game/GameResult.java +++ b/src/main/java/domain/game/GameResult.java @@ -1,33 +1,57 @@ package domain.game; -import static util.Constants.BLACK_JACK; +import domain.betting.BettingAmount; +import domain.player.Participant; public enum GameResult { - WIN("승"), - LOSE("패"), - DRAW("무"); + BLACK_JACK(1.5), + WIN(1.0), + LOSE(-1.0), + DRAW(0.0); - private String gameResult; + private final double benefitRatio; - GameResult(String gameResult) { - this.gameResult = gameResult; + GameResult(double gameResult) { + this.benefitRatio = gameResult; } - public static GameResult determine(int dealerScore, int gamblerScore) { - if(gamblerScore > BLACK_JACK) return LOSE; - if(dealerScore > BLACK_JACK) return WIN; + public static GameResult determine(Participant dealer, Participant gambler) { + if (gambler.isBust()) { + return LOSE; + } - if(dealerScore < gamblerScore) { + if (dealer.isBust()) { return WIN; } - if(dealerScore > gamblerScore) { + if (dealer.isBlackJack() && gambler.isBlackJack()) { + return DRAW; + } + if (gambler.isBlackJack()) { + return BLACK_JACK; + } + if (dealer.isBlackJack()) { + return LOSE; + } + if (dealer.getTotalScore() > gambler.getTotalScore()) { return LOSE; } + if (dealer.getTotalScore() < gambler.getTotalScore()) { + return WIN; + } return DRAW; } - public String getGameResult() { - return gameResult; + public Profit calculateProfit(BettingAmount bettingAmount) { + if (this == BLACK_JACK) { + return new Profit((bettingAmount.getBettingAmount() * 3) / 2); + } + if (this == WIN) { + return new Profit(bettingAmount.getBettingAmount()); + } + if (this == DRAW) { + return new Profit(0); + } + return new Profit(-bettingAmount.getBettingAmount()); } } diff --git a/src/main/java/domain/game/Profit.java b/src/main/java/domain/game/Profit.java new file mode 100644 index 00000000000..47b386baff3 --- /dev/null +++ b/src/main/java/domain/game/Profit.java @@ -0,0 +1,33 @@ +package domain.game; + +import java.util.Objects; + +public class Profit { + + private final int profit; + + public Profit(int profit) { + this.profit = profit; + } + + public int getProfit() { + return profit; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Profit that = (Profit) o; + return profit == that.profit; + } + + @Override + public int hashCode() { + return Objects.hash(profit); + } +} diff --git a/src/main/java/domain/player/Dealer.java b/src/main/java/domain/player/Dealer.java index c3d1ff3aa36..9e4e54c3196 100644 --- a/src/main/java/domain/player/Dealer.java +++ b/src/main/java/domain/player/Dealer.java @@ -1,11 +1,12 @@ package domain.player; -import static util.Constants.DEALER_REFERENCE_POINT; - public class Dealer extends Participant { - public Dealer(String name) { - super(name); + public static final String DEALER_NAME = "딜러"; + public static final int DEALER_REFERENCE_POINT = 16; + + public Dealer(String DEALER_NAME) { + super(DEALER_NAME); } public boolean isBelowDrawThreshold() { diff --git a/src/main/java/domain/player/Gambler.java b/src/main/java/domain/player/Gambler.java index c446a84ae8a..d82bbb2d72d 100644 --- a/src/main/java/domain/player/Gambler.java +++ b/src/main/java/domain/player/Gambler.java @@ -1,7 +1,17 @@ package domain.player; -public class Gambler extends Participant{ - public Gambler(String name) { +import domain.betting.BettingAmount; + +public class Gambler extends Participant { + + private final BettingAmount bettingAmount; + + public Gambler(String name, BettingAmount bettingAmount) { super(name); + this.bettingAmount = bettingAmount; + } + + public BettingAmount getBettingAmount() { + return bettingAmount; } } diff --git a/src/main/java/domain/player/Gamblers.java b/src/main/java/domain/player/Gamblers.java index 9b22ec0113f..4a3db1cef6a 100644 --- a/src/main/java/domain/player/Gamblers.java +++ b/src/main/java/domain/player/Gamblers.java @@ -1,5 +1,6 @@ package domain.player; +import domain.betting.BettingAmount; import domain.card.GameCards; import java.util.LinkedHashMap; import java.util.List; @@ -10,13 +11,17 @@ public class Gamblers { private List gamblers; - public Gamblers(List names) { - validateDuplicateNames(names); - this.gamblers = names.stream() - .map(Gambler::new) + public Gamblers(Map gamblerNameAndBettingInfo) { + this.gamblers = gamblerNameAndBettingInfo.entrySet() + .stream() + .map(entry -> new Gambler(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); } + public Gamblers(List gamblerList) { + this.gamblers = gamblerList; + } + public boolean containGambler(String name) { return gamblers.stream() .anyMatch(gambler -> gambler.isEqualName(name)); @@ -58,11 +63,7 @@ public List getGamblers() { return gamblers; } - public void validateDuplicateNames(List names) { - List distinctNamesCount = names.stream(). - distinct().collect(Collectors.toList()); - if(distinctNamesCount.size() != names.size()) { - throw new IllegalArgumentException("중복된 이름이 입력됩니다."); - } + public int getGamblersSize() { + return gamblers.size(); } } diff --git a/src/main/java/domain/player/Participant.java b/src/main/java/domain/player/Participant.java index 2a0fa73c96a..fe31f132f43 100644 --- a/src/main/java/domain/player/Participant.java +++ b/src/main/java/domain/player/Participant.java @@ -51,4 +51,12 @@ public ParticipantGameInfo getParticipantGameInfo() { public boolean isEqualName(String name) { return this.name.isEqualName(name); } + + public boolean isBlackJack() { + return hand.isBlackJack(); + } + + public boolean canHit() { + return !isBlackJack() && !isBust(); + } } diff --git a/src/main/java/domain/player/ParticipantGameInfo.java b/src/main/java/domain/player/ParticipantGameInfo.java index 5871574af4f..80266ca6df7 100644 --- a/src/main/java/domain/player/ParticipantGameInfo.java +++ b/src/main/java/domain/player/ParticipantGameInfo.java @@ -6,4 +6,5 @@ public record ParticipantGameInfo( String name, List cards, int score) { + } diff --git a/src/main/java/domain/player/attribute/Hand.java b/src/main/java/domain/player/attribute/Hand.java index 7b7f2fc87be..9bf1069c27e 100644 --- a/src/main/java/domain/player/attribute/Hand.java +++ b/src/main/java/domain/player/attribute/Hand.java @@ -1,9 +1,5 @@ package domain.player.attribute; -import static util.Constants.ACE_HIGH_SCORE; -import static util.Constants.ACE_LOW_SCORE; -import static util.Constants.BLACK_JACK; - import domain.card.Card; import java.util.ArrayList; import java.util.List; @@ -11,6 +7,11 @@ public class Hand { + public static final int ACE_HIGH_SCORE = 11; + public static final int ACE_LOW_SCORE = 1; + + public static final int BLACK_JACK_SCORE = 21; + private final List cards; public Hand() { @@ -26,18 +27,16 @@ public int getCardsSize() { } public boolean isBust() { - return calculateScore() > BLACK_JACK; + return calculateScore() > BLACK_JACK_SCORE; } public int calculateScore() { int sum = calculateBaseScore(); int aceCount = countAce(); - - while (sum > BLACK_JACK && aceCount > 0) { + while (sum > BLACK_JACK_SCORE && aceCount > 0) { sum -= (ACE_HIGH_SCORE - ACE_LOW_SCORE); aceCount--; } - return sum; } @@ -53,21 +52,21 @@ public String getFirstCardInfo() { private int calculateBaseScore() { int sum = 0; - for (Card card : cards) { sum += getCardScore(card); } - return sum; } + public boolean isBlackJack() { + return getCardsSize() == 2 && calculateScore() == BLACK_JACK_SCORE; + } + private int countAce() { int aceCount = 0; - for (Card card : cards) { aceCount += getAceToInt(card); } - return aceCount; } diff --git a/src/main/java/domain/player/attribute/Name.java b/src/main/java/domain/player/attribute/Name.java index 2d2f2dc237e..45b514df301 100644 --- a/src/main/java/domain/player/attribute/Name.java +++ b/src/main/java/domain/player/attribute/Name.java @@ -1,9 +1,9 @@ package domain.player.attribute; -import static util.Constants.MAXIMUM_NAME_LENGTH; -import static util.Constants.MINIMUM_NAME_LENGTH; - public class Name { + + public static final int MINIMUM_NAME_LENGTH = 2; + public static final int MAXIMUM_NAME_LENGTH = 10; private final String name; public Name(String name) { diff --git a/src/main/java/dto/DealerResultDto.java b/src/main/java/dto/DealerResultDto.java deleted file mode 100644 index d34f30f59bc..00000000000 --- a/src/main/java/dto/DealerResultDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package dto; - -public record DealerResultDto(int dealerWinCount, int dealerLoseCount, int dealerDrawCount) { -} diff --git a/src/main/java/dto/NameRequestDto.java b/src/main/java/dto/NameRequestDto.java deleted file mode 100644 index bcffbfc7716..00000000000 --- a/src/main/java/dto/NameRequestDto.java +++ /dev/null @@ -1,14 +0,0 @@ -package dto; - -public record NameRequestDto(String name) { - - public NameRequestDto { - validateNameIsNotNullAndIsNotBlank(name); - } - - private void validateNameIsNotNullAndIsNotBlank(String name) { - if (name == null || name.isBlank()) { - throw new IllegalArgumentException("이름 리스트는 null 또는 공백이면 안됩니다"); - } - } -} diff --git a/src/main/java/util/Constants.java b/src/main/java/util/Constants.java deleted file mode 100644 index 334940f9a82..00000000000 --- a/src/main/java/util/Constants.java +++ /dev/null @@ -1,31 +0,0 @@ -package util; - -public class Constants { - - public static final String COMMA_DELIMITER = ","; - - public static final int DEFAULT_CARD_SET = 1; - - public static final int DEFAULT_START_CARD_COUNT = 2; - - public static final int ACE_HIGH_SCORE = 11; - - public static final int ACE_LOW_SCORE = 1; - - public static final int BLACK_JACK = 21; - - public static final int DEALER_REFERENCE_POINT = 16; - - public static final String DEALER_NAME = "딜러"; - - public static final String HIT = "y"; - - public static final String STAND = "n"; - - public static final int MINIMUM_NAME_LENGTH = 2; - - public static final int MAXIMUM_NAME_LENGTH = 10; - - private Constants() { - } -} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index e5e633946ae..fe39c416a9e 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,19 +1,28 @@ package view; -import dto.AgreementRequestDto; -import dto.NameRequestDto; +import view.requestDto.AgreementRequestDto; +import view.requestDto.BettingAmountRequestDto; +import view.requestDto.NameRequestDto; import java.util.Scanner; public class InputView { + + public static final String HIT = "y"; + public static final String STAND = "n"; private Scanner sc = new Scanner(System.in); public NameRequestDto askGamblerNames() { System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); - return new NameRequestDto(sc.nextLine()); + return NameRequestDto.from(sc.nextLine()); } public AgreementRequestDto askHitOrStand(String name) { - System.out.println(name + "는 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)"); + System.out.println(name + "는 한장의 카드를 더 받겠습니까?(예는 " + HIT + " 아니오는 " + STAND + ")"); return new AgreementRequestDto(sc.nextLine()); } + + public BettingAmountRequestDto askBettingAmount(String name) { + System.out.println(name + "의 배팅 금액은?"); + return new BettingAmountRequestDto(sc.nextLine()); + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index c2fb020e88d..ac15589ac2b 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,10 +1,11 @@ package view; +import domain.game.Profit; import domain.player.ParticipantGameInfo; -import dto.DealerResultDto; -import dto.ParticipantHandResponseDto; -import dto.ParticipantsGameInfoDto; -import dto.ParticipantsHandResponseDto; +import view.responseDto.DealerResultDto; +import view.responseDto.ParticipantHandResponseDto; +import view.responseDto.ParticipantsGameInfoDto; +import view.responseDto.ParticipantsHandResponseDto; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -14,19 +15,19 @@ public class OutputView { public void printInitialDeal(List names) { System.out.println(); System.out.println("딜러와 " - + String.join(", ", names) - + "에게 2장을 나누었습니다."); + + String.join(", ", names) + + "에게 2장을 나누었습니다."); } public void printParticipantsInfo(ParticipantsHandResponseDto responseDto) { - for(Entry> gamblers : responseDto.gamblersInfo().entrySet()) { + for (Entry> gamblers : responseDto.gamblersInfo().entrySet()) { System.out.println(gamblers.getKey() + "카드: " + String.join(", ", gamblers.getValue())); } System.out.println(); } - public void printDealerCardIsUnder16() { + public void printDealerCardIsBelowDrawThreshold() { System.out.println(); System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다.\n"); } @@ -46,23 +47,18 @@ public void printParticipantsGameInfo(ParticipantsGameInfoDto responseDto) { } public void printDealerResult(DealerResultDto resultDto) { - System.out.println("## 최종 승패"); - System.out.print("딜러: "); - if (resultDto.dealerWinCount() > 0) { - System.out.print(resultDto.dealerWinCount() + "승 "); - } - if (resultDto.dealerLoseCount() > 0) { - System.out.print(resultDto.dealerLoseCount() + "패 "); - } - if (resultDto.dealerDrawCount() > 0) { - System.out.print(resultDto.dealerLoseCount() + "무 "); - } + System.out.println("## 최종 수익"); + System.out.print("딜러: " + resultDto.dealerProfit()); System.out.println(); } - public void printGamblerResult(Map gamblersResult) { - for (Entry result : gamblersResult.entrySet()) { - System.out.println(result.getKey() + ": " + result.getValue()); + public void printGamblerResult(Map gamblersResult) { + for (Entry result : gamblersResult.entrySet()) { + System.out.println(result.getKey() + ": " + result.getValue().getProfit()); } } + + public void printBlackJackMessage(String name) { + System.out.println(name + " 블랙잭입니다!"); + } } diff --git a/src/main/java/util/Parser.java b/src/main/java/view/Parser.java similarity index 86% rename from src/main/java/util/Parser.java rename to src/main/java/view/Parser.java index 57270a4d4f8..432a406d9e2 100644 --- a/src/main/java/util/Parser.java +++ b/src/main/java/view/Parser.java @@ -1,11 +1,12 @@ -package util; +package view; import java.util.Arrays; import java.util.List; public class Parser { - private Parser() {} + private Parser() { + } public static List parse(String input, String delimiter) { return Arrays.stream(input.split(delimiter)) diff --git a/src/main/java/dto/AgreementRequestDto.java b/src/main/java/view/requestDto/AgreementRequestDto.java similarity index 96% rename from src/main/java/dto/AgreementRequestDto.java rename to src/main/java/view/requestDto/AgreementRequestDto.java index d48012d2b83..ce16d9274b5 100644 --- a/src/main/java/dto/AgreementRequestDto.java +++ b/src/main/java/view/requestDto/AgreementRequestDto.java @@ -1,4 +1,4 @@ -package dto; +package view.requestDto; public record AgreementRequestDto(String agreement) { diff --git a/src/main/java/view/requestDto/BettingAmountRequestDto.java b/src/main/java/view/requestDto/BettingAmountRequestDto.java new file mode 100644 index 00000000000..7c2c9047f68 --- /dev/null +++ b/src/main/java/view/requestDto/BettingAmountRequestDto.java @@ -0,0 +1,37 @@ +package view.requestDto; + +public record BettingAmountRequestDto(String bettingAmount) { + + public static final int MINIMUM_BETTING_AMOUNT = 10; + + public BettingAmountRequestDto { + validateBettingAmountIsNotNullAndNotBlank(bettingAmount); + validateBettingAmountIsDigit(bettingAmount); + validateBettingAmountIsOverMinimumAmount(bettingAmount); + } + + private void validateBettingAmountIsNotNullAndNotBlank(String bettingAmount) { + if (bettingAmount == null || bettingAmount.isBlank()) { + throw new IllegalArgumentException("베팅 금액은 null 또는 공백이면 안 됩니다."); + } + } + + private void validateBettingAmountIsDigit(String bettingAmount) { + try { + Integer.parseInt(bettingAmount); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] 숫자만 입력 가능합니다."); + } + } + + private void validateBettingAmountIsOverMinimumAmount(String bettingAmount) { + if (Integer.parseInt(bettingAmount) < MINIMUM_BETTING_AMOUNT) { + throw new IllegalArgumentException( + "[ERROR] 최소 베팅 금액은 " + MINIMUM_BETTING_AMOUNT + " 입니다"); + } + } + + public int getBettingAmount() { + return Integer.parseInt(bettingAmount); + } +} diff --git a/src/main/java/view/requestDto/NameRequestDto.java b/src/main/java/view/requestDto/NameRequestDto.java new file mode 100644 index 00000000000..dd299c1dadd --- /dev/null +++ b/src/main/java/view/requestDto/NameRequestDto.java @@ -0,0 +1,21 @@ +package view.requestDto; + +import java.util.List; +import view.Parser; + +public record NameRequestDto(List names) { + + public static final String COMMA_DELIMITER = ","; + + public static NameRequestDto from(String input) { + validateNameIsNotNullAndIsNotBlank(input); + List parsedNames = Parser.parse(input, COMMA_DELIMITER); + return new NameRequestDto(parsedNames); + } + + private static void validateNameIsNotNullAndIsNotBlank(String name) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("이름 리스트는 null 또는 공백이면 안됩니다"); + } + } +} diff --git a/src/main/java/view/responseDto/DealerResultDto.java b/src/main/java/view/responseDto/DealerResultDto.java new file mode 100644 index 00000000000..b6f54a75036 --- /dev/null +++ b/src/main/java/view/responseDto/DealerResultDto.java @@ -0,0 +1,5 @@ +package view.responseDto; + +public record DealerResultDto(int dealerProfit) { + +} diff --git a/src/main/java/dto/ParticipantHandResponseDto.java b/src/main/java/view/responseDto/ParticipantHandResponseDto.java similarity index 77% rename from src/main/java/dto/ParticipantHandResponseDto.java rename to src/main/java/view/responseDto/ParticipantHandResponseDto.java index d28b48b2a6a..2ce16ed5074 100644 --- a/src/main/java/dto/ParticipantHandResponseDto.java +++ b/src/main/java/view/responseDto/ParticipantHandResponseDto.java @@ -1,8 +1,10 @@ -package dto; +package view.responseDto; import java.util.List; public record ParticipantHandResponseDto( String name, List cards -) {} +) { + +} diff --git a/src/main/java/dto/ParticipantsGameInfoDto.java b/src/main/java/view/responseDto/ParticipantsGameInfoDto.java similarity index 85% rename from src/main/java/dto/ParticipantsGameInfoDto.java rename to src/main/java/view/responseDto/ParticipantsGameInfoDto.java index 7299c755a05..3b0144e4c47 100644 --- a/src/main/java/dto/ParticipantsGameInfoDto.java +++ b/src/main/java/view/responseDto/ParticipantsGameInfoDto.java @@ -1,4 +1,4 @@ -package dto; +package view.responseDto; import domain.player.ParticipantGameInfo; import java.util.List; diff --git a/src/main/java/dto/ParticipantsHandResponseDto.java b/src/main/java/view/responseDto/ParticipantsHandResponseDto.java similarity index 83% rename from src/main/java/dto/ParticipantsHandResponseDto.java rename to src/main/java/view/responseDto/ParticipantsHandResponseDto.java index 60e9886692a..20734cea684 100644 --- a/src/main/java/dto/ParticipantsHandResponseDto.java +++ b/src/main/java/view/responseDto/ParticipantsHandResponseDto.java @@ -1,7 +1,8 @@ -package dto; +package view.responseDto; import java.util.List; import java.util.Map; public record ParticipantsHandResponseDto(Map> gamblersInfo) { + } diff --git a/src/test/java/domain/betting/BettingTest.java b/src/test/java/domain/betting/BettingTest.java new file mode 100644 index 00000000000..cc519d0a443 --- /dev/null +++ b/src/test/java/domain/betting/BettingTest.java @@ -0,0 +1,44 @@ +package domain.betting; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class BettingTest { + + @Test + @DisplayName("겜블러 별로 베팅 금액을 저장하고 조회하는 테스트") + void 겜블러별_베팅_금액을_저장하고_조회_수_있다() { + // given + List nameValues = List.of("pobi", "woni"); + Betting betting = new Betting(nameValues); + + // when + betting.betBettingAmount("pobi", new BettingAmount(10000)); + betting.betBettingAmount("woni", new BettingAmount(20000)); + + // then + assertAll( + () -> assertThat(betting.getBettingAmountByName("pobi")) + .isEqualTo(new BettingAmount(10000)), + () -> assertThat(betting.getBettingAmountByName("woni")) + .isEqualTo(new BettingAmount(20000)) + ); + } + + @Test + @DisplayName("이름 중복 없음 테스트") + void 이름_중복_없음_테스트() { + // given + List names = List.of("pobi", "coco", "coco", "kaiya"); + // then + assertThrows(IllegalArgumentException.class, () -> { + new Betting(names); + }); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/card/CardTest.java b/src/test/java/domain/card/CardTest.java index 0c7eb1bb16d..459a083612c 100644 --- a/src/test/java/domain/card/CardTest.java +++ b/src/test/java/domain/card/CardTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import domain.card.Card; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -54,7 +53,7 @@ class CardTest { Assertions.assertThrows(IllegalArgumentException.class, () -> { new Card("14", "하트"); - }); + }); } @Test @@ -63,7 +62,7 @@ class CardTest { Assertions.assertThrows(IllegalArgumentException.class, () -> { new Card("10", "별"); - }); + }); } @Test diff --git a/src/test/java/domain/card/GameCardsTest.java b/src/test/java/domain/card/GameCardsTest.java index ed3f5849749..c67b311ad48 100644 --- a/src/test/java/domain/card/GameCardsTest.java +++ b/src/test/java/domain/card/GameCardsTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import domain.card.GameCards; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -24,10 +23,14 @@ class GameCardsTest { } @ParameterizedTest - @ValueSource(strings = {"2클로버","3클로버","4클로버","5클로버","6클로버","7클로버","8클로버","9클로버","10클로버","J클로버","Q클로버","K클로버","A클로버", - "2스페이드","3스페이드","4스페이드","5스페이드","6스페이드","7스페이드","8스페이드","9스페이드","10스페이드","J스페이드","Q스페이드","K스페이드","A스페이드", - "2하트","3하트","4하트","5하트","6하트","7하트","8하트","9하트","10하트","J하트","Q하트","K하트","A하트", - "2다이아몬드","3다이아몬드","4다이아몬드","5다이아몬드","6다이아몬드","7다이아몬드","8다이아몬드","9다이아몬드","10다이아몬드","J다이아몬드","Q다이아몬드","K다이아몬드","A다이아몬드"}) + @ValueSource(strings = {"2클로버", "3클로버", "4클로버", "5클로버", "6클로버", "7클로버", "8클로버", "9클로버", "10클로버", + "J클로버", "Q클로버", "K클로버", "A클로버", + "2스페이드", "3스페이드", "4스페이드", "5스페이드", "6스페이드", "7스페이드", "8스페이드", "9스페이드", "10스페이드", + "J스페이드", "Q스페이드", "K스페이드", "A스페이드", + "2하트", "3하트", "4하트", "5하트", "6하트", "7하트", "8하트", "9하트", "10하트", "J하트", "Q하트", "K하트", + "A하트", + "2다이아몬드", "3다이아몬드", "4다이아몬드", "5다이아몬드", "6다이아몬드", "7다이아몬드", "8다이아몬드", "9다이아몬드", + "10다이아몬드", "J다이아몬드", "Q다이아몬드", "K다이아몬드", "A다이아몬드"}) @DisplayName("52개 종류의 카드 포함 여부 검증") void 덱_종류_검증(String string) { // given diff --git a/src/test/java/domain/game/GamblersGameResultTest.java b/src/test/java/domain/game/GamblersGameResultTest.java index 7b369b924f2..00527f121ae 100644 --- a/src/test/java/domain/game/GamblersGameResultTest.java +++ b/src/test/java/domain/game/GamblersGameResultTest.java @@ -1,7 +1,11 @@ package domain.game; -import java.util.HashMap; -import java.util.Map; +import domain.betting.BettingAmount; +import domain.card.Card; +import domain.player.Dealer; +import domain.player.Gambler; +import domain.player.Gamblers; +import java.util.List; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -9,21 +13,34 @@ class GamblersGameResultTest { @Test - @DisplayName("승패 결과 저장 검증") - void 승패_결과_저장_검증() { + @DisplayName("딜러, 참여자들의 수익을 정산") + void 딜러_참여자들_수익_정산() { // given - Map gamblers = new HashMap<>(); - gamblers.put("pobi",10); - gamblers.put("coco", 21); - gamblers.put("kaiya", 20); + Dealer dealer = new Dealer(Dealer.DEALER_NAME); + dealer.addCard(new Card("K", "하트")); + dealer.addCard(new Card("Q", "하트")); + Gambler pobi = new Gambler("pobi", new BettingAmount(10000)); + pobi.addCard(new Card("A", "스페이드")); + pobi.addCard(new Card("J", "클로버")); + + Gambler coco = new Gambler("coco", new BettingAmount(20000)); + coco.addCard(new Card("7", "하트")); + coco.addCard(new Card("Q", "스페이드")); + + Gambler kaiya = new Gambler("kaiya", new BettingAmount(30000)); + kaiya.addCard(new Card("J", "하트")); + kaiya.addCard(new Card("Q", "다이아몬드")); + + Gamblers gamblers = new Gamblers(List.of(pobi, coco, kaiya)); // when - GamblersGameResult gameResult = new GamblersGameResult(20, gamblers); + GamblersGameResult gameResult = new GamblersGameResult(dealer, gamblers); // then - Assertions.assertThat(gameResult.getMatchResult("pobi")).isEqualTo(GameResult.LOSE); - Assertions.assertThat(gameResult.getMatchResult("coco")).isEqualTo(GameResult.WIN); - Assertions.assertThat(gameResult.getMatchResult("kaiya")).isEqualTo(GameResult.DRAW); + Assertions.assertThat(gameResult.getDealerProfit()).isEqualTo(new Profit(5000)); + Assertions.assertThat(gameResult.getMatchProfits("pobi")).isEqualTo(new Profit(15000)); + Assertions.assertThat(gameResult.getMatchProfits("coco")).isEqualTo(new Profit(-20000)); + Assertions.assertThat(gameResult.getMatchProfits("kaiya")).isEqualTo(new Profit(0)); } } diff --git a/src/test/java/domain/game/GameResultTest.java b/src/test/java/domain/game/GameResultTest.java index 52613550085..98b651e8653 100644 --- a/src/test/java/domain/game/GameResultTest.java +++ b/src/test/java/domain/game/GameResultTest.java @@ -1,25 +1,97 @@ package domain.game; +import domain.betting.BettingAmount; +import domain.card.Card; +import domain.player.Dealer; +import domain.player.Gambler; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class GameResultTest { + + @Test + @DisplayName("게임 최종 결과 딜러, 겜블러 동시에 블랙잭") + void 게임_최종_결과_딜러_겜블러_블랙잭() { + Dealer dealer = new Dealer(Dealer.DEALER_NAME); + dealer.addCard(new Card("K", "다이아몬드")); + dealer.addCard(new Card("A", "다이아몬드")); + + Gambler gambler = new Gambler("pobi", new BettingAmount(10000)); + gambler.addCard(new Card("Q", "다이아몬드")); + gambler.addCard(new Card("A", "하트")); + Assertions.assertThat(GameResult.determine(dealer, gambler)).isEqualTo(GameResult.DRAW); + } + + @Test + @DisplayName("게임 최종 결과 겜블러 블랙잭") + void 게임_최종_결과_겜블러_블랙잭() { + Dealer dealer = new Dealer(Dealer.DEALER_NAME); + dealer.addCard(new Card("2", "다이아몬드")); + dealer.addCard(new Card("A", "다이아몬드")); + + Gambler gambler = new Gambler("pobi", new BettingAmount(10000)); + gambler.addCard(new Card("Q", "다이아몬드")); + gambler.addCard(new Card("A", "하트")); + Assertions.assertThat(GameResult.determine(dealer, gambler)) + .isEqualTo(GameResult.BLACK_JACK); + } + + @Test + @DisplayName("게임 최종 결과 딜러 승리") + void 게임_최종_결과_딜러_승() { + Dealer dealer = new Dealer(Dealer.DEALER_NAME); + dealer.addCard(new Card("8", "다이아몬드")); + dealer.addCard(new Card("A", "다이아몬드")); + + Gambler gambler = new Gambler("pobi", new BettingAmount(10000)); + gambler.addCard(new Card("2", "다이아몬드")); + gambler.addCard(new Card("3", "하트")); + Assertions.assertThat(GameResult.determine(dealer, gambler)).isEqualTo(GameResult.LOSE); + } + + @Test + @DisplayName("게임 최종 결과 겜블러 승리") + void 게임_최종_결과_겜블러_승리() { + Dealer dealer = new Dealer(Dealer.DEALER_NAME); + dealer.addCard(new Card("3", "다이아몬드")); + dealer.addCard(new Card("6", "다이아몬드")); + + Gambler gambler = new Gambler("pobi", new BettingAmount(10000)); + gambler.addCard(new Card("9", "다이아몬드")); + gambler.addCard(new Card("A", "하트")); + Assertions.assertThat(GameResult.determine(dealer, gambler)).isEqualTo(GameResult.WIN); + } + + @Test + @DisplayName("블랙잭 시 베팅 금액의 1.5배 수익을 반환한다") + void 겜블러_블랙잭_수익금액_계산() { + BettingAmount bettingAmount = new BettingAmount(10000); + Profit resultProfit = GameResult.BLACK_JACK.calculateProfit(bettingAmount); + Assertions.assertThat(resultProfit).isEqualTo(new Profit(15000)); + } + @Test - @DisplayName("게임 최종 결과 테스트") - void 게임_최종_결과_검증_겜블러_패() { - Assertions.assertThat(GameResult.determine(20, 16)).isEqualTo(GameResult.LOSE); + @DisplayName("승리 시 베팅 금액의 1배 수익을 반환한다") + void 겜블러_승리_수익금액_계산() { + BettingAmount bettingAmount = new BettingAmount(10000); + Profit resultProfit = GameResult.WIN.calculateProfit(bettingAmount); + Assertions.assertThat(resultProfit).isEqualTo(new Profit(10000)); } @Test - @DisplayName("게임 최종 결과 테스트") - void 게임_최종_결과_검증_겜블러_승() { - Assertions.assertThat(GameResult.determine(18, 21)).isEqualTo(GameResult.WIN); + @DisplayName("패배 시 베팅 금액의 -1배 수익을 반환한다") + void 겜블러_패배_수익금액_계산() { + BettingAmount bettingAmount = new BettingAmount(10000); + Profit resultProfit = GameResult.LOSE.calculateProfit(bettingAmount); + Assertions.assertThat(resultProfit).isEqualTo(new Profit(-10000)); } @Test - @DisplayName("게임 최종 결과 테스트") - void 게임_최종_결과_검증_무승부() { - Assertions.assertThat(GameResult.determine(20, 20)).isEqualTo(GameResult.DRAW); + @DisplayName("무승부 시 베팅 금액의 0배 수익을 반환한다") + void 겜블러_블랙잭_무승부_수익금액_계산() { + BettingAmount bettingAmount = new BettingAmount(10000); + Profit resultProfit = GameResult.DRAW.calculateProfit(bettingAmount); + Assertions.assertThat(resultProfit).isEqualTo(new Profit(0)); } } diff --git a/src/test/java/domain/game/GameTest.java b/src/test/java/domain/game/GameTest.java index a8c7e0d6162..7f55c9ae687 100644 --- a/src/test/java/domain/game/GameTest.java +++ b/src/test/java/domain/game/GameTest.java @@ -1,10 +1,10 @@ package domain.game; -import static util.Constants.DEALER_NAME; -import static util.Constants.DEFAULT_CARD_SET; -import static util.Constants.DEFAULT_START_CARD_COUNT; - -import java.util.List; +import domain.betting.BettingAmount; +import domain.card.GameCards; +import domain.player.Dealer; +import java.util.HashMap; +import java.util.Map; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -13,9 +13,12 @@ class GameTest { @Test @DisplayName("게임을 처음 시작했을 떄 딜러와 참가자들 각각에게 카드가 2장씩 가는지 검증") - void 게임_초기화_검증 () { + void 게임_초기화_검증() { // given - Game game = new Game(DEALER_NAME, List.of("pobi", "jason"), DEFAULT_CARD_SET); + Map tempGamblers = new HashMap<>(); + tempGamblers.put("pobi", new BettingAmount(10000)); + tempGamblers.put("jason", new BettingAmount(20000)); + Game game = new Game(Dealer.DEALER_NAME, tempGamblers, GameCards.DEFAULT_CARD_SET); // when game.initializeGame(); @@ -23,8 +26,8 @@ class GameTest { // then Assertions.assertThat(game.getDealerHandSize()).isEqualTo(2); Assertions.assertThat(game.getGamblersHandSize() - .stream() - .allMatch(count -> count == DEFAULT_START_CARD_COUNT)) - .isEqualTo(true); + .stream() + .allMatch(count -> count == GameCards.DEFAULT_START_CARD_COUNT)) + .isEqualTo(true); } } diff --git a/src/test/java/domain/player/DealerTest.java b/src/test/java/domain/player/DealerTest.java index ad07061b87d..4b8cad89074 100644 --- a/src/test/java/domain/player/DealerTest.java +++ b/src/test/java/domain/player/DealerTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test; class DealerTest { + @Test @DisplayName("딜러 카드 값의 합이 드로우 임계치 미만일 때 true를 정상적으로 반환함을 테스트") void 딜러_카드_합_드로우_임계치_미만_true_반환_테스트() { diff --git a/src/test/java/domain/player/GamblerTest.java b/src/test/java/domain/player/GamblerTest.java index 4f3a2014df1..1ff350b4b33 100644 --- a/src/test/java/domain/player/GamblerTest.java +++ b/src/test/java/domain/player/GamblerTest.java @@ -1,5 +1,6 @@ package domain.player; +import domain.betting.BettingAmount; import domain.card.Card; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -12,7 +13,7 @@ class GamblerTest { void 카드_정상적으로_받기_테스트() { // given Card card = new Card("2", "하트"); - Gambler gambler = new Gambler("coco"); + Gambler gambler = new Gambler("coco", new BettingAmount(20000)); // when gambler.addCard(card); @@ -31,7 +32,7 @@ class GamblerTest { Card card2 = new Card("K", "다이아몬드"); Card card3 = new Card("K", "클로버"); - Gambler gambler = new Gambler("coco"); + Gambler gambler = new Gambler("coco", new BettingAmount(20000)); // when gambler.addCard(card1); @@ -51,7 +52,7 @@ class GamblerTest { Card card2 = new Card("K", "다이아몬드"); Card card3 = new Card("K", "클로버"); - Gambler gambler = new Gambler("coco"); + Gambler gambler = new Gambler("coco", new BettingAmount(20000)); // when gambler.addCard(card1); diff --git a/src/test/java/domain/player/GamblersTest.java b/src/test/java/domain/player/GamblersTest.java index c6029b19889..0dd19a4372c 100644 --- a/src/test/java/domain/player/GamblersTest.java +++ b/src/test/java/domain/player/GamblersTest.java @@ -1,8 +1,8 @@ package domain.player; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.List; +import domain.betting.BettingAmount; +import java.util.HashMap; +import java.util.Map; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -10,30 +10,18 @@ class GamblersTest { @Test - @DisplayName("이름 리스트를 통해 player 객체들이 제대로 생성되는지 테스트") - void 이름_정상_저장_테스트() { + @DisplayName("이름, 베팅금액 정상 저장 테스트") + void 겜블러_이름_베팅금액_정상_저장_생성_테스트() { // given - List names = List.of("pobi", "coco"); + Map gamblerBettingInfo = new HashMap() { + }; + gamblerBettingInfo.put("pobi", new BettingAmount(10000)); + gamblerBettingInfo.put("coco", new BettingAmount(20000)); // when - Gamblers gamblers = new Gamblers(names); - - // then - boolean allContainName = names.stream() - .allMatch(name -> gamblers.containGambler(name)); - - Assertions.assertThat(allContainName).isEqualTo(true); - } - - @Test - @DisplayName("이름 중복 없음 테스트") - void 이름_중복_없음_테스트() { - // given - List names = List.of("pobi", "coco", "coco", "kaiya"); + Gamblers gamblers = new Gamblers(gamblerBettingInfo); // then - assertThrows(IllegalArgumentException.class, () -> { - new Gamblers(names); - }); + Assertions.assertThat(gamblers.getGamblersSize()).isEqualTo(2); } } diff --git a/src/test/java/domain/player/HandTest.java b/src/test/java/domain/player/HandTest.java index 11b821a002d..32902988b90 100644 --- a/src/test/java/domain/player/HandTest.java +++ b/src/test/java/domain/player/HandTest.java @@ -2,13 +2,13 @@ import domain.card.Card; import domain.player.attribute.Hand; -import java.util.Arrays; import java.util.List; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class HandTest { + @Test @DisplayName("카드 정보를 문자열 리스트로 반환하는지 검증") void 카드_정보_문자열_반환_테스트() { diff --git a/src/test/java/domain/player/NameTest.java b/src/test/java/domain/player/NameTest.java index c935a0ccc5b..8174377df0b 100644 --- a/src/test/java/domain/player/NameTest.java +++ b/src/test/java/domain/player/NameTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test; class NameTest { + @Test @DisplayName("이름 영어, 글자 수, 이름 내 공백 여부 테스트") void 이름_영어_글자수_공백미포함_검증() { diff --git a/src/test/java/domain/player/ParticipantTest.java b/src/test/java/domain/player/ParticipantTest.java new file mode 100644 index 00000000000..28240dc74ed --- /dev/null +++ b/src/test/java/domain/player/ParticipantTest.java @@ -0,0 +1,20 @@ +package domain.player; + +import org.assertj.core.api.Assertions; + +import domain.card.Card; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class ParticipantTest { + + @Test + @DisplayName("초기 2장의 합이 21, 블랙잭인지 확인") + void 초기_2장의_합이_21_블랙잭인지_검증() { + Participant participant = new Participant("pobi"); + participant.addCard(new Card("K", "다이아몬드")); + participant.addCard(new Card("A", "다이아몬드")); + + Assertions.assertThat(participant.isBlackJack()).isEqualTo(true); + } +} \ No newline at end of file diff --git a/src/test/java/dto/AgreementRequestDtoTest.java b/src/test/java/dto/AgreementRequestDtoTest.java index 59740cf5230..91d0028641e 100644 --- a/src/test/java/dto/AgreementRequestDtoTest.java +++ b/src/test/java/dto/AgreementRequestDtoTest.java @@ -3,8 +3,10 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import view.requestDto.AgreementRequestDto; class AgreementRequestDtoTest { + @Test @DisplayName("y/n 입력 문자열이 null이면 에러 발생 검증") void agreement_is_not_null() { diff --git a/src/test/java/dto/BettingAmountRequestDtoTest.java b/src/test/java/dto/BettingAmountRequestDtoTest.java new file mode 100644 index 00000000000..3b0e56d1cf8 --- /dev/null +++ b/src/test/java/dto/BettingAmountRequestDtoTest.java @@ -0,0 +1,37 @@ +package dto; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import view.requestDto.BettingAmountRequestDto; + +class BettingAmountRequestDtoTest { + + @Test + @DisplayName("베팅 금액 입력 문자열이 null이면 에러 발생 검증") + void 베팅_금액_null_입력_에러_발생_테스트() { + Assertions.assertThrows(IllegalArgumentException.class, + () -> new BettingAmountRequestDto(null)); + } + + @Test + @DisplayName("베팅 금액 입력 문자열이 빈 문자열(\"\")이면 에러 발생 검증") + void 베팅_금액_공백_입력_에러_발생_테스트() { + Assertions.assertThrows(IllegalArgumentException.class, + () -> new BettingAmountRequestDto("")); + } + + @Test + @DisplayName("베팅 금액 입력 문자열이 숫자가 아닌 문자면 에러 발생 검증") + void 베팅_금액_숫자_검증_테스트() { + Assertions.assertThrows(IllegalArgumentException.class, + () -> new BettingAmountRequestDto("QWER")); + } + + @Test + @DisplayName("베팅 금액 입력 문자열이 양수가 아닌 문자면 에러 발생 검증") + void 베팅_금액_양수_검증_테스트() { + Assertions.assertThrows(IllegalArgumentException.class, + () -> new BettingAmountRequestDto("-1000")); + } +} diff --git a/src/test/java/dto/NameRequestDtoTest.java b/src/test/java/dto/NameRequestDtoTest.java index 59221e4e23b..3e0ce10412c 100644 --- a/src/test/java/dto/NameRequestDtoTest.java +++ b/src/test/java/dto/NameRequestDtoTest.java @@ -1,17 +1,17 @@ package dto; -import static org.junit.jupiter.api.Assertions.*; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import view.requestDto.NameRequestDto; class NameRequestDtoTest { + @Test @DisplayName("이름 입력 문자열이 null이면 에러 발생 검증") void name_is_not_null() { Assertions.assertThrows(IllegalArgumentException.class, - () -> new NameRequestDto(null)); + () -> NameRequestDto.from(null)); } @@ -19,6 +19,6 @@ void name_is_not_null() { @DisplayName("이름 입력 문자열이 빈 문자열(\"\")이면 에러 발생 검증") void name_is_not_blank() { Assertions.assertThrows(IllegalArgumentException.class, - () -> new NameRequestDto("")); + () -> NameRequestDto.from("")); } } diff --git a/src/test/java/util/ParserTest.java b/src/test/java/util/ParserTest.java index b33cd7f1c4a..83f9c9468cc 100644 --- a/src/test/java/util/ParserTest.java +++ b/src/test/java/util/ParserTest.java @@ -4,9 +4,10 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import util.Parser; +import view.Parser; class ParserTest { + @Test @DisplayName("게임 참가자 이름 문자열 구분자 기준 분리 테스트") void 게임_참가자_이름_문자열_분리_테스트() {