Skip to content

Commit

Permalink
[1단계 - 블랙잭 게임 실행] 히이로(문제웅) 미션 제출합니다. (#447)
Browse files Browse the repository at this point in the history
  • Loading branch information
MoonJeWoong authored Mar 10, 2023
1 parent b467f6f commit b679262
Show file tree
Hide file tree
Showing 37 changed files with 1,388 additions and 0 deletions.
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,68 @@
## 우아한테크코스 코드리뷰

- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md)

## Controller
- [x] 게임에 참여할 플레이어의 이름을 입력받는다.
- [x] 딜러와 플레이어들에게 카드를 두 장씩 랜덤하게 나눠준다.
- [x] 딜러와 플레이어들이 받은 카드를 출력한다.
- [x] 딜러는 한장의 카드만 공개한다.
- [x] 플레이어 별로 카드를 더 받을지 물어본다.
- [x] 플레이어는 카드를 한 장 뽑고 가진 카드 현황을 출력한다.
- [x] 플레이어가 가진 카드 숫자의 총합이 21을 초과하면 그만 받도록 한다.
- [x] 플레이어가 가진 카드 숫자의 총합이 21 이하라면 플레이어의 선택에 따라 카드를 계속 받을 수 있다.
- [x] 딜러는 자신의 숫자 카드 합이 17 이상이 되도록 카드를 더 뽑는다.
- [x] 딜러와 플레이어의 카드 합 결과를 계산한다.
- [x] 딜러와 플레이어 최종 카드 현황과 각 합을 출력한다.
- [x] 게임결과를 출력하고 게임을 종료한다.
- [x] 딜러는 총 몇 승 몇 패를 했는지 출력한다.
- [x] 플레이어는 각자의 승패 결과를 출력한다.

## Model
- [x] 블랙잭 전체 카드 생성
- [x] 전체 카드 개수는 52장
- [x] 문양은 하트, 다이아, 클로버, 스페이드
- [x] 각 문양 별 Ace, 2~10, K,Q,J 로 구성
- [x] Ace는 1 또는 11로 계산할 수 있다.
- [x] K,Q,J는 각각 10으로 계산한다.
- [x] 52장 카드는 중복되지 않는다.
- [x] 블랙잭 카드 드로우
- [x] 모든 카드는 랜덤하게 셔플된다.
- [x] 드로우는 셔플된 카드에서 순서대로 가져간다.
- [x] 블랙잭 카드 현황 저장한다.
- [x] 전체 카드에서 남은 카드 현황
- [x] 드로우된 카드는 제외한다.
- [x] 딜러 카드 현황
- [x] 플레이어 카드 현황
- [x] 블랙잭 게임 진행
- [x] 게임의 플레이어 수는 딜러 제외 5명으로 제한한다.
- [x] 플레이어와 딜러는 게임을 시작하며 카드를 2장씩 드로우한다.
- [x] 딜러는 처음에 뽑은 카드 1장만 공개하고, 남은 카드는 최종 결과 확인 전까지 비공개한다.
- [x] 보유한 카드의 숫자 합산
- [x] 보유한 카드의 숫자 합산 유효성 확인
- [x] 합산 결과가 21을 초과하면 더 이상 카드를 뽑지 않는다.
- [x] 딜러와 플레이어 간 승패 결정
- [x] 딜러와 플레이어의 카드 숫자 합산 비교
- [x] 딜러와 플레이어 둘 다 버스트일 시 딜러 승
- [x] 딜러와 플레이어 결과가 무승부일 때 딜러 승

## View
### InputView
- [x] 플레이어 이름 입력
- [x] [예외처리] 쉼표 기준으로 분리하다(pobi,jason)
- [x] 카드 추가로 받을지 말지 여부 입력
- [x] [예외처리] 'y' 또는 'n'이 아닌 입력
### OutputView
- [x] 초기 게임 세팅
- [x] 플레이어 이름 입력 메세지 출력
- [x] 딜러와 플레이어 첫 카드 세팅 결과 출력
- [x] 딜러와 플레이어 별로 가진 카드를 출력
- [x] 게임 진행
- [x] 플레이어가 카드를 추가로 받을지 여부 메세지 출력
- [x] 플레이어가 가진 카드 현황을 출력
- [x] 딜러 추가 카드 수령 메세지
- [x] 게임 결과
- [x] 딜러와 플레이어 최종 카드 결과 출력
- [x] 딜러와 플레이어 최종 승패 결과 출력

## TODO
12 changes: 12 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import controller.BlackJackGameController;
import view.InputView;
import view.OutputView;

public class Application {
public static void main(String[] args) {
InputView inputview = new InputView();
OutputView outputView = new OutputView();
BlackJackGameController blackJackGameController = new BlackJackGameController(inputview, outputView);
blackJackGameController.run();
}
}
120 changes: 120 additions & 0 deletions src/main/java/controller/BlackJackGameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package controller;

import domain.DrawCommand;
import domain.card.Card;
import domain.card.GameDeck;
import domain.card.ShuffleDeckGenerator;
import domain.game.BlackJackGame;
import domain.game.GameResult;
import domain.user.Dealer;
import domain.user.Name;
import domain.user.Names;
import domain.user.Player;
import domain.user.PlayerStatus;
import domain.user.User;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import view.InputView;
import view.OutputView;

public class BlackJackGameController {
private final InputView inputView;
private final OutputView outputView;

public BlackJackGameController(InputView inputView, OutputView outputView) {
this.inputView = inputView;
this.outputView = outputView;
}

public void run() {
BlackJackGame blackJackGame = setUp();
playGame(blackJackGame);
}

private BlackJackGame setUp() {
GameDeck gameDeck = new GameDeck(new ShuffleDeckGenerator());
Dealer dealer = new Dealer(gameDeck.drawForFirstTurn());
List<Player> players = setUpPlayers(gameDeck);
showSetUpResult(dealer, players);
return new BlackJackGame(players, dealer, gameDeck);
}

private List<Player> setUpPlayers(GameDeck gameDeck) {
return readUsersName().stream()
.map(name -> new Player(name, gameDeck.drawForFirstTurn()))
.collect(Collectors.toList());
}

private List<Name> readUsersName() {
outputView.printInputPlayerNameMessage();
Names names = new Names(inputView.readPlayersName());
return names.getNames();
}

private void showSetUpResult(Dealer dealer, List<Player> players) {
HashMap<String, List<Card>> setUpResult = new LinkedHashMap<>();
setUpResult.put("딜러", dealer.getCards().subList(0, 1));
players.forEach(player -> setUpResult.put(player.getName(), player.getCards()));
outputView.printSetUpResult(setUpResult);
}

private void playGame(BlackJackGame blackJackGame) {
progressPlayersTurn(blackJackGame);
progressDealerTurn(blackJackGame);
showUsersCardResult(blackJackGame);
GameResult gameResult = new GameResult(blackJackGame.getPlayerNames());
gameResult.saveResults(blackJackGame.getDealer(), blackJackGame.getPlayers());
showFinalResult(gameResult);
}

private void progressPlayersTurn(BlackJackGame blackJackGame) {
List<Player> players = blackJackGame.getPlayers();
for (Player player : players) {
progressPlayerTurn(blackJackGame, player);
}
}

private void progressPlayerTurn(BlackJackGame blackJackGame, Player player) {
while (player.isUserStatus(PlayerStatus.NORMAL) && readDrawCommand(player).equals(DrawCommand.DRAW)) {
blackJackGame.drawOneMoreCardForPlayer(player);
showDrawResult(player);
}
if (player.isUserStatus(PlayerStatus.NORMAL)) {
showDrawResult(player);
}
}

private DrawCommand readDrawCommand(Player player) {
outputView.printAskOneMoreCardMessage(player.getName());
return inputView.readDrawCommand();
}

private void showDrawResult(Player player) {
outputView.printPlayerDrawResult(player.getName(), player.getCards());
}

private void progressDealerTurn(BlackJackGame blackJackGame) {
blackJackGame.drawCardUntilOverSixteen();

Dealer dealer = blackJackGame.getDealer();
int dealerDrawCount = dealer.getCards().size() - 2;

if (dealerDrawCount > 0) {
outputView.printDealerDrawResult(dealerDrawCount);
}
}

private void showUsersCardResult(BlackJackGame blackJackGame) {
Map<User, List<Card>> userResult = new LinkedHashMap<>();
userResult.put(blackJackGame.getDealer(), blackJackGame.getDealer().getCards());
blackJackGame.getPlayers().forEach(player -> userResult.put(player, player.getCards()));
outputView.printUsersCardResult(userResult);
}

private void showFinalResult(GameResult gameResult) {
outputView.printFinalResult(gameResult.getDealerResult(), gameResult.getPlayerResults());
}
}
31 changes: 31 additions & 0 deletions src/main/java/domain/DrawCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package domain;

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public enum DrawCommand {
DRAW("y"),
STOP("n");

private static final Map<String, DrawCommand> inputDrawCommandMap = Stream.of(values())
.collect(Collectors.toMap(DrawCommand::getCommand, Function.identity()));

private final String command;

DrawCommand(String command) {
this.command = command;
}

public static DrawCommand of(String inputCommand) {
if(inputDrawCommandMap.containsKey(inputCommand)) {
return inputDrawCommandMap.get(inputCommand);
}
throw new IllegalArgumentException("[ERROR] 카드 드로우 커맨드는 y,n 둘 중 하나입니다.");
}

private String getCommand() {
return command;
}
}
33 changes: 33 additions & 0 deletions src/main/java/domain/Number.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package domain;

public enum Number {
ACE(11, "A"),
TWO(2, "2"),
THREE(3, "3"),
FOUR(4, "4"),
FIVE(5, "5"),
SIX(6, "6"),
SEVEN(7, "7"),
EIGHT(8, "8"),
NINE(9, "9"),
TEN(10, "10"),
JACK(10, "J"),
QUEEN(10, "Q"),
KING(10, "K");

private final int score;
private final String number;

Number(int score, String number) {
this.score = score;
this.number = number;
}

public int getScore() {
return score;
}

public String getNumber() {
return number;
}
}
18 changes: 18 additions & 0 deletions src/main/java/domain/Pattern.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package domain;

public enum Pattern {
HEART("하트"),
DIAMOND("다이아몬드"),
CLOVER("클로버"),
SPADE("스페이드");

private final String pattern;

Pattern(String pattern) {
this.pattern = pattern;
}

public String getPattern() {
return pattern;
}
}
7 changes: 7 additions & 0 deletions src/main/java/domain/card/Card.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package domain.card;

public interface Card {
int getScore();

String getSymbol();
}
38 changes: 38 additions & 0 deletions src/main/java/domain/card/CloverCard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package domain.card;

import domain.Number;
import domain.Pattern;

public enum CloverCard implements Card {
CLOVER_ACE(Pattern.CLOVER, Number.ACE),
CLOVER_TWO(Pattern.CLOVER, Number.TWO),
CLOVER_THREE(Pattern.CLOVER, Number.THREE),
CLOVER_FOUR(Pattern.CLOVER, Number.FOUR),
CLOVER_FIVE(Pattern.CLOVER, Number.FIVE),
CLOVER_SIX(Pattern.CLOVER, Number.SIX),
CLOVER_SEVEN(Pattern.CLOVER, Number.SEVEN),
CLOVER_EIGHT(Pattern.CLOVER, Number.EIGHT),
CLOVER_NINE(Pattern.CLOVER, Number.NINE),
CLOVER_TEN(Pattern.CLOVER, Number.TEN),
CLOVER_JACK(Pattern.CLOVER, Number.JACK),
CLOVER_QUEEN(Pattern.CLOVER, Number.QUEEN),
CLOVER_KING(Pattern.CLOVER, Number.KING);

private final Pattern pattern;
private final Number number;

CloverCard(Pattern pattern, Number number) {
this.pattern = pattern;
this.number = number;
}

@Override
public String getSymbol() {
return number.getNumber() + pattern.getPattern();
}

@Override
public int getScore() {
return number.getScore();
}
}
7 changes: 7 additions & 0 deletions src/main/java/domain/card/DeckGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package domain.card;

import java.util.List;

public interface DeckGenerator {
public abstract List<Card> generate();
}
38 changes: 38 additions & 0 deletions src/main/java/domain/card/DiamondCard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package domain.card;

import domain.Number;
import domain.Pattern;

public enum DiamondCard implements Card {
DIAMOND_ACE(Pattern.DIAMOND, Number.ACE),
DIAMOND_TWO(Pattern.DIAMOND, Number.TWO),
DIAMOND_THREE(Pattern.DIAMOND, Number.THREE),
DIAMOND_FOUR(Pattern.DIAMOND, Number.FOUR),
DIAMOND_FIVE(Pattern.DIAMOND, Number.FIVE),
DIAMOND_SIX(Pattern.DIAMOND, Number.SIX),
DIAMOND_SEVEN(Pattern.DIAMOND, Number.SEVEN),
DIAMOND_EIGHT(Pattern.DIAMOND, Number.EIGHT),
DIAMOND_NINE(Pattern.DIAMOND, Number.NINE),
DIAMOND_TEN(Pattern.DIAMOND, Number.TEN),
DIAMOND_JACK(Pattern.DIAMOND, Number.JACK),
DIAMOND_QUEEN(Pattern.DIAMOND, Number.QUEEN),
DIAMOND_KING(Pattern.DIAMOND, Number.KING);

private final Pattern pattern;
private final Number number;

DiamondCard(Pattern pattern, Number number) {
this.pattern = pattern;
this.number = number;
}

@Override
public String getSymbol() {
return number.getNumber() + pattern.getPattern();
}

@Override
public int getScore() {
return number.getScore();
}
}
Loading

0 comments on commit b679262

Please sign in to comment.