-
Notifications
You must be signed in to change notification settings - Fork 0
오잉의 블랙잭이노라 구경하노라 #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: hanueleee
Are you sure you want to change the base?
오잉의 블랙잭이노라 구경하노라 #12
Changes from all commits
9aec21d
7f42057
2041f62
1c2cdf5
baa7e32
6dcdbc5
9a91451
d1ee2d1
177f327
c94bf60
13aab78
37bf000
bae4f70
fc80dfb
12f43ec
a221486
2a6944d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| ### UI | ||
| - 입력 | ||
| - [x] 참여할 사람의 이름 입력 | ||
| - [x] 플레이어별 배팅 금액 입력 | ||
| - [x] 카드 추가 지급 의사 입력 | ||
|
|
||
| - 출력 | ||
| - [x] 카드 지급 완료 문구 출력 | ||
| - [x] 개인 카드 목록 출력 | ||
| - [x] 딜러 카드 추가 지급 여부 출력 | ||
| - [x] 최종 카드 상태 출력 | ||
| - [x] 최종 수익 출력 | ||
|
|
||
| ### 기능 | ||
| - BlackJackGame : 게임 관리 시스템 | ||
| - [x] 모든 플레이어에게 시작 카드를 2장씩 나누어준다 | ||
| - [x] 플레이어에게 카드를 1장 나누어준다 | ||
| - [x] 게임 결과를 만들어 반환한다 | ||
|
|
||
| - Player : 게임 참여자 | ||
| - [x] 초기 카드 2장을 받는다 | ||
| - [x] 추가 카드를 뽑는다 | ||
| - [x] Bust인지 확인한다 (21이 넘는지) | ||
| - [x] BlackJack인지 확인한다 (21인지) | ||
| - Challenger : 일반 참여자 (Player를 상속받는다) | ||
| - [x] 이름을 입력받는다 | ||
| - [x] 플레이어 이름이 `딜러`인 경우 예외가 발생한다 | ||
| - [x] 카드의 합이 21 초과인지 확인한다 | ||
| - Dealer : 딜러 (Player를 상속받는다) | ||
| - [x] 카드의 합이 16 초과인지 확인한다 | ||
| - [x] 도전자의 게임 결과를 판정한다 | ||
|
|
||
| - Players : Player 목록을 가지고 있는 일급 컬렉션 | ||
| - [x] 플레이어 이름 중복 시 예외가 발생한다 | ||
|
|
||
| - Card : 카드 | ||
| - [x] 카드 숫자를 보고 점수를 반환한다 (ex. Ace -> 1 or 11 // King, Queen, Jack -> 10) | ||
|
|
||
| - CardDeck : 덱에 있는 카드. Card 목록을 가지고 있는 일급 컬렉션 | ||
| - [x] 52장의 카드를 생성한다 | ||
| - [x] 카드 순서를 무작위로 섞는다 | ||
| - [x] 맨 위의 카드를 게임 참여자에게 전달한다 | ||
|
|
||
| - HolingCards : 참여자가 소유하고 있는 카드. Card 목록을 가지고 있는 일급 컬렉션 | ||
| - [x] 뽑은 카드를 저장한다 | ||
| - [x] 가진 카드로 가능한 합 목록을 반환한다 | ||
| - [x] 가진 카드들 중에 21보다 작은 가장 큰 값을 반환한다 | ||
|
|
||
| - GameResult : 플레이어의 최종 수익 | ||
| - [x] 도전자의 최종 승패 결과에 따라 수익을 계산한다 | ||
| - [x] 딜러의 수익을 계산한다 | ||
|
|
||
| - Money | ||
| - [x] 배팅 금액은 10000원 이상 100000원 이하여야 한다 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package blackjack; | ||
|
|
||
| import blackjack.controller.BlackJackController; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| BlackJackController blackJackController = new BlackJackController(); | ||
| blackJackController.run(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| package blackjack.controller; | ||
|
|
||
| import blackjack.domain.card.Card; | ||
| import blackjack.domain.game.BlackJackGame; | ||
| import blackjack.domain.game.Money; | ||
| import blackjack.domain.player.Challenger; | ||
| import blackjack.domain.player.Dealer; | ||
| import blackjack.domain.player.Player; | ||
| import blackjack.domain.player.Players; | ||
| import blackjack.domain.result.GameResult; | ||
| import blackjack.dto.ChallengerResultDto; | ||
| import blackjack.dto.PlayerStatusDto; | ||
| import blackjack.exception.BlackJackGameException; | ||
| import blackjack.view.InputView; | ||
| import blackjack.view.OutputView; | ||
| import java.util.ArrayList; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class BlackJackController { | ||
|
|
||
| private BlackJackGame blackJackGame; | ||
|
|
||
| private static List<String> makeCardInfo(List<Card> inputCards) { | ||
| List<String> cardInfo = new ArrayList<>(); | ||
| inputCards.stream() | ||
| .forEach(card -> cardInfo.add(card.getSymbol().getName() + card.getShape().getName())); | ||
| return cardInfo; | ||
| } | ||
|
|
||
| public void run() { | ||
| init(); | ||
| start(); | ||
| takeTurn(); | ||
| showResult(); | ||
| } | ||
|
|
||
| private void init() { | ||
| try { | ||
| List<String> playerNames = InputView.inputPlayerNames(); | ||
| Players players = Players.from(playerNames); | ||
| bet(players); | ||
| } catch (BlackJackGameException e) { | ||
| OutputView.printErrorMessage(e); | ||
| init(); | ||
| } | ||
| } | ||
|
|
||
| private void bet(Players players) { | ||
| List<Challenger> challengers = players.getChallengers(); | ||
| List<Money> betAmounts = new ArrayList<>(); | ||
| challengers.stream() | ||
| .forEach(challenger -> betEachPlayer(challenger, betAmounts)); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. stream보다 for-each가 가독성이 더 좋을 것 같은데 어떻게 생각하시나요? for (Challenger challenger: players.getChallengers()) {
betEachPlayer(challenger, betAmounts));
}
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 리뷰어께서 stream 연습삼아 만들어보라고 하셔서 수정했던 부분임미다 ,, 🦹♂️ |
||
| blackJackGame = BlackJackGame.from(players, betAmounts); | ||
| } | ||
|
|
||
| private void betEachPlayer(Challenger challenger, List<Money> betAmounts) { | ||
| try { | ||
| int inputMoney = InputView.inputPlayerBetMoney(challenger.getName()); | ||
| betAmounts.add(Money.bet(inputMoney)); | ||
| } catch (BlackJackGameException e) { | ||
| OutputView.printErrorMessage(e); | ||
| betEachPlayer(challenger, betAmounts); | ||
| } | ||
| } | ||
|
|
||
| private void start() { | ||
| blackJackGame.handOutStartCards(); | ||
| showStartStatus(); | ||
| } | ||
|
|
||
| private void showStartStatus() { | ||
| PlayerStatusDto dealerStatus = makeDealerStatus(); | ||
| List<PlayerStatusDto> challengersStatus = makeChallengersStatus(); | ||
| OutputView.printStartStatus(dealerStatus, challengersStatus); | ||
| } | ||
|
|
||
| private PlayerStatusDto makeDealerStatus() { | ||
| Player dealer = blackJackGame.getDealer(); | ||
| return makePlayerStatusDto(dealer); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기에 makePlayerStatusDto가 있는것보다는, PlayerStatusDto.from() 가 더 좋지 않을까요? |
||
| } | ||
|
|
||
| private List<PlayerStatusDto> makeChallengersStatus() { | ||
| List<Challenger> challengers = blackJackGame.getChallengers(); | ||
| return challengers.stream() | ||
| .map(challenger -> makePlayerStatusDto(challenger)) | ||
| .collect(Collectors.toUnmodifiableList()); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굳이 toUnmodifiableList로 하신 이유가 있나요 |
||
| } | ||
|
|
||
| private void takeTurn() { | ||
| try { | ||
| takeAllChallengersTurn(); | ||
| takeDealerTurn(); | ||
| } catch (BlackJackGameException e) { | ||
| OutputView.printErrorMessage(e); | ||
| } | ||
| } | ||
|
|
||
| private void takeAllChallengersTurn() { | ||
| for (Player player : blackJackGame.getChallengers()) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blackJackGame의 자율성을 침해하는 것 같아요 |
||
| takeEachChallengerTurn(player); | ||
| } | ||
| } | ||
|
|
||
| private void takeEachChallengerTurn(Player player) { | ||
| if (player.canPick()) { | ||
| checkChoice(player); | ||
| } | ||
| } | ||
|
|
||
| private void checkChoice(Player player) { | ||
| try { | ||
| inputChoice(player); | ||
| } catch (BlackJackGameException e) { | ||
| OutputView.printErrorMessage(e); | ||
| checkChoice(player); | ||
| } | ||
| } | ||
|
|
||
| private void inputChoice(Player player) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 입력만 받는 줄 알았는데, hit까지 하네요? |
||
| boolean choice = InputView.inputPlayerChoice(player.getName()); | ||
| if (choice) { | ||
| blackJackGame.hit(player); | ||
| OutputView.printChallengerStatusInGame(makePlayerStatusDto(player)); | ||
| takeEachChallengerTurn(player); | ||
| } | ||
| } | ||
|
|
||
| private void takeDealerTurn() { | ||
| Player dealer = blackJackGame.getDealer(); | ||
| boolean dealerCanPick = dealer.canPick(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 마찬가지로 blackJackGame의 자율성이 침해되는 것 같아요 |
||
| if (dealerCanPick) { | ||
| blackJackGame.hit(dealer); | ||
| } | ||
| OutputView.printDealerTurnResult(dealerCanPick, Dealer.MAXIMUM_POINT); | ||
| } | ||
|
|
||
| private void showResult() { | ||
| showPoint(); | ||
| showRevenue(); | ||
| } | ||
|
|
||
| private void showPoint() { | ||
| PlayerStatusDto dealerStatus = makeDealerStatus(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어디에서는 makeStatus() 어디서는 makeStatusDto()네요? |
||
| List<PlayerStatusDto> challengersStatus = makeChallengersStatus(); | ||
| OutputView.printEndStatus(dealerStatus, challengersStatus); | ||
| } | ||
|
|
||
| private void showRevenue() { | ||
| GameResult resultMap = blackJackGame.makeResult(); | ||
|
|
||
| ChallengerResultDto challengerResultDto = makeChallengerResultDto(resultMap, blackJackGame.getChallengers()); | ||
| OutputView.printRevenue(challengerResultDto); | ||
| } | ||
|
|
||
| private PlayerStatusDto makePlayerStatusDto(Player player) { | ||
| String playerName = player.getName(); | ||
| List<Card> inputCards = player.getHoldingCards().getCards(); | ||
| int playerPoint = player.getTotalPoint(); | ||
| return new PlayerStatusDto(playerName, makeCardInfo(inputCards), playerPoint); | ||
| } | ||
|
Comment on lines
+158
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| private ChallengerResultDto makeChallengerResultDto(GameResult gameResult, List<Challenger> challengers) { | ||
| Map<String, Integer> nameAndResult = new LinkedHashMap<>(); | ||
| nameAndResult.put(Dealer.NAME, gameResult.getDealerRevenue().getValue()); | ||
| challengers.stream() | ||
| .forEach(challenger -> nameAndResult.put(challenger.getName(), | ||
| gameResult.getChallengerRevenue(challenger).getValue())); | ||
| return new ChallengerResultDto(nameAndResult); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| import java.util.Objects; | ||
|
|
||
| public class Card { | ||
|
|
||
| private final Shape shape; | ||
| private final Symbol symbol; | ||
|
|
||
| public Card(Shape shape, Symbol symbol) { | ||
| this.shape = shape; | ||
| this.symbol = symbol; | ||
| } | ||
|
|
||
| public boolean isAce() { | ||
| return symbol == Symbol.ACE; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) { | ||
| return true; | ||
| } | ||
| if (o == null || getClass() != o.getClass()) { | ||
| return false; | ||
| } | ||
| Card card = (Card) o; | ||
| return shape == card.shape && symbol == card.symbol; | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(shape, symbol); | ||
| } | ||
|
|
||
| public Shape getShape() { | ||
| return shape; | ||
| } | ||
|
|
||
| public Symbol getSymbol() { | ||
| return symbol; | ||
| } | ||
|
|
||
| public int getPoint() { | ||
| return symbol.getValue(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| import static java.util.stream.Collectors.toList; | ||
|
|
||
| import blackjack.exception.NoMoreCardException; | ||
| import java.util.ArrayDeque; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.Deque; | ||
| import java.util.List; | ||
|
|
||
| public class CardDeck { | ||
|
|
||
| private final Deque<Card> cards; | ||
|
|
||
| private CardDeck(Deque<Card> cards) { | ||
| this.cards = cards; | ||
| } | ||
|
|
||
| public static CardDeck create() { | ||
| List<Card> cards = Arrays.stream(Shape.values()) | ||
| .flatMap(shape -> Arrays.stream(Symbol.values()).map(symbol -> new Card(shape, symbol))) | ||
| .collect(toList()); | ||
| Collections.shuffle(cards); | ||
| return new CardDeck(new ArrayDeque<>(cards)); | ||
| } | ||
|
|
||
| public Card pick() { | ||
| validateCardExist(); | ||
| return cards.remove(); | ||
| } | ||
|
|
||
| private void validateCardExist() { | ||
| if (cards.isEmpty()) { | ||
| throw new NoMoreCardException(); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class HoldingCards { | ||
|
|
||
| private static final int MAXIMUM_SUM = 21; | ||
| private static final int ACE_BONUS = 10; | ||
|
|
||
| private final List<Card> cards = new ArrayList<>(); | ||
|
|
||
| public void initialize(Card firstCard, Card secondCard) { | ||
| cards.addAll(List.of(firstCard, secondCard)); | ||
| } | ||
|
|
||
| public void add(Card card) { | ||
| cards.add(card); | ||
| } | ||
|
|
||
| public List<Card> getCards() { | ||
| return List.copyOf(cards); | ||
| } | ||
|
|
||
| public int getSum() { | ||
| int aceCount = getAceCount(); | ||
| int pointSum = getNotAceSum() + aceCount; | ||
| while (pointSum + ACE_BONUS <= MAXIMUM_SUM && aceCount > 0) { | ||
| pointSum += ACE_BONUS; | ||
| aceCount--; | ||
| } | ||
| return pointSum; | ||
| } | ||
|
|
||
| private int getNotAceSum() { | ||
| return cards.stream() | ||
| .filter(card -> !card.isAce()) | ||
| .mapToInt(Card::getPoint) | ||
| .sum(); | ||
| } | ||
|
|
||
| private int getAceCount() { | ||
| return (int) cards.stream() | ||
| .filter(Card::isAce) | ||
| .count(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package blackjack.domain.card; | ||
|
|
||
| public enum Shape { | ||
| SPADE("스페이드"), | ||
| HEART("하트"), | ||
| CLOVER("클로버"), | ||
| DIAMOND("다이아몬드"); | ||
|
|
||
| private final String name; | ||
|
|
||
| Shape(String name) { | ||
| this.name = name; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
List 말고 Map으로 관리하는건 어떻게 생각하세요?