diff --git a/README.md b/README.md index 03ba7ed3..25ca1934 100644 --- a/README.md +++ b/README.md @@ -1 +1,69 @@ -# java-blackjack \ No newline at end of file +# java-rentcompany +# 기능 요구사항 +- [X] 이동거리를 입력받아 자동차 객체를 생성한다. +- [X] 이동거리를 활용해 차량 별로 필요한 연료를 계산한다. +- [X] 보고서를 출력한다. + +# java-blackjack +## 기능 요구 사항 +- 블랙잭 게임을 변형한 프로그램을 구현한다. 블랙잭 게임은 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 숫자를 가지는 쪽이 이기는 게임이다. +- 카드의 숫자 계산은 카드 숫자를 기본으로 하며, 예외로 Ace는 1 또는 11로 계산할 수 있으며, King, Queen, Jack은 각각 10으로 계산한다. +- 게임을 시작하면 플레이어는 두 장의 카드를 지급 받으며, 두 장의 카드 숫자를 합쳐 21을 초과하지 않으면서 21에 가깝게 만들면 이긴다. 21을 넘지 않을 경우 원한다면 얼마든지 카드를 계속 뽑을 수 있다. +- 딜러는 처음에 받은 2장의 합계가 16이하이면 반드시 1장의 카드를 추가로 받아야 하고, 17점 이상이면 추가로 받을 수 없다. +- 게임을 완료한 후 각 플레이어별로 승패를 출력한다. + +## 기능 설계 +- GamePlayers + - GamePlayers는 딜러와 플레이어를 갖고 있다. + - Dealer + - [X] 딜러는 처음에 카드를 두 장 받는다. + - [X] 딜러는 카드의 합이 16이하이면 1장을 반드시 받고, 17 이상이면 추가로 받을 수 없다. + - Players + - Players에는 Player를 담고 있다. + - Player + - [X] 플레이어는 InputView를 통해 입력받는다. + - [X] 입력 받은 Player는 인스턴스 생성 +- OwnCards + - 플레이어들이 가지고 있는 카드들 + - 이 카드들을 사용하여 게임의 결과를 정한다. +- Deck + - Deck은 Card를 담고 있다. + - 게임에 사용할 52장의 카드를 생성한다. + - Card + - CardNumber + - [X] 카드 번호를 생성하는 객체 + - CardType + - [X] 카드 타입을 생성하는 객체 +- CardTotal + - [X] 게임 이용자들의 카드 합을 구하는 클래스 +- GamePlay + - [X] 게임을 진행하는 클래스 +- GameResult + - [X] 게임의 결과를 만드는 클래스 + - ResultValue + - [X] 승, 무, 패를 가지고 있는 ENUM 클래스 +- InputView +- ResultView + +## 프로그래밍 요구 사항 +- 자바 코드 컨벤션을 지키면서 프로그래밍한다. +- 기본적으로 Google Java Style Guide을 원칙으로 한다. +- 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다. +- indent(인덴트, 들여쓰기) depth를 2를 넘지 않도록 구현한다. 1까지만 허용한다. +- 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. +- 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. +- 3항 연산자를 쓰지 않는다. +- else 예약어, switch/case를 사용하지 않는다. +- 힌트: if문에서 값을 반환하는 방식으로 구현하면 else 예약어를 사용하지 않아도 된다. +- 모든 기능을 TDD로 구현해 단위 테스트가 존재해야 한다. 단, UI(System.out, System.in) 로직은 제외 +- 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 구분한다. +- UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다. +- 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다. +- 함수(또는 메소드)가 한 가지 일만 하도록 최대한 작게 만들어라. +- 배열 대신 컬렉션을 사용한다. +- 모든 원시 값과 문자열을 포장한다 +- 줄여 쓰지 않는다(축약 금지). +- 일급 컬렉션을 쓴다. +- 모든 엔티티를 작게 유지한다. +- 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다. +- 딜러와 플레이어에서 발생하는 중복 코드를 제거해야 한다. diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java new file mode 100644 index 00000000..b9691cb7 --- /dev/null +++ b/src/main/java/blackjack/Application.java @@ -0,0 +1,10 @@ +package blackjack; + +import blackjack.controller.BlackJackController; + +public class Application { + + public static void main(String[] args) { + BlackJackController.playBlackJack(); + } +} diff --git a/src/main/java/blackjack/controller/BlackJackController.java b/src/main/java/blackjack/controller/BlackJackController.java new file mode 100644 index 00000000..6011de9f --- /dev/null +++ b/src/main/java/blackjack/controller/BlackJackController.java @@ -0,0 +1,47 @@ +package blackjack.controller; + +import blackjack.domain.Dealer; +import blackjack.domain.Deck; +import blackjack.domain.GameResult; +import blackjack.domain.Players; +import blackjack.view.InputView; +import blackjack.view.ResultView; +import java.util.Objects; + +public class BlackJackController { + + public static void playBlackJack() { + Deck deck = Deck.createDeck(); + Dealer dealer = new Dealer(); + Players players = Players.createPlayers(InputView.getPlayers()); + + ResultView resultView = new ResultView(dealer, players); + resultView.inputPlayersPrint(); + + dealer.initOwnCards(deck); + players.getPlayers().forEach(player -> player.initOwnCards(deck)); + + resultView.playerCardsPrint(dealer); + players.getPlayers().forEach(resultView::playerCardsPrint); + + players.getPlayers().forEach(player -> { + while (player.isAvailDraw() && Objects.equals(InputView.doQuestion(player), "y")) { + player.drawOneCards(deck); + resultView.playerCardsPrint(player); + } + }); + + if (dealer.isAvailDraw()) { + dealer.drawOneCards(deck); + resultView.dealerDrawCardPrint(dealer); + } + + resultView.playersGetTotalScore(dealer); + players.getPlayers().forEach(resultView::playersGetTotalScore); + + resultView.gameResultMessagePrint(); + GameResult gameResult = GameResult.calGameResult(dealer, players); + resultView.dealerGameResultPrint(gameResult); + resultView.playerGameResultPrint(gameResult); + } +} diff --git a/src/main/java/blackjack/domain/Card.java b/src/main/java/blackjack/domain/Card.java new file mode 100644 index 00000000..6ef9eab8 --- /dev/null +++ b/src/main/java/blackjack/domain/Card.java @@ -0,0 +1,28 @@ +package blackjack.domain; + +public class Card { + + private final CardNumber cardNumber; + private final CardType cardType; + + public Card(CardNumber cardNumber, CardType cardType) { + this.cardNumber = cardNumber; + this.cardType = cardType; + } + + public String getCardName() { + return cardNumber.getName(); + } + + public int getCardNumber() { + return cardNumber.getScore(); + } + + public String getCardType() { + return cardType.getType(); + } + + public boolean isAceCard() { + return cardNumber.isAce(); + } +} diff --git a/src/main/java/blackjack/domain/CardNumber.java b/src/main/java/blackjack/domain/CardNumber.java new file mode 100644 index 00000000..a0c14ecf --- /dev/null +++ b/src/main/java/blackjack/domain/CardNumber.java @@ -0,0 +1,37 @@ +package blackjack.domain; + +public enum CardNumber { + ACE(1, "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 name; + + CardNumber(int score, String name) { + this.score = score; + this.name = name; + } + + public int getScore() { + return score; + } + + public String getName() { + return name; + } + + public boolean isAce() { + return this == ACE; + } +} diff --git a/src/main/java/blackjack/domain/CardType.java b/src/main/java/blackjack/domain/CardType.java new file mode 100644 index 00000000..4f915b7d --- /dev/null +++ b/src/main/java/blackjack/domain/CardType.java @@ -0,0 +1,18 @@ +package blackjack.domain; + +public enum CardType { + SPADE("스페이드"), + CLOBER("클로버"), + HEART("하트"), + DIAMOND("다이아몬드"); + + private final String type; + + CardType(String type) { + this.type = type; + } + + public String getType() { + return type; + } +} diff --git a/src/main/java/blackjack/domain/Dealer.java b/src/main/java/blackjack/domain/Dealer.java new file mode 100644 index 00000000..cd56e4b3 --- /dev/null +++ b/src/main/java/blackjack/domain/Dealer.java @@ -0,0 +1,20 @@ +package blackjack.domain; + +public class Dealer extends GamePlayers { + + private static final String DEALER_NAME = "딜러"; + private final int DEALER_DRAW_LIMIT = 16; + + public Dealer() { + super(DEALER_NAME); + } + + public Dealer(OwnCards ownCards) { + super(DEALER_NAME, ownCards); + } + + public boolean isAvailDraw() { + return ownCards.getTotalScore() <= DEALER_DRAW_LIMIT && !ownCards.isScoreLimit(); + } + +} diff --git a/src/main/java/blackjack/domain/Deck.java b/src/main/java/blackjack/domain/Deck.java new file mode 100644 index 00000000..2736f8ae --- /dev/null +++ b/src/main/java/blackjack/domain/Deck.java @@ -0,0 +1,45 @@ +package blackjack.domain; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class Deck { + + private final int TOP_OF_CARDS = 0; + private final String INVALID_DRAW = "남아있는 카드가 없습니다"; + private final List cards; + + private Deck(List cards) { + this.cards = cards; + } + + public static Deck createDeck() { + List blackJack = makeBlackJackCards(); + + Collections.shuffle(blackJack); + + return new Deck(blackJack); + } + + private static List makeBlackJackCards() { + return Arrays.stream(CardNumber.values()) + .flatMap(number -> + Arrays.stream(CardType.values()) + .map(type -> new Card(number, type))) + .collect(Collectors.toList()); + } + + public Card cardDraw() { + if (cards.isEmpty()) { + throw new RuntimeException(INVALID_DRAW); + } + + return cards.remove(TOP_OF_CARDS); + } + + public List getCards() { + return cards; + } +} diff --git a/src/main/java/blackjack/domain/GamePlayers.java b/src/main/java/blackjack/domain/GamePlayers.java new file mode 100644 index 00000000..6ec06775 --- /dev/null +++ b/src/main/java/blackjack/domain/GamePlayers.java @@ -0,0 +1,39 @@ +package blackjack.domain; + +public abstract class GamePlayers { + + private static final int INIT_CNT = 2; + + protected final String playerName; + protected final OwnCards ownCards; + + protected GamePlayers(String playerName) { + this.playerName = playerName; + this.ownCards = new OwnCards(); + } + + protected GamePlayers(String playerName, OwnCards ownCards) { + this.playerName = playerName; + this.ownCards = ownCards; + } + + public abstract boolean isAvailDraw(); + + public void initOwnCards(Deck deck) { + for (int i = 0; i < INIT_CNT; i++) { + ownCards.addCard(deck.cardDraw()); + } + } + + public void drawOneCards(Deck deck) { + ownCards.addCard(deck.cardDraw()); + } + + public String getPlayerName() { + return playerName; + } + + public OwnCards myOwnCards() { + return ownCards; + } +} diff --git a/src/main/java/blackjack/domain/GameResult.java b/src/main/java/blackjack/domain/GameResult.java new file mode 100644 index 00000000..c992e51b --- /dev/null +++ b/src/main/java/blackjack/domain/GameResult.java @@ -0,0 +1,82 @@ +package blackjack.domain; + +import static blackjack.domain.ResultValue.DRAW; +import static blackjack.domain.ResultValue.LOSE; +import static blackjack.domain.ResultValue.WIN; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class GameResult { + + private final LinkedHashMap gameStatus; + + private GameResult(LinkedHashMap gameStatus) { + this.gameStatus = gameStatus; + } + + public static GameResult calGameResult(Dealer dealer, Players players) { + LinkedHashMap result = new LinkedHashMap<>(); + + players.getPlayers() + .forEach(player -> result.put(player.getPlayerName(), getPlayerResult(dealer, player))); + + return new GameResult(result); + } + + private static ResultValue getPlayerResult(Dealer dealer, Player player) { + OwnCards dealerDeck = dealer.ownCards; + OwnCards playerDeck = player.ownCards; + + if (playerDeck.isScoreLimit()) { + return LOSE; + } + + if (dealerDeck.isScoreLimit()) { + return WIN; + } + + if (playerDeck.isBlackJack() && dealerDeck.isBlackJack()) { + return DRAW; + } + + if (playerDeck.isBlackJack()) { + return WIN; + } + + if (dealerDeck.isBlackJack()) { + return LOSE; + } + + if (playerDeck.getTotalScore() == dealerDeck.getTotalScore()) { + return DRAW; + } + + if (playerDeck.getTotalScore() > dealerDeck.getTotalScore()) { + return WIN; + } + + return LOSE; + } + + public List getDealerGameResult() { + return gameStatus + .values() + .stream() + .map(ResultValue::reverseScore) + .collect(Collectors.groupingBy(group -> group, Collectors.counting())) + .entrySet() + .stream() + .sorted(Map.Entry.comparingByKey()) + .map(m -> m.getValue() + m.getKey().getName()) + .collect(Collectors.toList()); + } + + public List getplayerGameResult() { + return gameStatus.entrySet().stream() + .map(player -> player.getKey() + " : " + player.getValue().getName()).collect( + Collectors.toList()); + } +} diff --git a/src/main/java/blackjack/domain/OwnCards.java b/src/main/java/blackjack/domain/OwnCards.java new file mode 100644 index 00000000..efc806ae --- /dev/null +++ b/src/main/java/blackjack/domain/OwnCards.java @@ -0,0 +1,43 @@ +package blackjack.domain; + +import java.util.ArrayList; +import java.util.List; + +public class OwnCards { + + private final int BLACKJACK = 21; + private final int ACE_NUMBER_TEN = 10; + private final int ACE_NUMBER_ONE = 1; + + private final List ownCards; + + public OwnCards() { + this.ownCards = new ArrayList<>(); + } + + public int getTotalScore() { + int total = ownCards.stream().mapToInt(Card::getCardNumber).sum(); + + if (total <= BLACKJACK - ACE_NUMBER_TEN && ownCards.stream().anyMatch(Card::isAceCard)) { + return total + ACE_NUMBER_TEN - ACE_NUMBER_ONE; + } + + return total; + } + + public boolean isScoreLimit() { + return getTotalScore() > BLACKJACK; + } + + public boolean isBlackJack() { + return getTotalScore() == BLACKJACK; + } + + public void addCard(Card card) { + ownCards.add(card); + } + + public List getOwnCards() { + return ownCards; + } +} diff --git a/src/main/java/blackjack/domain/Player.java b/src/main/java/blackjack/domain/Player.java new file mode 100644 index 00000000..c5d6d30c --- /dev/null +++ b/src/main/java/blackjack/domain/Player.java @@ -0,0 +1,15 @@ +package blackjack.domain; + +public class Player extends GamePlayers { + + private final int DEALER_DRAW_LIMIT = 21; + + public Player(String playerName) { + super(playerName); + } + + @Override + public boolean isAvailDraw() { + return ownCards.getTotalScore() <= DEALER_DRAW_LIMIT && !ownCards.isScoreLimit(); + } +} diff --git a/src/main/java/blackjack/domain/Players.java b/src/main/java/blackjack/domain/Players.java new file mode 100644 index 00000000..81e1ab52 --- /dev/null +++ b/src/main/java/blackjack/domain/Players.java @@ -0,0 +1,21 @@ +package blackjack.domain; + +import java.util.List; +import java.util.stream.Collectors; + +public class Players { + + private final List players; + + public Players(List players) { + this.players = players; + } + + public static Players createPlayers(List input) { + return new Players(input.stream().map(Player::new).collect(Collectors.toList())); + } + + public List getPlayers() { + return players; + } +} diff --git a/src/main/java/blackjack/domain/ResultValue.java b/src/main/java/blackjack/domain/ResultValue.java new file mode 100644 index 00000000..1649a786 --- /dev/null +++ b/src/main/java/blackjack/domain/ResultValue.java @@ -0,0 +1,32 @@ +package blackjack.domain; + +import java.util.Arrays; + +public enum ResultValue { + + WIN(1, "승"), + DRAW(0, "무"), + LOSE(-1, "패"); + + private static final String INVALID_KEY = "존재하지 않는 값입니다."; + private int score; + private String name; + + ResultValue(int score, String name) { + this.score = score; + this.name = name; + } + + private static ResultValue create(int score) { + return Arrays.stream(ResultValue.values()).filter(value -> value.score == score) + .findFirst().orElseThrow(() -> new IllegalArgumentException(INVALID_KEY)); + } + + public ResultValue reverseScore() { + return ResultValue.create(-score); + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/blackjack/util/Parser.java b/src/main/java/blackjack/util/Parser.java new file mode 100644 index 00000000..add70f72 --- /dev/null +++ b/src/main/java/blackjack/util/Parser.java @@ -0,0 +1,18 @@ +package blackjack.util; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class Parser { + + private static final String DELIMITER = ","; + private static final String SPACE = " "; + private static final String NOT_SPACE = ""; + + public static List parseInput(String input) { + String[] splitInput = input.replace(SPACE, NOT_SPACE).split(DELIMITER); + + return Arrays.stream(splitInput).collect(Collectors.toList()); + } +} diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java new file mode 100644 index 00000000..fa93b8ae --- /dev/null +++ b/src/main/java/blackjack/view/InputView.java @@ -0,0 +1,57 @@ +package blackjack.view; + +import blackjack.domain.GamePlayers; +import blackjack.util.Parser; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Scanner; +import java.util.Set; + +public class InputView { + + private static final String SPACE = " "; + private static final String PLAYERS_INPUT_MESSAGE = "게임에 참여할 사람의 이름을 입력하세요. (쉼표 기준으로 분리)"; + private static final String EXIST_MIN_PLAYER = "최소한 1명의 플레이어가 있어야 합니다."; + private static final String DUPLICATE_PLAYER = "중복되는 플레이어가 있습니다."; + private static final String QUESTION = "는 한장의 카드를 더 받겠습니까? (예는 y, 아니오는 n)"; + + private static final Scanner scanner = new Scanner(System.in); + + private InputView() { + + } + + public static List getPlayers() { + System.out.println(PLAYERS_INPUT_MESSAGE); + + String input = scanner.nextLine().replace(SPACE, ""); + + validateEmptyValue(input); + + List parseInput = Parser.parseInput(input); + validateDuplePlayer(parseInput); + + return parseInput; + } + + private static void validateEmptyValue(String input) { + if (Objects.isNull(input) || input.isEmpty()) { + throw new IllegalArgumentException(EXIST_MIN_PLAYER); + } + } + + private static void validateDuplePlayer(List input) { + Set duple = new HashSet<>(input); + + if (duple.size() != input.size()) { + throw new IllegalArgumentException(DUPLICATE_PLAYER); + } + } + + public static String doQuestion(GamePlayers gamePlayers) { + System.out.println(gamePlayers.getPlayerName() + QUESTION); + + return scanner.nextLine(); + } +} diff --git a/src/main/java/blackjack/view/ResultView.java b/src/main/java/blackjack/view/ResultView.java new file mode 100644 index 00000000..bd6b0f1b --- /dev/null +++ b/src/main/java/blackjack/view/ResultView.java @@ -0,0 +1,70 @@ +package blackjack.view; + +import blackjack.domain.Dealer; +import blackjack.domain.GamePlayers; +import blackjack.domain.GameResult; +import blackjack.domain.Players; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ResultView { + + private static String DELIMETER = ", "; + private static String COLON = " : "; + private static String INIT_DISPENSER_MESSAGE = "에게 2장의 카드를 나누었습니다."; + private static String DEALER_DRAW_CARD_MESSAGE = "는 16이하라 한장의 카드를 더 받았습니다."; + private static String PLAYER_TOTAL_SCORE_MESSAGE = " - 결과 : "; + private static String GAME_RESULT_MESSAGE = "## 최종 승패"; + + private final Dealer dealer; + private final Players players; + + public ResultView(Dealer dealer, Players players) { + this.dealer = dealer; + this.players = players; + } + + public void inputPlayersPrint() { + String resultPlayers = dealer.getPlayerName() + DELIMETER + players.getPlayers().stream() + .map(GamePlayers::getPlayerName).collect(Collectors.joining(DELIMETER)) + + INIT_DISPENSER_MESSAGE; + + System.out.println(resultPlayers); + } + + public void playerCardsPrint(GamePlayers gamePlayers) { + System.out.println(playersOwnCards(gamePlayers)); + } + + public String playersOwnCards(GamePlayers gamePlayers) { + return gamePlayers.getPlayerName() + COLON + + gamePlayers.myOwnCards().getOwnCards().stream() + .flatMap(card -> Stream.of(card.getCardName() + card.getCardType())).collect( + Collectors.toList()); + } + + public void dealerDrawCardPrint(GamePlayers gamePlayers) { + String result = gamePlayers.getPlayerName() + DEALER_DRAW_CARD_MESSAGE; + + System.out.println(result + "\n"); + } + + public void playersGetTotalScore(GamePlayers gamePlayers) { + String result = playersOwnCards(gamePlayers) + PLAYER_TOTAL_SCORE_MESSAGE + + gamePlayers.myOwnCards().getTotalScore(); + + System.out.println(result); + } + + public void gameResultMessagePrint() { + System.out.println(GAME_RESULT_MESSAGE); + } + + public void dealerGameResultPrint(GameResult gameResult) { + System.out.println(dealer.getPlayerName() + COLON + gameResult.getDealerGameResult()); + } + + public void playerGameResultPrint(GameResult gameResult) { + gameResult.getplayerGameResult().forEach(System.out::println); + } +} diff --git a/src/main/java/empty.txt b/src/main/java/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/rentcompany/Avante.java b/src/main/java/rentcompany/Avante.java new file mode 100644 index 00000000..61db2d81 --- /dev/null +++ b/src/main/java/rentcompany/Avante.java @@ -0,0 +1,27 @@ +package rentcompany; + +public class Avante extends Car{ + + private static final String NAME = "Avante"; + private static final double DISTANCE_PER_LITER = 15; + private double distance; + + public Avante(double distance) { + this.distance = distance; + } + + @Override + double getDistancePerLiter() { + return DISTANCE_PER_LITER; + } + + @Override + double getTripDistance() { + return this.distance; + } + + @Override + String getName() { + return NAME; + } +} diff --git a/src/main/java/rentcompany/Car.java b/src/main/java/rentcompany/Car.java new file mode 100644 index 00000000..550fcaa5 --- /dev/null +++ b/src/main/java/rentcompany/Car.java @@ -0,0 +1,15 @@ +package rentcompany; + +public abstract class Car { + + abstract double getDistancePerLiter(); + + abstract double getTripDistance(); + + abstract String getName(); + + double getChargeQuantity() { + return getTripDistance() / getDistancePerLiter(); + } + +} \ No newline at end of file diff --git a/src/main/java/rentcompany/K5.java b/src/main/java/rentcompany/K5.java new file mode 100644 index 00000000..dcd07109 --- /dev/null +++ b/src/main/java/rentcompany/K5.java @@ -0,0 +1,27 @@ +package rentcompany; + +public class K5 extends Car{ + + private static final String NAME = "K5"; + private static final double DISTANCE_PER_LITER = 13; + private double distance; + + public K5(double distance) { + this.distance = distance; + } + + @Override + double getDistancePerLiter() { + return DISTANCE_PER_LITER; + } + + @Override + double getTripDistance() { + return this.distance; + } + + @Override + String getName() { + return NAME; + } +} diff --git a/src/main/java/rentcompany/RentCompany.java b/src/main/java/rentcompany/RentCompany.java new file mode 100644 index 00000000..98a84173 --- /dev/null +++ b/src/main/java/rentcompany/RentCompany.java @@ -0,0 +1,33 @@ +package rentcompany; + +import java.util.ArrayList; +import java.util.List; + +public class RentCompany { + + private static final String NEW_LINE = System.getProperty("line.separator"); + private static final String LITER = "리터"; + + private List cars; + + private RentCompany() { + cars = new ArrayList<>(); + } + + public static RentCompany create() { + return new RentCompany(); + } + + public void addCar(Car car) { + cars.add(car); + } + + public String generateReport() { + StringBuilder report = new StringBuilder(); + for(Car car : cars){ + report.append(car.getName()+" : "+(int)car.getChargeQuantity()+ LITER + NEW_LINE); + } + System.out.println(report); + return report.toString(); + } +} diff --git a/src/main/java/rentcompany/Sonata.java b/src/main/java/rentcompany/Sonata.java new file mode 100644 index 00000000..9a710f58 --- /dev/null +++ b/src/main/java/rentcompany/Sonata.java @@ -0,0 +1,27 @@ +package rentcompany; + +public class Sonata extends Car { + + private static final String NAME = "Sonata"; + private static final double DISTANCE_PER_LITER = 10; + private double distance; + + public Sonata(double distance) { + this.distance = distance; + } + + @Override + public double getDistancePerLiter() { + return DISTANCE_PER_LITER; + } + + @Override + public double getTripDistance() { + return this.distance; + } + + @Override + public String getName() { + return NAME; + } +} diff --git a/src/test/java/blackjack/domain/CardNumberTest.java b/src/test/java/blackjack/domain/CardNumberTest.java new file mode 100644 index 00000000..cff05bcb --- /dev/null +++ b/src/test/java/blackjack/domain/CardNumberTest.java @@ -0,0 +1,20 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class CardNumberTest { + + @Test + void 카드_전체_크기_확인() { + assertThat(CardNumber.values()).hasSize(13); + } + + @Test + void 카드_확인() { + CardNumber cardNumber = CardNumber.ACE; + assertTrue(cardNumber.isAce()); + } +} diff --git a/src/test/java/blackjack/domain/CardTest.java b/src/test/java/blackjack/domain/CardTest.java new file mode 100644 index 00000000..5da735e6 --- /dev/null +++ b/src/test/java/blackjack/domain/CardTest.java @@ -0,0 +1,16 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class CardTest { + + @Test + void 카드_만들기_테스트() { + Card card = new Card(CardNumber.ACE, CardType.CLOBER); + + assertThat(card.getCardName()).isEqualTo("A"); + assertThat(card.getCardType()).isEqualTo("클로버"); + } +} diff --git a/src/test/java/blackjack/domain/CardTypeTest.java b/src/test/java/blackjack/domain/CardTypeTest.java new file mode 100644 index 00000000..55ac78f4 --- /dev/null +++ b/src/test/java/blackjack/domain/CardTypeTest.java @@ -0,0 +1,20 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class CardTypeTest { + + @Test + void 카드_타입_크기_확인() { + assertThat(CardType.values()).hasSize(4); + } + + @Test + void 카드_타입_확인() { + CardType cardType = CardType.DIAMOND; + assertThat(cardType.getType()).isEqualTo("다이아몬드"); + } +} diff --git a/src/test/java/blackjack/domain/DealerTest.java b/src/test/java/blackjack/domain/DealerTest.java new file mode 100644 index 00000000..64f80910 --- /dev/null +++ b/src/test/java/blackjack/domain/DealerTest.java @@ -0,0 +1,41 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class DealerTest { + + private Deck deck; + private Dealer dealer; + + @BeforeEach + void 덱_만들기() { + dealer = new Dealer(); + deck = Deck.createDeck(); + } + + @Test + void 카드_뽑기_가능_테스트() { + dealer.initOwnCards(deck); + dealer.initOwnCards(deck); + + assertFalse(dealer.isAvailDraw()); + } + + @Test + void 카드_두장_뽑기_테스트() { + dealer.initOwnCards(deck); + + assertThat(dealer.ownCards.getOwnCards().size()).isEqualTo(2); + } + + @Test + void 카드_한장_뽑기_테스트() { + dealer.drawOneCards(deck); + + assertThat(dealer.ownCards.getOwnCards().size()).isEqualTo(1); + } +} diff --git a/src/test/java/blackjack/domain/DeckTest.java b/src/test/java/blackjack/domain/DeckTest.java new file mode 100644 index 00000000..f9ad8e65 --- /dev/null +++ b/src/test/java/blackjack/domain/DeckTest.java @@ -0,0 +1,28 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class DeckTest { + + private Deck deck; + + @BeforeEach + void 덱_만들기() { + deck = Deck.createDeck(); + } + + @Test + void 게임에_사용할_덱_만들기() { + Set cards = IntStream.range(0, 52) + .mapToObj(card -> deck.cardDraw()) + .collect(Collectors.toSet()); + + assertThat(cards.size()).isEqualTo(52); + } +} diff --git a/src/test/java/blackjack/domain/GamePlayersTest.java b/src/test/java/blackjack/domain/GamePlayersTest.java new file mode 100644 index 00000000..878c8251 --- /dev/null +++ b/src/test/java/blackjack/domain/GamePlayersTest.java @@ -0,0 +1,41 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class GamePlayersTest { + + private Deck deck; + private GamePlayers gamePlayers; + + @BeforeEach + void 덱_만들기() { + gamePlayers = new Dealer(); + deck = Deck.createDeck(); + } + + @Test + void 카드_뽑기_가능_테스트() { + gamePlayers.initOwnCards(deck); + gamePlayers.initOwnCards(deck); + + assertFalse(gamePlayers.isAvailDraw()); + } + + @Test + void 카드_두장_뽑기_테스트() { + gamePlayers.initOwnCards(deck); + + assertThat(gamePlayers.ownCards.getOwnCards().size()).isEqualTo(2); + } + + @Test + void 카드_한장_뽑기_테스트() { + gamePlayers.drawOneCards(deck); + + assertThat(gamePlayers.ownCards.getOwnCards().size()).isEqualTo(1); + } +} diff --git a/src/test/java/blackjack/domain/GameResultTest.java b/src/test/java/blackjack/domain/GameResultTest.java new file mode 100644 index 00000000..5e7ae622 --- /dev/null +++ b/src/test/java/blackjack/domain/GameResultTest.java @@ -0,0 +1,43 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class GameResultTest { + + Dealer dealer; + Players players; + + @BeforeEach + void 테스트_셋업() { + dealer = new Dealer(); + dealer.ownCards.addCard(new Card(CardNumber.KING, CardType.DIAMOND)); + dealer.ownCards.addCard(new Card(CardNumber.QUEEN, CardType.DIAMOND)); + + Player player = new Player("pobi"); + player.ownCards.addCard(new Card(CardNumber.FIVE, CardType.HEART)); + player.ownCards.addCard(new Card(CardNumber.EIGHT, CardType.HEART)); + + Player player2 = new Player("pubi"); + player2.ownCards.addCard(new Card(CardNumber.TEN, CardType.HEART)); + player2.ownCards.addCard(new Card(CardNumber.TEN, CardType.CLOBER)); + player2.ownCards.addCard(new Card(CardNumber.ACE, CardType.CLOBER)); + + players = new Players(Arrays.asList(player, player2)); + } + + @Test + void 블랙잭_딜러_결과_테스트() { + assertThat(GameResult.calGameResult(dealer, players).getDealerGameResult()).isEqualTo( + Arrays.asList("1승", "1패")); + } + + @Test + void 블랙잭_플레이어_결과_테스트() { + assertThat(GameResult.calGameResult(dealer, players).getplayerGameResult()).isEqualTo( + Arrays.asList("pobi : 패", "pubi : 승")); + } +} diff --git a/src/test/java/blackjack/domain/OwnCardsTest.java b/src/test/java/blackjack/domain/OwnCardsTest.java new file mode 100644 index 00000000..d51c6630 --- /dev/null +++ b/src/test/java/blackjack/domain/OwnCardsTest.java @@ -0,0 +1,41 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class OwnCardsTest { + + @Test + void 사용자_카드_추가_테스트() { + OwnCards ownCards = new OwnCards(); + + ownCards.addCard(new Card(CardNumber.ACE, CardType.DIAMOND)); + ownCards.addCard(new Card(CardNumber.FIVE, CardType.DIAMOND)); + + assertThat(ownCards.getTotalScore()).isEqualTo(15); + } + + @Test + void 사용자_카드_점수_초과() { + OwnCards ownCards = new OwnCards(); + + ownCards.addCard(new Card(CardNumber.KING, CardType.DIAMOND)); + ownCards.addCard(new Card(CardNumber.QUEEN, CardType.DIAMOND)); + ownCards.addCard(new Card(CardNumber.EIGHT, CardType.CLOBER)); + + assertTrue(ownCards.isScoreLimit()); + } + + @Test + void 사용자_카드_블랙잭() { + OwnCards ownCards = new OwnCards(); + + ownCards.addCard(new Card(CardNumber.KING, CardType.DIAMOND)); + ownCards.addCard(new Card(CardNumber.QUEEN, CardType.DIAMOND)); + ownCards.addCard(new Card(CardNumber.ACE, CardType.CLOBER)); + + assertTrue(ownCards.isBlackJack()); + } +} diff --git a/src/test/java/blackjack/domain/PlayerTest.java b/src/test/java/blackjack/domain/PlayerTest.java new file mode 100644 index 00000000..81e06e6a --- /dev/null +++ b/src/test/java/blackjack/domain/PlayerTest.java @@ -0,0 +1,38 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class PlayerTest { + + private Deck deck; + private Player player; + + @BeforeEach + void 덱_만들기() { + player = new Player("Player"); + deck = Deck.createDeck(); + } + + @Test + void 카드_뽑기_가능_테스트() { + assertTrue(player.isAvailDraw()); + } + + @Test + void 카드_두장_뽑기_테스트() { + player.initOwnCards(deck); + + assertThat(player.ownCards.getOwnCards().size()).isEqualTo(2); + } + + @Test + void 카드_한장_뽑기_테스트() { + player.drawOneCards(deck); + + assertThat(player.ownCards.getOwnCards().size()).isEqualTo(1); + } +} diff --git a/src/test/java/blackjack/domain/PlayersTest.java b/src/test/java/blackjack/domain/PlayersTest.java new file mode 100644 index 00000000..4ab9c9cb --- /dev/null +++ b/src/test/java/blackjack/domain/PlayersTest.java @@ -0,0 +1,17 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class PlayersTest { + + @Test + void 플레이어_만들기_테스트() { + Players players = Players.createPlayers(Arrays.asList("a", "b", "c", "d")); + + assertThat(players.getPlayers().size()).isEqualTo(4); + } +} diff --git a/src/test/java/blackjack/domain/ResultValueTest.java b/src/test/java/blackjack/domain/ResultValueTest.java new file mode 100644 index 00000000..0adda02b --- /dev/null +++ b/src/test/java/blackjack/domain/ResultValueTest.java @@ -0,0 +1,26 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.Test; + +class ResultValueTest { + + @Test + void 블랙잭_결과_테스트() { + Dealer dealer = new Dealer(); + dealer.ownCards.addCard(new Card(CardNumber.KING, CardType.DIAMOND)); + dealer.ownCards.addCard(new Card(CardNumber.QUEEN, CardType.DIAMOND)); + + Player player = new Player("pobi"); + player.ownCards.addCard(new Card(CardNumber.FIVE, CardType.HEART)); + player.ownCards.addCard(new Card(CardNumber.EIGHT, CardType.HEART)); + + Players players = new Players(Arrays.asList(player)); + + assertThat(GameResult.calGameResult(dealer, players).getDealerGameResult()).isEqualTo( + Collections.singletonList("1승")); + } +} diff --git a/src/test/java/rentcompany/RentCompanyTest.java b/src/test/java/rentcompany/RentCompanyTest.java new file mode 100644 index 00000000..fb3f8edd --- /dev/null +++ b/src/test/java/rentcompany/RentCompanyTest.java @@ -0,0 +1,28 @@ +package rentcompany; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class RentCompanyTest { private static final String NEWLINE = System.getProperty("line.separator"); + + @Test + public void report() throws Exception { + RentCompany company = RentCompany.create(); + company.addCar(new Sonata(150)); + company.addCar(new K5(260)); + company.addCar(new Sonata(120)); + company.addCar(new Avante(300)); + company.addCar(new K5(390)); + + String report = company.generateReport(); + assertThat(report).isEqualTo( + "Sonata : 15리터" + NEWLINE + + "K5 : 20리터" + NEWLINE + + "Sonata : 12리터" + NEWLINE + + "Avante : 20리터" + NEWLINE + + "K5 : 30리터" + NEWLINE + ); + } + +} \ No newline at end of file