From 3dfe0a148cc11b9a788f0c2dae4c2204f3bfa691 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Wed, 1 Jul 2020 15:52:03 +0900 Subject: [PATCH 01/13] =?UTF-8?q?docs:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 30 ++++++++++++++++++++++++++++++ src/main/java/empty.txt | 0 src/test/java/empty.txt | 0 3 files changed, 30 insertions(+) delete mode 100644 src/main/java/empty.txt delete mode 100644 src/test/java/empty.txt diff --git a/README.md b/README.md index 3bcfc257847..ce0a1e23bf8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,35 @@ # java-blackjack 블랙잭 게임 미션 저장소 +## 요구사항 + + [ ] 플레이어 이름 입력 + + [ ] , 기준으로 분리 + + [ ] 미입력, 공백 입력 등 예외처리 + + [ ] 배팅 금액 입력 + + [ ] 모든 플레이어의 배팅 금액 입력 + + [ ] 미입력, 문자입력, 0 이하 입력 등 예외처리 + + [ ] 딜러, 플레이어 모두에게 무작위의 2장의 카드 지급 + + [ ] 나누어준 카드 출력 + + [ ] 딜러는 1장만 출력, 플레이어는 2장 모두 출 + + [ ] 각 플레이어의 카드 합이 21이하인 경우 카드 더 받을지 질문 + + [ ] 플레이어 마다 진행, n 입력 혹은 합이 21초과인경우 중지 + + [ ] y(Y),n(N) 외의 입력 예외처리 + + [ ] y 입력한 경우 무작위의 카드 장한 더 지 + + [ ] 카드를 받은 플레이어의 모든 카드 출 + + [ ] 딜러의 경우 16 이하인 경우 카드 한 장 더 지급 + + [ ] 딜러와 플레이어의 카드, 점수 합 출력 + + [ ] 최종 승패 출력 + + [ ] 딜러의 경우 몇승 몇패인지 출력 + + [ ] 플레이어의 경우 승/패 여부만 출력 + + [ ] 카드 계산 구현 + + [ ] 카드의 숫자 계산은 카드 숫자를 기본으로 함. + + [ ] 예외로 Ace는 1 또는 11로 계산 가능 + + [ ] ace 제외 카드 합 <= 10 인 경우 ace 는 11로 계산 + + [ ] King, Queen, Jack은 각각 10 + + [ ] 수익 금액 구현 + + [ ] 첫 두장의 카드 합이 21 인 경우 수익은 배팅금액 * 1.5 + + [ ] + + ## 우아한테크코스 코드리뷰 * [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) \ No newline at end of file diff --git a/src/main/java/empty.txt b/src/main/java/empty.txt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/java/empty.txt b/src/test/java/empty.txt deleted file mode 100644 index e69de29bb2d..00000000000 From 88cdd0b0a3f22e4c29cecd1c105dd99ec5725a82 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Wed, 1 Jul 2020 16:01:23 +0900 Subject: [PATCH 02/13] =?UTF-8?q?docs:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce0a1e23bf8..e9a3e55c94c 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,11 @@ + [ ] ace 제외 카드 합 <= 10 인 경우 ace 는 11로 계산 + [ ] King, Queen, Jack은 각각 10 + [ ] 수익 금액 구현 - + [ ] 첫 두장의 카드 합이 21 인 경우 수익은 배팅금액 * 1.5 - + [ ] + + [ ] 플레이어의 카드 합만 21 인 경우 수익은 배팅금액 * 1.5 + + [ ] 딜러와 플레이어 모두 블랙잭인경우 수익은 배팅금액 * 1 + + [ ] 합이 21 초과, 지는 경우면 수익은 배팅금액 * -1 + + [ ] 21 이하이면서 21에 가까운 경우 수익은 배팅금액 * 1 + + [ ] 플레이어와 딜러 무승부인 경우(모두 21 초과, 동점)인 경우 수익은 0 ## 우아한테크코스 코드리뷰 From 0595db469706c91958b26a00209ccf43e7621b9a Mon Sep 17 00:00:00 2001 From: YerinCho Date: Wed, 1 Jul 2020 20:23:24 +0900 Subject: [PATCH 03/13] =?UTF-8?q?feat:=20=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이름 입력 구현 배팅금액 입력 구현 --- src/main/java/BlackjackApplication.java | 11 +++++ src/main/java/controller/Controller.java | 26 +++++++++++ src/main/java/domain/user/BettingMoney.java | 18 ++++++++ src/main/java/domain/user/Name.java | 17 +++++++ src/main/java/domain/user/Participant.java | 15 +++++++ src/main/java/domain/user/Player.java | 19 ++++++++ src/main/java/domain/user/PlayerFactory.java | 24 ++++++++++ src/main/java/domain/user/Players.java | 25 +++++++++++ src/main/java/view/InputView.java | 24 ++++++++++ src/main/java/view/OutputView.java | 4 ++ .../java/domain/user/BettingMoneyTest.java | 29 ++++++++++++ src/test/java/domain/user/NameTest.java | 29 ++++++++++++ .../java/domain/user/PlayerFactoryTest.java | 37 +++++++++++++++ src/test/java/domain/user/PlayerTest.java | 29 ++++++++++++ src/test/java/domain/user/PlayersTest.java | 45 +++++++++++++++++++ 15 files changed, 352 insertions(+) create mode 100644 src/main/java/BlackjackApplication.java create mode 100644 src/main/java/controller/Controller.java create mode 100644 src/main/java/domain/user/BettingMoney.java create mode 100644 src/main/java/domain/user/Name.java create mode 100644 src/main/java/domain/user/Participant.java create mode 100644 src/main/java/domain/user/Player.java create mode 100644 src/main/java/domain/user/PlayerFactory.java create mode 100644 src/main/java/domain/user/Players.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/OutputView.java create mode 100644 src/test/java/domain/user/BettingMoneyTest.java create mode 100644 src/test/java/domain/user/NameTest.java create mode 100644 src/test/java/domain/user/PlayerFactoryTest.java create mode 100644 src/test/java/domain/user/PlayerTest.java create mode 100644 src/test/java/domain/user/PlayersTest.java diff --git a/src/main/java/BlackjackApplication.java b/src/main/java/BlackjackApplication.java new file mode 100644 index 00000000000..a0eb9857333 --- /dev/null +++ b/src/main/java/BlackjackApplication.java @@ -0,0 +1,11 @@ +import controller.Controller; +import view.InputView; +import view.OutputView; + +public class BlackjackApplication { + + public static void main(String[] args) { + Controller controller = new Controller(new InputView(), new OutputView()); + controller.run(); + } +} diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java new file mode 100644 index 00000000000..ea12a65ed57 --- /dev/null +++ b/src/main/java/controller/Controller.java @@ -0,0 +1,26 @@ +package controller; + +import domain.user.PlayerFactory; +import domain.user.Players; +import view.InputView; +import view.OutputView; + +import java.util.List; +import java.util.Map; + +public class Controller { + + private final InputView inputView; + private final OutputView outputView; + + public Controller(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void run() { + List names = inputView.inputNames(); + Map inputs = inputView.inputBettingMoneys(names); + Players players = PlayerFactory.createPlayers(inputs); + } +} diff --git a/src/main/java/domain/user/BettingMoney.java b/src/main/java/domain/user/BettingMoney.java new file mode 100644 index 00000000000..54a8f5c4f1f --- /dev/null +++ b/src/main/java/domain/user/BettingMoney.java @@ -0,0 +1,18 @@ +package domain.user; + +public class BettingMoney { + + public static final int MIN_BETTING_MONEY = 1; + private final double bettingMoney; + + public BettingMoney(final double bettingMoney) { + validate(bettingMoney); + this.bettingMoney = bettingMoney; + } + + private void validate(final double bettingMoney) { + if (bettingMoney < MIN_BETTING_MONEY) { + throw new IllegalArgumentException("배팅금액은 1원 이상이어야 합니다. 입력금액 : " + bettingMoney); + } + } +} diff --git a/src/main/java/domain/user/Name.java b/src/main/java/domain/user/Name.java new file mode 100644 index 00000000000..7c4a8bec18d --- /dev/null +++ b/src/main/java/domain/user/Name.java @@ -0,0 +1,17 @@ +package domain.user; + +public class Name { + + private final String name; + + public Name(String name) { + validate(name); + this.name = name; + } + + private void validate(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("이름은 최소 한 글자 이상이어야 합니다."); + } + } +} diff --git a/src/main/java/domain/user/Participant.java b/src/main/java/domain/user/Participant.java new file mode 100644 index 00000000000..86fa3104ab8 --- /dev/null +++ b/src/main/java/domain/user/Participant.java @@ -0,0 +1,15 @@ +package domain.user; + +import domain.card.Card; + +import java.util.ArrayList; +import java.util.List; + +public abstract class Participant { + + protected final List cards = new ArrayList<>(); + + public void addCard(Card card) { + cards.add(card); + } +} diff --git a/src/main/java/domain/user/Player.java b/src/main/java/domain/user/Player.java new file mode 100644 index 00000000000..d92e03c648e --- /dev/null +++ b/src/main/java/domain/user/Player.java @@ -0,0 +1,19 @@ +package domain.user; + +import java.util.Objects; + +public class Player extends Participant { + private final Name name; + private final BettingMoney bettingMoney; + + public Player(final Name name, final BettingMoney bettingMoney) { + Objects.requireNonNull(name, "null 비허용"); + Objects.requireNonNull(bettingMoney, "null 비허용"); + this.name = name; + this.bettingMoney = bettingMoney; + } + + + // TODO 추가 기능 구현 + +} \ No newline at end of file diff --git a/src/main/java/domain/user/PlayerFactory.java b/src/main/java/domain/user/PlayerFactory.java new file mode 100644 index 00000000000..25284258cea --- /dev/null +++ b/src/main/java/domain/user/PlayerFactory.java @@ -0,0 +1,24 @@ +package domain.user; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class PlayerFactory { + + public static Players createPlayers(Map inputs) { + validate(inputs); + List players = new ArrayList<>(); + for (Map.Entry input : inputs.entrySet()) { + players.add(new Player( + new Name(input.getKey()), new BettingMoney(input.getValue()))); + } + return new Players(players); + } + + private static void validate(Map inputs) { + if (inputs == null || inputs.isEmpty()) { + throw new IllegalArgumentException("null / empty 값입니다."); + } + } +} diff --git a/src/main/java/domain/user/Players.java b/src/main/java/domain/user/Players.java new file mode 100644 index 00000000000..f91eb6413a8 --- /dev/null +++ b/src/main/java/domain/user/Players.java @@ -0,0 +1,25 @@ +package domain.user; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class Players { + private final List players; + + public Players(final List players) { + validate(players); + this.players = players; + } + + private void validate(final List players) { + Objects.requireNonNull(players, "플레이어는 1명 이상이어야 합니다. 입력값 : null"); + if (players.isEmpty()) { + throw new IllegalArgumentException("플레이어는 1명 이상이어야 합니다. 입력값 : empty"); + } + } + + public List getPlayers() { + return Collections.unmodifiableList(players); + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000000..37b0d605400 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,24 @@ +package view; + +import java.util.*; + +public class InputView { + + private final Scanner SCANNER = new Scanner(System.in); + + public List inputNames() { + System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); + return Arrays.asList(SCANNER.nextLine() + .replace(" ", "") + .split(",")); + } + + public Map inputBettingMoneys(List names) { + Map bettingMoneys = new HashMap<>(); + for (String name : names) { + System.out.println(name + " 의 배팅 금액은?"); + bettingMoneys.put(name, Integer.parseInt(SCANNER.nextLine())); + } + return bettingMoneys; + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 00000000000..d8f9743ccfe --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,4 @@ +package view; + +public class OutputView { +} diff --git a/src/test/java/domain/user/BettingMoneyTest.java b/src/test/java/domain/user/BettingMoneyTest.java new file mode 100644 index 00000000000..ea7eb0dfab3 --- /dev/null +++ b/src/test/java/domain/user/BettingMoneyTest.java @@ -0,0 +1,29 @@ +package domain.user; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class BettingMoneyTest { + + @Test + @DisplayName("정상 생성 테스트") + void create() { + BettingMoney bettingMoney = new BettingMoney(300); + assertThat(bettingMoney).isNotNull(); + } + + @ParameterizedTest + @ValueSource(doubles = {0, -1}) + @DisplayName("유효성 검사") + void validate(double input) { + assertThatThrownBy(() -> new BettingMoney(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("배팅금액은 1원 이상이어야 합니다. 입력금액 : " + input); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/user/NameTest.java b/src/test/java/domain/user/NameTest.java new file mode 100644 index 00000000000..32c08ee00bf --- /dev/null +++ b/src/test/java/domain/user/NameTest.java @@ -0,0 +1,29 @@ +package domain.user; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class NameTest { + + @Test + @DisplayName("정상 생성 테스트") + void create() { + Name name = new Name("name"); + assertThat(name).isNotNull(); + } + + @ParameterizedTest + @NullAndEmptySource + @DisplayName("이름 입력에 대한 유효성 검사") + void validate(String name) { + assertThatThrownBy(() -> new Name(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("이름은 최소 한 글자 이상이어야 합니다."); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/user/PlayerFactoryTest.java b/src/test/java/domain/user/PlayerFactoryTest.java new file mode 100644 index 00000000000..4a2613db2c6 --- /dev/null +++ b/src/test/java/domain/user/PlayerFactoryTest.java @@ -0,0 +1,37 @@ +package domain.user; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PlayerFactoryTest { + + @Test + @DisplayName("String name 입력받고, Players 정상 생성 확인") + void create() { + Map inputs = new HashMap<>(); + inputs.put("yerin", 10000); + inputs.put("orange", 10000); + inputs.put("dasom", 10000); + Players players = PlayerFactory.createPlayers(inputs); + assertThat(players).isNotNull(); + assertThat(players.getPlayers()).hasSize(3); + } + + @ParameterizedTest + @NullAndEmptySource + @DisplayName("null, 공백 유효성 테스트") + void validate(Map input) { + assertThatThrownBy(() -> PlayerFactory.createPlayers(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("null / empty 값입니다."); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/user/PlayerTest.java b/src/test/java/domain/user/PlayerTest.java new file mode 100644 index 00000000000..8a1efe3a013 --- /dev/null +++ b/src/test/java/domain/user/PlayerTest.java @@ -0,0 +1,29 @@ +package domain.user; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PlayerTest { + + @Test + @DisplayName("정상 생성 테스트") + void create() { + Player player = new Player(new Name("name"), new BettingMoney(30)); + assertThat(player).isNotNull(); + } + + @ParameterizedTest + @NullSource + @DisplayName("생성에 대한 유효성 검사") + void validate(Object object) { + assertThatThrownBy(() -> new Player((Name) object, (BettingMoney) object)) + .isInstanceOf(NullPointerException.class) + .hasMessage("null 비허용"); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/user/PlayersTest.java b/src/test/java/domain/user/PlayersTest.java new file mode 100644 index 00000000000..b99aac1fe50 --- /dev/null +++ b/src/test/java/domain/user/PlayersTest.java @@ -0,0 +1,45 @@ +package domain.user; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EmptySource; +import org.junit.jupiter.params.provider.NullSource; + +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PlayersTest { + + @Test + @DisplayName("정상생성 테스트") + void create() { + List playerList = Arrays.asList( + new Player(new Name("Dasom"), new BettingMoney(1000)), + new Player(new Name("yerin"), new BettingMoney(1))); + Players players = new Players(playerList); + assertThat(players).isNotNull(); + } + + @ParameterizedTest + @NullSource + @DisplayName("null 유효성 검사") + void validateNull(List input) { + assertThatThrownBy(() -> new Players(input)) + .isInstanceOf(NullPointerException.class) + .hasMessage("플레이어는 1명 이상이어야 합니다. 입력값 : " + input); + } + + @ParameterizedTest + @EmptySource + @DisplayName("empty 유효성 검사") + void validateEmpty(List input) { + assertThatThrownBy(() -> new Players(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("플레이어는 1명 이상이어야 합니다. 입력값 : empty"); + } + +} \ No newline at end of file From cee048c13ceb616439c10863a46ab2b326ecf358 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Wed, 1 Jul 2020 20:48:13 +0900 Subject: [PATCH 04/13] =?UTF-8?q?refactor:=20=EB=B6=88=EB=B3=80=20?= =?UTF-8?q?=EB=B3=B4=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/user/Dealer.java | 7 +++++++ src/main/java/domain/user/Name.java | 8 ++++++-- src/main/java/domain/user/Participant.java | 2 +- src/main/java/domain/user/PlayerFactory.java | 8 ++++---- src/main/java/domain/user/Players.java | 2 +- 5 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 src/main/java/domain/user/Dealer.java diff --git a/src/main/java/domain/user/Dealer.java b/src/main/java/domain/user/Dealer.java new file mode 100644 index 00000000000..3dd20f06f2d --- /dev/null +++ b/src/main/java/domain/user/Dealer.java @@ -0,0 +1,7 @@ +package domain.user; + +public class Dealer extends Participant { + + public Dealer() { + } +} diff --git a/src/main/java/domain/user/Name.java b/src/main/java/domain/user/Name.java index 7c4a8bec18d..92263784018 100644 --- a/src/main/java/domain/user/Name.java +++ b/src/main/java/domain/user/Name.java @@ -4,14 +4,18 @@ public class Name { private final String name; - public Name(String name) { + public Name(final String name) { validate(name); this.name = name; } - private void validate(String name) { + private void validate(final String name) { if (name == null || name.isEmpty()) { throw new IllegalArgumentException("이름은 최소 한 글자 이상이어야 합니다."); } } + + public String getName() { + return name; + } } diff --git a/src/main/java/domain/user/Participant.java b/src/main/java/domain/user/Participant.java index 86fa3104ab8..aba11f12760 100644 --- a/src/main/java/domain/user/Participant.java +++ b/src/main/java/domain/user/Participant.java @@ -9,7 +9,7 @@ public abstract class Participant { protected final List cards = new ArrayList<>(); - public void addCard(Card card) { + public void addCard(final Card card) { cards.add(card); } } diff --git a/src/main/java/domain/user/PlayerFactory.java b/src/main/java/domain/user/PlayerFactory.java index 25284258cea..3f5627c1b73 100644 --- a/src/main/java/domain/user/PlayerFactory.java +++ b/src/main/java/domain/user/PlayerFactory.java @@ -6,17 +6,17 @@ public class PlayerFactory { - public static Players createPlayers(Map inputs) { + public static Players createPlayers(final Map inputs) { validate(inputs); List players = new ArrayList<>(); - for (Map.Entry input : inputs.entrySet()) { + for (Map.Entry input : inputs.entrySet()) { players.add(new Player( - new Name(input.getKey()), new BettingMoney(input.getValue()))); + input.getKey(), new BettingMoney(input.getValue()))); } return new Players(players); } - private static void validate(Map inputs) { + private static void validate(final Map inputs) { if (inputs == null || inputs.isEmpty()) { throw new IllegalArgumentException("null / empty 값입니다."); } diff --git a/src/main/java/domain/user/Players.java b/src/main/java/domain/user/Players.java index f91eb6413a8..799230afbbe 100644 --- a/src/main/java/domain/user/Players.java +++ b/src/main/java/domain/user/Players.java @@ -7,7 +7,7 @@ public class Players { private final List players; - public Players(final List players) { + Players(final List players) { validate(players); this.players = players; } From 5570d56611bb5633c6456eb8c72dbff3845d0fcf Mon Sep 17 00:00:00 2001 From: YerinCho Date: Wed, 1 Jul 2020 20:51:32 +0900 Subject: [PATCH 05/13] =?UTF-8?q?refactor:=20=EB=B6=88=EB=B3=80=20?= =?UTF-8?q?=EB=B3=B4=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++------ ...ckApplication.java => BlackJackApplication.java} | 2 +- src/main/java/controller/Controller.java | 13 ++++++++++--- src/main/java/view/InputView.java | 12 +++++++----- src/test/java/domain/user/PlayerFactoryTest.java | 10 +++++----- 5 files changed, 29 insertions(+), 20 deletions(-) rename src/main/java/{BlackjackApplication.java => BlackJackApplication.java} (87%) diff --git a/README.md b/README.md index e9a3e55c94c..6aaadc97f85 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ 블랙잭 게임 미션 저장소 ## 요구사항 - + [ ] 플레이어 이름 입력 - + [ ] , 기준으로 분리 - + [ ] 미입력, 공백 입력 등 예외처리 - + [ ] 배팅 금액 입력 - + [ ] 모든 플레이어의 배팅 금액 입력 - + [ ] 미입력, 문자입력, 0 이하 입력 등 예외처리 + + [x] 플레이어 이름 입력 + + [x] , 기준으로 분리 + + [x] 미입력, 공백 입력 등 예외처리 + + [x] 배팅 금액 입력 + + [x] 모든 플레이어의 배팅 금액 입력 + + [x] 미입력, 문자입력, 0 이하 입력 등 예외처리 + [ ] 딜러, 플레이어 모두에게 무작위의 2장의 카드 지급 + [ ] 나누어준 카드 출력 + [ ] 딜러는 1장만 출력, 플레이어는 2장 모두 출 diff --git a/src/main/java/BlackjackApplication.java b/src/main/java/BlackJackApplication.java similarity index 87% rename from src/main/java/BlackjackApplication.java rename to src/main/java/BlackJackApplication.java index a0eb9857333..164edf1333a 100644 --- a/src/main/java/BlackjackApplication.java +++ b/src/main/java/BlackJackApplication.java @@ -2,7 +2,7 @@ import view.InputView; import view.OutputView; -public class BlackjackApplication { +public class BlackJackApplication { public static void main(String[] args) { Controller controller = new Controller(new InputView(), new OutputView()); diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index ea12a65ed57..a3a51463a12 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,5 +1,7 @@ package controller; +import domain.user.Dealer; +import domain.user.Name; import domain.user.PlayerFactory; import domain.user.Players; import view.InputView; @@ -7,20 +9,25 @@ import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class Controller { private final InputView inputView; private final OutputView outputView; - public Controller(InputView inputView, OutputView outputView) { + public Controller(final InputView inputView, final OutputView outputView) { this.inputView = inputView; this.outputView = outputView; } public void run() { - List names = inputView.inputNames(); - Map inputs = inputView.inputBettingMoneys(names); + List names = inputView.inputNames() + .stream() + .map(Name::new) + .collect(Collectors.toList()); + Map inputs = inputView.inputBettingMoneys(names); Players players = PlayerFactory.createPlayers(inputs); + Dealer dealer = new Dealer(); } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 37b0d605400..c8500cf907a 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,5 +1,7 @@ package view; +import domain.user.Name; + import java.util.*; public class InputView { @@ -13,12 +15,12 @@ public List inputNames() { .split(",")); } - public Map inputBettingMoneys(List names) { - Map bettingMoneys = new HashMap<>(); - for (String name : names) { - System.out.println(name + " 의 배팅 금액은?"); + public Map inputBettingMoneys(final List names) { + Map bettingMoneys = new HashMap<>(); + for (Name name : names) { + System.out.println(name.getName() + " 의 배팅 금액은?"); bettingMoneys.put(name, Integer.parseInt(SCANNER.nextLine())); } - return bettingMoneys; + return Collections.unmodifiableMap(bettingMoneys); } } diff --git a/src/test/java/domain/user/PlayerFactoryTest.java b/src/test/java/domain/user/PlayerFactoryTest.java index 4a2613db2c6..1f6625c4159 100644 --- a/src/test/java/domain/user/PlayerFactoryTest.java +++ b/src/test/java/domain/user/PlayerFactoryTest.java @@ -16,10 +16,10 @@ class PlayerFactoryTest { @Test @DisplayName("String name 입력받고, Players 정상 생성 확인") void create() { - Map inputs = new HashMap<>(); - inputs.put("yerin", 10000); - inputs.put("orange", 10000); - inputs.put("dasom", 10000); + Map inputs = new HashMap<>(); + inputs.put(new Name("yerin"), 10000); + inputs.put(new Name("orange"), 10000); + inputs.put(new Name("dasom"), 10000); Players players = PlayerFactory.createPlayers(inputs); assertThat(players).isNotNull(); assertThat(players.getPlayers()).hasSize(3); @@ -28,7 +28,7 @@ void create() { @ParameterizedTest @NullAndEmptySource @DisplayName("null, 공백 유효성 테스트") - void validate(Map input) { + void validate(Map input) { assertThatThrownBy(() -> PlayerFactory.createPlayers(input)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("null / empty 값입니다."); From 719e1c7477460f37b0d1f21a041975b65872be03 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Wed, 1 Jul 2020 21:01:59 +0900 Subject: [PATCH 06/13] =?UTF-8?q?feat:=20=EA=B8=B0=EB=B3=B8=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/card/Card.java | 37 +++++++++++++++++++ src/main/java/domain/card/CardFactory.java | 24 ++++++++++++ src/main/java/domain/card/Deck.java | 13 +++++++ src/main/java/domain/card/Symbol.java | 27 ++++++++++++++ src/main/java/domain/card/Type.java | 8 ++++ .../java/domain/card/CardFactoryTest.java | 20 ++++++++++ 6 files changed, 129 insertions(+) create mode 100644 src/main/java/domain/card/Card.java create mode 100644 src/main/java/domain/card/CardFactory.java create mode 100644 src/main/java/domain/card/Deck.java create mode 100644 src/main/java/domain/card/Symbol.java create mode 100644 src/main/java/domain/card/Type.java create mode 100644 src/test/java/domain/card/CardFactoryTest.java diff --git a/src/main/java/domain/card/Card.java b/src/main/java/domain/card/Card.java new file mode 100644 index 00000000000..55f52470b75 --- /dev/null +++ b/src/main/java/domain/card/Card.java @@ -0,0 +1,37 @@ +package domain.card; + +import java.util.Objects; + +public class Card { + private final Symbol symbol; + + private final Type type; + + public Card(Symbol symbol, Type type) { + this.symbol = symbol; + this.type = type; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Card card = (Card) o; + return symbol == card.symbol && + type == card.type; + } + + @Override + public int hashCode() { + return Objects.hash(symbol, type); + } + + @Override + public String toString() { + return "Card{" + + "symbol=" + symbol + + ", type=" + type + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/domain/card/CardFactory.java b/src/main/java/domain/card/CardFactory.java new file mode 100644 index 00000000000..409bbbbe8a8 --- /dev/null +++ b/src/main/java/domain/card/CardFactory.java @@ -0,0 +1,24 @@ +package domain.card; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class CardFactory { + + public static List create() { + List cards = new ArrayList<>(); + Symbol[] symbols = Symbol.values(); + for (Symbol symbol : symbols) { + createByType(cards, symbol); + } + return Collections.unmodifiableList(cards); + } + + private static void createByType(final List cards, final Symbol symbol) { + Type[] types = Type.values(); + for (Type type : types) { + cards.add(new Card(symbol, type)); + } + } +} \ No newline at end of file diff --git a/src/main/java/domain/card/Deck.java b/src/main/java/domain/card/Deck.java new file mode 100644 index 00000000000..10529363d29 --- /dev/null +++ b/src/main/java/domain/card/Deck.java @@ -0,0 +1,13 @@ +package domain.card; + +import java.util.Collections; +import java.util.List; + +public class Deck { + private final List cards; + + public Deck() { + cards = CardFactory.create(); + Collections.shuffle(cards); + } +} \ No newline at end of file diff --git a/src/main/java/domain/card/Symbol.java b/src/main/java/domain/card/Symbol.java new file mode 100644 index 00000000000..f99f5eaf9a0 --- /dev/null +++ b/src/main/java/domain/card/Symbol.java @@ -0,0 +1,27 @@ +package domain.card; + +public enum Symbol { + ACE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + TEN(10), + JACK(10), + QUEEN(10), + KING(10); + + private final int score; + + Symbol(final int score) { + this.score = score; + } + + public int getScore() { + return score; + } +} \ No newline at end of file diff --git a/src/main/java/domain/card/Type.java b/src/main/java/domain/card/Type.java new file mode 100644 index 00000000000..566eca75d48 --- /dev/null +++ b/src/main/java/domain/card/Type.java @@ -0,0 +1,8 @@ +package domain.card; + +public enum Type { + SPADE, + DIAMOND, + HEART, + CLUB +} \ No newline at end of file diff --git a/src/test/java/domain/card/CardFactoryTest.java b/src/test/java/domain/card/CardFactoryTest.java new file mode 100644 index 00000000000..3ae4b2df673 --- /dev/null +++ b/src/test/java/domain/card/CardFactoryTest.java @@ -0,0 +1,20 @@ +package domain.card; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class CardFactoryTest { + + @Test + @DisplayName("52장 카드생성 확인") + void create() { + List cards = CardFactory.create(); + assertThat(cards).hasSize(52); + System.out.println(cards); + } + +} \ No newline at end of file From 016bd97177e25f61bc31329ec6dbecee98e05194 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Wed, 1 Jul 2020 23:31:40 +0900 Subject: [PATCH 07/13] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91=20=EC=8B=9C=202=EC=9E=A5=EC=9D=98=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EC=A7=80=EA=B8=89=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++-- src/main/java/controller/Controller.java | 12 ++++- .../java/domain/{user => }/BettingMoney.java | 6 ++- src/main/java/domain/Game.java | 47 +++++++++++++++++++ src/main/java/domain/card/Card.java | 5 +- src/main/java/domain/card/CardFactory.java | 3 +- src/main/java/domain/card/Deck.java | 4 ++ src/main/java/domain/card/Hands.java | 21 +++++++++ src/main/java/domain/user/Participant.java | 17 +++++-- src/main/java/domain/user/Player.java | 10 +++- src/main/java/domain/user/PlayerFactory.java | 2 + src/main/java/domain/user/Players.java | 12 +++++ src/main/java/view/InputView.java | 8 ++-- src/main/java/view/OutputView.java | 19 ++++++++ src/test/java/domain/GameTest.java | 47 +++++++++++++++++++ src/test/java/domain/card/DeckTest.java | 18 +++++++ src/test/java/domain/card/HandsTest.java | 18 +++++++ .../java/domain/user/BettingMoneyTest.java | 1 + .../java/domain/user/PlayerFactoryTest.java | 1 + src/test/java/domain/user/PlayerTest.java | 1 + src/test/java/domain/user/PlayersTest.java | 29 +++++++++++- 21 files changed, 267 insertions(+), 24 deletions(-) rename src/main/java/domain/{user => }/BettingMoney.java (84%) create mode 100644 src/main/java/domain/Game.java create mode 100644 src/main/java/domain/card/Hands.java create mode 100644 src/test/java/domain/GameTest.java create mode 100644 src/test/java/domain/card/DeckTest.java create mode 100644 src/test/java/domain/card/HandsTest.java diff --git a/README.md b/README.md index 6aaadc97f85..57f9300d12d 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ + [x] 배팅 금액 입력 + [x] 모든 플레이어의 배팅 금액 입력 + [x] 미입력, 문자입력, 0 이하 입력 등 예외처리 - + [ ] 딜러, 플레이어 모두에게 무작위의 2장의 카드 지급 - + [ ] 나누어준 카드 출력 - + [ ] 딜러는 1장만 출력, 플레이어는 2장 모두 출 + + [x] 딜러, 플레이어 모두에게 무작위의 2장의 카드 지급 + + [x] 나누어준 카드 출력 + + [x] 딜러는 1장만 출력, 플레이어는 2장 모두 출력 + [ ] 각 플레이어의 카드 합이 21이하인 경우 카드 더 받을지 질문 + [ ] 플레이어 마다 진행, n 입력 혹은 합이 21초과인경우 중지 + [ ] y(Y),n(N) 외의 입력 예외처리 @@ -27,8 +27,8 @@ + [ ] ace 제외 카드 합 <= 10 인 경우 ace 는 11로 계산 + [ ] King, Queen, Jack은 각각 10 + [ ] 수익 금액 구현 - + [ ] 플레이어의 카드 합만 21 인 경우 수익은 배팅금액 * 1.5 - + [ ] 딜러와 플레이어 모두 블랙잭인경우 수익은 배팅금액 * 1 + + [ ] 플레이어의 카드 합만 21 인 경우(블랙잭) 수익은 배팅금액 * 1.5 + + [ ] 딜러와 플레이어 모두 블랙잭인 경우 수익은 배팅금액 * 1 + [ ] 합이 21 초과, 지는 경우면 수익은 배팅금액 * -1 + [ ] 21 이하이면서 21에 가까운 경우 수익은 배팅금액 * 1 + [ ] 플레이어와 딜러 무승부인 경우(모두 21 초과, 동점)인 경우 수익은 0 diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index a3a51463a12..1de20039839 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,5 +1,7 @@ package controller; +import domain.Game; +import domain.card.Deck; import domain.user.Dealer; import domain.user.Name; import domain.user.PlayerFactory; @@ -15,6 +17,7 @@ public class Controller { private final InputView inputView; private final OutputView outputView; + private Game game; public Controller(final InputView inputView, final OutputView outputView) { this.inputView = inputView; @@ -22,12 +25,19 @@ public Controller(final InputView inputView, final OutputView outputView) { } public void run() { + game = createGame(); + game.drawFirst(); + outputView.printFirstCards(game.getDealer(), game.getPlayers()); + } + + private Game createGame() { List names = inputView.inputNames() .stream() .map(Name::new) .collect(Collectors.toList()); - Map inputs = inputView.inputBettingMoneys(names); + Map inputs = inputView.inputBettingMonies(names); Players players = PlayerFactory.createPlayers(inputs); Dealer dealer = new Dealer(); + return new Game(new Deck(), players, dealer); } } diff --git a/src/main/java/domain/user/BettingMoney.java b/src/main/java/domain/BettingMoney.java similarity index 84% rename from src/main/java/domain/user/BettingMoney.java rename to src/main/java/domain/BettingMoney.java index 54a8f5c4f1f..8b1895a6bc5 100644 --- a/src/main/java/domain/user/BettingMoney.java +++ b/src/main/java/domain/BettingMoney.java @@ -1,4 +1,4 @@ -package domain.user; +package domain; public class BettingMoney { @@ -15,4 +15,8 @@ private void validate(final double bettingMoney) { throw new IllegalArgumentException("배팅금액은 1원 이상이어야 합니다. 입력금액 : " + bettingMoney); } } + + public double getBettingMoney() { + return bettingMoney; + } } diff --git a/src/main/java/domain/Game.java b/src/main/java/domain/Game.java new file mode 100644 index 00000000000..2eb356a1f5e --- /dev/null +++ b/src/main/java/domain/Game.java @@ -0,0 +1,47 @@ +package domain; + +import domain.card.Card; +import domain.card.Deck; +import domain.user.Dealer; +import domain.user.Player; +import domain.user.Players; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Game { + + private Deck deck; + private Players players; + private Dealer dealer; + + public Game(Deck deck, Players players, Dealer dealer) { + this.deck = deck; + this.players = players; + this.dealer = dealer; + } + + public void drawFirst() { + for (int index = 0; index < 2; index++) { + drawAll(); + } + } + + public void drawAll() { + List drawCards = new ArrayList<>(); + for (int index = 0; index < players.size(); index++) { + drawCards.add(deck.deal()); + } + players.draw(drawCards); + dealer.draw(deck.deal()); + } + + public List getPlayers() { + return Collections.unmodifiableList(players.getPlayers()); + } + + public Dealer getDealer() { + return dealer; + } +} diff --git a/src/main/java/domain/card/Card.java b/src/main/java/domain/card/Card.java index 55f52470b75..d87bfc07e19 100644 --- a/src/main/java/domain/card/Card.java +++ b/src/main/java/domain/card/Card.java @@ -29,9 +29,6 @@ public int hashCode() { @Override public String toString() { - return "Card{" + - "symbol=" + symbol + - ", type=" + type + - '}'; + return symbol + " " + type; } } \ No newline at end of file diff --git a/src/main/java/domain/card/CardFactory.java b/src/main/java/domain/card/CardFactory.java index 409bbbbe8a8..a8bcd2d4f3c 100644 --- a/src/main/java/domain/card/CardFactory.java +++ b/src/main/java/domain/card/CardFactory.java @@ -1,7 +1,6 @@ package domain.card; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class CardFactory { @@ -12,7 +11,7 @@ public static List create() { for (Symbol symbol : symbols) { createByType(cards, symbol); } - return Collections.unmodifiableList(cards); + return cards; } private static void createByType(final List cards, final Symbol symbol) { diff --git a/src/main/java/domain/card/Deck.java b/src/main/java/domain/card/Deck.java index 10529363d29..eac522f268d 100644 --- a/src/main/java/domain/card/Deck.java +++ b/src/main/java/domain/card/Deck.java @@ -10,4 +10,8 @@ public Deck() { cards = CardFactory.create(); Collections.shuffle(cards); } + + public Card deal() { + return cards.remove(0); + } } \ No newline at end of file diff --git a/src/main/java/domain/card/Hands.java b/src/main/java/domain/card/Hands.java new file mode 100644 index 00000000000..34747f0dbfd --- /dev/null +++ b/src/main/java/domain/card/Hands.java @@ -0,0 +1,21 @@ +package domain.card; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Hands { + private final List cards; + + public Hands() { + this.cards = new ArrayList<>(); + } + + public List getCards() { + return Collections.unmodifiableList(cards); + } + + public void add(final Card card) { + cards.add(card); + } +} diff --git a/src/main/java/domain/user/Participant.java b/src/main/java/domain/user/Participant.java index aba11f12760..58c755c97ab 100644 --- a/src/main/java/domain/user/Participant.java +++ b/src/main/java/domain/user/Participant.java @@ -1,15 +1,24 @@ package domain.user; import domain.card.Card; +import domain.card.Hands; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public abstract class Participant { - protected final List cards = new ArrayList<>(); + protected final Hands hands; - public void addCard(final Card card) { - cards.add(card); + public Participant() { + this.hands = new Hands(); + } + + public void draw(final Card card) { + hands.add(card); + } + + public List getHands() { + return Collections.unmodifiableList(hands.getCards()); } } diff --git a/src/main/java/domain/user/Player.java b/src/main/java/domain/user/Player.java index d92e03c648e..174bc75ed2b 100644 --- a/src/main/java/domain/user/Player.java +++ b/src/main/java/domain/user/Player.java @@ -1,5 +1,7 @@ package domain.user; +import domain.BettingMoney; + import java.util.Objects; public class Player extends Participant { @@ -13,7 +15,11 @@ public Player(final Name name, final BettingMoney bettingMoney) { this.bettingMoney = bettingMoney; } + public String getName() { + return name.getName(); + } - // TODO 추가 기능 구현 - + public double getBettingMoney() { + return bettingMoney.getBettingMoney(); + } } \ No newline at end of file diff --git a/src/main/java/domain/user/PlayerFactory.java b/src/main/java/domain/user/PlayerFactory.java index 3f5627c1b73..f30bdca7336 100644 --- a/src/main/java/domain/user/PlayerFactory.java +++ b/src/main/java/domain/user/PlayerFactory.java @@ -1,5 +1,7 @@ package domain.user; +import domain.BettingMoney; + import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/src/main/java/domain/user/Players.java b/src/main/java/domain/user/Players.java index 799230afbbe..fd9d0239434 100644 --- a/src/main/java/domain/user/Players.java +++ b/src/main/java/domain/user/Players.java @@ -1,5 +1,7 @@ package domain.user; +import domain.card.Card; + import java.util.Collections; import java.util.List; import java.util.Objects; @@ -19,6 +21,16 @@ private void validate(final List players) { } } + public void draw(List drawCards) { + for (Player player : players) { + player.draw(drawCards.remove(0)); + } + } + + public int size() { + return players.size(); + } + public List getPlayers() { return Collections.unmodifiableList(players); } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index c8500cf907a..8df237bc65e 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -15,12 +15,12 @@ public List inputNames() { .split(",")); } - public Map inputBettingMoneys(final List names) { - Map bettingMoneys = new HashMap<>(); + public Map inputBettingMonies(final List names) { + Map bettingMonies = new HashMap<>(); for (Name name : names) { System.out.println(name.getName() + " 의 배팅 금액은?"); - bettingMoneys.put(name, Integer.parseInt(SCANNER.nextLine())); + bettingMonies.put(name, Integer.parseInt(SCANNER.nextLine())); } - return Collections.unmodifiableMap(bettingMoneys); + return Collections.unmodifiableMap(bettingMonies); } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index d8f9743ccfe..648119a3672 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,4 +1,23 @@ package view; +import domain.card.Card; +import domain.user.Dealer; +import domain.user.Player; + +import java.util.List; +import java.util.stream.Collectors; + public class OutputView { + public void printFirstCards(Dealer dealer, List players) { + String names = players.stream() + .map(Player::getName) + .collect(Collectors.joining(", ")); + System.out.println("딜러와 " + names + "에게 2장의 카드를 나누어주었습니다."); + System.out.println("딜러 : " + dealer.getHands().get(0).toString()); + for (Player player : players) { + String cards = player.getHands().stream().map(Card::toString).collect(Collectors.joining(", ")); + System.out.println(player.getName() + " : " + cards); + } + + } } diff --git a/src/test/java/domain/GameTest.java b/src/test/java/domain/GameTest.java new file mode 100644 index 00000000000..9b0deb56cd5 --- /dev/null +++ b/src/test/java/domain/GameTest.java @@ -0,0 +1,47 @@ +package domain; + +import domain.card.Deck; +import domain.user.Dealer; +import domain.user.Name; +import domain.user.PlayerFactory; +import domain.user.Players; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +class GameTest { + + private Deck deck; + private Players players; + private Dealer dealer; + private Game game; + + @BeforeEach + void setUp() { + Map inputs = new HashMap<>(); + inputs.put(new Name("yerin"), 10000); + inputs.put(new Name("orange"), 20000); + inputs.put(new Name("dasom"), 30000); + players = PlayerFactory.createPlayers(inputs); + dealer = new Dealer(); + deck = new Deck(); + game = new Game(deck, players, dealer); + } + + @ParameterizedTest + @ValueSource(ints = {0, 1, 2}) + @DisplayName("게임 시작 시 참가자들에게 카드 두 장씩 부여") + void firstDraw(int index) { + game.drawFirst(); + assertThat(game.getDealer().getHands()).hasSize(2); + assertThat(game.getPlayers().get(index).getHands()).hasSize(2); + } + + +} \ No newline at end of file diff --git a/src/test/java/domain/card/DeckTest.java b/src/test/java/domain/card/DeckTest.java new file mode 100644 index 00000000000..b7102948a5d --- /dev/null +++ b/src/test/java/domain/card/DeckTest.java @@ -0,0 +1,18 @@ +package domain.card; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class DeckTest { + + @Test + @DisplayName("카드 한 장 나눠주기") + void deal() { + Deck deck = new Deck(); + Card card = deck.deal(); + assertThat(card).isNotNull(); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/card/HandsTest.java b/src/test/java/domain/card/HandsTest.java new file mode 100644 index 00000000000..5ee9fff058a --- /dev/null +++ b/src/test/java/domain/card/HandsTest.java @@ -0,0 +1,18 @@ +package domain.card; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class HandsTest { + + @Test + @DisplayName("카드 한 장 추가") + void add() { + Hands hands = new Hands(); + hands.add(new Card(Symbol.ACE, Type.CLUB)); + assertThat(hands.getCards()).hasSize(1); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/user/BettingMoneyTest.java b/src/test/java/domain/user/BettingMoneyTest.java index ea7eb0dfab3..1974f0c8673 100644 --- a/src/test/java/domain/user/BettingMoneyTest.java +++ b/src/test/java/domain/user/BettingMoneyTest.java @@ -1,5 +1,6 @@ package domain.user; +import domain.BettingMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/domain/user/PlayerFactoryTest.java b/src/test/java/domain/user/PlayerFactoryTest.java index 1f6625c4159..3ea75377ab0 100644 --- a/src/test/java/domain/user/PlayerFactoryTest.java +++ b/src/test/java/domain/user/PlayerFactoryTest.java @@ -13,6 +13,7 @@ class PlayerFactoryTest { + @Test @DisplayName("String name 입력받고, Players 정상 생성 확인") void create() { diff --git a/src/test/java/domain/user/PlayerTest.java b/src/test/java/domain/user/PlayerTest.java index 8a1efe3a013..eee929efd74 100644 --- a/src/test/java/domain/user/PlayerTest.java +++ b/src/test/java/domain/user/PlayerTest.java @@ -1,5 +1,6 @@ package domain.user; +import domain.BettingMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/domain/user/PlayersTest.java b/src/test/java/domain/user/PlayersTest.java index b99aac1fe50..099f9aba9a8 100644 --- a/src/test/java/domain/user/PlayersTest.java +++ b/src/test/java/domain/user/PlayersTest.java @@ -1,11 +1,18 @@ package domain.user; +import domain.BettingMoney; +import domain.card.Card; +import domain.card.Deck; +import domain.card.Symbol; +import domain.card.Type; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EmptySource; import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -14,13 +21,16 @@ class PlayersTest { + private Players players; + private Deck deck; + @Test @DisplayName("정상생성 테스트") void create() { List playerList = Arrays.asList( new Player(new Name("Dasom"), new BettingMoney(1000)), new Player(new Name("yerin"), new BettingMoney(1))); - Players players = new Players(playerList); + players = new Players(playerList); assertThat(players).isNotNull(); } @@ -42,4 +52,21 @@ void validateEmpty(List input) { .hasMessage("플레이어는 1명 이상이어야 합니다. 입력값 : empty"); } + @ParameterizedTest + @ValueSource(ints = {0, 1}) + @DisplayName("모든 플레이어에게 카드 부여") + void drawFirst(int index) { + create(); + List cards = new ArrayList<>(Arrays.asList(new Card(Symbol.ACE, Type.CLUB), new Card(Symbol.ACE, Type.DIAMOND))); + players.draw(cards); + assertThat(players.getPlayers().get(index).getHands()).hasSize(1); + } + + @Test + @DisplayName("플레이어의 수 구하기") + void size() { + create(); + assertThat(players.size()).isEqualTo(2); + } + } \ No newline at end of file From f8c9d2013c5e43ffb45211302d553fdc017a39d9 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Thu, 2 Jul 2020 00:28:30 +0900 Subject: [PATCH 08/13] =?UTF-8?q?feat:=20=EC=83=81=ED=83=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/card/Hands.java | 4 +++ src/main/java/domain/state/Blackjack.java | 15 +++++++++++ src/main/java/domain/state/Bust.java | 15 +++++++++++ src/main/java/domain/state/Finished.java | 33 +++++++++++++++++++++++ src/main/java/domain/state/Hit.java | 25 +++++++++++++++++ src/main/java/domain/state/Running.java | 20 ++++++++++++++ src/main/java/domain/state/Started.java | 16 +++++++++++ src/main/java/domain/state/State.java | 17 ++++++++++++ src/main/java/domain/state/Stay.java | 15 +++++++++++ 9 files changed, 160 insertions(+) create mode 100644 src/main/java/domain/state/Blackjack.java create mode 100644 src/main/java/domain/state/Bust.java create mode 100644 src/main/java/domain/state/Finished.java create mode 100644 src/main/java/domain/state/Hit.java create mode 100644 src/main/java/domain/state/Running.java create mode 100644 src/main/java/domain/state/Started.java create mode 100644 src/main/java/domain/state/State.java create mode 100644 src/main/java/domain/state/Stay.java diff --git a/src/main/java/domain/card/Hands.java b/src/main/java/domain/card/Hands.java index 34747f0dbfd..113718afe00 100644 --- a/src/main/java/domain/card/Hands.java +++ b/src/main/java/domain/card/Hands.java @@ -18,4 +18,8 @@ public List getCards() { public void add(final Card card) { cards.add(card); } + + public boolean isBust() { + return false; + } } diff --git a/src/main/java/domain/state/Blackjack.java b/src/main/java/domain/state/Blackjack.java new file mode 100644 index 00000000000..adfe6b53d82 --- /dev/null +++ b/src/main/java/domain/state/Blackjack.java @@ -0,0 +1,15 @@ +package domain.state; + +import domain.card.Hands; + +public class Blackjack extends Finished { + + public Blackjack(Hands hands) { + super(hands); + } + + @Override + public double earningRate() { + return 1.5; + } +} diff --git a/src/main/java/domain/state/Bust.java b/src/main/java/domain/state/Bust.java new file mode 100644 index 00000000000..c6a87787802 --- /dev/null +++ b/src/main/java/domain/state/Bust.java @@ -0,0 +1,15 @@ +package domain.state; + +import domain.card.Hands; + +public class Bust extends Finished { + + public Bust(Hands hands) { + super(hands); + } + + @Override + public double earningRate() { + return -1; + } +} diff --git a/src/main/java/domain/state/Finished.java b/src/main/java/domain/state/Finished.java new file mode 100644 index 00000000000..9354e49d8d0 --- /dev/null +++ b/src/main/java/domain/state/Finished.java @@ -0,0 +1,33 @@ +package domain.state; + +import domain.card.Card; +import domain.card.Hands; + +public abstract class Finished extends Started { + + public Finished(Hands hands) { + super(hands); + } + + public abstract double earningRate(); + + @Override + public State draw(Card card) { + throw new UnsupportedOperationException(); + } + + @Override + public State stay() { + throw new UnsupportedOperationException(); + } + + @Override + public double profit(int money) { + return earningRate() * money; + } + + @Override + public boolean isFinished() { + return true; + } +} diff --git a/src/main/java/domain/state/Hit.java b/src/main/java/domain/state/Hit.java new file mode 100644 index 00000000000..8411ac51b5d --- /dev/null +++ b/src/main/java/domain/state/Hit.java @@ -0,0 +1,25 @@ +package domain.state; + +import domain.card.Card; +import domain.card.Hands; + +public class Hit extends Running { + + public Hit(Hands hands) { + super(hands); + } + + @Override + public State draw(Card card) { + hands.add(card); + if (hands.isBust()) { + return new Bust(hands); + } + return new Hit(hands); + } + + @Override + public State stay() { + return new Stay(hands); + } +} diff --git a/src/main/java/domain/state/Running.java b/src/main/java/domain/state/Running.java new file mode 100644 index 00000000000..613b258cbbf --- /dev/null +++ b/src/main/java/domain/state/Running.java @@ -0,0 +1,20 @@ +package domain.state; + +import domain.card.Hands; + +public abstract class Running extends Started { + + public Running(Hands hands) { + super(hands); + } + + @Override + public double profit(int money) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isFinished() { + return false; + } +} diff --git a/src/main/java/domain/state/Started.java b/src/main/java/domain/state/Started.java new file mode 100644 index 00000000000..0a6b1bf7a92 --- /dev/null +++ b/src/main/java/domain/state/Started.java @@ -0,0 +1,16 @@ +package domain.state; + +import domain.card.Hands; + +public abstract class Started implements State { + + protected final Hands hands; + + public Started(Hands hands) { + this.hands = hands; + } + + public Hands hands() { + return this.hands; + } +} diff --git a/src/main/java/domain/state/State.java b/src/main/java/domain/state/State.java new file mode 100644 index 00000000000..e6ddee1ea3b --- /dev/null +++ b/src/main/java/domain/state/State.java @@ -0,0 +1,17 @@ +package domain.state; + +import domain.card.Card; +import domain.card.Hands; + +public interface State { + + State draw(Card card); + + State stay(); + + Hands hands(); + + boolean isFinished(); + + double profit(int money); +} diff --git a/src/main/java/domain/state/Stay.java b/src/main/java/domain/state/Stay.java new file mode 100644 index 00000000000..692889d628b --- /dev/null +++ b/src/main/java/domain/state/Stay.java @@ -0,0 +1,15 @@ +package domain.state; + +import domain.card.Hands; + +public class Stay extends Finished { + + public Stay(Hands hands) { + super(hands); + } + + @Override + public double earningRate() { + return 1; + } +} From 176562c915564872c5811bdc6c1be68d797edef5 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Thu, 2 Jul 2020 01:16:52 +0900 Subject: [PATCH 09/13] =?UTF-8?q?feat:=20=EC=B9=B4=EB=93=9C=20=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=EA=B3=84=EC=82=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +++---- src/main/java/domain/card/Card.java | 7 +++++ src/main/java/domain/card/Hands.java | 21 +++++++++++++++ src/test/java/domain/card/CardTest.java | 26 +++++++++++++++++++ src/test/java/domain/card/HandsTest.java | 33 +++++++++++++++++++++++- 5 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/test/java/domain/card/CardTest.java diff --git a/README.md b/README.md index 57f9300d12d..b0bd0e1db73 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,11 @@ + [ ] 최종 승패 출력 + [ ] 딜러의 경우 몇승 몇패인지 출력 + [ ] 플레이어의 경우 승/패 여부만 출력 - + [ ] 카드 계산 구현 - + [ ] 카드의 숫자 계산은 카드 숫자를 기본으로 함. - + [ ] 예외로 Ace는 1 또는 11로 계산 가능 - + [ ] ace 제외 카드 합 <= 10 인 경우 ace 는 11로 계산 - + [ ] King, Queen, Jack은 각각 10 + + [x] 카드 계산 구현 + + [x] 카드의 숫자 계산은 카드 숫자를 기본으로 함. + + [x] 예외로 Ace는 1 또는 11로 계산 가능 + + [x] ace 제외 카드 합 <= 10 인 경우 ace 는 11로 계산 + + [x] King, Queen, Jack은 각각 10 + [ ] 수익 금액 구현 + [ ] 플레이어의 카드 합만 21 인 경우(블랙잭) 수익은 배팅금액 * 1.5 + [ ] 딜러와 플레이어 모두 블랙잭인 경우 수익은 배팅금액 * 1 diff --git a/src/main/java/domain/card/Card.java b/src/main/java/domain/card/Card.java index d87bfc07e19..c80bfd1da48 100644 --- a/src/main/java/domain/card/Card.java +++ b/src/main/java/domain/card/Card.java @@ -12,6 +12,9 @@ public Card(Symbol symbol, Type type) { this.type = type; } + public boolean isAce() { + return symbol == Symbol.ACE; + } @Override public boolean equals(Object o) { @@ -31,4 +34,8 @@ public int hashCode() { public String toString() { return symbol + " " + type; } + + public int getScore() { + return symbol.getScore(); + } } \ No newline at end of file diff --git a/src/main/java/domain/card/Hands.java b/src/main/java/domain/card/Hands.java index 113718afe00..c00bfb247c2 100644 --- a/src/main/java/domain/card/Hands.java +++ b/src/main/java/domain/card/Hands.java @@ -5,6 +5,8 @@ import java.util.List; public class Hands { + public static final int TEN = 10; + public static final int ELEVEN = 11; private final List cards; public Hands() { @@ -22,4 +24,23 @@ public void add(final Card card) { public boolean isBust() { return false; } + + public int sum() { + int sum = cards.stream() + .mapToInt(Card::getScore) + .sum(); + if (isAceOne(sum)) { + return sum; + } + return sum + TEN; + } + + private boolean isAceOne(int sum) { + return isAceExist() && sum > ELEVEN; + } + + private boolean isAceExist() { + return cards.stream() + .anyMatch(Card::isAce); + } } diff --git a/src/test/java/domain/card/CardTest.java b/src/test/java/domain/card/CardTest.java new file mode 100644 index 00000000000..a7b9e0778a0 --- /dev/null +++ b/src/test/java/domain/card/CardTest.java @@ -0,0 +1,26 @@ +package domain.card; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class CardTest { + + @Test + @DisplayName("카드의 점수 반환") + void getScore() { + Card card = new Card(Symbol.EIGHT, Type.DIAMOND); + assertThat(card.getScore()).isEqualTo(8); + } + + @Test + @DisplayName("에이스 카드인지 확인") + void isAce() { + Card cardA = new Card(Symbol.ACE, Type.DIAMOND); + Card card8 = new Card(Symbol.EIGHT, Type.DIAMOND); + assertThat(cardA.isAce()).isTrue(); + assertThat(card8.isAce()).isFalse(); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/card/HandsTest.java b/src/test/java/domain/card/HandsTest.java index 5ee9fff058a..aa190dc5b95 100644 --- a/src/test/java/domain/card/HandsTest.java +++ b/src/test/java/domain/card/HandsTest.java @@ -1,5 +1,6 @@ package domain.card; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -7,12 +8,42 @@ class HandsTest { + private Hands hands; + + @BeforeEach + void setUp() { + hands = new Hands(); + } + @Test @DisplayName("카드 한 장 추가") void add() { - Hands hands = new Hands(); hands.add(new Card(Symbol.ACE, Type.CLUB)); assertThat(hands.getCards()).hasSize(1); } + @Test + @DisplayName("에이스 없는 경우 카드합(17) 구하기") + void sum() { + hands.add(new Card(Symbol.EIGHT, Type.DIAMOND)); + hands.add(new Card(Symbol.NINE, Type.DIAMOND)); + assertThat(hands.sum()).isEqualTo(17); + } + + @Test + @DisplayName("에이스 있는 경우(1로 계산되는 경우) 카드합 구하기") + void sumWhenAceOne() { + hands.add(new Card(Symbol.ACE, Type.DIAMOND)); + hands.add(new Card(Symbol.EIGHT, Type.DIAMOND)); + hands.add(new Card(Symbol.NINE, Type.DIAMOND)); + assertThat(hands.sum()).isEqualTo(18); + } + + @Test + @DisplayName("에이스 있는 경우(11로 계산되는 경우) 카드합 구하기") + void sumWhenAceEleven() { + hands.add(new Card(Symbol.ACE, Type.DIAMOND)); + hands.add(new Card(Symbol.TEN, Type.DIAMOND)); + assertThat(hands.sum()).isEqualTo(21); + } } \ No newline at end of file From 6ef10b756059186778f0cf793a8d90b09787f6ca Mon Sep 17 00:00:00 2001 From: YerinCho Date: Thu, 2 Jul 2020 03:24:35 +0900 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20=EA=B0=81=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EC=9D=98=20=EC=B9=B4=EB=93=9C=20=ED=95=A9?= =?UTF-8?q?=EC=9D=B4=2021=EC=9D=B4=ED=95=98=EC=9D=B8=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=20=EB=8D=94=20=EB=B0=9B=EA=B8=B0=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++--- src/main/java/controller/Controller.java | 34 ++++++++++------ src/main/java/domain/BettingMoney.java | 1 + src/main/java/domain/Game.java | 32 +++++---------- src/main/java/domain/YesOrNo.java | 22 +++++++++++ src/main/java/domain/card/Hands.java | 21 +++++++++- src/main/java/domain/state/StateFactory.java | 17 ++++++++ src/main/java/domain/user/Dealer.java | 5 +++ src/main/java/domain/user/Participant.java | 18 +++++---- src/main/java/domain/user/Player.java | 8 +++- src/main/java/domain/user/Players.java | 6 +++ src/main/java/view/InputView.java | 11 +++++- src/main/java/view/OutputView.java | 11 +++++- src/test/java/domain/GameTest.java | 17 ++++++-- src/test/java/domain/YesOrNoTest.java | 28 +++++++++++++ src/test/java/domain/card/HandsTest.java | 39 +++++++++++++++++++ .../java/domain/state/StateFactoryTest.java | 33 ++++++++++++++++ src/test/java/domain/user/DealerTest.java | 22 +++++++++++ src/test/java/domain/user/PlayerTest.java | 14 +++++++ src/test/java/domain/user/PlayersTest.java | 12 +++--- 20 files changed, 300 insertions(+), 61 deletions(-) create mode 100644 src/main/java/domain/YesOrNo.java create mode 100644 src/main/java/domain/state/StateFactory.java create mode 100644 src/test/java/domain/YesOrNoTest.java create mode 100644 src/test/java/domain/state/StateFactoryTest.java create mode 100644 src/test/java/domain/user/DealerTest.java diff --git a/README.md b/README.md index b0bd0e1db73..6eca23d1952 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ + [x] 딜러, 플레이어 모두에게 무작위의 2장의 카드 지급 + [x] 나누어준 카드 출력 + [x] 딜러는 1장만 출력, 플레이어는 2장 모두 출력 - + [ ] 각 플레이어의 카드 합이 21이하인 경우 카드 더 받을지 질문 - + [ ] 플레이어 마다 진행, n 입력 혹은 합이 21초과인경우 중지 - + [ ] y(Y),n(N) 외의 입력 예외처리 - + [ ] y 입력한 경우 무작위의 카드 장한 더 지 - + [ ] 카드를 받은 플레이어의 모든 카드 출 + + [x] 각 플레이어의 카드 합이 21이하인 경우 카드 더 받을지 질문 + + [x] 플레이어 마다 진행, n 입력 혹은 합이 21초과인경우 중지 + + [x] y(Y),n(N) 외의 입력 예외처리 + + [x] y 입력한 경우 무작위의 카드 장한 더 지 + + [x] 카드를 받은 플레이어의 모든 카드 출력 + [ ] 딜러의 경우 16 이하인 경우 카드 한 장 더 지급 + [ ] 딜러와 플레이어의 카드, 점수 합 출력 + [ ] 최종 승패 출력 diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 1de20039839..814c6c89cca 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -2,10 +2,7 @@ import domain.Game; import domain.card.Deck; -import domain.user.Dealer; -import domain.user.Name; -import domain.user.PlayerFactory; -import domain.user.Players; +import domain.user.*; import view.InputView; import view.OutputView; @@ -17,7 +14,8 @@ public class Controller { private final InputView inputView; private final OutputView outputView; - private Game game; + private Players players; + private Dealer dealer; public Controller(final InputView inputView, final OutputView outputView) { this.inputView = inputView; @@ -25,9 +23,10 @@ public Controller(final InputView inputView, final OutputView outputView) { } public void run() { - game = createGame(); - game.drawFirst(); - outputView.printFirstCards(game.getDealer(), game.getPlayers()); + Game game = createGame(); + game.drawFirst(players, dealer); + outputView.printFirstCards(dealer, players.getPlayers()); + playPlayers(game); } private Game createGame() { @@ -36,8 +35,21 @@ private Game createGame() { .map(Name::new) .collect(Collectors.toList()); Map inputs = inputView.inputBettingMonies(names); - Players players = PlayerFactory.createPlayers(inputs); - Dealer dealer = new Dealer(); - return new Game(new Deck(), players, dealer); + players = PlayerFactory.createPlayers(inputs); + dealer = new Dealer(); + return new Game(new Deck()); + } + + private void playPlayers(Game game) { + for (Player player : players.getPlayers()) { + playPlayer(player, game); + } + } + + private void playPlayer(Player player, Game game) { + while (player.canDrawCard() && inputView.inputWantMoreCard(player)) { + game.draw(player); + outputView.printCards(player); + } } } diff --git a/src/main/java/domain/BettingMoney.java b/src/main/java/domain/BettingMoney.java index 8b1895a6bc5..0cd7974a79c 100644 --- a/src/main/java/domain/BettingMoney.java +++ b/src/main/java/domain/BettingMoney.java @@ -3,6 +3,7 @@ public class BettingMoney { public static final int MIN_BETTING_MONEY = 1; + private final double bettingMoney; public BettingMoney(final double bettingMoney) { diff --git a/src/main/java/domain/Game.java b/src/main/java/domain/Game.java index 2eb356a1f5e..64d70b622af 100644 --- a/src/main/java/domain/Game.java +++ b/src/main/java/domain/Game.java @@ -3,45 +3,31 @@ import domain.card.Card; import domain.card.Deck; import domain.user.Dealer; -import domain.user.Player; +import domain.user.Participant; import domain.user.Players; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class Game { + public static final int FIRST_DRAW_NUMBER = 2; private Deck deck; - private Players players; - private Dealer dealer; - public Game(Deck deck, Players players, Dealer dealer) { + public Game(Deck deck) { this.deck = deck; - this.players = players; - this.dealer = dealer; } - public void drawFirst() { - for (int index = 0; index < 2; index++) { - drawAll(); - } - } - - public void drawAll() { + public void drawFirst(Players players, Dealer dealer) { List drawCards = new ArrayList<>(); - for (int index = 0; index < players.size(); index++) { + for (int index = 0; index < players.size() * FIRST_DRAW_NUMBER; index++) { drawCards.add(deck.deal()); } - players.draw(drawCards); - dealer.draw(deck.deal()); - } - - public List getPlayers() { - return Collections.unmodifiableList(players.getPlayers()); + players.firstDraw(drawCards); + dealer.drawFirst(deck.deal(), deck.deal()); } - public Dealer getDealer() { - return dealer; + public void draw(Participant participant) { + participant.draw(deck.deal()); } } diff --git a/src/main/java/domain/YesOrNo.java b/src/main/java/domain/YesOrNo.java new file mode 100644 index 00000000000..4c41bbeadd1 --- /dev/null +++ b/src/main/java/domain/YesOrNo.java @@ -0,0 +1,22 @@ +package domain; + +import java.util.Arrays; + +public enum YesOrNo { + + YES("y"), + NO("n"); + + private final String response; + + YesOrNo(final String response) { + this.response = response; + } + + public static YesOrNo of(String response) { + return Arrays.stream(YesOrNo.values()) + .filter(yesOrNo -> yesOrNo.response.equals(response)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("유효하지 않은 답변입니다. 답변 : " + response)); + } +} diff --git a/src/main/java/domain/card/Hands.java b/src/main/java/domain/card/Hands.java index c00bfb247c2..298616cf86c 100644 --- a/src/main/java/domain/card/Hands.java +++ b/src/main/java/domain/card/Hands.java @@ -4,9 +4,14 @@ import java.util.Collections; import java.util.List; +import static domain.Game.FIRST_DRAW_NUMBER; + public class Hands { public static final int TEN = 10; public static final int ELEVEN = 11; + public static final int BLACKJACK = 21; + public static final int DEALER_BUST_NUMBER = 16; + private final List cards; public Hands() { @@ -22,14 +27,14 @@ public void add(final Card card) { } public boolean isBust() { - return false; + return sum() > BLACKJACK; } public int sum() { int sum = cards.stream() .mapToInt(Card::getScore) .sum(); - if (isAceOne(sum)) { + if (isAceNotExist() || isAceOne(sum)) { return sum; } return sum + TEN; @@ -43,4 +48,16 @@ private boolean isAceExist() { return cards.stream() .anyMatch(Card::isAce); } + + private boolean isAceNotExist() { + return !isAceExist(); + } + + public boolean isBlackjack() { + return cards.size() == FIRST_DRAW_NUMBER && sum() == BLACKJACK; + } + + public boolean isDealerBust() { + return sum() >= DEALER_BUST_NUMBER; + } } diff --git a/src/main/java/domain/state/StateFactory.java b/src/main/java/domain/state/StateFactory.java new file mode 100644 index 00000000000..5bddf72059f --- /dev/null +++ b/src/main/java/domain/state/StateFactory.java @@ -0,0 +1,17 @@ +package domain.state; + +import domain.card.Card; +import domain.card.Hands; + +public class StateFactory { + + public static State drawFirst(Card firstCard, Card secondCard) { + Hands hands = new Hands(); + hands.add(firstCard); + hands.add(secondCard); + if (hands.isBlackjack()) { + return new Blackjack(hands); + } + return new Hit(hands); + } +} diff --git a/src/main/java/domain/user/Dealer.java b/src/main/java/domain/user/Dealer.java index 3dd20f06f2d..85d657b9fd9 100644 --- a/src/main/java/domain/user/Dealer.java +++ b/src/main/java/domain/user/Dealer.java @@ -4,4 +4,9 @@ public class Dealer extends Participant { public Dealer() { } + + @Override + public boolean canDrawCard() { + return !state.hands().isDealerBust(); + } } diff --git a/src/main/java/domain/user/Participant.java b/src/main/java/domain/user/Participant.java index 58c755c97ab..6a21a3d1dd9 100644 --- a/src/main/java/domain/user/Participant.java +++ b/src/main/java/domain/user/Participant.java @@ -1,24 +1,28 @@ package domain.user; import domain.card.Card; -import domain.card.Hands; +import domain.state.State; +import domain.state.StateFactory; import java.util.Collections; import java.util.List; public abstract class Participant { - protected final Hands hands; + // protected final Hands hands; + protected State state; - public Participant() { - this.hands = new Hands(); + public void draw(final Card card) { + state = state.draw(card); } - public void draw(final Card card) { - hands.add(card); + public void drawFirst(Card firstCard, Card secondCard) { + state = StateFactory.drawFirst(firstCard, secondCard); } + public abstract boolean canDrawCard(); + public List getHands() { - return Collections.unmodifiableList(hands.getCards()); + return Collections.unmodifiableList(state.hands().getCards()); } } diff --git a/src/main/java/domain/user/Player.java b/src/main/java/domain/user/Player.java index 174bc75ed2b..bdfdda94ae0 100644 --- a/src/main/java/domain/user/Player.java +++ b/src/main/java/domain/user/Player.java @@ -5,8 +5,9 @@ import java.util.Objects; public class Player extends Participant { - private final Name name; + private final BettingMoney bettingMoney; + private final Name name; public Player(final Name name, final BettingMoney bettingMoney) { Objects.requireNonNull(name, "null 비허용"); @@ -15,6 +16,11 @@ public Player(final Name name, final BettingMoney bettingMoney) { this.bettingMoney = bettingMoney; } + @Override + public boolean canDrawCard() { + return !state.hands().isBust(); + } + public String getName() { return name.getName(); } diff --git a/src/main/java/domain/user/Players.java b/src/main/java/domain/user/Players.java index fd9d0239434..a18e4694af6 100644 --- a/src/main/java/domain/user/Players.java +++ b/src/main/java/domain/user/Players.java @@ -21,6 +21,12 @@ private void validate(final List players) { } } + public void firstDraw(List drawCards) { + for (Player player : players) { + player.drawFirst(drawCards.remove(0), drawCards.remove(0)); + } + } + public void draw(List drawCards) { for (Player player : players) { player.draw(drawCards.remove(0)); diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 8df237bc65e..2942d39bdfa 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,9 +1,13 @@ package view; +import domain.YesOrNo; import domain.user.Name; +import domain.user.Player; import java.util.*; +import static domain.YesOrNo.YES; + public class InputView { private final Scanner SCANNER = new Scanner(System.in); @@ -16,11 +20,16 @@ public List inputNames() { } public Map inputBettingMonies(final List names) { - Map bettingMonies = new HashMap<>(); + Map bettingMonies = new LinkedHashMap<>(); for (Name name : names) { System.out.println(name.getName() + " 의 배팅 금액은?"); bettingMonies.put(name, Integer.parseInt(SCANNER.nextLine())); } return Collections.unmodifiableMap(bettingMonies); } + + public boolean inputWantMoreCard(Player player) { + System.out.println(player.getName() + " 은 한 장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)"); + return YES.equals(YesOrNo.of(SCANNER.nextLine())); + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 648119a3672..407c548ccaf 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -8,6 +8,7 @@ import java.util.stream.Collectors; public class OutputView { + public void printFirstCards(Dealer dealer, List players) { String names = players.stream() .map(Player::getName) @@ -15,9 +16,17 @@ public void printFirstCards(Dealer dealer, List players) { System.out.println("딜러와 " + names + "에게 2장의 카드를 나누어주었습니다."); System.out.println("딜러 : " + dealer.getHands().get(0).toString()); for (Player player : players) { - String cards = player.getHands().stream().map(Card::toString).collect(Collectors.joining(", ")); + String cards = player.getHands() + .stream().map(Card::toString) + .collect(Collectors.joining(", ")); System.out.println(player.getName() + " : " + cards); } + } + public void printCards(Player player) { + String cards = player.getHands() + .stream().map(Card::toString) + .collect(Collectors.joining(", ")); + System.out.println(player.getName() + " : " + cards); } } diff --git a/src/test/java/domain/GameTest.java b/src/test/java/domain/GameTest.java index 9b0deb56cd5..ebbc26579aa 100644 --- a/src/test/java/domain/GameTest.java +++ b/src/test/java/domain/GameTest.java @@ -31,16 +31,25 @@ void setUp() { players = PlayerFactory.createPlayers(inputs); dealer = new Dealer(); deck = new Deck(); - game = new Game(deck, players, dealer); + game = new Game(deck); } @ParameterizedTest @ValueSource(ints = {0, 1, 2}) @DisplayName("게임 시작 시 참가자들에게 카드 두 장씩 부여") void firstDraw(int index) { - game.drawFirst(); - assertThat(game.getDealer().getHands()).hasSize(2); - assertThat(game.getPlayers().get(index).getHands()).hasSize(2); + game.drawFirst(players, dealer); + assertThat(dealer.getHands()).hasSize(2); + assertThat(players.getPlayers().get(index).getHands()).hasSize(2); + } + + @ParameterizedTest + @ValueSource(ints = {0, 1, 2}) + @DisplayName("한 장의 카드 지급") + void draw(int index) { + firstDraw(index); + game.draw(players.getPlayers().get(index)); + assertThat(players.getPlayers().get(index).getHands()).hasSize(3); } diff --git a/src/test/java/domain/YesOrNoTest.java b/src/test/java/domain/YesOrNoTest.java new file mode 100644 index 00000000000..00328dcbbd5 --- /dev/null +++ b/src/test/java/domain/YesOrNoTest.java @@ -0,0 +1,28 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class YesOrNoTest { + + @ParameterizedTest + @CsvSource(value = {"y,YES", "n,NO"}) + @DisplayName("정상 반환 확인") + void of(String input, YesOrNo expected) { + assertThat(YesOrNo.of(input)).isEqualTo(expected); + } + + @Test + @DisplayName("비정상 입력 예외처리") + void validateOf() { + assertThatThrownBy(() -> YesOrNo.of("r")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("유효하지 않은 답변입니다. 답변 : r"); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/card/HandsTest.java b/src/test/java/domain/card/HandsTest.java index aa190dc5b95..f674866970a 100644 --- a/src/test/java/domain/card/HandsTest.java +++ b/src/test/java/domain/card/HandsTest.java @@ -3,6 +3,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import static org.assertj.core.api.Assertions.assertThat; @@ -46,4 +48,41 @@ void sumWhenAceEleven() { hands.add(new Card(Symbol.TEN, Type.DIAMOND)); assertThat(hands.sum()).isEqualTo(21); } + + @ParameterizedTest + @CsvSource(value = {"TWO,false", "NINE,true"}) + @DisplayName("Bust인지 확인") + void isBust(Symbol symbol, boolean expected) { + hands.add(new Card(symbol, Type.DIAMOND)); + hands.add(new Card(symbol, Type.DIAMOND)); + hands.add(new Card(symbol, Type.DIAMOND)); + assertThat(hands.isBust()).isEqualTo(expected); + } + + @ParameterizedTest + @CsvSource(value = {"JACK,ACE,true", "TWO,THREE,false"}) + @DisplayName("두 장 받았을 때 블랙잭인지 확인") + void isBlackJack(Symbol symbol1, Symbol symbol2, boolean expected) { + hands.add(new Card(symbol1, Type.DIAMOND)); + hands.add(new Card(symbol2, Type.DIAMOND)); + assertThat(hands.isBlackjack()).isEqualTo(expected); + } + + @Test + @DisplayName("세장 이상 받았을 때 합은 21이지만 블랙잭이 아님 확인") + void isBlackjack() { + hands.add(new Card(Symbol.JACK, Type.DIAMOND)); + hands.add(new Card(Symbol.JACK, Type.DIAMOND)); + hands.add(new Card(Symbol.ACE, Type.DIAMOND)); + assertThat(hands.isBlackjack()).isFalse(); + } + + @ParameterizedTest + @CsvSource(value = {"SIX, true", "FIVE, false"}) + @DisplayName("딜러 버스트 확인") + void isDealerBust(Symbol symbol, boolean expected) { + hands.add(new Card(Symbol.JACK, Type.DIAMOND)); + hands.add(new Card(symbol, Type.DIAMOND)); + assertThat(hands.isDealerBust()).isEqualTo(expected); + } } \ No newline at end of file diff --git a/src/test/java/domain/state/StateFactoryTest.java b/src/test/java/domain/state/StateFactoryTest.java new file mode 100644 index 00000000000..2a4d75aeb0a --- /dev/null +++ b/src/test/java/domain/state/StateFactoryTest.java @@ -0,0 +1,33 @@ +package domain.state; + +import domain.card.Card; +import domain.card.Hands; +import domain.card.Symbol; +import domain.card.Type; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThat; + +class StateFactoryTest { + + @Test + @DisplayName("처음 두장 받은 후 블랙잭인 경우, 블랙잭 반환") + void blackjack() { + Card card1 = new Card(Symbol.ACE, Type.DIAMOND); + Card card2 = new Card(Symbol.JACK, Type.DIAMOND); + assertThat(Objects.requireNonNull(StateFactory.drawFirst(card1, card2)).getClass()).isEqualTo(Blackjack.class); + } + + @Test + @DisplayName("처음 두장 받은 후 블랙잭이 아니면 Hit 반환") + void hit() { + Hands hands = new Hands(); + Card card1 = new Card(Symbol.JACK, Type.DIAMOND); + Card card2 = new Card(Symbol.TWO, Type.DIAMOND); + assertThat(Objects.requireNonNull(StateFactory.drawFirst(card1, card2)).getClass()).isEqualTo(Hit.class); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/user/DealerTest.java b/src/test/java/domain/user/DealerTest.java new file mode 100644 index 00000000000..93511c37d09 --- /dev/null +++ b/src/test/java/domain/user/DealerTest.java @@ -0,0 +1,22 @@ +package domain.user; + +import domain.card.Card; +import domain.card.Symbol; +import domain.card.Type; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.Assertions.assertThat; + +class DealerTest { + + @ParameterizedTest + @CsvSource(value = {"SIX, false", "FIVE,true"}) + @DisplayName("카드를 더 받을 수 있는지 확인") + void canReceiveCard(Symbol symbol, boolean expected) { + Dealer dealer = new Dealer(); + dealer.drawFirst(new Card(Symbol.TEN, Type.DIAMOND), new Card(symbol, Type.DIAMOND)); + assertThat(dealer.canDrawCard()).isEqualTo(expected); + } +} \ No newline at end of file diff --git a/src/test/java/domain/user/PlayerTest.java b/src/test/java/domain/user/PlayerTest.java index eee929efd74..1f492b138f2 100644 --- a/src/test/java/domain/user/PlayerTest.java +++ b/src/test/java/domain/user/PlayerTest.java @@ -1,9 +1,13 @@ package domain.user; import domain.BettingMoney; +import domain.card.Card; +import domain.card.Symbol; +import domain.card.Type; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.NullSource; import static org.assertj.core.api.Assertions.assertThat; @@ -27,4 +31,14 @@ void validate(Object object) { .hasMessage("null 비허용"); } + @ParameterizedTest + @CsvSource(value = {"ACE, true", "FIVE,false"}) + @DisplayName("카드를 더 받을 수 있는지 확인") + void canReceiveCard(Symbol symbol, boolean expected) { + Player player = new Player(new Name("name"), new BettingMoney(30)); + player.drawFirst(new Card(Symbol.TEN, Type.DIAMOND), new Card(Symbol.TEN, Type.DIAMOND)); + player.draw(new Card(symbol, Type.DIAMOND)); + assertThat(player.canDrawCard()).isEqualTo(expected); + } + } \ No newline at end of file diff --git a/src/test/java/domain/user/PlayersTest.java b/src/test/java/domain/user/PlayersTest.java index 099f9aba9a8..b813bf83f06 100644 --- a/src/test/java/domain/user/PlayersTest.java +++ b/src/test/java/domain/user/PlayersTest.java @@ -2,7 +2,6 @@ import domain.BettingMoney; import domain.card.Card; -import domain.card.Deck; import domain.card.Symbol; import domain.card.Type; import org.junit.jupiter.api.DisplayName; @@ -22,7 +21,6 @@ class PlayersTest { private Players players; - private Deck deck; @Test @DisplayName("정상생성 테스트") @@ -54,12 +52,14 @@ void validateEmpty(List input) { @ParameterizedTest @ValueSource(ints = {0, 1}) - @DisplayName("모든 플레이어에게 카드 부여") + @DisplayName("모든 플레이어에게 첫 카드 부여") void drawFirst(int index) { create(); - List cards = new ArrayList<>(Arrays.asList(new Card(Symbol.ACE, Type.CLUB), new Card(Symbol.ACE, Type.DIAMOND))); - players.draw(cards); - assertThat(players.getPlayers().get(index).getHands()).hasSize(1); + List cards = new ArrayList<>( + Arrays.asList(new Card(Symbol.ACE, Type.CLUB), new Card(Symbol.ACE, Type.DIAMOND), + new Card(Symbol.ACE, Type.CLUB), new Card(Symbol.ACE, Type.CLUB))); + players.firstDraw(cards); + assertThat(players.getPlayers().get(index).getHands()).hasSize(2); } @Test From c9b4270d5583c9cd3dd8193641ec241119ce0d0a Mon Sep 17 00:00:00 2001 From: YerinCho Date: Thu, 2 Jul 2020 03:37:42 +0900 Subject: [PATCH 11/13] =?UTF-8?q?feat:=20=EB=94=9C=EB=9F=AC=EC=9D=98=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=2016=20=EC=9D=B4=ED=95=98=EC=9D=B8=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=B9=B4=EB=93=9C=20=ED=95=9C=20=EC=9E=A5?= =?UTF-8?q?=20=EB=8D=94=20=EC=A7=80=EA=B8=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/controller/Controller.java | 11 +++++++++++ src/main/java/domain/card/Hands.java | 2 +- src/main/java/domain/user/Participant.java | 5 ++++- src/main/java/view/OutputView.java | 4 ++++ src/test/java/domain/card/HandsTest.java | 2 +- src/test/java/domain/user/DealerTest.java | 2 +- 7 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6eca23d1952..00f442bc7d9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ + [x] y(Y),n(N) 외의 입력 예외처리 + [x] y 입력한 경우 무작위의 카드 장한 더 지 + [x] 카드를 받은 플레이어의 모든 카드 출력 - + [ ] 딜러의 경우 16 이하인 경우 카드 한 장 더 지급 + + [x] 딜러의 경우 16 이하인 경우 카드 한 장 더 지급 + [ ] 딜러와 플레이어의 카드, 점수 합 출력 + [ ] 최종 승패 출력 + [ ] 딜러의 경우 몇승 몇패인지 출력 diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 814c6c89cca..0e47949f44f 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -27,6 +27,7 @@ public void run() { game.drawFirst(players, dealer); outputView.printFirstCards(dealer, players.getPlayers()); playPlayers(game); + playDealer(game); } private Game createGame() { @@ -51,5 +52,15 @@ private void playPlayer(Player player, Game game) { game.draw(player); outputView.printCards(player); } + if (player.canDrawCard()) { + player.stay(); + } + } + + private void playDealer(Game game) { + if (dealer.canDrawCard()) { + outputView.printDealerHit(); + game.draw(dealer); + } } } diff --git a/src/main/java/domain/card/Hands.java b/src/main/java/domain/card/Hands.java index 298616cf86c..543c00bb4d3 100644 --- a/src/main/java/domain/card/Hands.java +++ b/src/main/java/domain/card/Hands.java @@ -10,7 +10,7 @@ public class Hands { public static final int TEN = 10; public static final int ELEVEN = 11; public static final int BLACKJACK = 21; - public static final int DEALER_BUST_NUMBER = 16; + public static final int DEALER_BUST_NUMBER = 17; private final List cards; diff --git a/src/main/java/domain/user/Participant.java b/src/main/java/domain/user/Participant.java index 6a21a3d1dd9..3475663cc5a 100644 --- a/src/main/java/domain/user/Participant.java +++ b/src/main/java/domain/user/Participant.java @@ -9,7 +9,6 @@ public abstract class Participant { - // protected final Hands hands; protected State state; public void draw(final Card card) { @@ -20,6 +19,10 @@ public void drawFirst(Card firstCard, Card secondCard) { state = StateFactory.drawFirst(firstCard, secondCard); } + public void stay() { + state = state.stay(); + } + public abstract boolean canDrawCard(); public List getHands() { diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 407c548ccaf..feca7115f54 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -29,4 +29,8 @@ public void printCards(Player player) { .collect(Collectors.joining(", ")); System.out.println(player.getName() + " : " + cards); } + + public void printDealerHit() { + System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); + } } diff --git a/src/test/java/domain/card/HandsTest.java b/src/test/java/domain/card/HandsTest.java index f674866970a..49df47d7f81 100644 --- a/src/test/java/domain/card/HandsTest.java +++ b/src/test/java/domain/card/HandsTest.java @@ -78,7 +78,7 @@ void isBlackjack() { } @ParameterizedTest - @CsvSource(value = {"SIX, true", "FIVE, false"}) + @CsvSource(value = {"SEVEN, true", "SIX, false"}) @DisplayName("딜러 버스트 확인") void isDealerBust(Symbol symbol, boolean expected) { hands.add(new Card(Symbol.JACK, Type.DIAMOND)); diff --git a/src/test/java/domain/user/DealerTest.java b/src/test/java/domain/user/DealerTest.java index 93511c37d09..68a2610e646 100644 --- a/src/test/java/domain/user/DealerTest.java +++ b/src/test/java/domain/user/DealerTest.java @@ -12,7 +12,7 @@ class DealerTest { @ParameterizedTest - @CsvSource(value = {"SIX, false", "FIVE,true"}) + @CsvSource(value = {"SEVEN, false", "SIX,true"}) @DisplayName("카드를 더 받을 수 있는지 확인") void canReceiveCard(Symbol symbol, boolean expected) { Dealer dealer = new Dealer(); From 457056c4802e237d6bcf9b8c81cf870253f0e7b1 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Thu, 2 Jul 2020 03:45:42 +0900 Subject: [PATCH 12/13] =?UTF-8?q?feat:=20=EB=94=9C=EB=9F=AC=EC=99=80=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EC=9D=98=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C,=20=EC=A0=90=EC=88=98=ED=95=A9=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/controller/Controller.java | 1 + src/main/java/domain/user/Participant.java | 8 +++----- src/main/java/view/OutputView.java | 24 ++++++++++++++++++++-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 00f442bc7d9..bf43057114e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ + [x] y 입력한 경우 무작위의 카드 장한 더 지 + [x] 카드를 받은 플레이어의 모든 카드 출력 + [x] 딜러의 경우 16 이하인 경우 카드 한 장 더 지급 - + [ ] 딜러와 플레이어의 카드, 점수 합 출력 + + [x] 딜러와 플레이어의 카드, 점수 합 출력 + [ ] 최종 승패 출력 + [ ] 딜러의 경우 몇승 몇패인지 출력 + [ ] 플레이어의 경우 승/패 여부만 출력 diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 0e47949f44f..e66fb9cb90e 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -28,6 +28,7 @@ public void run() { outputView.printFirstCards(dealer, players.getPlayers()); playPlayers(game); playDealer(game); + outputView.printResultCards(dealer, players); } private Game createGame() { diff --git a/src/main/java/domain/user/Participant.java b/src/main/java/domain/user/Participant.java index 3475663cc5a..9ac932e8d58 100644 --- a/src/main/java/domain/user/Participant.java +++ b/src/main/java/domain/user/Participant.java @@ -1,12 +1,10 @@ package domain.user; import domain.card.Card; +import domain.card.Hands; import domain.state.State; import domain.state.StateFactory; -import java.util.Collections; -import java.util.List; - public abstract class Participant { protected State state; @@ -25,7 +23,7 @@ public void stay() { public abstract boolean canDrawCard(); - public List getHands() { - return Collections.unmodifiableList(state.hands().getCards()); + public Hands getHands() { + return state.hands(); } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index feca7115f54..fc11d7a396a 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -3,6 +3,7 @@ import domain.card.Card; import domain.user.Dealer; import domain.user.Player; +import domain.user.Players; import java.util.List; import java.util.stream.Collectors; @@ -14,23 +15,42 @@ public void printFirstCards(Dealer dealer, List players) { .map(Player::getName) .collect(Collectors.joining(", ")); System.out.println("딜러와 " + names + "에게 2장의 카드를 나누어주었습니다."); - System.out.println("딜러 : " + dealer.getHands().get(0).toString()); + System.out.println("딜러 : " + dealer.getHands().getCards().get(0).toString()); for (Player player : players) { String cards = player.getHands() + .getCards() .stream().map(Card::toString) .collect(Collectors.joining(", ")); System.out.println(player.getName() + " : " + cards); } + System.out.println(); } public void printCards(Player player) { String cards = player.getHands() + .getCards() .stream().map(Card::toString) .collect(Collectors.joining(", ")); System.out.println(player.getName() + " : " + cards); } public void printDealerHit() { - System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); + System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다.\n"); + } + + public void printResultCards(Dealer dealer, Players players) { + String dealerCards = dealer.getHands() + .getCards() + .stream().map(Card::toString) + .collect(Collectors.joining(", ")); + System.out.println("딜러 : " + dealerCards + " - 결과 : " + dealer.getHands().sum()); + for (Player player : players.getPlayers()) { + String cards = player.getHands() + .getCards() + .stream().map(Card::toString) + .collect(Collectors.joining(", ")); + System.out.println(player.getName() + " : " + cards + " - 결과 : " + player.getHands().sum()); + } + System.out.println(); } } From 79af801b0db94e3a7e98279febf497d2a22e54b1 Mon Sep 17 00:00:00 2001 From: YerinCho Date: Thu, 2 Jul 2020 05:03:34 +0900 Subject: [PATCH 13/13] =?UTF-8?q?feat:=20=EC=88=98=EC=9D=B5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 ++--- src/main/java/controller/Controller.java | 21 +++++-- src/main/java/domain/card/Hands.java | 8 +++ .../java/domain/{ => money}/BettingMoney.java | 10 ++-- src/main/java/domain/money/EarningMoney.java | 57 +++++++++++++++++++ src/main/java/domain/state/StateFactory.java | 8 +++ src/main/java/domain/user/Participant.java | 10 +++- src/main/java/domain/user/Player.java | 4 +- src/main/java/domain/user/PlayerFactory.java | 2 +- src/main/java/view/InputView.java | 3 +- src/main/java/view/OutputView.java | 14 +++++ src/main/java/{domain => view}/YesOrNo.java | 2 +- src/test/java/domain/GameTest.java | 6 +- src/test/java/domain/YesOrNoTest.java | 1 + src/test/java/domain/card/HandsTest.java | 18 ++++++ .../java/domain/money/EarningMoneyTest.java | 7 +++ .../java/domain/user/BettingMoneyTest.java | 6 +- src/test/java/domain/user/PlayerTest.java | 2 +- src/test/java/domain/user/PlayersTest.java | 4 +- 19 files changed, 163 insertions(+), 35 deletions(-) rename src/main/java/domain/{ => money}/BettingMoney.java (66%) create mode 100644 src/main/java/domain/money/EarningMoney.java rename src/main/java/{domain => view}/YesOrNo.java (97%) create mode 100644 src/test/java/domain/money/EarningMoneyTest.java diff --git a/README.md b/README.md index bf43057114e..8556219d51a 100644 --- a/README.md +++ b/README.md @@ -18,20 +18,17 @@ + [x] 카드를 받은 플레이어의 모든 카드 출력 + [x] 딜러의 경우 16 이하인 경우 카드 한 장 더 지급 + [x] 딜러와 플레이어의 카드, 점수 합 출력 - + [ ] 최종 승패 출력 - + [ ] 딜러의 경우 몇승 몇패인지 출력 - + [ ] 플레이어의 경우 승/패 여부만 출력 + [x] 카드 계산 구현 + [x] 카드의 숫자 계산은 카드 숫자를 기본으로 함. + [x] 예외로 Ace는 1 또는 11로 계산 가능 + [x] ace 제외 카드 합 <= 10 인 경우 ace 는 11로 계산 + [x] King, Queen, Jack은 각각 10 - + [ ] 수익 금액 구현 - + [ ] 플레이어의 카드 합만 21 인 경우(블랙잭) 수익은 배팅금액 * 1.5 - + [ ] 딜러와 플레이어 모두 블랙잭인 경우 수익은 배팅금액 * 1 - + [ ] 합이 21 초과, 지는 경우면 수익은 배팅금액 * -1 - + [ ] 21 이하이면서 21에 가까운 경우 수익은 배팅금액 * 1 - + [ ] 플레이어와 딜러 무승부인 경우(모두 21 초과, 동점)인 경우 수익은 0 + + [x] 수익 금액 구현 + + [x] 플레이어의 카드 합만 21 인 경우(블랙잭) 수익은 배팅금액 * 1.5 + + [x] 딜러와 플레이어 모두 블랙잭인 경우 수익은 배팅금액 * 1 + + [x] 합이 21 초과, 지는 경우면 수익은 배팅금액 * -1 + + [x] 21 이하이면서 21에 가까운 경우 수익은 배팅금액 * 1 + + [x] 플레이어와 딜러 무승부인 경우(모두 21 초과, 동점)인 경우 수익은 0 ## 우아한테크코스 코드리뷰 diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index e66fb9cb90e..01d0ced29c4 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -2,6 +2,7 @@ import domain.Game; import domain.card.Deck; +import domain.money.EarningMoney; import domain.user.*; import view.InputView; import view.OutputView; @@ -24,11 +25,8 @@ public Controller(final InputView inputView, final OutputView outputView) { public void run() { Game game = createGame(); - game.drawFirst(players, dealer); - outputView.printFirstCards(dealer, players.getPlayers()); - playPlayers(game); - playDealer(game); - outputView.printResultCards(dealer, players); + play(game); + calculateResult(); } private Game createGame() { @@ -42,6 +40,13 @@ private Game createGame() { return new Game(new Deck()); } + private void play(Game game) { + game.drawFirst(players, dealer); + outputView.printFirstCards(dealer, players.getPlayers()); + playPlayers(game); + playDealer(game); + } + private void playPlayers(Game game) { for (Player player : players.getPlayers()) { playPlayer(player, game); @@ -64,4 +69,10 @@ private void playDealer(Game game) { game.draw(dealer); } } + + private void calculateResult() { + EarningMoney earningMoney = new EarningMoney(); + outputView.printResultCards(dealer, players); + outputView.printEarningMoney(EarningMoney.calculateMoney(dealer, players)); + } } diff --git a/src/main/java/domain/card/Hands.java b/src/main/java/domain/card/Hands.java index 543c00bb4d3..ba4ad592bdd 100644 --- a/src/main/java/domain/card/Hands.java +++ b/src/main/java/domain/card/Hands.java @@ -60,4 +60,12 @@ public boolean isBlackjack() { public boolean isDealerBust() { return sum() >= DEALER_BUST_NUMBER; } + + public boolean isBiggerThan(Hands hands) { + return sum() > hands.sum(); + } + + public boolean isSame(Hands hands) { + return sum() == hands.sum(); + } } diff --git a/src/main/java/domain/BettingMoney.java b/src/main/java/domain/money/BettingMoney.java similarity index 66% rename from src/main/java/domain/BettingMoney.java rename to src/main/java/domain/money/BettingMoney.java index 0cd7974a79c..e9b8f743e16 100644 --- a/src/main/java/domain/BettingMoney.java +++ b/src/main/java/domain/money/BettingMoney.java @@ -1,23 +1,23 @@ -package domain; +package domain.money; public class BettingMoney { public static final int MIN_BETTING_MONEY = 1; - private final double bettingMoney; + private final int bettingMoney; - public BettingMoney(final double bettingMoney) { + public BettingMoney(final int bettingMoney) { validate(bettingMoney); this.bettingMoney = bettingMoney; } - private void validate(final double bettingMoney) { + private void validate(final int bettingMoney) { if (bettingMoney < MIN_BETTING_MONEY) { throw new IllegalArgumentException("배팅금액은 1원 이상이어야 합니다. 입력금액 : " + bettingMoney); } } - public double getBettingMoney() { + public int getBettingMoney() { return bettingMoney; } } diff --git a/src/main/java/domain/money/EarningMoney.java b/src/main/java/domain/money/EarningMoney.java new file mode 100644 index 00000000000..5799a5e48d8 --- /dev/null +++ b/src/main/java/domain/money/EarningMoney.java @@ -0,0 +1,57 @@ +package domain.money; + +import domain.card.Hands; +import domain.user.Dealer; +import domain.user.Player; +import domain.user.Players; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class EarningMoney { + + public static Map calculateMoney(Dealer dealer, Players players) { + Map earningMonies = new LinkedHashMap<>(); + for (Player player : players.getPlayers()) { + earningMonies.put(player.getName(), calculate(dealer, player)); + } + return earningMonies; + } + + private static double calculate(Dealer dealer, Player player) { + Hands dealerHands = dealer.getHands(); + Hands playerHands = player.getHands(); + if (playerHands.isBust()) { + calculateWhenBust(dealerHands, player); + return player.getState().profit(player.getBettingMoney()); + } + if (playerHands.isBlackjack()) { + calculateWhenBlackjack(dealerHands, player); + return player.getState().profit(player.getBettingMoney()); + } + calculateWhenStay(dealerHands, player); + return player.getState().profit(player.getBettingMoney()); + } + + private static void calculateWhenStay(Hands dealerHands, Player player) { + if (dealerHands.isBust() || player.getHands().isBiggerThan(dealerHands)) { + player.stay(); + } + if (dealerHands.isBiggerThan(player.getHands())) { + player.bust(); + } + } + + private static void calculateWhenBlackjack(Hands dealerHands, Player player) { + if (dealerHands.isBlackjack()) { + player.stay(); + } + } + + private static void calculateWhenBust(Hands dealerHands, Player player) { + if (dealerHands.isBust()) { + player.stay(); + } + } + +} diff --git a/src/main/java/domain/state/StateFactory.java b/src/main/java/domain/state/StateFactory.java index 5bddf72059f..e3ebddac42c 100644 --- a/src/main/java/domain/state/StateFactory.java +++ b/src/main/java/domain/state/StateFactory.java @@ -14,4 +14,12 @@ public static State drawFirst(Card firstCard, Card secondCard) { } return new Hit(hands); } + + public static State bust(State state) { + return new Bust(state.hands()); + } + + public static State stay(State state) { + return new Stay(state.hands()); + } } diff --git a/src/main/java/domain/user/Participant.java b/src/main/java/domain/user/Participant.java index 9ac932e8d58..4cca952f688 100644 --- a/src/main/java/domain/user/Participant.java +++ b/src/main/java/domain/user/Participant.java @@ -18,11 +18,19 @@ public void drawFirst(Card firstCard, Card secondCard) { } public void stay() { - state = state.stay(); + state = StateFactory.stay(state); + } + + public void bust() { + state = StateFactory.bust(state); } public abstract boolean canDrawCard(); + public State getState() { + return state; + } + public Hands getHands() { return state.hands(); } diff --git a/src/main/java/domain/user/Player.java b/src/main/java/domain/user/Player.java index bdfdda94ae0..9b3e712e0fe 100644 --- a/src/main/java/domain/user/Player.java +++ b/src/main/java/domain/user/Player.java @@ -1,6 +1,6 @@ package domain.user; -import domain.BettingMoney; +import domain.money.BettingMoney; import java.util.Objects; @@ -25,7 +25,7 @@ public String getName() { return name.getName(); } - public double getBettingMoney() { + public int getBettingMoney() { return bettingMoney.getBettingMoney(); } } \ No newline at end of file diff --git a/src/main/java/domain/user/PlayerFactory.java b/src/main/java/domain/user/PlayerFactory.java index f30bdca7336..9c3485dc846 100644 --- a/src/main/java/domain/user/PlayerFactory.java +++ b/src/main/java/domain/user/PlayerFactory.java @@ -1,6 +1,6 @@ package domain.user; -import domain.BettingMoney; +import domain.money.BettingMoney; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 2942d39bdfa..378f8e35b9c 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,12 +1,11 @@ package view; -import domain.YesOrNo; import domain.user.Name; import domain.user.Player; import java.util.*; -import static domain.YesOrNo.YES; +import static view.YesOrNo.YES; public class InputView { diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index fc11d7a396a..e311d566e54 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -6,6 +6,7 @@ import domain.user.Players; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class OutputView { @@ -53,4 +54,17 @@ public void printResultCards(Dealer dealer, Players players) { } System.out.println(); } + + public void printEarningMoney(Map earningMonies) { + int dealerEarningMoney = earningMonies.values() + .stream() + .mapToInt(Double::intValue) + .sum() * -1; + System.out.println("## 최종 수익"); + System.out.println("딜러 : " + dealerEarningMoney); + for (Map.Entry money : earningMonies.entrySet()) { + System.out.println(money.getKey() + " : " + money.getValue().intValue()); + } + + } } diff --git a/src/main/java/domain/YesOrNo.java b/src/main/java/view/YesOrNo.java similarity index 97% rename from src/main/java/domain/YesOrNo.java rename to src/main/java/view/YesOrNo.java index 4c41bbeadd1..323f72418c1 100644 --- a/src/main/java/domain/YesOrNo.java +++ b/src/main/java/view/YesOrNo.java @@ -1,4 +1,4 @@ -package domain; +package view; import java.util.Arrays; diff --git a/src/test/java/domain/GameTest.java b/src/test/java/domain/GameTest.java index ebbc26579aa..fcd1c8423fc 100644 --- a/src/test/java/domain/GameTest.java +++ b/src/test/java/domain/GameTest.java @@ -39,8 +39,8 @@ void setUp() { @DisplayName("게임 시작 시 참가자들에게 카드 두 장씩 부여") void firstDraw(int index) { game.drawFirst(players, dealer); - assertThat(dealer.getHands()).hasSize(2); - assertThat(players.getPlayers().get(index).getHands()).hasSize(2); + assertThat(dealer.getHands().getCards()).hasSize(2); + assertThat(players.getPlayers().get(index).getHands().getCards()).hasSize(2); } @ParameterizedTest @@ -49,7 +49,7 @@ void firstDraw(int index) { void draw(int index) { firstDraw(index); game.draw(players.getPlayers().get(index)); - assertThat(players.getPlayers().get(index).getHands()).hasSize(3); + assertThat(players.getPlayers().get(index).getHands().getCards()).hasSize(3); } diff --git a/src/test/java/domain/YesOrNoTest.java b/src/test/java/domain/YesOrNoTest.java index 00328dcbbd5..67ddc4a8698 100644 --- a/src/test/java/domain/YesOrNoTest.java +++ b/src/test/java/domain/YesOrNoTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import view.YesOrNo; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/src/test/java/domain/card/HandsTest.java b/src/test/java/domain/card/HandsTest.java index 49df47d7f81..be9372123ff 100644 --- a/src/test/java/domain/card/HandsTest.java +++ b/src/test/java/domain/card/HandsTest.java @@ -85,4 +85,22 @@ void isDealerBust(Symbol symbol, boolean expected) { hands.add(new Card(symbol, Type.DIAMOND)); assertThat(hands.isDealerBust()).isEqualTo(expected); } + + @Test + @DisplayName("합이 더 큰지 확인") + void isBiggerThan() { + hands.add(new Card(Symbol.JACK, Type.DIAMOND)); + Hands newHands = new Hands(); + newHands.add(new Card(Symbol.EIGHT, Type.DIAMOND)); + assertThat(newHands.isBiggerThan(hands)).isFalse(); + } + + @Test + @DisplayName("합이 같은지 확인") + void isSame() { + hands.add(new Card(Symbol.JACK, Type.DIAMOND)); + Hands newHands = new Hands(); + newHands.add(new Card(Symbol.JACK, Type.DIAMOND)); + assertThat(newHands.isSame(hands)).isTrue(); + } } \ No newline at end of file diff --git a/src/test/java/domain/money/EarningMoneyTest.java b/src/test/java/domain/money/EarningMoneyTest.java new file mode 100644 index 00000000000..a16b1d98abb --- /dev/null +++ b/src/test/java/domain/money/EarningMoneyTest.java @@ -0,0 +1,7 @@ +package domain.money; + +class EarningMoneyTest { + + //Todo 넘 빡쳐서 테스트를 안만듬... + +} \ No newline at end of file diff --git a/src/test/java/domain/user/BettingMoneyTest.java b/src/test/java/domain/user/BettingMoneyTest.java index 1974f0c8673..92cd71f4f12 100644 --- a/src/test/java/domain/user/BettingMoneyTest.java +++ b/src/test/java/domain/user/BettingMoneyTest.java @@ -1,6 +1,6 @@ package domain.user; -import domain.BettingMoney; +import domain.money.BettingMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -19,9 +19,9 @@ void create() { } @ParameterizedTest - @ValueSource(doubles = {0, -1}) + @ValueSource(ints = {0, -1}) @DisplayName("유효성 검사") - void validate(double input) { + void validate(int input) { assertThatThrownBy(() -> new BettingMoney(input)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("배팅금액은 1원 이상이어야 합니다. 입력금액 : " + input); diff --git a/src/test/java/domain/user/PlayerTest.java b/src/test/java/domain/user/PlayerTest.java index 1f492b138f2..008124f747a 100644 --- a/src/test/java/domain/user/PlayerTest.java +++ b/src/test/java/domain/user/PlayerTest.java @@ -1,9 +1,9 @@ package domain.user; -import domain.BettingMoney; import domain.card.Card; import domain.card.Symbol; import domain.card.Type; +import domain.money.BettingMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/domain/user/PlayersTest.java b/src/test/java/domain/user/PlayersTest.java index b813bf83f06..48bce972c5d 100644 --- a/src/test/java/domain/user/PlayersTest.java +++ b/src/test/java/domain/user/PlayersTest.java @@ -1,9 +1,9 @@ package domain.user; -import domain.BettingMoney; import domain.card.Card; import domain.card.Symbol; import domain.card.Type; +import domain.money.BettingMoney; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -59,7 +59,7 @@ void drawFirst(int index) { Arrays.asList(new Card(Symbol.ACE, Type.CLUB), new Card(Symbol.ACE, Type.DIAMOND), new Card(Symbol.ACE, Type.CLUB), new Card(Symbol.ACE, Type.CLUB))); players.firstDraw(cards); - assertThat(players.getPlayers().get(index).getHands()).hasSize(2); + assertThat(players.getPlayers().get(index).getHands().getCards()).hasSize(2); } @Test