From 870ad1a893dfbf69797c77ad32f12703f743e8aa Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 5 Mar 2024 15:17:22 +0900 Subject: [PATCH 01/62] =?UTF-8?q?docs=20:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=85?= =?UTF-8?q?=EC=84=B8=20=EB=B0=8F=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=84=A4?= =?UTF-8?q?=EA=B3=84=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 51 ++++++++++++++++++++++++++++++++++++++++++ src/main/java/.gitkeep | 0 src/test/java/.gitkeep | 0 3 files changed, 51 insertions(+) delete mode 100644 src/main/java/.gitkeep delete mode 100644 src/test/java/.gitkeep diff --git a/README.md b/README.md index 556099c4de..dab5baa8ff 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,54 @@ ## 우아한테크코스 코드리뷰 - [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) + +## 기능 요구 사항 + +- 블랙잭 게임은 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 숫자를 가지는 쪽이 이기는 게임이다. +- 각 카드는 점수를 가진다. + - 숫자 카드는 카드 숫자로 계산한다. + - King, Queen, Jack은 각각 10으로 계산한다. + - Ace는 1 또는 11로 계산한다. + +### 플레이어 승리 조건 + +- 아래의 두 조건을 모두 만족하면 플레이어가 승리한다. + - 카드의 점수 합이 21을 넘기지 않는다. + - 딜러보다 점수가 높거나 딜러의 카드 점수 합이 21을 초과한다. + +### 프로그램 진행 순서 +1. 참가자 이름 입력한다. +2. 카드를 2장씩 나눠준 후에, 현재 카드 상태 출력한다. +3. 각 참가자들의 턴을 진행한다. + 1. 카드가 21을 넘은 경우, 턴이 종료된다. + 2. 카드를 더 받을 지 여부를 입력한다. + 3. 만약 더 받는다면, 카드를 한 장 추가하고 1으로 돌아간다. + 4. 더 받지 않을 경우, 턴을 종료한다. +4. 딜러의 턴을 진행한다. + 1. 카드가 16을 넘은 경우, 턴이 종료된다. + 2. 카드를 한 장 더 추가하고, 1로 돌아간다. +5. 딜러 및 모든 참가자의 보유 카드들과 점수를 출력한다. +6. 딜러 및 모든 참가자의 승패를 출력한다. + +#### Card + +- 문양과 숫자를 가진다. +- 점수를 반환할 수 있어야 한다. + - 숫자 카드는 숫자 그대로 점수로 사용한다. + - King, Queen, Jack은 모두 10점으로 사용한다. + - Ace는 1, 또는 11 점으로 사용할 수 있다. + +#### Deck + +- 카드 한장을 제공할 수 있다. + +#### Dealer + +- 카드 합이 16 이하일 때 카드를 뽑는다. +- 보유 중인 카드 정보와 점수를 반환할 수 있다. + +#### Player + +- 카드 합이 21 이하일 떄 카드를 뽑을 수 있다. +- 보유 중인 카드 정보와 점수를 반환할 수 있다. +- 카드를 더 뽑을 수 있는지 알 수 있다. diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 From a0a12354f8bafd81686449bdbfb305be5f71cfa5 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 5 Mar 2024 16:12:51 +0900 Subject: [PATCH 02/62] =?UTF-8?q?feat=20(Card)=20:=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=A0=90=EC=88=98=EB=A5=BC=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=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 --- src/main/java/blackjack/domain/Card.java | 55 ++++++++++++++++++++ src/test/java/blackjack/domain/CardTest.java | 55 ++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/main/java/blackjack/domain/Card.java create mode 100644 src/test/java/blackjack/domain/CardTest.java diff --git a/src/main/java/blackjack/domain/Card.java b/src/main/java/blackjack/domain/Card.java new file mode 100644 index 0000000000..4aeba8f518 --- /dev/null +++ b/src/main/java/blackjack/domain/Card.java @@ -0,0 +1,55 @@ +package blackjack.domain; + +public class Card { + private final Value value; + + public Card(Value value, Shape shape) { + this.value = value; + } + + public int getMinScore() { + return value.getMinScore(); + } + + public int getMaxScore() { + return value.getMaxScore(); + } + + // TODO 외부 class로 분리 할 것인지 논의 + enum Value { + 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 minScore; + + Value(int minScore) { + this.minScore = minScore; + } + + public int getMinScore() { + return minScore; + } + + public int getMaxScore() { + if (this == ACE) { + return minScore + 10; + } + return minScore; + } + } + + enum Shape { + SPADE, DIAMOND, HEART, CLOVER; + } +} diff --git a/src/test/java/blackjack/domain/CardTest.java b/src/test/java/blackjack/domain/CardTest.java new file mode 100644 index 0000000000..16eafb0958 --- /dev/null +++ b/src/test/java/blackjack/domain/CardTest.java @@ -0,0 +1,55 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +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.EnumSource; + +public class CardTest { + + @DisplayName("카드 값에 따라 점수를 확인할 수 있다") + @Nested + class CardScoreTest { + + @DisplayName("숫자 카드는 카드의 숫자 값을 점수로 가진다") + @ParameterizedTest + @CsvSource({"TWO, 2", "TEN, 10"}) + void scoreTest_whenNumberCard(Card.Value value, int expected) { + Card card = new Card(value, Card.Shape.CLOVER); + + assertAll( + () -> assertThat(card.getMinScore()).isEqualTo(expected), + () -> assertThat(card.getMaxScore()).isEqualTo(expected) + ); + } + + @DisplayName("Jack, Queen, King 카드는 모두 10점을 가진다.") + @ParameterizedTest + @EnumSource(names = {"JACK", "QUEEN", "KING"}) + void scoreTest_whenJQK_Card(Card.Value value) { + Card card = new Card(value, Card.Shape.HEART); + + assertAll( + () -> assertThat(card.getMinScore()).isEqualTo(10), + () -> assertThat(card.getMaxScore()).isEqualTo(10) + ); + } + + @DisplayName("Ace 카드는 1, 또는 11점을 가진다.") + @Test + void scoreTest_whenAceCard() { + Card card = new Card(Card.Value.ACE, Card.Shape.HEART); + + assertAll( + () -> assertThat(card.getMinScore()).isEqualTo(1), + () -> assertThat(card.getMaxScore()).isEqualTo(11) + ); + } + } + +} From 2b505f121de7843cd1b743b068f51262e04425c3 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 5 Mar 2024 17:08:48 +0900 Subject: [PATCH 03/62] =?UTF-8?q?feat=20(Deck)=20:=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=ED=95=9C=20=EC=9E=A5=20=EB=BD=91=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=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/blackjack/domain/Deck.java | 32 +++++++++++++++++ src/test/java/blackjack/domain/DeckTest.java | 36 ++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/main/java/blackjack/domain/Deck.java create mode 100644 src/test/java/blackjack/domain/DeckTest.java diff --git a/src/main/java/blackjack/domain/Deck.java b/src/main/java/blackjack/domain/Deck.java new file mode 100644 index 0000000000..b50b9bd49e --- /dev/null +++ b/src/main/java/blackjack/domain/Deck.java @@ -0,0 +1,32 @@ +package blackjack.domain; + +import blackjack.domain.Card.Shape; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class Deck { + + private final Queue cards; + + public Deck() { + cards = new LinkedList<>(Arrays.stream(Shape.values()) + .map(this::makeCards) + .flatMap(List::stream) + .toList()); + } + + private List makeCards(Shape shape) { + return Arrays.stream(Card.Value.values()) + .map(value -> new Card(value, shape)) + .toList(); + } + + public Card draw() { + if (cards.isEmpty()) { + throw new IllegalStateException("카드를 더 이상 뽑을 수 없습니다."); + } + return cards.poll(); + } +} diff --git a/src/test/java/blackjack/domain/DeckTest.java b/src/test/java/blackjack/domain/DeckTest.java new file mode 100644 index 0000000000..15e6706b68 --- /dev/null +++ b/src/test/java/blackjack/domain/DeckTest.java @@ -0,0 +1,36 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class DeckTest { + + @DisplayName("카드 한 장을 뽑을 수 있다") + @Test + void drawTest() { + Deck deck = new Deck(); + + assertThat(deck.draw()).isNotNull(); + } + + // TODO 테스트 네이밍 고민 + @DisplayName("카드는 최대 52장만 뽑을 수 있다.") + @Test + void drawTest_whenDraw53Times_throwException() { + Deck deck = new Deck(); + drawRepeat(deck, 52); + + assertThatThrownBy(() -> deck.draw()) + .isInstanceOf(IllegalStateException.class) + .hasMessage("카드를 더 이상 뽑을 수 없습니다."); + } + + private void drawRepeat(Deck deck, int times) { + for (int i = 0; i < times; i++) { + deck.draw(); + } + } +} From f774cc76dc26bf7bd99ebffe12b7e49207f990a5 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 5 Mar 2024 17:51:16 +0900 Subject: [PATCH 04/62] =?UTF-8?q?feat=20(Dealer)=20:=20=EB=94=9C=EB=9F=AC?= =?UTF-8?q?=EC=9D=98=20=EC=A0=90=EC=88=98=20=EA=B3=84=EC=82=B0=20=EB=B0=8F?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EB=BD=91=EC=9D=84=20=EC=88=98?= =?UTF-8?q?=20=EC=9E=88=EB=8A=94=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=9C=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/blackjack/domain/Dealer.java | 34 +++++++++ .../java/blackjack/domain/DealerTest.java | 70 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/main/java/blackjack/domain/Dealer.java create mode 100644 src/test/java/blackjack/domain/DealerTest.java diff --git a/src/main/java/blackjack/domain/Dealer.java b/src/main/java/blackjack/domain/Dealer.java new file mode 100644 index 0000000000..d36aaa7bf2 --- /dev/null +++ b/src/main/java/blackjack/domain/Dealer.java @@ -0,0 +1,34 @@ +package blackjack.domain; + +import java.util.List; + +public class Dealer { + + private static final int DRAWABLE_MAX_SCORE = 16; + private static final int BLACKJACK_SCORE = 21; + + private final List cards; + + public Dealer(List cards) { + this.cards = cards; + } + + public boolean isDrawable() { + return calculateScore() <= DRAWABLE_MAX_SCORE; + } + + public int calculateScore() { + int score = cards.stream() + .mapToInt(Card::getMaxScore) + .sum(); + + //TODO 인덴트 해결하기 + for (Card card : cards) { + if (score <= BLACKJACK_SCORE) { + return score; + } + score = score + card.getMinScore() - card.getMaxScore(); + } + return score; + } +} diff --git a/src/test/java/blackjack/domain/DealerTest.java b/src/test/java/blackjack/domain/DealerTest.java new file mode 100644 index 0000000000..ceac8f507b --- /dev/null +++ b/src/test/java/blackjack/domain/DealerTest.java @@ -0,0 +1,70 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.Card.Shape; +import blackjack.domain.Card.Value; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class DealerTest { + + @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 더 뽑을 수 있다") + @Test + void isDrawableTest_whenScoreIsUnder16_returnTrue() { + List CardsScore16 = List.of(new Card(Value.JACK, Shape.HEART), new Card(Value.SIX, Shape.HEART)); + Dealer dealer = new Dealer(CardsScore16); + + assertThat(dealer.isDrawable()).isTrue(); + } + + @DisplayName("카드의 총 점수가 17을 넘으면, 카드를 더 뽑을 수 없다") + @Test + void isDrawableTest_whenScoreIsOver17_returnFalse() { + List CardsScore17 = List.of(new Card(Value.JACK, Shape.HEART), new Card(Value.SEVEN, Shape.HEART)); + Dealer dealer = new Dealer(CardsScore17); + + assertThat(dealer.isDrawable()).isFalse(); + } + + @DisplayName("점수를 계산할 수 있다.") + @ParameterizedTest + @MethodSource("provideCardsAndScore") + void calculateScoreTest(List cards, int expected) { + Dealer dealer = new Dealer(cards); + + assertThat(dealer.calculateScore()).isEqualTo(expected); + } + + // TODO Fixture로 추출하기 + static Stream provideCardsAndScore() { + return Stream.of( + Arguments.of( + List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART) + ), 21), + Arguments.of( + List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.ACE, Shape.SPADE) + ), 12), + Arguments.of( + List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ), 13), + Arguments.of( + List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ), 12) + ); + } +} From 3e83ed236c59c241bbaab1432645cba88d8c0baf Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Tue, 5 Mar 2024 17:52:22 +0900 Subject: [PATCH 05/62] =?UTF-8?q?style=20:=20=EA=B0=80=EB=8F=85=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=B4=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=83=81=EB=8B=A8=EC=97=90=20=EA=B0=9C=ED=96=89=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=95=84=EB=9E=98?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EA=B0=9C=ED=96=89=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/Card.java | 1 + src/test/java/blackjack/domain/CardTest.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/Card.java b/src/main/java/blackjack/domain/Card.java index 4aeba8f518..f7adeb2cc3 100644 --- a/src/main/java/blackjack/domain/Card.java +++ b/src/main/java/blackjack/domain/Card.java @@ -1,6 +1,7 @@ package blackjack.domain; public class Card { + private final Value value; public Card(Value value, Shape shape) { diff --git a/src/test/java/blackjack/domain/CardTest.java b/src/test/java/blackjack/domain/CardTest.java index 16eafb0958..5f410c02bf 100644 --- a/src/test/java/blackjack/domain/CardTest.java +++ b/src/test/java/blackjack/domain/CardTest.java @@ -51,5 +51,4 @@ void scoreTest_whenAceCard() { ); } } - } From 99baedbdf014a7d14ccb824570905f727aafd0c2 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 14:41:14 +0900 Subject: [PATCH 06/62] =?UTF-8?q?feat=20(Dealer)=20:=20=EB=94=9C=EB=9F=AC?= =?UTF-8?q?=20=ED=84=B4=20=EC=A7=84=ED=96=89=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/blackjack/domain/Card.java | 21 +++++++++ src/main/java/blackjack/domain/Dealer.java | 13 +++++- src/main/java/blackjack/domain/Deck.java | 19 ++++++-- .../java/blackjack/domain/DealerTest.java | 46 +++++++++++++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/domain/Card.java b/src/main/java/blackjack/domain/Card.java index f7adeb2cc3..398a3210b9 100644 --- a/src/main/java/blackjack/domain/Card.java +++ b/src/main/java/blackjack/domain/Card.java @@ -1,11 +1,15 @@ package blackjack.domain; +import java.util.Objects; + public class Card { private final Value value; + private final Shape shape; public Card(Value value, Shape shape) { this.value = value; + this.shape = shape; } public int getMinScore() { @@ -16,6 +20,23 @@ public int getMaxScore() { return value.getMaxScore(); } + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + Card card = (Card) object; + return value == card.value && shape == card.shape; + } + + @Override + public int hashCode() { + return Objects.hash(value, shape); + } + // TODO 외부 class로 분리 할 것인지 논의 enum Value { ACE(1), diff --git a/src/main/java/blackjack/domain/Dealer.java b/src/main/java/blackjack/domain/Dealer.java index d36aaa7bf2..62a46ef95a 100644 --- a/src/main/java/blackjack/domain/Dealer.java +++ b/src/main/java/blackjack/domain/Dealer.java @@ -1,5 +1,6 @@ package blackjack.domain; +import java.util.ArrayList; import java.util.List; public class Dealer { @@ -10,7 +11,7 @@ public class Dealer { private final List cards; public Dealer(List cards) { - this.cards = cards; + this.cards = new ArrayList<>(cards); } public boolean isDrawable() { @@ -31,4 +32,14 @@ public int calculateScore() { } return score; } + + public void playTurn(Deck deck) { + while (isDrawable()) { + cards.add(deck.draw()); + } + } + + List getCards() { + return cards; + } } diff --git a/src/main/java/blackjack/domain/Deck.java b/src/main/java/blackjack/domain/Deck.java index b50b9bd49e..5573044c77 100644 --- a/src/main/java/blackjack/domain/Deck.java +++ b/src/main/java/blackjack/domain/Deck.java @@ -11,13 +11,26 @@ public class Deck { private final Queue cards; public Deck() { - cards = new LinkedList<>(Arrays.stream(Shape.values()) - .map(this::makeCards) + this.cards = new LinkedList<>(Arrays.stream(Shape.values()) + .map(Deck::makeCards) .flatMap(List::stream) .toList()); } - private List makeCards(Shape shape) { + Deck(List cards) { + this.cards = new LinkedList<>(cards); + } + + public static Deck createOrderedDeck() { + List cards = Arrays.stream(Shape.values()) + .map(Deck::makeCards) + .flatMap(List::stream) + .toList(); + + return new Deck(cards); + } + + private static List makeCards(Shape shape) { return Arrays.stream(Card.Value.values()) .map(value -> new Card(value, shape)) .toList(); diff --git a/src/test/java/blackjack/domain/DealerTest.java b/src/test/java/blackjack/domain/DealerTest.java index ceac8f507b..1379a16a0b 100644 --- a/src/test/java/blackjack/domain/DealerTest.java +++ b/src/test/java/blackjack/domain/DealerTest.java @@ -14,6 +14,7 @@ class DealerTest { + //TODO DisplayName 수정 @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnder16_returnTrue() { @@ -23,6 +24,7 @@ void isDrawableTest_whenScoreIsUnder16_returnTrue() { assertThat(dealer.isDrawable()).isTrue(); } + //TODO DisplayName 수정 @DisplayName("카드의 총 점수가 17을 넘으면, 카드를 더 뽑을 수 없다") @Test void isDrawableTest_whenScoreIsOver17_returnFalse() { @@ -67,4 +69,48 @@ static Stream provideCardsAndScore() { ), 12) ); } + + @DisplayName("카드의 총 점수가 16 이하인 동안, 카드를 반복해서 뽑을 수 있다") + @Test + void drawTest_whenCardScoreIsUnder16() { + Dealer dealer = new Dealer(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.FIVE, Shape.HEART) + )); + Deck deck = new Deck(List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.ACE, Shape.SPADE), + new Card(Value.ACE, Shape.DIAMOND) + )); + + dealer.playTurn(deck); + + assertThat(dealer.getCards()).containsExactly( + new Card(Value.KING, Shape.HEART), + new Card(Value.FIVE, Shape.HEART), + new Card(Value.ACE, Shape.HEART), + new Card(Value.ACE, Shape.SPADE) + ); + } + + @DisplayName("카드의 총 점수가 16 초과일 때, 카드를 더 이상 뽑지 않는다") + @Test + void drawTest_cardScoreIsOver16() { + Dealer dealer = new Dealer(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + )); + Deck deck = new Deck(List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.ACE, Shape.SPADE), + new Card(Value.ACE, Shape.DIAMOND) + )); + + dealer.playTurn(deck); + + assertThat(dealer.getCards()).containsExactly( + new Card(Value.KING, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + ); + } } From de19b03dbd0301b662627ba885e6cef2907e5660 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 14:51:45 +0900 Subject: [PATCH 07/62] =?UTF-8?q?feat=20(Player)=20:=20=EC=A0=90=EC=88=98?= =?UTF-8?q?=20=EA=B3=84=EC=82=B0=20=EA=B8=B0=EB=8A=A5=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/blackjack/domain/Player.java | 30 +++++++++++++++++ .../java/blackjack/domain/PlayerTest.java | 33 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/blackjack/domain/Player.java create mode 100644 src/test/java/blackjack/domain/PlayerTest.java diff --git a/src/main/java/blackjack/domain/Player.java b/src/main/java/blackjack/domain/Player.java new file mode 100644 index 0000000000..acca84afdd --- /dev/null +++ b/src/main/java/blackjack/domain/Player.java @@ -0,0 +1,30 @@ +package blackjack.domain; + +import java.util.ArrayList; +import java.util.List; + +public class Player { + + private static final int BLACKJACK_SCORE = 21; + + private final List cards; + + public Player(List cards) { + this.cards = new ArrayList<>(cards); + } + + public int calculateScore() { + int score = cards.stream() + .mapToInt(Card::getMaxScore) + .sum(); + + //TODO 인덴트 해결하기 + for (Card card : cards) { + if (score <= BLACKJACK_SCORE) { + return score; + } + score = score + card.getMinScore() - card.getMaxScore(); + } + return score; + } +} diff --git a/src/test/java/blackjack/domain/PlayerTest.java b/src/test/java/blackjack/domain/PlayerTest.java new file mode 100644 index 0000000000..5a371f7642 --- /dev/null +++ b/src/test/java/blackjack/domain/PlayerTest.java @@ -0,0 +1,33 @@ +package blackjack.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.domain.Card.Shape; +import blackjack.domain.Card.Value; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class PlayerTest { + + @DisplayName("점수를 계산할 수 있다.") + @ParameterizedTest + @MethodSource("provideCardsAndScore") + void calculateScoreTest(List cards, int expected) { + Player player = new Player(cards); + + assertThat(player.calculateScore()).isEqualTo(expected); + } + + // TODO Fixture로 추출하기 + static Stream provideCardsAndScore() { + return Stream.of(Arguments.of(List.of(new Card(Value.ACE, Shape.HEART), new Card(Value.KING, Shape.HEART)), 21), + Arguments.of(List.of(new Card(Value.ACE, Shape.HEART), new Card(Value.ACE, Shape.SPADE)), 12), + Arguments.of(List.of(new Card(Value.ACE, Shape.HEART), new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART)), 13), + Arguments.of(List.of(new Card(Value.KING, Shape.HEART), new Card(Value.TWO, Shape.HEART)), 12)); + } +} From 1da0e5741211342c95f3ecf0367e8817c3122601 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 15:04:34 +0900 Subject: [PATCH 08/62] =?UTF-8?q?feat=20(Player)=20:=20=EB=94=9C=EB=9F=AC?= =?UTF-8?q?=EC=9D=98=20=EC=A0=90=EC=88=98=20=EA=B3=84=EC=82=B0=20=EB=B0=8F?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EB=BD=91=EC=9D=84=20=EC=88=98?= =?UTF-8?q?=20=EC=9E=88=EB=8A=94=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=9C=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 Co-authored-by : zangsu --- src/main/java/blackjack/domain/Player.java | 4 +++ .../java/blackjack/domain/PlayerTest.java | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/main/java/blackjack/domain/Player.java b/src/main/java/blackjack/domain/Player.java index acca84afdd..f34dfb137b 100644 --- a/src/main/java/blackjack/domain/Player.java +++ b/src/main/java/blackjack/domain/Player.java @@ -13,6 +13,10 @@ public Player(List cards) { this.cards = new ArrayList<>(cards); } + public boolean isDrawable() { + return calculateScore() <= BLACKJACK_SCORE; + } + public int calculateScore() { int score = cards.stream() .mapToInt(Card::getMaxScore) diff --git a/src/test/java/blackjack/domain/PlayerTest.java b/src/test/java/blackjack/domain/PlayerTest.java index 5a371f7642..a4bf1f2dfd 100644 --- a/src/test/java/blackjack/domain/PlayerTest.java +++ b/src/test/java/blackjack/domain/PlayerTest.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -30,4 +31,32 @@ static Stream provideCardsAndScore() { new Card(Value.TWO, Shape.HEART)), 13), Arguments.of(List.of(new Card(Value.KING, Shape.HEART), new Card(Value.TWO, Shape.HEART)), 12)); } + + //TODO DisplayName 수정 + @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 더 뽑을 수 있다") + @Test + void isDrawableTest_whenScoreIsUnder21_returnTrue() { + List CardsScore21 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.EIGHT, Shape.HEART), + new Card(Value.THREE, Shape.HEART) + ); + Player player = new Player(CardsScore21); + + assertThat(player.isDrawable()).isTrue(); + } + + //TODO DisplayName 수정 + @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 더 뽑을 수 없다") + @Test + void isDrawableTest_whenScoreIsOver21_returnFalse() { + List CardsScore22 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART), + new Card(Value.FIVE, Shape.HEART) + ); + Player player = new Player(CardsScore22); + + assertThat(player.isDrawable()).isFalse(); + } } From ed6c932b0fea6f5fe47fe819a4c093080bd7499e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 15:31:48 +0900 Subject: [PATCH 09/62] =?UTF-8?q?feat=20(Player)=20:=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=ED=95=9C=20=EC=9E=A5=20=EC=B6=94=EA=B0=80=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/Player.java | 12 ++++++ .../java/blackjack/domain/PlayerTest.java | 37 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/Player.java b/src/main/java/blackjack/domain/Player.java index f34dfb137b..62c9613519 100644 --- a/src/main/java/blackjack/domain/Player.java +++ b/src/main/java/blackjack/domain/Player.java @@ -1,6 +1,7 @@ package blackjack.domain; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Player { @@ -31,4 +32,15 @@ public int calculateScore() { } return score; } + + public List getCards() { + return Collections.unmodifiableList(cards); + } + + public void add(Card card) { + if (!isDrawable()) { + throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); + } + cards.add(card); + } } diff --git a/src/test/java/blackjack/domain/PlayerTest.java b/src/test/java/blackjack/domain/PlayerTest.java index a4bf1f2dfd..df31a09101 100644 --- a/src/test/java/blackjack/domain/PlayerTest.java +++ b/src/test/java/blackjack/domain/PlayerTest.java @@ -1,6 +1,7 @@ package blackjack.domain; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import blackjack.domain.Card.Shape; import blackjack.domain.Card.Value; @@ -40,7 +41,7 @@ void isDrawableTest_whenScoreIsUnder21_returnTrue() { new Card(Value.JACK, Shape.HEART), new Card(Value.EIGHT, Shape.HEART), new Card(Value.THREE, Shape.HEART) - ); + ); Player player = new Player(CardsScore21); assertThat(player.isDrawable()).isTrue(); @@ -59,4 +60,38 @@ void isDrawableTest_whenScoreIsOver21_returnFalse() { assertThat(player.isDrawable()).isFalse(); } + + @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 한 장 뽑을 수 있다") + @Test + void addTest_whenScoreIsUnder21() { + Player player = new Player(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.NINE, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + )); + + player.add(new Card(Value.ACE, Shape.HEART)); + + assertThat(player.getCards()).containsExactly( + new Card(Value.KING, Shape.HEART), + new Card(Value.NINE, Shape.HEART), + new Card(Value.TWO, Shape.HEART), + new Card(Value.ACE, Shape.HEART) + ); + } + + @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 뽑을 때 예외가 발생한다.") + @Test + void addTest_whenScoreIsOver21_throwException() { + Player player = new Player(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.NINE, Shape.HEART), + new Card(Value.THREE, Shape.HEART) + )); + Card card = new Card(Value.ACE, Shape.HEART); + + assertThatThrownBy(() -> player.add(card)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("더 이상 카드를 추가할 수 없습니다."); + } } From e11dee2769d14475a4ac764a703ce4b3965ed42e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 15:40:05 +0900 Subject: [PATCH 10/62] =?UTF-8?q?refactor=20(Dealer)=20:=20=EC=9A=94?= =?UTF-8?q?=EA=B5=AC=20=EC=82=AC=ED=95=AD=EC=9D=84=20=EB=B0=98=EC=98=81?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=B4=20=ED=84=B4=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20?= =?UTF-8?q?=ED=95=9C=20=EC=9E=A5=20=EC=B6=94=EA=B0=80=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/Dealer.java | 13 ++++--- .../java/blackjack/domain/DealerTest.java | 38 +++++++------------ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/main/java/blackjack/domain/Dealer.java b/src/main/java/blackjack/domain/Dealer.java index 62a46ef95a..6b973fa29d 100644 --- a/src/main/java/blackjack/domain/Dealer.java +++ b/src/main/java/blackjack/domain/Dealer.java @@ -33,13 +33,14 @@ public int calculateScore() { return score; } - public void playTurn(Deck deck) { - while (isDrawable()) { - cards.add(deck.draw()); - } - } - List getCards() { return cards; } + + public void add(Card card) { + if (!isDrawable()) { + throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); + } + cards.add(card); + } } diff --git a/src/test/java/blackjack/domain/DealerTest.java b/src/test/java/blackjack/domain/DealerTest.java index 1379a16a0b..61fdb45f2f 100644 --- a/src/test/java/blackjack/domain/DealerTest.java +++ b/src/test/java/blackjack/domain/DealerTest.java @@ -1,6 +1,7 @@ package blackjack.domain; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import blackjack.domain.Card.Shape; import blackjack.domain.Card.Value; @@ -70,47 +71,34 @@ static Stream provideCardsAndScore() { ); } - @DisplayName("카드의 총 점수가 16 이하인 동안, 카드를 반복해서 뽑을 수 있다") + @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 한 장 뽑을 수 있다") @Test - void drawTest_whenCardScoreIsUnder16() { + void addTest_whenScoreIsUnder16() { Dealer dealer = new Dealer(List.of( new Card(Value.KING, Shape.HEART), - new Card(Value.FIVE, Shape.HEART) - )); - Deck deck = new Deck(List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.ACE, Shape.SPADE), - new Card(Value.ACE, Shape.DIAMOND) + new Card(Value.SIX, Shape.HEART) )); - dealer.playTurn(deck); + dealer.add(new Card(Value.ACE, Shape.HEART)); assertThat(dealer.getCards()).containsExactly( new Card(Value.KING, Shape.HEART), - new Card(Value.FIVE, Shape.HEART), - new Card(Value.ACE, Shape.HEART), - new Card(Value.ACE, Shape.SPADE) + new Card(Value.SIX, Shape.HEART), + new Card(Value.ACE, Shape.HEART) ); } - @DisplayName("카드의 총 점수가 16 초과일 때, 카드를 더 이상 뽑지 않는다") + @DisplayName("카드의 총 점수가 16을 넘으면, 카드를 뽑을 때 예외가 발생한다.") @Test - void drawTest_cardScoreIsOver16() { + void addTest_whenScoreIsOver16_throwException() { Dealer dealer = new Dealer(List.of( new Card(Value.KING, Shape.HEART), new Card(Value.SEVEN, Shape.HEART) )); - Deck deck = new Deck(List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.ACE, Shape.SPADE), - new Card(Value.ACE, Shape.DIAMOND) - )); + Card card = new Card(Value.ACE, Shape.HEART); - dealer.playTurn(deck); - - assertThat(dealer.getCards()).containsExactly( - new Card(Value.KING, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART) - ); + assertThatThrownBy(() -> dealer.add(card)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("더 이상 카드를 추가할 수 없습니다."); } } From 877680bd789583128c79e5349e37aa7cdf6377ff Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 16:09:07 +0900 Subject: [PATCH 11/62] =?UTF-8?q?refactor=20:=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=EB=B6=84=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?participant=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/Card.java | 8 ++++---- .../java/blackjack/domain/{ => participant}/Dealer.java | 3 ++- .../java/blackjack/domain/{ => participant}/Player.java | 3 ++- .../blackjack/domain/{ => participant}/DealerTest.java | 3 ++- .../blackjack/domain/{ => participant}/PlayerTest.java | 3 ++- 5 files changed, 12 insertions(+), 8 deletions(-) rename src/main/java/blackjack/domain/{ => participant}/Dealer.java (94%) rename src/main/java/blackjack/domain/{ => participant}/Player.java (94%) rename src/test/java/blackjack/domain/{ => participant}/DealerTest.java (98%) rename src/test/java/blackjack/domain/{ => participant}/PlayerTest.java (98%) diff --git a/src/main/java/blackjack/domain/Card.java b/src/main/java/blackjack/domain/Card.java index 398a3210b9..a011e24fae 100644 --- a/src/main/java/blackjack/domain/Card.java +++ b/src/main/java/blackjack/domain/Card.java @@ -37,8 +37,8 @@ public int hashCode() { return Objects.hash(value, shape); } - // TODO 외부 class로 분리 할 것인지 논의 - enum Value { + // TODO 외부 class로 분리 할 것인지 논의, 접근 제어자 논의 + public enum Value { ACE(1), TWO(2), THREE(3), @@ -71,7 +71,7 @@ public int getMaxScore() { } } - enum Shape { - SPADE, DIAMOND, HEART, CLOVER; + public enum Shape { + SPADE, DIAMOND, HEART, CLOVER } } diff --git a/src/main/java/blackjack/domain/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java similarity index 94% rename from src/main/java/blackjack/domain/Dealer.java rename to src/main/java/blackjack/domain/participant/Dealer.java index 6b973fa29d..6f02f2c011 100644 --- a/src/main/java/blackjack/domain/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -1,5 +1,6 @@ -package blackjack.domain; +package blackjack.domain.participant; +import blackjack.domain.Card; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/blackjack/domain/Player.java b/src/main/java/blackjack/domain/participant/Player.java similarity index 94% rename from src/main/java/blackjack/domain/Player.java rename to src/main/java/blackjack/domain/participant/Player.java index 62c9613519..9d2212d3c7 100644 --- a/src/main/java/blackjack/domain/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -1,5 +1,6 @@ -package blackjack.domain; +package blackjack.domain.participant; +import blackjack.domain.Card; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/src/test/java/blackjack/domain/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java similarity index 98% rename from src/test/java/blackjack/domain/DealerTest.java rename to src/test/java/blackjack/domain/participant/DealerTest.java index 61fdb45f2f..0adc650a1f 100644 --- a/src/test/java/blackjack/domain/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -1,8 +1,9 @@ -package blackjack.domain; +package blackjack.domain.participant; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.domain.Card; import blackjack.domain.Card.Shape; import blackjack.domain.Card.Value; import java.util.List; diff --git a/src/test/java/blackjack/domain/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java similarity index 98% rename from src/test/java/blackjack/domain/PlayerTest.java rename to src/test/java/blackjack/domain/participant/PlayerTest.java index df31a09101..add4188087 100644 --- a/src/test/java/blackjack/domain/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -1,8 +1,9 @@ -package blackjack.domain; +package blackjack.domain.participant; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.domain.Card; import blackjack.domain.Card.Shape; import blackjack.domain.Card.Value; import java.util.List; From d7e76855c7657978bf254c3b1709716b04151b14 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 16:29:53 +0900 Subject: [PATCH 12/62] =?UTF-8?q?refactor=20(Participant)=20:=20=EC=B0=B8?= =?UTF-8?q?=EA=B0=80=EC=9E=90=EC=9D=98=20=EA=B3=B5=ED=86=B5=20=EC=B1=85?= =?UTF-8?q?=EC=9E=84=EC=9D=84=20=EB=AC=B6=EA=B8=B0=20=EC=9C=84=ED=95=B4,?= =?UTF-8?q?=20=EC=B6=94=EC=83=81=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../blackjack/domain/participant/Dealer.java | 38 ++------------ .../domain/participant/Participant.java | 49 +++++++++++++++++++ .../blackjack/domain/participant/Player.java | 41 ++-------------- 3 files changed, 59 insertions(+), 69 deletions(-) create mode 100644 src/main/java/blackjack/domain/participant/Participant.java diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 6f02f2c011..ca1781e199 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -4,44 +4,16 @@ import java.util.ArrayList; import java.util.List; -public class Dealer { +public class Dealer extends Participant { private static final int DRAWABLE_MAX_SCORE = 16; - private static final int BLACKJACK_SCORE = 21; - - private final List cards; public Dealer(List cards) { - this.cards = new ArrayList<>(cards); - } - - public boolean isDrawable() { - return calculateScore() <= DRAWABLE_MAX_SCORE; - } - - public int calculateScore() { - int score = cards.stream() - .mapToInt(Card::getMaxScore) - .sum(); - - //TODO 인덴트 해결하기 - for (Card card : cards) { - if (score <= BLACKJACK_SCORE) { - return score; - } - score = score + card.getMinScore() - card.getMaxScore(); - } - return score; - } - - List getCards() { - return cards; + super(cards); } - public void add(Card card) { - if (!isDrawable()) { - throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); - } - cards.add(card); + @Override + protected int getMaxDrawableScore() { + return DRAWABLE_MAX_SCORE; } } diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java new file mode 100644 index 0000000000..192535842c --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -0,0 +1,49 @@ +package blackjack.domain.participant; + +import blackjack.domain.Card; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public abstract class Participant { + + protected static final int BLACKJACK_SCORE = 21; + + private final List cards; + + public Participant(List cards) { + this.cards = new ArrayList<>(cards); + } + + public final int calculateScore() { + int score = cards.stream() + .mapToInt(Card::getMaxScore) + .sum(); + + //TODO 인덴트 해결하기 + for (Card card : cards) { + if (score <= BLACKJACK_SCORE) { + return score; + } + score = score + card.getMinScore() - card.getMaxScore(); + } + return score; + } + + public final boolean isDrawable() { + return calculateScore() <= getMaxDrawableScore(); + } + + public final void add(Card card) { + if (!isDrawable()) { + throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); + } + cards.add(card); + } + + public final List getCards() { + return Collections.unmodifiableList(cards); + } + + protected abstract int getMaxDrawableScore(); +} diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 9d2212d3c7..db9b69861a 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -1,47 +1,16 @@ package blackjack.domain.participant; import blackjack.domain.Card; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; -public class Player { - - private static final int BLACKJACK_SCORE = 21; - - private final List cards; +public class Player extends Participant { public Player(List cards) { - this.cards = new ArrayList<>(cards); - } - - public boolean isDrawable() { - return calculateScore() <= BLACKJACK_SCORE; - } - - public int calculateScore() { - int score = cards.stream() - .mapToInt(Card::getMaxScore) - .sum(); - - //TODO 인덴트 해결하기 - for (Card card : cards) { - if (score <= BLACKJACK_SCORE) { - return score; - } - score = score + card.getMinScore() - card.getMaxScore(); - } - return score; - } - - public List getCards() { - return Collections.unmodifiableList(cards); + super(cards); } - public void add(Card card) { - if (!isDrawable()) { - throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); - } - cards.add(card); + @Override + protected int getMaxDrawableScore() { + return BLACKJACK_SCORE; } } From bcf2305710db536661530acfe022e2dc52eaf55e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 16:36:40 +0900 Subject: [PATCH 13/62] =?UTF-8?q?docs=20:=20=EC=9D=B4=EB=A6=84=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index dab5baa8ff..a32ee8465e 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,10 @@ - 숫자 카드는 카드 숫자로 계산한다. - King, Queen, Jack은 각각 10으로 계산한다. - Ace는 1 또는 11로 계산한다. +- 플레이어는 이름을 가진다. + - 이름은 공백으로만 구성될 수 없다. + - 이름은 앞뒤 공백을 가질 수 없다. + - 중복된 이름은 가질 수 없다. ### 플레이어 승리 조건 From 4b8ca832ff40f89a19e9ff496a924d13be877b9d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 17:41:44 +0900 Subject: [PATCH 14/62] =?UTF-8?q?feat=20(Name)=20:=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=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 Co-authored-by: zangsu --- .../blackjack/domain/participant/Name.java | 21 ++++++++++++ .../domain/participant/NameTest.java | 32 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/main/java/blackjack/domain/participant/Name.java create mode 100644 src/test/java/blackjack/domain/participant/NameTest.java diff --git a/src/main/java/blackjack/domain/participant/Name.java b/src/main/java/blackjack/domain/participant/Name.java new file mode 100644 index 0000000000..fccc74ad82 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Name.java @@ -0,0 +1,21 @@ +package blackjack.domain.participant; + +public class Name { + + private final String name; + + public Name(String name) { + validate(name); + this.name = name.strip(); + } + + private void validate(String name) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("이름은 적어도 한 글자 이상을 포함해야 합니다."); + } + } + + public String getName() { + return name; + } +} diff --git a/src/test/java/blackjack/domain/participant/NameTest.java b/src/test/java/blackjack/domain/participant/NameTest.java new file mode 100644 index 0000000000..486850bbef --- /dev/null +++ b/src/test/java/blackjack/domain/participant/NameTest.java @@ -0,0 +1,32 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +class NameTest { + + @DisplayName("이름은 적어도 한 글자를 가져야 한다.") + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = {" ", "\n"}) + void validateTest_whenNameIsEmpty_throwException(String name) { + + assertThatThrownBy(() -> new Name(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("이름은 적어도 한 글자 이상을 포함해야 합니다."); + } + + @DisplayName("이름의 앞 뒤 공백을 제거해준다.") + @ParameterizedTest + @ValueSource(strings = {" pobi", "pobi ", " pobi ", "\npobi\t"}) + void validateTest_nameHasStrippedName(String input) { + Name name = new Name(input); + + assertThat(name.getName()).isEqualTo("pobi"); + } +} From 3a71ec4e972074df864e835cd05dcf7ca631c33a Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 19:24:28 +0900 Subject: [PATCH 15/62] =?UTF-8?q?feat=20(Player)=20:=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EA=B0=80=20=EC=9D=B4=EB=A6=84=EC=9D=84=20?= =?UTF-8?q?=EA=B0=96=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../blackjack/domain/participant/Player.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index db9b69861a..2f6a1e1674 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -1,16 +1,33 @@ package blackjack.domain.participant; import blackjack.domain.Card; +import java.util.Collections; import java.util.List; public class Player extends Participant { - public Player(List cards) { + private final Name name; + + Player(List cards) { + super(cards); + this.name = new Name("name"); + } + + private Player(List cards, Name name) { super(cards); + this.name = name; + } + + public static Player from(String name) { + return new Player(Collections.emptyList(), new Name(name)); } @Override protected int getMaxDrawableScore() { return BLACKJACK_SCORE; } + + public Name getName() { + return name; + } } From 717e0cb374b27ec2aeaac0429f63738198348435 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 19:35:09 +0900 Subject: [PATCH 16/62] =?UTF-8?q?refactor=20:=20=EC=B0=B8=EA=B0=80?= =?UTF-8?q?=EC=9E=90=20=EA=B4=80=EB=A0=A8=20=EC=BD=94=EB=93=9C=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Player 가 Name 을 가지도록 생성자 변경 - 추상 클래스의 생성자 접근제어자 변경 - Dealer 기본 생성자 추가 Co-authored-by: zangsu --- .../java/blackjack/domain/participant/Dealer.java | 8 ++++++-- .../blackjack/domain/participant/Participant.java | 2 +- .../java/blackjack/domain/participant/Player.java | 7 +------ .../blackjack/domain/participant/PlayerTest.java | 14 ++++++++------ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index ca1781e199..96d8edf0ed 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -1,14 +1,18 @@ package blackjack.domain.participant; import blackjack.domain.Card; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Dealer extends Participant { private static final int DRAWABLE_MAX_SCORE = 16; - public Dealer(List cards) { + public Dealer() { + super(Collections.emptyList()); + } + + Dealer(List cards) { super(cards); } diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 192535842c..79bf7e0e87 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -11,7 +11,7 @@ public abstract class Participant { private final List cards; - public Participant(List cards) { + protected Participant(List cards) { this.cards = new ArrayList<>(cards); } diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 2f6a1e1674..c5c4acf71a 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -8,12 +8,7 @@ public class Player extends Participant { private final Name name; - Player(List cards) { - super(cards); - this.name = new Name("name"); - } - - private Player(List cards, Name name) { + Player(List cards, Name name) { super(cards); this.name = name; } diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index add4188087..81c8c8987a 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -14,13 +14,15 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -public class PlayerTest { +class PlayerTest { + + private static final Name DEFAULT_NAME = new Name("name"); @DisplayName("점수를 계산할 수 있다.") @ParameterizedTest @MethodSource("provideCardsAndScore") void calculateScoreTest(List cards, int expected) { - Player player = new Player(cards); + Player player = new Player(cards, DEFAULT_NAME); assertThat(player.calculateScore()).isEqualTo(expected); } @@ -43,7 +45,7 @@ void isDrawableTest_whenScoreIsUnder21_returnTrue() { new Card(Value.EIGHT, Shape.HEART), new Card(Value.THREE, Shape.HEART) ); - Player player = new Player(CardsScore21); + Player player = new Player(CardsScore21, DEFAULT_NAME); assertThat(player.isDrawable()).isTrue(); } @@ -57,7 +59,7 @@ void isDrawableTest_whenScoreIsOver21_returnFalse() { new Card(Value.SEVEN, Shape.HEART), new Card(Value.FIVE, Shape.HEART) ); - Player player = new Player(CardsScore22); + Player player = new Player(CardsScore22, DEFAULT_NAME); assertThat(player.isDrawable()).isFalse(); } @@ -69,7 +71,7 @@ void addTest_whenScoreIsUnder21() { new Card(Value.KING, Shape.HEART), new Card(Value.NINE, Shape.HEART), new Card(Value.TWO, Shape.HEART) - )); + ), DEFAULT_NAME); player.add(new Card(Value.ACE, Shape.HEART)); @@ -88,7 +90,7 @@ void addTest_whenScoreIsOver21_throwException() { new Card(Value.KING, Shape.HEART), new Card(Value.NINE, Shape.HEART), new Card(Value.THREE, Shape.HEART) - )); + ), DEFAULT_NAME); Card card = new Card(Value.ACE, Shape.HEART); assertThatThrownBy(() -> player.add(card)) From 940a3a7865d1e3032c3c1eb7dba7bfc178c77437 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 20:01:57 +0900 Subject: [PATCH 17/62] =?UTF-8?q?feat=20(Participant)=20:=20=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=20=EC=8B=9C=EC=9E=91=20=ED=9B=84=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=EB=91=90=20=EC=9E=A5=20=EB=BD=91=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../domain/participant/Participant.java | 12 ++++++++++ .../domain/participant/DealerTest.java | 24 +++++++++++++++++++ .../domain/participant/PlayerTest.java | 24 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 79bf7e0e87..33fa0644f4 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -1,6 +1,7 @@ package blackjack.domain.participant; import blackjack.domain.Card; +import blackjack.domain.Deck; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -8,6 +9,7 @@ public abstract class Participant { protected static final int BLACKJACK_SCORE = 21; + private static final int START_CARDS_SIZE = 2; private final List cards; @@ -34,6 +36,16 @@ public final boolean isDrawable() { return calculateScore() <= getMaxDrawableScore(); } + public void drawStartCards(Deck deck) { + if (!cards.isEmpty()) { + throw new IllegalStateException("이미 시작 카드를 뽑았습니다."); + } + for (int i = 0; i < START_CARDS_SIZE; i++) { + add(deck.draw()); + } + } + + //TODO : 시작 카드를 뽑은 이후에 호출 가능해야 한다. public final void add(Card card) { if (!isDrawable()) { throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 0adc650a1f..af997ffb81 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -6,6 +6,7 @@ import blackjack.domain.Card; import blackjack.domain.Card.Shape; import blackjack.domain.Card.Value; +import blackjack.domain.Deck; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; @@ -72,6 +73,29 @@ static Stream provideCardsAndScore() { ); } + @DisplayName("게임을 시작할 때는 카드를 두 장 뽑는다.") + @Test + void drawStartCardsTest() { + Dealer dealer = new Dealer(); + Deck deck = Deck.createOrderedDeck(); + + dealer.drawStartCards(deck); + + assertThat(dealer.getCards()).hasSize(2); + } + + @DisplayName("이미 카드를 가지고 있는 경우, 시작 카드를 뽑을 수 없다.") + @Test + void drawStartCardsTest_whenAlreadyStarted_throwException() { + Dealer dealer = new Dealer(); + Deck deck = Deck.createOrderedDeck(); + dealer.drawStartCards(deck); + + assertThatThrownBy(() -> dealer.drawStartCards(deck)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("이미 시작 카드를 뽑았습니다."); + } + @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 한 장 뽑을 수 있다") @Test void addTest_whenScoreIsUnder16() { diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 81c8c8987a..eadece19b0 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -6,6 +6,7 @@ import blackjack.domain.Card; import blackjack.domain.Card.Shape; import blackjack.domain.Card.Value; +import blackjack.domain.Deck; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; @@ -64,6 +65,29 @@ void isDrawableTest_whenScoreIsOver21_returnFalse() { assertThat(player.isDrawable()).isFalse(); } + @DisplayName("게임을 시작할 때는 카드를 두 장 뽑는다.") + @Test + void drawStartCardsTest() { + Player player = Player.from("name"); + Deck deck = Deck.createOrderedDeck(); + + player.drawStartCards(deck); + + assertThat(player.getCards()).hasSize(2); + } + + @DisplayName("이미 카드를 가지고 있는 경우, 시작 카드를 뽑을 수 없다.") + @Test + void drawStartCardsTest_whenAlreadyStarted_throwException() { + Player player = Player.from("name"); + Deck deck = Deck.createOrderedDeck(); + player.drawStartCards(deck); + + assertThatThrownBy(() -> player.drawStartCards(deck)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("이미 시작 카드를 뽑았습니다."); + } + @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 한 장 뽑을 수 있다") @Test void addTest_whenScoreIsUnder21() { From 2079c7ab24aaa9aa21def3cbff0c7590f9cf4c32 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 20:42:20 +0900 Subject: [PATCH 18/62] =?UTF-8?q?feat=20(Dealer)=20:=20=EB=94=9C=EB=9F=AC?= =?UTF-8?q?=EA=B0=80=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EC=99=80=20?= =?UTF-8?q?=EC=8A=B9=ED=8C=A8=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../blackjack/domain/participant/Dealer.java | 10 ++ .../domain/participant/Participant.java | 4 + .../domain/participant/DealerTest.java | 120 ++++++++++++++++++ 3 files changed, 134 insertions(+) diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 96d8edf0ed..fd022e9872 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -20,4 +20,14 @@ public Dealer() { protected int getMaxDrawableScore() { return DRAWABLE_MAX_SCORE; } + + public boolean isWin(Player player) { + if (player.isBusted()) { + return true; + } + if (this.isBusted()) { + return false; + } + return this.calculateScore() >= player.calculateScore(); + } } diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 33fa0644f4..aa4d8d3aa9 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -36,6 +36,10 @@ public final boolean isDrawable() { return calculateScore() <= getMaxDrawableScore(); } + public final boolean isBusted() { + return calculateScore() > BLACKJACK_SCORE; + } + public void drawStartCards(Deck deck) { if (!cards.isEmpty()) { throw new IllegalStateException("이미 시작 카드를 뽑았습니다."); diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index af997ffb81..2101afc32f 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -126,4 +127,123 @@ void addTest_whenScoreIsOver16_throwException() { .isInstanceOf(IllegalStateException.class) .hasMessage("더 이상 카드를 추가할 수 없습니다."); } + + @DisplayName("플레이어와의 승패를 판단할 수 있다.") + @Nested + class IsWinTest { + + @DisplayName("플레이어가 21일 넘을 경우, 딜러가 이긴다.") + @ParameterizedTest + @MethodSource("provideDealerCards") + void whenPlayerBusted_dealerWin(List cards) { + Dealer dealer = new Dealer(cards); + Player player = new Player(List.of( + new Card(Value.KING, Shape.DIAMOND), + new Card(Value.QUEEN, Shape.DIAMOND), + new Card(Value.JACK, Shape.DIAMOND) + ), new Name("name")); + + assertThat(dealer.isWin(player)).isTrue(); + } + + static Stream> provideDealerCards() { + return Stream.of( + List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART) + ), + List.of( + new Card(Value.TWO, Shape.HEART), + new Card(Value.TWO, Shape.SPADE) + ), + List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ), + List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.QUEEN, Shape.HEART), + new Card(Value.JACK, Shape.HEART) + ) + ); + } + + @DisplayName("딜러만 21을 넘길 경우, 플레이어가 이긴다.") + @ParameterizedTest + @MethodSource("providePlayerCards") + void whenOnlyDealerBusted_playerWin(List cards) { + + Dealer dealer = new Dealer(List.of( + new Card(Value.KING, Shape.DIAMOND), + new Card(Value.QUEEN, Shape.DIAMOND), + new Card(Value.JACK, Shape.DIAMOND) + )); + Player player = new Player(cards, new Name("name")); + + assertThat(dealer.isWin(player)).isFalse(); + } + + //TODO 픽스쳐 생성 + static Stream> providePlayerCards() { + return Stream.of( + List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART) + ), + List.of( + new Card(Value.TWO, Shape.HEART), + new Card(Value.TWO, Shape.SPADE) + ), + List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ) + ); + } + + @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 크다면 플레이어가 이긴다.") + @Test + void whenPlayerScoreIsBiggerThanDealerScore_playerWin() { + Player player = new Player(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + ), new Name("name")); + Dealer dealer = new Dealer(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.SIX, Shape.HEART) + )); + + assertThat(dealer.isWin(player)).isFalse(); + } + + @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 같다면 딜러가 이긴다.") + @Test + void whenPlayerScoreIsEqualToDealerScore_dealerWin() { + Player player = new Player(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + ), new Name("name")); + Dealer dealer = new Dealer(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + )); + + assertThat(dealer.isWin(player)).isTrue(); + } + + @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 작다면 딜러가 이긴다.") + @Test + void whenPlayerScoreIsSmallerThanDealerScore_dealerWin() { + Player player = new Player(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.SIX, Shape.HEART) + ), new Name("name")); + Dealer dealer = new Dealer(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + )); + + assertThat(dealer.isWin(player)).isTrue(); + } + } } From 541e6c2ffc97f118e3e58303d7f9cc147226fd54 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 20:44:55 +0900 Subject: [PATCH 19/62] =?UTF-8?q?feat=20(Player)=20:=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EA=B0=80=20=EB=94=9C=EB=9F=AC=EC=99=80=20?= =?UTF-8?q?=EC=8A=B9=ED=8C=A8=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/participant/Player.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index c5c4acf71a..81a9e544bc 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -22,6 +22,10 @@ protected int getMaxDrawableScore() { return BLACKJACK_SCORE; } + public boolean isWin(Dealer dealer) { + return !dealer.isWin(this); + } + public Name getName() { return name; } From c5aab0241f01cbf78a94dcd319f444173d4cd51d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Wed, 6 Mar 2024 20:45:55 +0900 Subject: [PATCH 20/62] =?UTF-8?q?refactor=20(Deck)=20:=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/Deck.java | 7 ------- src/test/java/blackjack/domain/DeckTest.java | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main/java/blackjack/domain/Deck.java b/src/main/java/blackjack/domain/Deck.java index 5573044c77..378fc937a4 100644 --- a/src/main/java/blackjack/domain/Deck.java +++ b/src/main/java/blackjack/domain/Deck.java @@ -10,13 +10,6 @@ public class Deck { private final Queue cards; - public Deck() { - this.cards = new LinkedList<>(Arrays.stream(Shape.values()) - .map(Deck::makeCards) - .flatMap(List::stream) - .toList()); - } - Deck(List cards) { this.cards = new LinkedList<>(cards); } diff --git a/src/test/java/blackjack/domain/DeckTest.java b/src/test/java/blackjack/domain/DeckTest.java index 15e6706b68..ea0a293102 100644 --- a/src/test/java/blackjack/domain/DeckTest.java +++ b/src/test/java/blackjack/domain/DeckTest.java @@ -11,7 +11,7 @@ class DeckTest { @DisplayName("카드 한 장을 뽑을 수 있다") @Test void drawTest() { - Deck deck = new Deck(); + Deck deck = Deck.createOrderedDeck(); assertThat(deck.draw()).isNotNull(); } @@ -20,7 +20,7 @@ void drawTest() { @DisplayName("카드는 최대 52장만 뽑을 수 있다.") @Test void drawTest_whenDraw53Times_throwException() { - Deck deck = new Deck(); + Deck deck = Deck.createOrderedDeck(); drawRepeat(deck, 52); assertThatThrownBy(() -> deck.draw()) From 3bc66d853ffde1928369ce868f996f115f7722f2 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 11:52:01 +0900 Subject: [PATCH 21/62] =?UTF-8?q?feat=20(Players)=20:=20=EC=A0=9C=ED=95=9C?= =?UTF-8?q?=EB=90=9C=20=EC=88=98=EC=9D=98=20=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=A7=8C=20=EA=B0=80=EC=A7=80=EB=8A=94=20Players=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../blackjack/domain/participant/Players.java | 31 ++++++++++++++++++ .../domain/participant/PlayersTest.java | 32 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/blackjack/domain/participant/Players.java create mode 100644 src/test/java/blackjack/domain/participant/PlayersTest.java diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java new file mode 100644 index 0000000000..2c49aeaae0 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -0,0 +1,31 @@ +package blackjack.domain.participant; + +import java.util.List; + +public class Players { + + private static final int MAX_PLAYERS_SIZE = 4; + + private final List players; + + private Players(List players) { + validateSize(players); + this.players = players; + } + + public static Players from(List names) { + List players = names.stream() + .map(Player::from) + .toList(); + return new Players(players); + } + + private void validateSize(List players) { + if (players.isEmpty()) { + throw new IllegalArgumentException("최소 한 명의 플레이어가 있어야 합니다."); + } + if (players.size() > MAX_PLAYERS_SIZE) { + throw new IllegalArgumentException("최대 4명의 플레이어만 참여 가능합니다."); + } + } +} diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java new file mode 100644 index 0000000000..cdc6e5331c --- /dev/null +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -0,0 +1,32 @@ +package blackjack.domain.participant; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +//TODO : 테스트 전반적으로 메서드 이름에 경계값 제거 +class PlayersTest { + + @DisplayName("최소 한 명 이상의 플레이어가 존재해야 한다.") + @Test + void validateTest_countOfPlayersIsZero_throwException() { + assertThatThrownBy(() -> Players.from(Collections.emptyList())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("최소 한 명의 플레이어가 있어야 합니다."); + } + + @DisplayName("N 명 이상의 플레이어를 가지면 예외가 발생한다.") + @Test + void validateTest_countOfPlayersIsOverFour_throwException() { + List manyNames = List.of("1", "2", "3", "4", "5"); + + assertThatThrownBy(() -> Players.from(manyNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("최대 4명의 플레이어만 참여 가능합니다."); + } + + //TODO : 중복 +} From da419b216fca0785dced70bd25d1f76e0127c471 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 12:04:21 +0900 Subject: [PATCH 22/62] =?UTF-8?q?feat=20(Players)=20:=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EA=B0=80=20=EC=A4=91=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../blackjack/domain/participant/Name.java | 19 +++++++++++++++++++ .../blackjack/domain/participant/Player.java | 18 ++++++++++++++++++ .../blackjack/domain/participant/Players.java | 11 +++++++++++ .../domain/participant/PlayersTest.java | 10 +++++++++- 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/participant/Name.java b/src/main/java/blackjack/domain/participant/Name.java index fccc74ad82..3baa06e97a 100644 --- a/src/main/java/blackjack/domain/participant/Name.java +++ b/src/main/java/blackjack/domain/participant/Name.java @@ -1,5 +1,7 @@ package blackjack.domain.participant; +import java.util.Objects; + public class Name { private final String name; @@ -18,4 +20,21 @@ private void validate(String name) { public String getName() { return name; } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + Name name1 = (Name) object; + return Objects.equals(name, name1.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } } diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 81a9e544bc..08be7e9d43 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -3,6 +3,7 @@ import blackjack.domain.Card; import java.util.Collections; import java.util.List; +import java.util.Objects; public class Player extends Participant { @@ -29,4 +30,21 @@ public boolean isWin(Dealer dealer) { public Name getName() { return name; } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + Player player = (Player) object; + return Objects.equals(name, player.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } } diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 2c49aeaae0..76b29f2864 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -10,6 +10,7 @@ public class Players { private Players(List players) { validateSize(players); + validateDistinct(players); this.players = players; } @@ -28,4 +29,14 @@ private void validateSize(List players) { throw new IllegalArgumentException("최대 4명의 플레이어만 참여 가능합니다."); } } + + private void validateDistinct(List players) { + if (isDuplicated(players)) { + throw new IllegalArgumentException("중복된 이름을 사용할 수 없습니다."); + } + } + + private boolean isDuplicated(List players) { + return players.size() != players.stream().distinct().count(); + } } diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java index cdc6e5331c..e776ecd881 100644 --- a/src/test/java/blackjack/domain/participant/PlayersTest.java +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -28,5 +28,13 @@ void validateTest_countOfPlayersIsOverFour_throwException() { .hasMessage("최대 4명의 플레이어만 참여 가능합니다."); } - //TODO : 중복 + @DisplayName("중복된 이름을 사용하면, 예외가 발생한다.") + @Test + void validateTest_whenNameIsDuplicated_throwException() { + List duplicatedNames = List.of("짱수", "커찬", "커찬"); + + assertThatThrownBy(() -> Players.from(duplicatedNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("중복된 이름을 사용할 수 없습니다."); + } } From fd9106dae7c6a529bb7cc4aa720be966e2d5a692 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 14:57:03 +0900 Subject: [PATCH 23/62] =?UTF-8?q?feat=20(Deck)=20:=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EA=B0=80=20=EC=84=9E=EC=9D=B8=20=EB=8D=B1=EC=9D=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EB=90=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/Deck.java | 9 ++++++--- src/test/java/blackjack/domain/DeckTest.java | 4 ++-- .../java/blackjack/domain/participant/DealerTest.java | 4 ++-- .../java/blackjack/domain/participant/PlayerTest.java | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/main/java/blackjack/domain/Deck.java b/src/main/java/blackjack/domain/Deck.java index 378fc937a4..d321df502d 100644 --- a/src/main/java/blackjack/domain/Deck.java +++ b/src/main/java/blackjack/domain/Deck.java @@ -1,7 +1,10 @@ package blackjack.domain; +import static java.util.stream.Collectors.toList; + import blackjack.domain.Card.Shape; import java.util.Arrays; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Queue; @@ -14,12 +17,12 @@ public class Deck { this.cards = new LinkedList<>(cards); } - public static Deck createOrderedDeck() { + public static Deck createShuffledDeck() { List cards = Arrays.stream(Shape.values()) .map(Deck::makeCards) .flatMap(List::stream) - .toList(); - + .collect(toList()); + Collections.shuffle(cards); return new Deck(cards); } diff --git a/src/test/java/blackjack/domain/DeckTest.java b/src/test/java/blackjack/domain/DeckTest.java index ea0a293102..7827d9fab3 100644 --- a/src/test/java/blackjack/domain/DeckTest.java +++ b/src/test/java/blackjack/domain/DeckTest.java @@ -11,7 +11,7 @@ class DeckTest { @DisplayName("카드 한 장을 뽑을 수 있다") @Test void drawTest() { - Deck deck = Deck.createOrderedDeck(); + Deck deck = Deck.createShuffledDeck(); assertThat(deck.draw()).isNotNull(); } @@ -20,7 +20,7 @@ void drawTest() { @DisplayName("카드는 최대 52장만 뽑을 수 있다.") @Test void drawTest_whenDraw53Times_throwException() { - Deck deck = Deck.createOrderedDeck(); + Deck deck = Deck.createShuffledDeck(); drawRepeat(deck, 52); assertThatThrownBy(() -> deck.draw()) diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 2101afc32f..c6cdb985ba 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -78,7 +78,7 @@ static Stream provideCardsAndScore() { @Test void drawStartCardsTest() { Dealer dealer = new Dealer(); - Deck deck = Deck.createOrderedDeck(); + Deck deck = Deck.createShuffledDeck(); dealer.drawStartCards(deck); @@ -89,7 +89,7 @@ void drawStartCardsTest() { @Test void drawStartCardsTest_whenAlreadyStarted_throwException() { Dealer dealer = new Dealer(); - Deck deck = Deck.createOrderedDeck(); + Deck deck = Deck.createShuffledDeck(); dealer.drawStartCards(deck); assertThatThrownBy(() -> dealer.drawStartCards(deck)) diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index eadece19b0..7c762cb058 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -69,7 +69,7 @@ void isDrawableTest_whenScoreIsOver21_returnFalse() { @Test void drawStartCardsTest() { Player player = Player.from("name"); - Deck deck = Deck.createOrderedDeck(); + Deck deck = Deck.createShuffledDeck(); player.drawStartCards(deck); @@ -80,7 +80,7 @@ void drawStartCardsTest() { @Test void drawStartCardsTest_whenAlreadyStarted_throwException() { Player player = Player.from("name"); - Deck deck = Deck.createOrderedDeck(); + Deck deck = Deck.createShuffledDeck(); player.drawStartCards(deck); assertThatThrownBy(() -> player.drawStartCards(deck)) From aea24578455454f698bd71e4d20b439b3004c8b1 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 15:27:58 +0900 Subject: [PATCH 24/62] =?UTF-8?q?feat=20(Players)=20:=20=EB=AA=A8=EB=93=A0?= =?UTF-8?q?=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EB=93=A4=EC=9D=B4=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EB=BD=91?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../blackjack/domain/participant/Players.java | 12 ++++++++++++ .../domain/participant/PlayersTest.java | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 76b29f2864..9e125c5a3b 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -1,5 +1,6 @@ package blackjack.domain.participant; +import blackjack.domain.Deck; import java.util.List; public class Players { @@ -39,4 +40,15 @@ private void validateDistinct(List players) { private boolean isDuplicated(List players) { return players.size() != players.stream().distinct().count(); } + + public void drawStartCards(Deck deck) { + for (Player player : players) { + player.drawStartCards(deck); + } + } + + //TODO 현재 얘는 테스트만을 위해서 임시로 작성된 코드 + List getPlayers() { + return players; + } } diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java index e776ecd881..d2c7a5e7ee 100644 --- a/src/test/java/blackjack/domain/participant/PlayersTest.java +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -1,7 +1,10 @@ package blackjack.domain.participant; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; +import blackjack.domain.Deck; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.DisplayName; @@ -37,4 +40,20 @@ void validateTest_whenNameIsDuplicated_throwException() { .isInstanceOf(IllegalArgumentException.class) .hasMessage("중복된 이름을 사용할 수 없습니다."); } + + @DisplayName("게임을 시작할 때 모든 플레이어들은 카드를 두 장 뽑는다.") + @Test + void drawStartCardsTest() { + Players players = Players.from(List.of("1", "2")); + Deck deck = Deck.createShuffledDeck(); + + players.drawStartCards(deck); + + List allPlayers = players.getPlayers(); + assertAll( + () -> assertThat(allPlayers.get(0).getCards()).hasSize(2), + () -> assertThat(allPlayers.get(1).getCards()).hasSize(2) + ); + + } } From 0fdf520286f9591d6cbee186352ff0b21c5ca34d Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 15:51:55 +0900 Subject: [PATCH 25/62] =?UTF-8?q?feat=20(BlackJackGame)=20:=20=EC=A0=84?= =?UTF-8?q?=EB=B0=98=EC=A0=81=EC=9D=B8=20=EC=A0=9C=EC=96=B4=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/BlackJackGame.java | 43 +++++++++++++++++++ .../blackjack/domain/participant/Player.java | 4 +- .../blackjack/domain/participant/Players.java | 7 +++ src/main/java/blackjack/view/InputView.java | 21 +++++++++ src/main/java/blackjack/view/OutputView.java | 7 +++ 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/main/java/blackjack/BlackJackGame.java create mode 100644 src/main/java/blackjack/view/InputView.java create mode 100644 src/main/java/blackjack/view/OutputView.java diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java new file mode 100644 index 0000000000..fcc74bdc28 --- /dev/null +++ b/src/main/java/blackjack/BlackJackGame.java @@ -0,0 +1,43 @@ +package blackjack; + +import blackjack.domain.Deck; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; +import blackjack.domain.participant.Players; +import blackjack.view.InputView; +import blackjack.view.OutputView; +import java.util.List; + +public class BlackJackGame { + + //TODO 2개로 줄이기 (논의사항) + private final InputView inputView = new InputView(); + private final OutputView outputView = new OutputView(); + private final Deck deck = Deck.createShuffledDeck(); + + public void run() { + Dealer dealer = new Dealer(); + List names = inputView.inputPlayerNames(); + Players players = Players.from(names); + + dealer.drawStartCards(deck); + players.drawStartCards(deck); + // TODO 카드 출력하기 + + players.play(this::playTurn); + while (dealer.isDrawable()) { + // TODO 출력 -> 딜러는 16이하라 한장의 카드를 더 받았습니다. + dealer.add(deck.draw()); + } + + // TODO 딜러, 플레이어들 카드 결과 및 점수 출력 + // TODO 딜러, 플레이어의 최종 승패 출력 + } + + private void playTurn(Player player) { + while (player.isDrawable() && inputView.isAddCard(player.getName())) { + player.add(deck.draw()); + outputView.printCards(); + } + } +} diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 08be7e9d43..228f7a8c0d 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -27,8 +27,8 @@ public boolean isWin(Dealer dealer) { return !dealer.isWin(this); } - public Name getName() { - return name; + public String getName() { + return name.getName(); } @Override diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 9e125c5a3b..a0b93d91a1 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -2,6 +2,7 @@ import blackjack.domain.Deck; import java.util.List; +import java.util.function.Consumer; public class Players { @@ -51,4 +52,10 @@ public void drawStartCards(Deck deck) { List getPlayers() { return players; } + + public void play(Consumer playTurn) { + for (Player player : players) { + playTurn.accept(player); + } + } } diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java new file mode 100644 index 0000000000..4afefd9063 --- /dev/null +++ b/src/main/java/blackjack/view/InputView.java @@ -0,0 +1,21 @@ +package blackjack.view; + +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private static final Scanner SCANNER = new Scanner(System.in); + private static final String NAME_DELIMITER = ","; + + public List inputPlayerNames() { + System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); + String names = SCANNER.nextLine(); + return List.of(names.split(NAME_DELIMITER, -1)); + } + + //TODO 네이밍 진짜 꼭 변경\ + public boolean isAddCard(String name) { + return false; + } +} diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java new file mode 100644 index 0000000000..acfd731a28 --- /dev/null +++ b/src/main/java/blackjack/view/OutputView.java @@ -0,0 +1,7 @@ +package blackjack.view; + +public class OutputView { + + public void printCards() { + } +} From a6af44f5c2ed649253a8198d19bc0e406c4960e8 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 16:16:10 +0900 Subject: [PATCH 26/62] =?UTF-8?q?feat=20(InputView)=20:=20=ED=95=9C?= =?UTF-8?q?=EC=9E=A5=EC=9D=98=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EB=8D=94=20?= =?UTF-8?q?=EB=B0=9B=EC=9D=84=EC=A7=80=20=EC=9A=94=EC=B2=AD=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/BlackJackGame.java | 2 +- src/main/java/blackjack/view/InputView.java | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index fcc74bdc28..7c1d9c25f6 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -35,7 +35,7 @@ public void run() { } private void playTurn(Player player) { - while (player.isDrawable() && inputView.isAddCard(player.getName())) { + while (player.isDrawable() && inputView.isPlayerWantDraw(player.getName())) { player.add(deck.draw()); outputView.printCards(); } diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index 4afefd9063..eb40910c95 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -7,6 +7,8 @@ public class InputView { private static final Scanner SCANNER = new Scanner(System.in); private static final String NAME_DELIMITER = ","; + private static final String WANT_DRAW_INPUT = "y"; + private static final String WANT_NOT_DRAW_INPUT = "n"; public List inputPlayerNames() { System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); @@ -14,8 +16,20 @@ public List inputPlayerNames() { return List.of(names.split(NAME_DELIMITER, -1)); } - //TODO 네이밍 진짜 꼭 변경\ - public boolean isAddCard(String name) { - return false; + public boolean isPlayerWantDraw(String name) { + System.out.printf("%s는 한장의 카드를 더 받겠습니까?(예는 %s, 아니오는 %s)%n", name, WANT_DRAW_INPUT, WANT_NOT_DRAW_INPUT); + String input = SCANNER.nextLine(); + return isWantDraw(input); + } + + private boolean isWantDraw(String input) { + if (WANT_DRAW_INPUT.equalsIgnoreCase(input)) { + return true; + } + if (WANT_NOT_DRAW_INPUT.equalsIgnoreCase(input)) { + return false; + } + throw new IllegalArgumentException("잘못된 입력입니다. 입력은 (%s/%s) 만 가능합니다." + .formatted(WANT_DRAW_INPUT, WANT_NOT_DRAW_INPUT)); } } From 1d288f10920c5a0043da679608fdb865267562c4 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 16:45:41 +0900 Subject: [PATCH 27/62] =?UTF-8?q?feat=20(OutputView)=20:=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../java/blackjack/BlackJackApplication.java | 8 ++++++++ src/main/java/blackjack/BlackJackGame.java | 1 + .../blackjack/domain/participant/Dealer.java | 18 +++++++++++++----- .../domain/participant/Participant.java | 10 +++++++++- .../blackjack/domain/participant/Player.java | 12 +++++++++--- .../blackjack/domain/participant/Players.java | 2 +- src/main/java/blackjack/view/OutputView.java | 14 ++++++++++++++ 7 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 src/main/java/blackjack/BlackJackApplication.java diff --git a/src/main/java/blackjack/BlackJackApplication.java b/src/main/java/blackjack/BlackJackApplication.java new file mode 100644 index 0000000000..c508abef18 --- /dev/null +++ b/src/main/java/blackjack/BlackJackApplication.java @@ -0,0 +1,8 @@ +package blackjack; + +public class BlackJackApplication { + public static void main(String[] args) { + BlackJackGame blackJackGame = new BlackJackGame(); + blackJackGame.run(); + } +} diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index 7c1d9c25f6..36807c5d25 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -23,6 +23,7 @@ public void run() { dealer.drawStartCards(deck); players.drawStartCards(deck); // TODO 카드 출력하기 + outputView.printStartCards(dealer, players); players.play(this::playTurn); while (dealer.isDrawable()) { diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index fd022e9872..969b83969e 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -7,6 +7,7 @@ public class Dealer extends Participant { private static final int DRAWABLE_MAX_SCORE = 16; + private static final int VISIBLE_START_CARD_SIZE = 1; public Dealer() { super(Collections.emptyList()); @@ -16,11 +17,6 @@ public Dealer() { super(cards); } - @Override - protected int getMaxDrawableScore() { - return DRAWABLE_MAX_SCORE; - } - public boolean isWin(Player player) { if (player.isBusted()) { return true; @@ -30,4 +26,16 @@ public boolean isWin(Player player) { } return this.calculateScore() >= player.calculateScore(); } + + @Override + protected int getVisibleStartCardSize() { + return VISIBLE_START_CARD_SIZE; + } + + @Override + protected int getMaxDrawableScore() { + return DRAWABLE_MAX_SCORE; + } + + } diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index aa4d8d3aa9..3419506a63 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -9,7 +9,7 @@ public abstract class Participant { protected static final int BLACKJACK_SCORE = 21; - private static final int START_CARDS_SIZE = 2; + protected static final int START_CARDS_SIZE = 2; private final List cards; @@ -61,5 +61,13 @@ public final List getCards() { return Collections.unmodifiableList(cards); } + public final List getStartCards() { + if (cards.size() < START_CARDS_SIZE) { + throw new IllegalStateException("시작 카드를 가지고 있지 않습니다."); + } + return getCards().subList(0, getVisibleStartCardSize()); + } + + protected abstract int getVisibleStartCardSize(); protected abstract int getMaxDrawableScore(); } diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 228f7a8c0d..5498010d13 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -18,14 +18,20 @@ public static Player from(String name) { return new Player(Collections.emptyList(), new Name(name)); } + public boolean isWin(Dealer dealer) { + return !dealer.isWin(this); + } + + @Override + protected int getVisibleStartCardSize() { + return START_CARDS_SIZE; + } + @Override protected int getMaxDrawableScore() { return BLACKJACK_SCORE; } - public boolean isWin(Dealer dealer) { - return !dealer.isWin(this); - } public String getName() { return name.getName(); diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index a0b93d91a1..8bf37bc085 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -49,7 +49,7 @@ public void drawStartCards(Deck deck) { } //TODO 현재 얘는 테스트만을 위해서 임시로 작성된 코드 - List getPlayers() { + public List getPlayers() { return players; } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index acfd731a28..3370436806 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,7 +1,21 @@ package blackjack.view; +import blackjack.domain.participant.Dealer; +import blackjack.domain.participant.Player; +import blackjack.domain.participant.Players; +import java.util.List; + public class OutputView { + public void printStartCards(Dealer dealer, Players players) { + System.out.println("딜러:" + dealer.getStartCards()); + List allPlayers = players.getPlayers(); + for (Player player : allPlayers) { + System.out.println(player.getName() + ": " + player.getStartCards()); + } + } + public void printCards() { } + } From fcef46a7c96c969be42b7d6cbb335f98e43d6c06 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 17:55:57 +0900 Subject: [PATCH 28/62] =?UTF-8?q?feat=20(OutputView)=20:=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=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 --- src/main/java/blackjack/BlackJackGame.java | 2 +- src/main/java/blackjack/domain/Card.java | 8 +++ src/main/java/blackjack/view/OutputView.java | 64 ++++++++++++++++++-- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index 36807c5d25..0ea3bdff2f 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -38,7 +38,7 @@ public void run() { private void playTurn(Player player) { while (player.isDrawable() && inputView.isPlayerWantDraw(player.getName())) { player.add(deck.draw()); - outputView.printCards(); + outputView.printPlayerCards(player); } } } diff --git a/src/main/java/blackjack/domain/Card.java b/src/main/java/blackjack/domain/Card.java index a011e24fae..10eac27852 100644 --- a/src/main/java/blackjack/domain/Card.java +++ b/src/main/java/blackjack/domain/Card.java @@ -37,6 +37,14 @@ public int hashCode() { return Objects.hash(value, shape); } + public Value getValue() { + return value; + } + + public Shape getShape() { + return shape; + } + // TODO 외부 class로 분리 할 것인지 논의, 접근 제어자 논의 public enum Value { ACE(1), diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 3370436806..dbf59398fd 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,21 +1,75 @@ package blackjack.view; +import blackjack.domain.Card; +import blackjack.domain.Card.Shape; +import blackjack.domain.Card.Value; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; public class OutputView { + private static final Map SHAPE_NAME = Map.of( + Shape.HEART, "하트", + Shape.SPADE, "스페이드", + Shape.DIAMOND, "다이아몬드", + Shape.CLOVER, "클로버" + ); + + private static final Map VALUE_NAME = Map.ofEntries( + Map.entry(Value.ACE, "A"), Map.entry(Value.TWO, "2"), + Map.entry(Value.THREE, "3"), Map.entry(Value.FOUR, "4"), + Map.entry(Value.FIVE, "5"), Map.entry(Value.SIX, "6"), + Map.entry(Value.SEVEN, "7"), Map.entry(Value.EIGHT, "8"), + Map.entry(Value.NINE, "9"), Map.entry(Value.TEN, "10"), + Map.entry(Value.JACK, "J"), Map.entry(Value.QUEEN, "Q"), + Map.entry(Value.KING, "K") + ); + + private static final int DEALER_START_CARDS_SIZE = 1; + private static final int PLAYER_START_CARDS_SIZE = 2; + public void printStartCards(Dealer dealer, Players players) { - System.out.println("딜러:" + dealer.getStartCards()); - List allPlayers = players.getPlayers(); - for (Player player : allPlayers) { - System.out.println(player.getName() + ": " + player.getStartCards()); + System.out.println(); + System.out.println("딜러와 " + toPrintedFormat(players) + "에게 2장을 나누었습니다."); + printDealerCards(dealer.getCards().subList(0, DEALER_START_CARDS_SIZE)); + for (Player player : players.getPlayers()) { + printPlayerCards(player.getName(), player.getCards().subList(0, PLAYER_START_CARDS_SIZE)); } + System.out.println(); + } + + private void printDealerCards(List cards) { + System.out.print("딜러: "); + printCards(cards); + } + + public void printPlayerCards(Player player) { + printPlayerCards(player.getName(), player.getCards()); + } + + private void printPlayerCards(String name, List cards) { + System.out.print(name + ": "); + printCards(cards); } - public void printCards() { + private void printCards(List cards) { + String printingFormat = cards.stream() + .map(this::toPrintedFormat) + .collect(Collectors.joining(", ")); + System.out.println(printingFormat); } + private String toPrintedFormat(Players players) { + return players.getPlayers().stream() + .map(Player::getName) + .collect(Collectors.joining(", ")); + } + + private String toPrintedFormat(Card card) { + return VALUE_NAME.get(card.getValue()) + SHAPE_NAME.get(card.getShape()); + } } From f35da092b32d61bb043faffcaf6ef8cf5030212c Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 17:57:09 +0900 Subject: [PATCH 29/62] =?UTF-8?q?refactor=20(Participant)=20:=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EC=B6=9C=EB=A0=A5=20=EA=B0=9C=EC=88=98=EB=A5=BC=20?= =?UTF-8?q?=EC=A0=95=ED=95=98=EB=8A=94=20=EC=B1=85=EC=9E=84=EC=9D=84=20Vie?= =?UTF-8?q?w=EB=A1=9C=20=EB=84=98=EA=B8=B0=EA=B8=B0=20=EC=9C=84=ED=95=B4?= =?UTF-8?q?=20=EC=8B=9C=EC=9E=91=20=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EA=B1=B4?= =?UTF-8?q?=EB=84=A4=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/participant/Dealer.java | 6 ------ .../java/blackjack/domain/participant/Participant.java | 8 -------- src/main/java/blackjack/domain/participant/Player.java | 5 ----- 3 files changed, 19 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 969b83969e..6fc61a96e8 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -7,7 +7,6 @@ public class Dealer extends Participant { private static final int DRAWABLE_MAX_SCORE = 16; - private static final int VISIBLE_START_CARD_SIZE = 1; public Dealer() { super(Collections.emptyList()); @@ -27,11 +26,6 @@ public boolean isWin(Player player) { return this.calculateScore() >= player.calculateScore(); } - @Override - protected int getVisibleStartCardSize() { - return VISIBLE_START_CARD_SIZE; - } - @Override protected int getMaxDrawableScore() { return DRAWABLE_MAX_SCORE; diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 3419506a63..49f57eded8 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -61,13 +61,5 @@ public final List getCards() { return Collections.unmodifiableList(cards); } - public final List getStartCards() { - if (cards.size() < START_CARDS_SIZE) { - throw new IllegalStateException("시작 카드를 가지고 있지 않습니다."); - } - return getCards().subList(0, getVisibleStartCardSize()); - } - - protected abstract int getVisibleStartCardSize(); protected abstract int getMaxDrawableScore(); } diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 5498010d13..27bfb2b3e1 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -22,11 +22,6 @@ public boolean isWin(Dealer dealer) { return !dealer.isWin(this); } - @Override - protected int getVisibleStartCardSize() { - return START_CARDS_SIZE; - } - @Override protected int getMaxDrawableScore() { return BLACKJACK_SCORE; From 7cbb8ca07e7658d2de6ca3e3725c109f3f3086c0 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 19:56:32 +0900 Subject: [PATCH 30/62] =?UTF-8?q?feat=20(Dealer)=20:=20=EB=AA=A8=EB=93=A0?= =?UTF-8?q?=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EB=A5=BC=20=EC=83=81?= =?UTF-8?q?=EB=8C=80=EB=A1=9C=20=EC=8A=B9=ED=8C=A8=EB=A5=BC=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=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 Co-authored-by: zangsu --- .../java/blackjack/domain/participant/Dealer.java | 15 +++++++++++++++ src/main/java/blackjack/dto/MatchResultDto.java | 4 ++++ 2 files changed, 19 insertions(+) create mode 100644 src/main/java/blackjack/dto/MatchResultDto.java diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 6fc61a96e8..d4d68ac2ad 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -1,6 +1,7 @@ package blackjack.domain.participant; import blackjack.domain.Card; +import blackjack.dto.MatchResultDto; import java.util.Collections; import java.util.List; @@ -26,6 +27,20 @@ public boolean isWin(Player player) { return this.calculateScore() >= player.calculateScore(); } + private boolean isLose(Player player) { + return !isWin(player); + } + + public MatchResultDto match(Players players) { + int winCount = (int) players.getPlayers().stream() + .filter(this::isWin) + .count(); + int loseCount = (int) players.getPlayers().stream() + .filter(this::isLose) + .count(); + return new MatchResultDto(winCount, loseCount); + } + @Override protected int getMaxDrawableScore() { return DRAWABLE_MAX_SCORE; diff --git a/src/main/java/blackjack/dto/MatchResultDto.java b/src/main/java/blackjack/dto/MatchResultDto.java new file mode 100644 index 0000000000..b17868ac01 --- /dev/null +++ b/src/main/java/blackjack/dto/MatchResultDto.java @@ -0,0 +1,4 @@ +package blackjack.dto; + +public record MatchResultDto(int winCount, int loseCount) { +} From f3968ade603f543da73cd6a87295d72a11422a9a Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 19:56:55 +0900 Subject: [PATCH 31/62] =?UTF-8?q?feat=20(OutputView)=20:=20=EC=B5=9C?= =?UTF-8?q?=EC=A2=85=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/BlackJackGame.java | 11 +++-- src/main/java/blackjack/view/OutputView.java | 46 ++++++++++++++++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index 0ea3bdff2f..0032e8d073 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -22,17 +22,20 @@ public void run() { dealer.drawStartCards(deck); players.drawStartCards(deck); - // TODO 카드 출력하기 outputView.printStartCards(dealer, players); players.play(this::playTurn); while (dealer.isDrawable()) { - // TODO 출력 -> 딜러는 16이하라 한장의 카드를 더 받았습니다. + outputView.printDealerDraw(); dealer.add(deck.draw()); } - // TODO 딜러, 플레이어들 카드 결과 및 점수 출력 - // TODO 딜러, 플레이어의 최종 승패 출력 + outputView.printResultCardAndScore(dealer, players); + + outputView.printDealerMatchResult(dealer.match(players)); + for (Player player : players.getPlayers()) { + outputView.printPlayerMatchResult(player.getName(), player.isWin(dealer)); + } } private void playTurn(Player player) { diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index dbf59398fd..ce23382d6e 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -6,6 +6,7 @@ import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; +import blackjack.dto.MatchResultDto; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -36,23 +37,44 @@ public void printStartCards(Dealer dealer, Players players) { System.out.println(); System.out.println("딜러와 " + toPrintedFormat(players) + "에게 2장을 나누었습니다."); printDealerCards(dealer.getCards().subList(0, DEALER_START_CARDS_SIZE)); + System.out.println(); for (Player player : players.getPlayers()) { printPlayerCards(player.getName(), player.getCards().subList(0, PLAYER_START_CARDS_SIZE)); + System.out.println(); + } + System.out.println(); + } + + public void printResultCardAndScore(Dealer dealer, Players players) { + System.out.println(); + System.out.println(); + printDealerCards(dealer.getCards()); + printScore(dealer.calculateScore()); + System.out.println(); + for (Player player : players.getPlayers()) { + printPlayerCards(player.getName(), player.getCards()); + printScore(player.calculateScore()); + System.out.println(); } System.out.println(); } + private void printScore(int score) { + System.out.print(" - 결과 : " + score); + } + private void printDealerCards(List cards) { - System.out.print("딜러: "); + System.out.print("딜러 카드: "); printCards(cards); } public void printPlayerCards(Player player) { printPlayerCards(player.getName(), player.getCards()); + System.out.println(); } private void printPlayerCards(String name, List cards) { - System.out.print(name + ": "); + System.out.print(name + "카드: "); printCards(cards); } @@ -60,7 +82,7 @@ private void printCards(List cards) { String printingFormat = cards.stream() .map(this::toPrintedFormat) .collect(Collectors.joining(", ")); - System.out.println(printingFormat); + System.out.print(printingFormat); } private String toPrintedFormat(Players players) { @@ -72,4 +94,22 @@ private String toPrintedFormat(Players players) { private String toPrintedFormat(Card card) { return VALUE_NAME.get(card.getValue()) + SHAPE_NAME.get(card.getShape()); } + + public void printDealerDraw() { + System.out.println(); + System.out.print("딜러는 16이하라 한장의 카드를 더 받았습니다."); + } + + public void printDealerMatchResult(MatchResultDto matchResult) { + System.out.println("## 최종 승패"); + System.out.printf("딜러 : %d승 %d패%n", matchResult.winCount(), matchResult.loseCount()); + } + + public void printPlayerMatchResult(String name, boolean isWin) { + if (isWin) { + System.out.println(name + ": 승"); + return; + } + System.out.println(name + ": 패"); + } } From 7c070798162a235d122d13cb6d2534d669dff46f Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 20:13:32 +0900 Subject: [PATCH 32/62] =?UTF-8?q?refactor=20(Participant)=20:=20=EC=B9=B4?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=90=EC=88=98=20=EA=B3=84=EC=82=B0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EC=9D=98=20=EC=9D=B8=EB=8D=B4=ED=8A=B8=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../domain/participant/Participant.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 49f57eded8..28ad3561a5 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -18,20 +18,22 @@ protected Participant(List cards) { } public final int calculateScore() { - int score = cards.stream() - .mapToInt(Card::getMaxScore) - .sum(); - - //TODO 인덴트 해결하기 - for (Card card : cards) { - if (score <= BLACKJACK_SCORE) { - return score; - } + int score = getMaxScore(); + int cardIndex = 0; + while (score > BLACKJACK_SCORE && cardIndex < cards.size()) { + Card card = cards.get(cardIndex); score = score + card.getMinScore() - card.getMaxScore(); + cardIndex++; } return score; } + private int getMaxScore() { + return cards.stream() + .mapToInt(Card::getMaxScore) + .sum(); + } + public final boolean isDrawable() { return calculateScore() <= getMaxDrawableScore(); } From dddca7cce77062bd12bc9632617997e8c721e1a4 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 20:27:52 +0900 Subject: [PATCH 33/62] =?UTF-8?q?style=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=9D=98=20DisplayName=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/test/java/blackjack/domain/participant/DealerTest.java | 4 +--- src/test/java/blackjack/domain/participant/PlayerTest.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index c6cdb985ba..d1aed2f693 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -18,7 +18,6 @@ class DealerTest { - //TODO DisplayName 수정 @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnder16_returnTrue() { @@ -28,7 +27,6 @@ void isDrawableTest_whenScoreIsUnder16_returnTrue() { assertThat(dealer.isDrawable()).isTrue(); } - //TODO DisplayName 수정 @DisplayName("카드의 총 점수가 17을 넘으면, 카드를 더 뽑을 수 없다") @Test void isDrawableTest_whenScoreIsOver17_returnFalse() { @@ -97,7 +95,7 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { .hasMessage("이미 시작 카드를 뽑았습니다."); } - @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 한 장 뽑을 수 있다") + @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 한 장 뽑는다") @Test void addTest_whenScoreIsUnder16() { Dealer dealer = new Dealer(List.of( diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 7c762cb058..25ce25b92c 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -37,7 +37,6 @@ static Stream provideCardsAndScore() { Arguments.of(List.of(new Card(Value.KING, Shape.HEART), new Card(Value.TWO, Shape.HEART)), 12)); } - //TODO DisplayName 수정 @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnder21_returnTrue() { @@ -51,7 +50,6 @@ void isDrawableTest_whenScoreIsUnder21_returnTrue() { assertThat(player.isDrawable()).isTrue(); } - //TODO DisplayName 수정 @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 더 뽑을 수 없다") @Test void isDrawableTest_whenScoreIsOver21_returnFalse() { @@ -88,7 +86,7 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { .hasMessage("이미 시작 카드를 뽑았습니다."); } - @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 한 장 뽑을 수 있다") + @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 한 장 뽑는다") @Test void addTest_whenScoreIsUnder21() { Player player = new Player(List.of( From 785590dd318faaa1f15cc5bd57913267cf7e6e20 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 20:36:14 +0900 Subject: [PATCH 34/62] =?UTF-8?q?refactor=20(Card)=20:=20Value,=20Shape=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/Deck.java | 6 ++- .../blackjack/domain/{ => card}/Card.java | 40 +------------------ .../java/blackjack/domain/card/Shape.java | 5 +++ .../java/blackjack/domain/card/Value.java | 34 ++++++++++++++++ .../blackjack/domain/participant/Dealer.java | 2 +- .../domain/participant/Participant.java | 3 +- .../blackjack/domain/participant/Player.java | 2 +- src/main/java/blackjack/view/OutputView.java | 11 ++--- src/test/java/blackjack/domain/CardTest.java | 13 +++--- .../domain/participant/DealerTest.java | 6 +-- .../domain/participant/PlayerTest.java | 6 +-- 11 files changed, 67 insertions(+), 61 deletions(-) rename src/main/java/blackjack/domain/{ => card}/Card.java (53%) create mode 100644 src/main/java/blackjack/domain/card/Shape.java create mode 100644 src/main/java/blackjack/domain/card/Value.java diff --git a/src/main/java/blackjack/domain/Deck.java b/src/main/java/blackjack/domain/Deck.java index d321df502d..726105664e 100644 --- a/src/main/java/blackjack/domain/Deck.java +++ b/src/main/java/blackjack/domain/Deck.java @@ -2,7 +2,9 @@ import static java.util.stream.Collectors.toList; -import blackjack.domain.Card.Shape; +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Value; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; @@ -27,7 +29,7 @@ public static Deck createShuffledDeck() { } private static List makeCards(Shape shape) { - return Arrays.stream(Card.Value.values()) + return Arrays.stream(Value.values()) .map(value -> new Card(value, shape)) .toList(); } diff --git a/src/main/java/blackjack/domain/Card.java b/src/main/java/blackjack/domain/card/Card.java similarity index 53% rename from src/main/java/blackjack/domain/Card.java rename to src/main/java/blackjack/domain/card/Card.java index 10eac27852..356458ce62 100644 --- a/src/main/java/blackjack/domain/Card.java +++ b/src/main/java/blackjack/domain/card/Card.java @@ -1,4 +1,4 @@ -package blackjack.domain; +package blackjack.domain.card; import java.util.Objects; @@ -44,42 +44,4 @@ public Value getValue() { public Shape getShape() { return shape; } - - // TODO 외부 class로 분리 할 것인지 논의, 접근 제어자 논의 - public enum Value { - 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 minScore; - - Value(int minScore) { - this.minScore = minScore; - } - - public int getMinScore() { - return minScore; - } - - public int getMaxScore() { - if (this == ACE) { - return minScore + 10; - } - return minScore; - } - } - - public enum Shape { - SPADE, DIAMOND, HEART, CLOVER - } } diff --git a/src/main/java/blackjack/domain/card/Shape.java b/src/main/java/blackjack/domain/card/Shape.java new file mode 100644 index 0000000000..292d024bab --- /dev/null +++ b/src/main/java/blackjack/domain/card/Shape.java @@ -0,0 +1,5 @@ +package blackjack.domain.card; + +public enum Shape { + SPADE, DIAMOND, HEART, CLOVER +} diff --git a/src/main/java/blackjack/domain/card/Value.java b/src/main/java/blackjack/domain/card/Value.java new file mode 100644 index 0000000000..8dc2b18b56 --- /dev/null +++ b/src/main/java/blackjack/domain/card/Value.java @@ -0,0 +1,34 @@ +package blackjack.domain.card; + +public enum Value { + 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 minScore; + + Value(int minScore) { + this.minScore = minScore; + } + + public int getMinScore() { + return minScore; + } + + public int getMaxScore() { + if (this == ACE) { + return minScore + 10; + } + return minScore; + } +} diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index d4d68ac2ad..5037220bec 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -1,6 +1,6 @@ package blackjack.domain.participant; -import blackjack.domain.Card; +import blackjack.domain.card.Card; import blackjack.dto.MatchResultDto; import java.util.Collections; import java.util.List; diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 28ad3561a5..9e26534854 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -1,7 +1,7 @@ package blackjack.domain.participant; -import blackjack.domain.Card; import blackjack.domain.Deck; +import blackjack.domain.card.Card; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -51,7 +51,6 @@ public void drawStartCards(Deck deck) { } } - //TODO : 시작 카드를 뽑은 이후에 호출 가능해야 한다. public final void add(Card card) { if (!isDrawable()) { throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 27bfb2b3e1..6c870e3c6e 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -1,6 +1,6 @@ package blackjack.domain.participant; -import blackjack.domain.Card; +import blackjack.domain.card.Card; import java.util.Collections; import java.util.List; import java.util.Objects; diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index ce23382d6e..95515a5453 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,8 +1,8 @@ package blackjack.view; -import blackjack.domain.Card; -import blackjack.domain.Card.Shape; -import blackjack.domain.Card.Value; +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Value; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; @@ -11,16 +11,17 @@ import java.util.Map; import java.util.stream.Collectors; +// TODO 메서드 순서 및 private 메서드 기능 재정리 public class OutputView { - private static final Map SHAPE_NAME = Map.of( + private static final Map SHAPE_NAME = Map.of( Shape.HEART, "하트", Shape.SPADE, "스페이드", Shape.DIAMOND, "다이아몬드", Shape.CLOVER, "클로버" ); - private static final Map VALUE_NAME = Map.ofEntries( + private static final Map VALUE_NAME = Map.ofEntries( Map.entry(Value.ACE, "A"), Map.entry(Value.TWO, "2"), Map.entry(Value.THREE, "3"), Map.entry(Value.FOUR, "4"), Map.entry(Value.FIVE, "5"), Map.entry(Value.SIX, "6"), diff --git a/src/test/java/blackjack/domain/CardTest.java b/src/test/java/blackjack/domain/CardTest.java index 5f410c02bf..dd8f30fd30 100644 --- a/src/test/java/blackjack/domain/CardTest.java +++ b/src/test/java/blackjack/domain/CardTest.java @@ -3,6 +3,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Value; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -19,8 +22,8 @@ class CardScoreTest { @DisplayName("숫자 카드는 카드의 숫자 값을 점수로 가진다") @ParameterizedTest @CsvSource({"TWO, 2", "TEN, 10"}) - void scoreTest_whenNumberCard(Card.Value value, int expected) { - Card card = new Card(value, Card.Shape.CLOVER); + void scoreTest_whenNumberCard(Value value, int expected) { + Card card = new Card(value, Shape.CLOVER); assertAll( () -> assertThat(card.getMinScore()).isEqualTo(expected), @@ -31,8 +34,8 @@ void scoreTest_whenNumberCard(Card.Value value, int expected) { @DisplayName("Jack, Queen, King 카드는 모두 10점을 가진다.") @ParameterizedTest @EnumSource(names = {"JACK", "QUEEN", "KING"}) - void scoreTest_whenJQK_Card(Card.Value value) { - Card card = new Card(value, Card.Shape.HEART); + void scoreTest_whenJQK_Card(Value value) { + Card card = new Card(value, Shape.HEART); assertAll( () -> assertThat(card.getMinScore()).isEqualTo(10), @@ -43,7 +46,7 @@ void scoreTest_whenJQK_Card(Card.Value value) { @DisplayName("Ace 카드는 1, 또는 11점을 가진다.") @Test void scoreTest_whenAceCard() { - Card card = new Card(Card.Value.ACE, Card.Shape.HEART); + Card card = new Card(Value.ACE, Shape.HEART); assertAll( () -> assertThat(card.getMinScore()).isEqualTo(1), diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index d1aed2f693..13fcc4cde8 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -3,10 +3,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import blackjack.domain.Card; -import blackjack.domain.Card.Shape; -import blackjack.domain.Card.Value; import blackjack.domain.Deck; +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Value; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 25ce25b92c..6bf0a135af 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -3,10 +3,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import blackjack.domain.Card; -import blackjack.domain.Card.Shape; -import blackjack.domain.Card.Value; import blackjack.domain.Deck; +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Value; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; From bf6367079e5ffc96b08b628c868960e6741b3b28 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 20:47:53 +0900 Subject: [PATCH 35/62] =?UTF-8?q?refactor=20(BlackJackGame)=20:=20?= =?UTF-8?q?=EA=B0=80=EB=8F=85=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=B4=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/BlackJackGame.java | 35 ++++++++++++------- .../blackjack/domain/participant/Players.java | 6 ++-- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index 0032e8d073..e08970e487 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -10,38 +10,49 @@ public class BlackJackGame { - //TODO 2개로 줄이기 (논의사항) private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); - private final Deck deck = Deck.createShuffledDeck(); public void run() { + Deck deck = Deck.createShuffledDeck(); Dealer dealer = new Dealer(); + Players players = createPlayers(); + drawStartCards(dealer, players, deck); + play(players, dealer, deck); + printResult(dealer, players); + } + + private Players createPlayers() { List names = inputView.inputPlayerNames(); - Players players = Players.from(names); + return Players.from(names); + } + private void drawStartCards(Dealer dealer, Players players, Deck deck) { dealer.drawStartCards(deck); players.drawStartCards(deck); outputView.printStartCards(dealer, players); + } - players.play(this::playTurn); + private void play(Players players, Dealer dealer, Deck deck) { + players.play(this::playTurn, deck); while (dealer.isDrawable()) { outputView.printDealerDraw(); dealer.add(deck.draw()); } - - outputView.printResultCardAndScore(dealer, players); - - outputView.printDealerMatchResult(dealer.match(players)); - for (Player player : players.getPlayers()) { - outputView.printPlayerMatchResult(player.getName(), player.isWin(dealer)); - } } - private void playTurn(Player player) { + private void playTurn(Player player, Deck deck) { while (player.isDrawable() && inputView.isPlayerWantDraw(player.getName())) { player.add(deck.draw()); outputView.printPlayerCards(player); } } + + private void printResult(Dealer dealer, Players players) { + outputView.printResultCardAndScore(dealer, players); + outputView.printDealerMatchResult(dealer.match(players)); + for (Player player : players.getPlayers()) { + outputView.printPlayerMatchResult(player.getName(), player.isWin(dealer)); + } + } } diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 8bf37bc085..ec9d18e8c7 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -2,6 +2,7 @@ import blackjack.domain.Deck; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; public class Players { @@ -48,14 +49,13 @@ public void drawStartCards(Deck deck) { } } - //TODO 현재 얘는 테스트만을 위해서 임시로 작성된 코드 public List getPlayers() { return players; } - public void play(Consumer playTurn) { + public void play(BiConsumer playTurn, Deck deck) { for (Player player : players) { - playTurn.accept(player); + playTurn.accept(player, deck); } } } From c23e7d2510714de1c226e907c6ae777e34073128 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 21:01:13 +0900 Subject: [PATCH 36/62] =?UTF-8?q?refactor=20(OutputView)=20:=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=88=9C=EC=84=9C=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/OutputView.java | 41 ++++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 95515a5453..1b27de189d 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -11,7 +11,6 @@ import java.util.Map; import java.util.stream.Collectors; -// TODO 메서드 순서 및 private 메서드 기능 재정리 public class OutputView { private static final Map SHAPE_NAME = Map.of( @@ -39,10 +38,7 @@ public void printStartCards(Dealer dealer, Players players) { System.out.println("딜러와 " + toPrintedFormat(players) + "에게 2장을 나누었습니다."); printDealerCards(dealer.getCards().subList(0, DEALER_START_CARDS_SIZE)); System.out.println(); - for (Player player : players.getPlayers()) { - printPlayerCards(player.getName(), player.getCards().subList(0, PLAYER_START_CARDS_SIZE)); - System.out.println(); - } + printPlayersCards(players); System.out.println(); } @@ -52,16 +48,15 @@ public void printResultCardAndScore(Dealer dealer, Players players) { printDealerCards(dealer.getCards()); printScore(dealer.calculateScore()); System.out.println(); - for (Player player : players.getPlayers()) { - printPlayerCards(player.getName(), player.getCards()); - printScore(player.calculateScore()); - System.out.println(); - } + printPlayersCardAndScore(players); System.out.println(); } - private void printScore(int score) { - System.out.print(" - 결과 : " + score); + private void printPlayersCards(Players players) { + for (Player player : players.getPlayers()) { + printPlayerCards(player.getName(), player.getCards().subList(0, PLAYER_START_CARDS_SIZE)); + System.out.println(); + } } private void printDealerCards(List cards) { @@ -69,16 +64,24 @@ private void printDealerCards(List cards) { printCards(cards); } - public void printPlayerCards(Player player) { - printPlayerCards(player.getName(), player.getCards()); - System.out.println(); - } - private void printPlayerCards(String name, List cards) { System.out.print(name + "카드: "); printCards(cards); } + private void printPlayersCardAndScore(Players players) { + for (Player player : players.getPlayers()) { + printPlayerCards(player.getName(), player.getCards()); + printScore(player.calculateScore()); + System.out.println(); + } + } + + public void printPlayerCards(Player player) { + printPlayerCards(player.getName(), player.getCards()); + System.out.println(); + } + private void printCards(List cards) { String printingFormat = cards.stream() .map(this::toPrintedFormat) @@ -86,6 +89,10 @@ private void printCards(List cards) { System.out.print(printingFormat); } + private void printScore(int score) { + System.out.print(" - 결과 : " + score); + } + private String toPrintedFormat(Players players) { return players.getPlayers().stream() .map(Player::getName) From 116a613271f4c2d02c08f9fdf6aee334ee421674 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 21:29:34 +0900 Subject: [PATCH 37/62] =?UTF-8?q?refactor=20(CardTest)=20:=20=EB=8B=A4?= =?UTF-8?q?=EC=96=91=ED=95=9C=20=EC=83=81=ED=99=A9=EC=9D=98=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=EB=93=A4=EC=9D=84=20=ED=94=BD=EC=8A=A4=EC=B3=90?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/test/java/blackjack/domain/CardTest.java | 42 +++++ .../domain/participant/DealerTest.java | 143 +++++------------- .../domain/participant/PlayerTest.java | 63 +++----- .../domain/participant/PlayersTest.java | 2 + 4 files changed, 104 insertions(+), 146 deletions(-) diff --git a/src/test/java/blackjack/domain/CardTest.java b/src/test/java/blackjack/domain/CardTest.java index dd8f30fd30..916fe6c250 100644 --- a/src/test/java/blackjack/domain/CardTest.java +++ b/src/test/java/blackjack/domain/CardTest.java @@ -6,6 +6,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Shape; import blackjack.domain.card.Value; +import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -15,6 +16,47 @@ public class CardTest { + public static final List CARDS_SCORE_4 = List.of( + new Card(Value.TWO, Shape.HEART), + new Card(Value.TWO, Shape.SPADE) + ); + public static final List TWO_ACE = List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.ACE, Shape.SPADE) + ); + public static final List SCORE_13_WITH_ACE = List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ); + public static final List CARDS_SCORE_16 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.SIX, Shape.HEART) + ); + public static final List CARDS_SCORE_17 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + ); + public static final List CARDS_SCORE_21 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.EIGHT, Shape.HEART), + new Card(Value.THREE, Shape.HEART) + ); + public static final List BLACKJACK = List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART) + ); + public static final List CARDS_SCORE_22 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART), + new Card(Value.FIVE, Shape.HEART) + ); + public static final List BUSTED = List.of( + new Card(Value.KING, Shape.DIAMOND), + new Card(Value.QUEEN, Shape.DIAMOND), + new Card(Value.JACK, Shape.DIAMOND) + ); + @DisplayName("카드 값에 따라 점수를 확인할 수 있다") @Nested class CardScoreTest { diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 13fcc4cde8..e8c72ef2d8 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.domain.CardTest; import blackjack.domain.Deck; import blackjack.domain.card.Card; import blackjack.domain.card.Shape; @@ -18,11 +19,19 @@ class DealerTest { + private static final List CARDS_SCORE_4 = CardTest.CARDS_SCORE_4; + private static final List TWO_ACE = CardTest.TWO_ACE; + private static final List SCORE_13_WITH_ACE = CardTest.SCORE_13_WITH_ACE; + private static final List CARDS_SCORE_16 = CardTest.CARDS_SCORE_16; + private static final List CARDS_SCORE_17 = CardTest.CARDS_SCORE_17; + private static final List BLACKJACK = CardTest.BLACKJACK; + private static final List BUSTED = CardTest.BUSTED; + private static final Name DEFAULT_NAME = new Name("name"); + @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnder16_returnTrue() { - List CardsScore16 = List.of(new Card(Value.JACK, Shape.HEART), new Card(Value.SIX, Shape.HEART)); - Dealer dealer = new Dealer(CardsScore16); + Dealer dealer = new Dealer(CARDS_SCORE_16); assertThat(dealer.isDrawable()).isTrue(); } @@ -30,8 +39,7 @@ void isDrawableTest_whenScoreIsUnder16_returnTrue() { @DisplayName("카드의 총 점수가 17을 넘으면, 카드를 더 뽑을 수 없다") @Test void isDrawableTest_whenScoreIsOver17_returnFalse() { - List CardsScore17 = List.of(new Card(Value.JACK, Shape.HEART), new Card(Value.SEVEN, Shape.HEART)); - Dealer dealer = new Dealer(CardsScore17); + Dealer dealer = new Dealer(CARDS_SCORE_17); assertThat(dealer.isDrawable()).isFalse(); } @@ -47,28 +55,10 @@ void calculateScoreTest(List cards, int expected) { // TODO Fixture로 추출하기 static Stream provideCardsAndScore() { - return Stream.of( - Arguments.of( - List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.KING, Shape.HEART) - ), 21), - Arguments.of( - List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.ACE, Shape.SPADE) - ), 12), - Arguments.of( - List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.KING, Shape.HEART), - new Card(Value.TWO, Shape.HEART) - ), 13), - Arguments.of( - List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.TWO, Shape.HEART) - ), 12) + return Stream.of(Arguments.of(BLACKJACK, 21), + Arguments.of(TWO_ACE, 12), + Arguments.of(SCORE_13_WITH_ACE, 13), + Arguments.of(CARDS_SCORE_16, 16) ); } @@ -98,27 +88,21 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 한 장 뽑는다") @Test void addTest_whenScoreIsUnder16() { - Dealer dealer = new Dealer(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SIX, Shape.HEART) - )); + Dealer dealer = new Dealer(CARDS_SCORE_16); - dealer.add(new Card(Value.ACE, Shape.HEART)); + Card additionalCard = new Card(Value.ACE, Shape.HEART); + dealer.add(additionalCard); - assertThat(dealer.getCards()).containsExactly( - new Card(Value.KING, Shape.HEART), - new Card(Value.SIX, Shape.HEART), - new Card(Value.ACE, Shape.HEART) - ); + assertThat(dealer.getCards()) + .containsAll(CARDS_SCORE_16) + .contains(additionalCard) + .hasSize(3); } @DisplayName("카드의 총 점수가 16을 넘으면, 카드를 뽑을 때 예외가 발생한다.") @Test void addTest_whenScoreIsOver16_throwException() { - Dealer dealer = new Dealer(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART) - )); + Dealer dealer = new Dealer(CARDS_SCORE_17); Card card = new Card(Value.ACE, Shape.HEART); assertThatThrownBy(() -> dealer.add(card)) @@ -135,35 +119,13 @@ class IsWinTest { @MethodSource("provideDealerCards") void whenPlayerBusted_dealerWin(List cards) { Dealer dealer = new Dealer(cards); - Player player = new Player(List.of( - new Card(Value.KING, Shape.DIAMOND), - new Card(Value.QUEEN, Shape.DIAMOND), - new Card(Value.JACK, Shape.DIAMOND) - ), new Name("name")); + Player player = new Player(BUSTED, DEFAULT_NAME); assertThat(dealer.isWin(player)).isTrue(); } static Stream> provideDealerCards() { - return Stream.of( - List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.KING, Shape.HEART) - ), - List.of( - new Card(Value.TWO, Shape.HEART), - new Card(Value.TWO, Shape.SPADE) - ), - List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.TWO, Shape.HEART) - ), - List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.QUEEN, Shape.HEART), - new Card(Value.JACK, Shape.HEART) - ) - ); + return Stream.of(BLACKJACK, CARDS_SCORE_4, CARDS_SCORE_16, BUSTED); } @DisplayName("딜러만 21을 넘길 경우, 플레이어가 이긴다.") @@ -171,45 +133,22 @@ static Stream> provideDealerCards() { @MethodSource("providePlayerCards") void whenOnlyDealerBusted_playerWin(List cards) { - Dealer dealer = new Dealer(List.of( - new Card(Value.KING, Shape.DIAMOND), - new Card(Value.QUEEN, Shape.DIAMOND), - new Card(Value.JACK, Shape.DIAMOND) - )); - Player player = new Player(cards, new Name("name")); + Dealer dealer = new Dealer(BUSTED); + Player player = new Player(cards, DEFAULT_NAME); assertThat(dealer.isWin(player)).isFalse(); } //TODO 픽스쳐 생성 static Stream> providePlayerCards() { - return Stream.of( - List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.KING, Shape.HEART) - ), - List.of( - new Card(Value.TWO, Shape.HEART), - new Card(Value.TWO, Shape.SPADE) - ), - List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.TWO, Shape.HEART) - ) - ); + return Stream.of(BLACKJACK, CARDS_SCORE_4, CARDS_SCORE_16); } @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 크다면 플레이어가 이긴다.") @Test void whenPlayerScoreIsBiggerThanDealerScore_playerWin() { - Player player = new Player(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART) - ), new Name("name")); - Dealer dealer = new Dealer(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SIX, Shape.HEART) - )); + Player player = new Player(CARDS_SCORE_17, DEFAULT_NAME); + Dealer dealer = new Dealer(CARDS_SCORE_16); assertThat(dealer.isWin(player)).isFalse(); } @@ -217,14 +156,8 @@ void whenPlayerScoreIsBiggerThanDealerScore_playerWin() { @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 같다면 딜러가 이긴다.") @Test void whenPlayerScoreIsEqualToDealerScore_dealerWin() { - Player player = new Player(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART) - ), new Name("name")); - Dealer dealer = new Dealer(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART) - )); + Player player = new Player(CARDS_SCORE_17, DEFAULT_NAME); + Dealer dealer = new Dealer(CARDS_SCORE_17); assertThat(dealer.isWin(player)).isTrue(); } @@ -232,14 +165,8 @@ void whenPlayerScoreIsEqualToDealerScore_dealerWin() { @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 작다면 딜러가 이긴다.") @Test void whenPlayerScoreIsSmallerThanDealerScore_dealerWin() { - Player player = new Player(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SIX, Shape.HEART) - ), new Name("name")); - Dealer dealer = new Dealer(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART) - )); + Player player = new Player(CARDS_SCORE_16, DEFAULT_NAME); + Dealer dealer = new Dealer(CARDS_SCORE_17); assertThat(dealer.isWin(player)).isTrue(); } diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 6bf0a135af..374ef39d0f 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.domain.CardTest; import blackjack.domain.Deck; import blackjack.domain.card.Card; import blackjack.domain.card.Shape; @@ -17,8 +18,14 @@ class PlayerTest { + private static final List TWO_ACE = CardTest.TWO_ACE; + private static final List SCORE_13_WITH_ACE = CardTest.SCORE_13_WITH_ACE; + private static final List CARDS_SCORE_16 = CardTest.CARDS_SCORE_16; + private static final List CARDS_SCORE_21 = CardTest.CARDS_SCORE_21; + private static final List BLACKJACK = CardTest.BLACKJACK; + private static final List CARDS_SCORE_22 = CardTest.CARDS_SCORE_22; private static final Name DEFAULT_NAME = new Name("name"); - + @DisplayName("점수를 계산할 수 있다.") @ParameterizedTest @MethodSource("provideCardsAndScore") @@ -28,24 +35,18 @@ void calculateScoreTest(List cards, int expected) { assertThat(player.calculateScore()).isEqualTo(expected); } - // TODO Fixture로 추출하기 static Stream provideCardsAndScore() { - return Stream.of(Arguments.of(List.of(new Card(Value.ACE, Shape.HEART), new Card(Value.KING, Shape.HEART)), 21), - Arguments.of(List.of(new Card(Value.ACE, Shape.HEART), new Card(Value.ACE, Shape.SPADE)), 12), - Arguments.of(List.of(new Card(Value.ACE, Shape.HEART), new Card(Value.KING, Shape.HEART), - new Card(Value.TWO, Shape.HEART)), 13), - Arguments.of(List.of(new Card(Value.KING, Shape.HEART), new Card(Value.TWO, Shape.HEART)), 12)); + return Stream.of(Arguments.of(BLACKJACK, 21), + Arguments.of(TWO_ACE, 12), + Arguments.of(SCORE_13_WITH_ACE, 13), + Arguments.of(CARDS_SCORE_16, 16) + ); } @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnder21_returnTrue() { - List CardsScore21 = List.of( - new Card(Value.JACK, Shape.HEART), - new Card(Value.EIGHT, Shape.HEART), - new Card(Value.THREE, Shape.HEART) - ); - Player player = new Player(CardsScore21, DEFAULT_NAME); + Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); assertThat(player.isDrawable()).isTrue(); } @@ -53,12 +54,7 @@ void isDrawableTest_whenScoreIsUnder21_returnTrue() { @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 더 뽑을 수 없다") @Test void isDrawableTest_whenScoreIsOver21_returnFalse() { - List CardsScore22 = List.of( - new Card(Value.JACK, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART), - new Card(Value.FIVE, Shape.HEART) - ); - Player player = new Player(CardsScore22, DEFAULT_NAME); + Player player = new Player(CARDS_SCORE_22, DEFAULT_NAME); assertThat(player.isDrawable()).isFalse(); } @@ -89,30 +85,21 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 한 장 뽑는다") @Test void addTest_whenScoreIsUnder21() { - Player player = new Player(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.NINE, Shape.HEART), - new Card(Value.TWO, Shape.HEART) - ), DEFAULT_NAME); - - player.add(new Card(Value.ACE, Shape.HEART)); - - assertThat(player.getCards()).containsExactly( - new Card(Value.KING, Shape.HEART), - new Card(Value.NINE, Shape.HEART), - new Card(Value.TWO, Shape.HEART), - new Card(Value.ACE, Shape.HEART) - ); + Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); + + Card additionalCard = new Card(Value.ACE, Shape.HEART); + player.add(additionalCard); + + assertThat(player.getCards()) + .containsAll(CARDS_SCORE_21) + .contains(additionalCard) + .hasSize(4); } @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 뽑을 때 예외가 발생한다.") @Test void addTest_whenScoreIsOver21_throwException() { - Player player = new Player(List.of( - new Card(Value.KING, Shape.HEART), - new Card(Value.NINE, Shape.HEART), - new Card(Value.THREE, Shape.HEART) - ), DEFAULT_NAME); + Player player = new Player(CARDS_SCORE_22, DEFAULT_NAME); Card card = new Card(Value.ACE, Shape.HEART); assertThatThrownBy(() -> player.add(card)) diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java index d2c7a5e7ee..3ef508fcfe 100644 --- a/src/test/java/blackjack/domain/participant/PlayersTest.java +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -4,7 +4,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; +import blackjack.domain.CardTest; import blackjack.domain.Deck; +import blackjack.domain.card.Card; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.DisplayName; From 0d2c7d5ad698ad44830e47c3e68f537c014ed803 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 21:38:26 +0900 Subject: [PATCH 38/62] =?UTF-8?q?style=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=EC=97=90=EC=84=9C=20=EA=B2=BD=EA=B3=84?= =?UTF-8?q?=EA=B0=92=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/test/java/blackjack/domain/DeckTest.java | 3 +-- .../domain/participant/DealerTest.java | 25 +++++++++---------- .../domain/participant/PlayerTest.java | 17 +++++++------ .../domain/participant/PlayersTest.java | 6 +---- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/test/java/blackjack/domain/DeckTest.java b/src/test/java/blackjack/domain/DeckTest.java index 7827d9fab3..8fecea2791 100644 --- a/src/test/java/blackjack/domain/DeckTest.java +++ b/src/test/java/blackjack/domain/DeckTest.java @@ -16,10 +16,9 @@ void drawTest() { assertThat(deck.draw()).isNotNull(); } - // TODO 테스트 네이밍 고민 @DisplayName("카드는 최대 52장만 뽑을 수 있다.") @Test - void drawTest_whenDraw53Times_throwException() { + void drawTest_drawTooManyTimes_throwException() { Deck deck = Deck.createShuffledDeck(); drawRepeat(deck, 52); diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index e8c72ef2d8..3825f487e3 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -30,7 +30,7 @@ class DealerTest { @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test - void isDrawableTest_whenScoreIsUnder16_returnTrue() { + void isDrawableTest_whenScoreIsUnderBound_returnTrue() { Dealer dealer = new Dealer(CARDS_SCORE_16); assertThat(dealer.isDrawable()).isTrue(); @@ -38,7 +38,7 @@ void isDrawableTest_whenScoreIsUnder16_returnTrue() { @DisplayName("카드의 총 점수가 17을 넘으면, 카드를 더 뽑을 수 없다") @Test - void isDrawableTest_whenScoreIsOver17_returnFalse() { + void isDrawableTest_whenScoreIsOverBound_returnFalse() { Dealer dealer = new Dealer(CARDS_SCORE_17); assertThat(dealer.isDrawable()).isFalse(); @@ -46,16 +46,16 @@ void isDrawableTest_whenScoreIsOver17_returnFalse() { @DisplayName("점수를 계산할 수 있다.") @ParameterizedTest - @MethodSource("provideCardsAndScore") + @MethodSource("cardsAndScore") void calculateScoreTest(List cards, int expected) { Dealer dealer = new Dealer(cards); assertThat(dealer.calculateScore()).isEqualTo(expected); } - // TODO Fixture로 추출하기 - static Stream provideCardsAndScore() { - return Stream.of(Arguments.of(BLACKJACK, 21), + static Stream cardsAndScore() { + return Stream.of( + Arguments.of(BLACKJACK, 21), Arguments.of(TWO_ACE, 12), Arguments.of(SCORE_13_WITH_ACE, 13), Arguments.of(CARDS_SCORE_16, 16) @@ -87,7 +87,7 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 한 장 뽑는다") @Test - void addTest_whenScoreIsUnder16() { + void addTest_whenScoreIsUnderBound() { Dealer dealer = new Dealer(CARDS_SCORE_16); Card additionalCard = new Card(Value.ACE, Shape.HEART); @@ -101,7 +101,7 @@ void addTest_whenScoreIsUnder16() { @DisplayName("카드의 총 점수가 16을 넘으면, 카드를 뽑을 때 예외가 발생한다.") @Test - void addTest_whenScoreIsOver16_throwException() { + void addTest_whenScoreIsOverBound_throwException() { Dealer dealer = new Dealer(CARDS_SCORE_17); Card card = new Card(Value.ACE, Shape.HEART); @@ -116,7 +116,7 @@ class IsWinTest { @DisplayName("플레이어가 21일 넘을 경우, 딜러가 이긴다.") @ParameterizedTest - @MethodSource("provideDealerCards") + @MethodSource("dealerCards") void whenPlayerBusted_dealerWin(List cards) { Dealer dealer = new Dealer(cards); Player player = new Player(BUSTED, DEFAULT_NAME); @@ -124,13 +124,13 @@ void whenPlayerBusted_dealerWin(List cards) { assertThat(dealer.isWin(player)).isTrue(); } - static Stream> provideDealerCards() { + static Stream> dealerCards() { return Stream.of(BLACKJACK, CARDS_SCORE_4, CARDS_SCORE_16, BUSTED); } @DisplayName("딜러만 21을 넘길 경우, 플레이어가 이긴다.") @ParameterizedTest - @MethodSource("providePlayerCards") + @MethodSource("playerCards") void whenOnlyDealerBusted_playerWin(List cards) { Dealer dealer = new Dealer(BUSTED); @@ -139,8 +139,7 @@ void whenOnlyDealerBusted_playerWin(List cards) { assertThat(dealer.isWin(player)).isFalse(); } - //TODO 픽스쳐 생성 - static Stream> providePlayerCards() { + static Stream> playerCards() { return Stream.of(BLACKJACK, CARDS_SCORE_4, CARDS_SCORE_16); } diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 374ef39d0f..ce690e6e11 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -25,18 +25,19 @@ class PlayerTest { private static final List BLACKJACK = CardTest.BLACKJACK; private static final List CARDS_SCORE_22 = CardTest.CARDS_SCORE_22; private static final Name DEFAULT_NAME = new Name("name"); - + @DisplayName("점수를 계산할 수 있다.") @ParameterizedTest - @MethodSource("provideCardsAndScore") + @MethodSource("cardsAndScore") void calculateScoreTest(List cards, int expected) { Player player = new Player(cards, DEFAULT_NAME); assertThat(player.calculateScore()).isEqualTo(expected); } - static Stream provideCardsAndScore() { - return Stream.of(Arguments.of(BLACKJACK, 21), + static Stream cardsAndScore() { + return Stream.of( + Arguments.of(BLACKJACK, 21), Arguments.of(TWO_ACE, 12), Arguments.of(SCORE_13_WITH_ACE, 13), Arguments.of(CARDS_SCORE_16, 16) @@ -45,7 +46,7 @@ static Stream provideCardsAndScore() { @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test - void isDrawableTest_whenScoreIsUnder21_returnTrue() { + void isDrawableTest_whenScoreIsUnderBound_returnTrue() { Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); assertThat(player.isDrawable()).isTrue(); @@ -53,7 +54,7 @@ void isDrawableTest_whenScoreIsUnder21_returnTrue() { @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 더 뽑을 수 없다") @Test - void isDrawableTest_whenScoreIsOver21_returnFalse() { + void isDrawableTest_whenScoreIsOverBound_returnFalse() { Player player = new Player(CARDS_SCORE_22, DEFAULT_NAME); assertThat(player.isDrawable()).isFalse(); @@ -84,7 +85,7 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 한 장 뽑는다") @Test - void addTest_whenScoreIsUnder21() { + void addTest_whenScoreIsUnderBound() { Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); Card additionalCard = new Card(Value.ACE, Shape.HEART); @@ -98,7 +99,7 @@ void addTest_whenScoreIsUnder21() { @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 뽑을 때 예외가 발생한다.") @Test - void addTest_whenScoreIsOver21_throwException() { + void addTest_whenScoreIsOverBound_throwException() { Player player = new Player(CARDS_SCORE_22, DEFAULT_NAME); Card card = new Card(Value.ACE, Shape.HEART); diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java index 3ef508fcfe..e8e457064f 100644 --- a/src/test/java/blackjack/domain/participant/PlayersTest.java +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -4,15 +4,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; -import blackjack.domain.CardTest; import blackjack.domain.Deck; -import blackjack.domain.card.Card; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -//TODO : 테스트 전반적으로 메서드 이름에 경계값 제거 class PlayersTest { @DisplayName("최소 한 명 이상의 플레이어가 존재해야 한다.") @@ -25,7 +22,7 @@ void validateTest_countOfPlayersIsZero_throwException() { @DisplayName("N 명 이상의 플레이어를 가지면 예외가 발생한다.") @Test - void validateTest_countOfPlayersIsOverFour_throwException() { + void validateTest_tooManyPlayers_throwException() { List manyNames = List.of("1", "2", "3", "4", "5"); assertThatThrownBy(() -> Players.from(manyNames)) @@ -56,6 +53,5 @@ void drawStartCardsTest() { () -> assertThat(allPlayers.get(0).getCards()).hasSize(2), () -> assertThat(allPlayers.get(1).getCards()).hasSize(2) ); - } } From 7d5b4e4da29f3cee3a53a9590840edd3d8ebfd58 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 21:39:54 +0900 Subject: [PATCH 39/62] =?UTF-8?q?refactor=20:=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=EC=97=90=20=EA=B4=80=ED=95=9C=20=ED=94=BD=EC=8A=A4=EC=B3=90=20?= =?UTF-8?q?NameTest=EC=97=90=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/test/java/blackjack/domain/participant/DealerTest.java | 2 +- src/test/java/blackjack/domain/participant/NameTest.java | 2 ++ src/test/java/blackjack/domain/participant/PlayerTest.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 3825f487e3..035f255e1c 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -26,7 +26,7 @@ class DealerTest { private static final List CARDS_SCORE_17 = CardTest.CARDS_SCORE_17; private static final List BLACKJACK = CardTest.BLACKJACK; private static final List BUSTED = CardTest.BUSTED; - private static final Name DEFAULT_NAME = new Name("name"); + private static final Name DEFAULT_NAME = NameTest.DEFAULT_NAME; @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test diff --git a/src/test/java/blackjack/domain/participant/NameTest.java b/src/test/java/blackjack/domain/participant/NameTest.java index 486850bbef..973317b0d2 100644 --- a/src/test/java/blackjack/domain/participant/NameTest.java +++ b/src/test/java/blackjack/domain/participant/NameTest.java @@ -10,6 +10,8 @@ class NameTest { + public static final Name DEFAULT_NAME = new Name("name"); + @DisplayName("이름은 적어도 한 글자를 가져야 한다.") @ParameterizedTest @NullAndEmptySource diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index ce690e6e11..25ab972446 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -24,7 +24,7 @@ class PlayerTest { private static final List CARDS_SCORE_21 = CardTest.CARDS_SCORE_21; private static final List BLACKJACK = CardTest.BLACKJACK; private static final List CARDS_SCORE_22 = CardTest.CARDS_SCORE_22; - private static final Name DEFAULT_NAME = new Name("name"); + private static final Name DEFAULT_NAME = NameTest.DEFAULT_NAME; @DisplayName("점수를 계산할 수 있다.") @ParameterizedTest From 10bb3a8e70d21fe6ad12b9e3a322a1e157b70a90 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Thu, 7 Mar 2024 21:41:35 +0900 Subject: [PATCH 40/62] =?UTF-8?q?style=20:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20=EB=AC=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/participant/Players.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index ec9d18e8c7..7982a0c5b5 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -3,7 +3,6 @@ import blackjack.domain.Deck; import java.util.List; import java.util.function.BiConsumer; -import java.util.function.Consumer; public class Players { From 1fa7850a78da52422fd6c3df4516a5dbac63057b Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 8 Mar 2024 14:40:55 +0900 Subject: [PATCH 41/62] =?UTF-8?q?style=20:=20=EC=9D=98=EB=AF=B8=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EA=B3=B5=EB=B0=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/participant/Dealer.java | 2 -- src/main/java/blackjack/domain/participant/Player.java | 1 - 2 files changed, 3 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 5037220bec..21ecfe5bf3 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -45,6 +45,4 @@ public MatchResultDto match(Players players) { protected int getMaxDrawableScore() { return DRAWABLE_MAX_SCORE; } - - } diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index 6c870e3c6e..f49cfbf9d6 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -27,7 +27,6 @@ protected int getMaxDrawableScore() { return BLACKJACK_SCORE; } - public String getName() { return name.getName(); } From 4f2994a8ebde4b408c12eb511b652eec2b6831c6 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 8 Mar 2024 14:42:03 +0900 Subject: [PATCH 42/62] =?UTF-8?q?feat=20:=20=EC=83=9D=EC=84=B1=20=EB=8B=A8?= =?UTF-8?q?=EA=B3=84=EC=97=90=EC=84=9C=20null=EC=9D=84=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EB=B0=9B=EC=95=98=EC=9D=84=20=EA=B2=BD=EC=9A=B0,=20Nu?= =?UTF-8?q?llPointerException=EC=9D=84=20=EB=8D=98=EC=A7=80=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/Card.java | 4 ++-- src/main/java/blackjack/domain/participant/Player.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java index 356458ce62..c6651d338f 100644 --- a/src/main/java/blackjack/domain/card/Card.java +++ b/src/main/java/blackjack/domain/card/Card.java @@ -8,8 +8,8 @@ public class Card { private final Shape shape; public Card(Value value, Shape shape) { - this.value = value; - this.shape = shape; + this.value = Objects.requireNonNull(value); + this.shape = Objects.requireNonNull(shape); } public int getMinScore() { diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index f49cfbf9d6..d23d546ef1 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -11,7 +11,7 @@ public class Player extends Participant { Player(List cards, Name name) { super(cards); - this.name = name; + this.name = Objects.requireNonNull(name); } public static Player from(String name) { From b2c1c91f19036ab7f4641d03d0cdbba5c6fbd54f Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 8 Mar 2024 14:43:37 +0900 Subject: [PATCH 43/62] =?UTF-8?q?refactor=20(Participant)=20:=20=EC=99=B8?= =?UTF-8?q?=EB=B6=80=EC=97=90=EC=84=9C=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B3=80=EC=88=98=EC=9D=98=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EC=A0=9C=EC=96=B4=EC=9E=90=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/participant/Participant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 9e26534854..2af42936dd 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -9,7 +9,7 @@ public abstract class Participant { protected static final int BLACKJACK_SCORE = 21; - protected static final int START_CARDS_SIZE = 2; + private static final int START_CARDS_SIZE = 2; private final List cards; From 4c5d0518ae812e34dee07a4efa2010d42efd576a Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Fri, 8 Mar 2024 14:52:54 +0900 Subject: [PATCH 44/62] =?UTF-8?q?docs=20:=20README=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=EC=97=90=20=EA=B4=80=EB=A0=A8=EB=90=9C=20?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=EB=93=A4=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- README.md | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/README.md b/README.md index a32ee8465e..a37241d90d 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ - 딜러보다 점수가 높거나 딜러의 카드 점수 합이 21을 초과한다. ### 프로그램 진행 순서 + 1. 참가자 이름 입력한다. 2. 카드를 2장씩 나눠준 후에, 현재 카드 상태 출력한다. 3. 각 참가자들의 턴을 진행한다. @@ -37,26 +38,3 @@ 2. 카드를 한 장 더 추가하고, 1로 돌아간다. 5. 딜러 및 모든 참가자의 보유 카드들과 점수를 출력한다. 6. 딜러 및 모든 참가자의 승패를 출력한다. - -#### Card - -- 문양과 숫자를 가진다. -- 점수를 반환할 수 있어야 한다. - - 숫자 카드는 숫자 그대로 점수로 사용한다. - - King, Queen, Jack은 모두 10점으로 사용한다. - - Ace는 1, 또는 11 점으로 사용할 수 있다. - -#### Deck - -- 카드 한장을 제공할 수 있다. - -#### Dealer - -- 카드 합이 16 이하일 때 카드를 뽑는다. -- 보유 중인 카드 정보와 점수를 반환할 수 있다. - -#### Player - -- 카드 합이 21 이하일 떄 카드를 뽑을 수 있다. -- 보유 중인 카드 정보와 점수를 반환할 수 있다. -- 카드를 더 뽑을 수 있는지 알 수 있다. From efc2b15493c46fbb117777bb389aa61ebbd71d27 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 15:55:17 +0900 Subject: [PATCH 45/62] =?UTF-8?q?style=20(OutputView)=20:=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=9D=B4=EB=A6=84=EC=9D=84=20=EC=B6=94?= =?UTF-8?q?=EC=83=81=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/BlackJackGame.java | 4 ++-- src/main/java/blackjack/view/OutputView.java | 24 ++++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index e08970e487..b9fb771ba4 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -30,7 +30,7 @@ private Players createPlayers() { private void drawStartCards(Dealer dealer, Players players, Deck deck) { dealer.drawStartCards(deck); players.drawStartCards(deck); - outputView.printStartCards(dealer, players); + outputView.printStartStatus(dealer, players); } private void play(Players players, Dealer dealer, Deck deck) { @@ -49,7 +49,7 @@ private void playTurn(Player player, Deck deck) { } private void printResult(Dealer dealer, Players players) { - outputView.printResultCardAndScore(dealer, players); + outputView.printEndingStatus(dealer, players); outputView.printDealerMatchResult(dealer.match(players)); for (Player player : players.getPlayers()) { outputView.printPlayerMatchResult(player.getName(), player.isWin(dealer)); diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 1b27de189d..58aada64b8 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -33,7 +33,7 @@ public class OutputView { private static final int DEALER_START_CARDS_SIZE = 1; private static final int PLAYER_START_CARDS_SIZE = 2; - public void printStartCards(Dealer dealer, Players players) { + public void printStartStatus(Dealer dealer, Players players) { System.out.println(); System.out.println("딜러와 " + toPrintedFormat(players) + "에게 2장을 나누었습니다."); printDealerCards(dealer.getCards().subList(0, DEALER_START_CARDS_SIZE)); @@ -42,16 +42,19 @@ public void printStartCards(Dealer dealer, Players players) { System.out.println(); } - public void printResultCardAndScore(Dealer dealer, Players players) { + public void printEndingStatus(Dealer dealer, Players players) { System.out.println(); System.out.println(); - printDealerCards(dealer.getCards()); - printScore(dealer.calculateScore()); - System.out.println(); - printPlayersCardAndScore(players); + printDealerEndingStatus(dealer); + printPlayersEndingStatus(players); System.out.println(); } + private void printDealerCards(List cards) { + System.out.print("딜러 카드: "); + printCards(cards); + } + private void printPlayersCards(Players players) { for (Player player : players.getPlayers()) { printPlayerCards(player.getName(), player.getCards().subList(0, PLAYER_START_CARDS_SIZE)); @@ -59,9 +62,10 @@ private void printPlayersCards(Players players) { } } - private void printDealerCards(List cards) { - System.out.print("딜러 카드: "); - printCards(cards); + private void printDealerEndingStatus(Dealer dealer) { + printDealerCards(dealer.getCards()); + printScore(dealer.calculateScore()); + System.out.println(); } private void printPlayerCards(String name, List cards) { @@ -69,7 +73,7 @@ private void printPlayerCards(String name, List cards) { printCards(cards); } - private void printPlayersCardAndScore(Players players) { + private void printPlayersEndingStatus(Players players) { for (Player player : players.getPlayers()) { printPlayerCards(player.getName(), player.getCards()); printScore(player.calculateScore()); From d7c7f646dd0ec8c9ca384cf29dd1ff072b150557 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:02:06 +0900 Subject: [PATCH 46/62] =?UTF-8?q?refactor=20(PlayerTurn)=20:=20=EA=B0=80?= =?UTF-8?q?=EB=8F=85=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=B4=20`BiConsumer`?= =?UTF-8?q?=20->=20`PlayerTurn`=20=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../java/blackjack/domain/participant/PlayerTurn.java | 8 ++++++++ src/main/java/blackjack/domain/participant/Players.java | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 src/main/java/blackjack/domain/participant/PlayerTurn.java diff --git a/src/main/java/blackjack/domain/participant/PlayerTurn.java b/src/main/java/blackjack/domain/participant/PlayerTurn.java new file mode 100644 index 0000000000..167b67d172 --- /dev/null +++ b/src/main/java/blackjack/domain/participant/PlayerTurn.java @@ -0,0 +1,8 @@ +package blackjack.domain.participant; + +import blackjack.domain.Deck; + +@FunctionalInterface +public interface PlayerTurn { + void play(Player player, Deck deck); +} diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 7982a0c5b5..6b3f5bdc27 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -52,9 +52,9 @@ public List getPlayers() { return players; } - public void play(BiConsumer playTurn, Deck deck) { + public void play(PlayerTurn playTurn, Deck deck) { for (Player player : players) { - playTurn.accept(player, deck); + playTurn.play(player, deck); } } } From 4465e8e767f90cbf045df9bb86c73852b9352390 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:06:30 +0900 Subject: [PATCH 47/62] =?UTF-8?q?refactor=20(Value)=20:=20=EC=B6=94?= =?UTF-8?q?=ED=9B=84=20=EC=9C=A0=EC=A7=80=EB=B3=B4=EC=88=98=EC=9D=98=20?= =?UTF-8?q?=EC=9A=A9=EC=9D=B4=EC=84=B1=EA=B3=BC=20enum=20=EC=9D=B8?= =?UTF-8?q?=EC=8A=A4=ED=84=B4=EC=8A=A4=20=EC=9E=90=EC=B2=B4=EA=B0=80=20?= =?UTF-8?q?=EA=B0=92=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=B1=85=EC=9E=84?= =?UTF-8?q?=EC=9D=84=20=EA=B0=80=EC=A7=80=EA=B8=B0=20=EC=9C=84=ED=95=B4=20?= =?UTF-8?q?`maxValue`=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../java/blackjack/domain/card/Value.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/blackjack/domain/card/Value.java b/src/main/java/blackjack/domain/card/Value.java index 8dc2b18b56..ad4e86eaa9 100644 --- a/src/main/java/blackjack/domain/card/Value.java +++ b/src/main/java/blackjack/domain/card/Value.java @@ -1,24 +1,26 @@ package blackjack.domain.card; public enum Value { - 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); + ACE(1, 11), + TWO(2, 2), + THREE(3, 3), + FOUR(4, 4), + FIVE(5, 5), + SIX(6, 6), + SEVEN(7, 7), + EIGHT(8, 8), + NINE(9, 9), + TEN(10, 10), + JACK(10, 10), + QUEEN(10, 10), + KING(10, 10); private final int minScore; + private final int maxScore; - Value(int minScore) { + Value(int minScore, int maxScore) { this.minScore = minScore; + this.maxScore = maxScore; } public int getMinScore() { @@ -26,9 +28,6 @@ public int getMinScore() { } public int getMaxScore() { - if (this == ACE) { - return minScore + 10; - } - return minScore; + return maxScore; } } From cf3878f98296e74213840456451af8d4b8670049 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:11:17 +0900 Subject: [PATCH 48/62] =?UTF-8?q?refactor=20(Deck)=20:=20=ED=8C=A8?= =?UTF-8?q?=ED=82=A4=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/BlackJackGame.java | 2 +- src/main/java/blackjack/domain/{ => card}/Deck.java | 8 +++----- .../java/blackjack/domain/participant/Participant.java | 2 +- .../java/blackjack/domain/participant/PlayerTurn.java | 2 +- src/main/java/blackjack/domain/participant/Players.java | 3 +-- src/test/java/blackjack/domain/{ => card}/CardTest.java | 3 ++- src/test/java/blackjack/domain/{ => card}/DeckTest.java | 3 ++- .../java/blackjack/domain/participant/DealerTest.java | 4 ++-- .../java/blackjack/domain/participant/PlayerTest.java | 4 ++-- .../java/blackjack/domain/participant/PlayersTest.java | 2 +- 10 files changed, 16 insertions(+), 17 deletions(-) rename src/main/java/blackjack/domain/{ => card}/Deck.java (85%) rename src/test/java/blackjack/domain/{ => card}/CardTest.java (97%) rename src/test/java/blackjack/domain/{ => card}/DeckTest.java (93%) diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index b9fb771ba4..284c79a9e6 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -1,6 +1,6 @@ package blackjack; -import blackjack.domain.Deck; +import blackjack.domain.card.Deck; import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; diff --git a/src/main/java/blackjack/domain/Deck.java b/src/main/java/blackjack/domain/card/Deck.java similarity index 85% rename from src/main/java/blackjack/domain/Deck.java rename to src/main/java/blackjack/domain/card/Deck.java index 726105664e..e4a6f668ac 100644 --- a/src/main/java/blackjack/domain/Deck.java +++ b/src/main/java/blackjack/domain/card/Deck.java @@ -1,21 +1,19 @@ -package blackjack.domain; +package blackjack.domain.card; import static java.util.stream.Collectors.toList; -import blackjack.domain.card.Card; -import blackjack.domain.card.Shape; -import blackjack.domain.card.Value; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Queue; +// TODO 패키지 변경 public class Deck { private final Queue cards; - Deck(List cards) { + private Deck(List cards) { this.cards = new LinkedList<>(cards); } diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 2af42936dd..96541df8de 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -1,6 +1,6 @@ package blackjack.domain.participant; -import blackjack.domain.Deck; +import blackjack.domain.card.Deck; import blackjack.domain.card.Card; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/blackjack/domain/participant/PlayerTurn.java b/src/main/java/blackjack/domain/participant/PlayerTurn.java index 167b67d172..53ae62cc63 100644 --- a/src/main/java/blackjack/domain/participant/PlayerTurn.java +++ b/src/main/java/blackjack/domain/participant/PlayerTurn.java @@ -1,6 +1,6 @@ package blackjack.domain.participant; -import blackjack.domain.Deck; +import blackjack.domain.card.Deck; @FunctionalInterface public interface PlayerTurn { diff --git a/src/main/java/blackjack/domain/participant/Players.java b/src/main/java/blackjack/domain/participant/Players.java index 6b3f5bdc27..ca19558f47 100644 --- a/src/main/java/blackjack/domain/participant/Players.java +++ b/src/main/java/blackjack/domain/participant/Players.java @@ -1,8 +1,7 @@ package blackjack.domain.participant; -import blackjack.domain.Deck; +import blackjack.domain.card.Deck; import java.util.List; -import java.util.function.BiConsumer; public class Players { diff --git a/src/test/java/blackjack/domain/CardTest.java b/src/test/java/blackjack/domain/card/CardTest.java similarity index 97% rename from src/test/java/blackjack/domain/CardTest.java rename to src/test/java/blackjack/domain/card/CardTest.java index 916fe6c250..c222b2189a 100644 --- a/src/test/java/blackjack/domain/CardTest.java +++ b/src/test/java/blackjack/domain/card/CardTest.java @@ -1,4 +1,4 @@ -package blackjack.domain; +package blackjack.domain.card; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; @@ -16,6 +16,7 @@ public class CardTest { + // TODO HandFixture 로 변경 (클래스 분리) public static final List CARDS_SCORE_4 = List.of( new Card(Value.TWO, Shape.HEART), new Card(Value.TWO, Shape.SPADE) diff --git a/src/test/java/blackjack/domain/DeckTest.java b/src/test/java/blackjack/domain/card/DeckTest.java similarity index 93% rename from src/test/java/blackjack/domain/DeckTest.java rename to src/test/java/blackjack/domain/card/DeckTest.java index 8fecea2791..4feada985e 100644 --- a/src/test/java/blackjack/domain/DeckTest.java +++ b/src/test/java/blackjack/domain/card/DeckTest.java @@ -1,8 +1,9 @@ -package blackjack.domain; +package blackjack.domain.card; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.domain.card.Deck; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 035f255e1c..ca9afce1f0 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -3,8 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import blackjack.domain.CardTest; -import blackjack.domain.Deck; +import blackjack.domain.card.CardTest; +import blackjack.domain.card.Deck; import blackjack.domain.card.Card; import blackjack.domain.card.Shape; import blackjack.domain.card.Value; diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 25ab972446..89dc264b3d 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -3,8 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import blackjack.domain.CardTest; -import blackjack.domain.Deck; +import blackjack.domain.card.CardTest; +import blackjack.domain.card.Deck; import blackjack.domain.card.Card; import blackjack.domain.card.Shape; import blackjack.domain.card.Value; diff --git a/src/test/java/blackjack/domain/participant/PlayersTest.java b/src/test/java/blackjack/domain/participant/PlayersTest.java index e8e457064f..a776e17578 100644 --- a/src/test/java/blackjack/domain/participant/PlayersTest.java +++ b/src/test/java/blackjack/domain/participant/PlayersTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; -import blackjack.domain.Deck; +import blackjack.domain.card.Deck; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.DisplayName; From f3a92c0ebb58ddd074a1f5aabed3a2ce84c79a52 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:18:40 +0900 Subject: [PATCH 49/62] =?UTF-8?q?refactor=20:=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EA=B0=84=EA=B2=B0=ED=95=98=EA=B2=8C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4,=20Te?= =?UTF-8?q?st=EC=9A=A9=20=EC=83=9D=EC=84=B1=EC=9E=90=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../java/blackjack/domain/participant/DealerTest.java | 8 +++----- .../java/blackjack/domain/participant/PlayerTest.java | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index ca9afce1f0..64a6e31527 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -3,9 +3,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.domain.card.Card; import blackjack.domain.card.CardTest; import blackjack.domain.card.Deck; -import blackjack.domain.card.Card; import blackjack.domain.card.Shape; import blackjack.domain.card.Value; import java.util.List; @@ -76,9 +76,8 @@ void drawStartCardsTest() { @DisplayName("이미 카드를 가지고 있는 경우, 시작 카드를 뽑을 수 없다.") @Test void drawStartCardsTest_whenAlreadyStarted_throwException() { - Dealer dealer = new Dealer(); + Dealer dealer = new Dealer(CARDS_SCORE_16); Deck deck = Deck.createShuffledDeck(); - dealer.drawStartCards(deck); assertThatThrownBy(() -> dealer.drawStartCards(deck)) .isInstanceOf(IllegalStateException.class) @@ -89,8 +88,8 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { @Test void addTest_whenScoreIsUnderBound() { Dealer dealer = new Dealer(CARDS_SCORE_16); - Card additionalCard = new Card(Value.ACE, Shape.HEART); + dealer.add(additionalCard); assertThat(dealer.getCards()) @@ -132,7 +131,6 @@ static Stream> dealerCards() { @ParameterizedTest @MethodSource("playerCards") void whenOnlyDealerBusted_playerWin(List cards) { - Dealer dealer = new Dealer(BUSTED); Player player = new Player(cards, DEFAULT_NAME); diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 89dc264b3d..a913f86522 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -74,9 +74,8 @@ void drawStartCardsTest() { @DisplayName("이미 카드를 가지고 있는 경우, 시작 카드를 뽑을 수 없다.") @Test void drawStartCardsTest_whenAlreadyStarted_throwException() { - Player player = Player.from("name"); + Player player = new Player(CARDS_SCORE_16, DEFAULT_NAME); Deck deck = Deck.createShuffledDeck(); - player.drawStartCards(deck); assertThatThrownBy(() -> player.drawStartCards(deck)) .isInstanceOf(IllegalStateException.class) From a1ca3246a23c5f98f9533ac1ae0dbc0f5f1428f0 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:22:22 +0900 Subject: [PATCH 50/62] =?UTF-8?q?style=20:=20import=20=EB=AC=B8=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=20=EB=B0=8F=20TODO=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/card/Deck.java | 1 - src/main/java/blackjack/domain/participant/Participant.java | 2 +- src/test/java/blackjack/domain/card/CardTest.java | 3 --- src/test/java/blackjack/domain/card/DeckTest.java | 1 - src/test/java/blackjack/domain/participant/PlayerTest.java | 2 +- 5 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/blackjack/domain/card/Deck.java b/src/main/java/blackjack/domain/card/Deck.java index e4a6f668ac..3c759f38d3 100644 --- a/src/main/java/blackjack/domain/card/Deck.java +++ b/src/main/java/blackjack/domain/card/Deck.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.Queue; -// TODO 패키지 변경 public class Deck { private final Queue cards; diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 96541df8de..4739d895bd 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -1,7 +1,7 @@ package blackjack.domain.participant; -import blackjack.domain.card.Deck; import blackjack.domain.card.Card; +import blackjack.domain.card.Deck; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/src/test/java/blackjack/domain/card/CardTest.java b/src/test/java/blackjack/domain/card/CardTest.java index c222b2189a..eba3cab46c 100644 --- a/src/test/java/blackjack/domain/card/CardTest.java +++ b/src/test/java/blackjack/domain/card/CardTest.java @@ -3,9 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import blackjack.domain.card.Card; -import blackjack.domain.card.Shape; -import blackjack.domain.card.Value; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; diff --git a/src/test/java/blackjack/domain/card/DeckTest.java b/src/test/java/blackjack/domain/card/DeckTest.java index 4feada985e..d28ee2e53e 100644 --- a/src/test/java/blackjack/domain/card/DeckTest.java +++ b/src/test/java/blackjack/domain/card/DeckTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import blackjack.domain.card.Deck; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index a913f86522..79fe72d6a6 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -3,9 +3,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.domain.card.Card; import blackjack.domain.card.CardTest; import blackjack.domain.card.Deck; -import blackjack.domain.card.Card; import blackjack.domain.card.Shape; import blackjack.domain.card.Value; import java.util.List; From cfe591e9d109aabc607fbc46b3179555a11dd34b Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:32:13 +0900 Subject: [PATCH 51/62] =?UTF-8?q?feat=20(Hand)=20:=20=EC=86=90=ED=8C=A8=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=EC=9D=98=20=EC=B1=85=EC=9E=84=EC=9D=84=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=B4=20Han?= =?UTF-8?q?d=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/card/Hand.java | 30 ++++++++++++++ .../java/blackjack/domain/card/HandTest.java | 39 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/main/java/blackjack/domain/card/Hand.java create mode 100644 src/test/java/blackjack/domain/card/HandTest.java diff --git a/src/main/java/blackjack/domain/card/Hand.java b/src/main/java/blackjack/domain/card/Hand.java new file mode 100644 index 0000000000..050d827a79 --- /dev/null +++ b/src/main/java/blackjack/domain/card/Hand.java @@ -0,0 +1,30 @@ +package blackjack.domain.card; + +import java.util.List; + +public class Hand { + + private static final int BLACKJACK_SCORE = 21; + private final List cards; + + Hand(List cards) { + this.cards = List.copyOf(cards); + } + + public int calculateScore() { + int score = getMaxScore(); + int cardIndex = 0; + while (score > BLACKJACK_SCORE && cardIndex < cards.size()) { + Card card = cards.get(cardIndex); + score = score + card.getMinScore() - card.getMaxScore(); + cardIndex++; + } + return score; + } + + private int getMaxScore() { + return cards.stream() + .mapToInt(Card::getMaxScore) + .sum(); + } +} diff --git a/src/test/java/blackjack/domain/card/HandTest.java b/src/test/java/blackjack/domain/card/HandTest.java new file mode 100644 index 0000000000..12afc54543 --- /dev/null +++ b/src/test/java/blackjack/domain/card/HandTest.java @@ -0,0 +1,39 @@ +package blackjack.domain.card; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class HandTest { + + private static final List TWO_ACE = CardTest.TWO_ACE; + private static final List SCORE_13_WITH_ACE = CardTest.SCORE_13_WITH_ACE; + private static final List CARDS_SCORE_16 = CardTest.CARDS_SCORE_16; + private static final List CARDS_SCORE_21 = CardTest.CARDS_SCORE_21; + private static final List BLACKJACK = CardTest.BLACKJACK; + private static final List CARDS_SCORE_22 = CardTest.CARDS_SCORE_22; + + @DisplayName("점수를 계산할 수 있다.") + @ParameterizedTest + @MethodSource("cardsAndScore") + void calculateScoreTest(List cards, int expected) { + Hand hand = new Hand(cards); + + assertThat(hand.calculateScore()).isEqualTo(expected); + } + + static Stream cardsAndScore() { + return Stream.of( + Arguments.of(BLACKJACK, 21), + Arguments.of(TWO_ACE, 12), + Arguments.of(SCORE_13_WITH_ACE, 13), + Arguments.of(CARDS_SCORE_16, 16) + ); + } + +} From ba33f16e6f241e384e71d4819554fcf0865d667b Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:40:12 +0900 Subject: [PATCH 52/62] =?UTF-8?q?feat=20(Hand)=20:=20=EB=B2=84=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=83=81=ED=83=9C=EB=A5=BC=20=ED=8C=90=EB=8B=A8?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/card/Hand.java | 4 +++ .../java/blackjack/domain/card/HandTest.java | 28 ++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/domain/card/Hand.java b/src/main/java/blackjack/domain/card/Hand.java index 050d827a79..abe10eb225 100644 --- a/src/main/java/blackjack/domain/card/Hand.java +++ b/src/main/java/blackjack/domain/card/Hand.java @@ -27,4 +27,8 @@ private int getMaxScore() { .mapToInt(Card::getMaxScore) .sum(); } + + public boolean isBusted() { + return calculateScore() > BLACKJACK_SCORE; + } } diff --git a/src/test/java/blackjack/domain/card/HandTest.java b/src/test/java/blackjack/domain/card/HandTest.java index 12afc54543..4707694e65 100644 --- a/src/test/java/blackjack/domain/card/HandTest.java +++ b/src/test/java/blackjack/domain/card/HandTest.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -28,12 +30,30 @@ void calculateScoreTest(List cards, int expected) { } static Stream cardsAndScore() { - return Stream.of( - Arguments.of(BLACKJACK, 21), + return Stream.of(Arguments.of(BLACKJACK, 21), Arguments.of(TWO_ACE, 12), Arguments.of(SCORE_13_WITH_ACE, 13), - Arguments.of(CARDS_SCORE_16, 16) - ); + Arguments.of(CARDS_SCORE_16, 16)); } + @DisplayName("카드의 버스트 상태를 알 수 있다.") + @Nested + class BustTest { + + @DisplayName("21점이 넘으면 버스트이다.") + @Test + void whenBusted_returnTrue() { + Hand bustedHand = new Hand(CARDS_SCORE_22); + + assertThat(bustedHand.isBusted()).isTrue(); + } + + @DisplayName("21점 이하 점수는 버스트가 아니다.") + @Test + void whenNotBusted_returnFalse() { + Hand hand = new Hand(CARDS_SCORE_21); + + assertThat(hand.isBusted()).isFalse(); + } + } } From cf5c48127e505bd289af70b65b53370d880f3e64 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:50:37 +0900 Subject: [PATCH 53/62] =?UTF-8?q?feat=20(Hand)=20:=20=EB=B8=94=EB=9E=99?= =?UTF-8?q?=EC=9E=AD=20=ED=8C=90=EB=8B=A8=20=EA=B8=B0=EB=8A=A5=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 Co-authored-by: zangsu --- src/main/java/blackjack/domain/card/Hand.java | 5 +++ .../java/blackjack/domain/card/HandTest.java | 41 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/main/java/blackjack/domain/card/Hand.java b/src/main/java/blackjack/domain/card/Hand.java index abe10eb225..c2db35e5d0 100644 --- a/src/main/java/blackjack/domain/card/Hand.java +++ b/src/main/java/blackjack/domain/card/Hand.java @@ -5,6 +5,7 @@ public class Hand { private static final int BLACKJACK_SCORE = 21; + private static final int BLACKJACK_SIZE = 2; private final List cards; Hand(List cards) { @@ -31,4 +32,8 @@ private int getMaxScore() { public boolean isBusted() { return calculateScore() > BLACKJACK_SCORE; } + + public boolean isBlackjack() { + return cards.size() == BLACKJACK_SIZE && calculateScore() == BLACKJACK_SCORE; + } } diff --git a/src/test/java/blackjack/domain/card/HandTest.java b/src/test/java/blackjack/domain/card/HandTest.java index 4707694e65..2764d827a8 100644 --- a/src/test/java/blackjack/domain/card/HandTest.java +++ b/src/test/java/blackjack/domain/card/HandTest.java @@ -56,4 +56,45 @@ void whenNotBusted_returnFalse() { assertThat(hand.isBusted()).isFalse(); } } + + @DisplayName("카드의 블랙잭 상태를 판단할 수 있다.") + @Nested + class BlackjackTest { + + @DisplayName("21점이면서 2장의 카드라면 블랙잭이다.") + @Test + void whenBlackjack_returnTrue() { + Hand blackjackHand = new Hand(BLACKJACK); + + assertThat(blackjackHand.isBlackjack()).isTrue(); + } + + @DisplayName("21점 미만 점수는 블랙잭이 아니다.") + @Test + void whenUnderScore_returnFalse() { + Hand blackjackHand = new Hand(List.of( + new Card(Value.KING, Shape.HEART), + new Card(Value.QUEEN, Shape.HEART) + )); + + assertThat(blackjackHand.isBlackjack()).isFalse(); + } + + @DisplayName("21점이지만 3장의 카드라면 블랙잭이 아니다.") + @Test + void whenOverSize_returnFalse() { + Hand blackjackHand = new Hand(CARDS_SCORE_21); + + assertThat(blackjackHand.isBlackjack()).isFalse(); + } + + @DisplayName("21점 초과 점수는 블랙잭이 아니다.") + @Test + void whenOverScore_returnFalse() { + Hand blackjackHand = new Hand(CARDS_SCORE_22); + + assertThat(blackjackHand.isBlackjack()).isFalse(); + } + + } } From 6bccbbbdb377858d944b0a268ac5223e8f18e175 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 16:59:20 +0900 Subject: [PATCH 54/62] =?UTF-8?q?feat=20(Hand)=20:=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=98=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/card/Hand.java | 12 +++++++++++- src/test/java/blackjack/domain/card/HandTest.java | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/card/Hand.java b/src/main/java/blackjack/domain/card/Hand.java index c2db35e5d0..be6c7b32dc 100644 --- a/src/main/java/blackjack/domain/card/Hand.java +++ b/src/main/java/blackjack/domain/card/Hand.java @@ -1,5 +1,7 @@ package blackjack.domain.card; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Hand { @@ -9,7 +11,11 @@ public class Hand { private final List cards; Hand(List cards) { - this.cards = List.copyOf(cards); + this.cards = new ArrayList<>(cards); + } + + public void add(Card card) { + cards.add(card); } public int calculateScore() { @@ -36,4 +42,8 @@ public boolean isBusted() { public boolean isBlackjack() { return cards.size() == BLACKJACK_SIZE && calculateScore() == BLACKJACK_SCORE; } + + public List getCards() { + return Collections.unmodifiableList(cards); + } } diff --git a/src/test/java/blackjack/domain/card/HandTest.java b/src/test/java/blackjack/domain/card/HandTest.java index 2764d827a8..693a8d4e70 100644 --- a/src/test/java/blackjack/domain/card/HandTest.java +++ b/src/test/java/blackjack/domain/card/HandTest.java @@ -36,6 +36,20 @@ static Stream cardsAndScore() { Arguments.of(CARDS_SCORE_16, 16)); } + @DisplayName("카드를 한 장 뽑는다") + @Test + void addTest() { + Hand hand = new Hand(CARDS_SCORE_16); + + Card additionalCard = new Card(Value.ACE, Shape.HEART); + hand.add(additionalCard); + + assertThat(hand.getCards()) + .containsAll(CARDS_SCORE_16) + .contains(additionalCard) + .hasSize(CARDS_SCORE_16.size() + 1); + } + @DisplayName("카드의 버스트 상태를 알 수 있다.") @Nested class BustTest { From 770c1a9f63c05a4b672a35f9b2c252f01a41ab60 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 17:10:18 +0900 Subject: [PATCH 55/62] =?UTF-8?q?feat=20(Hand)=20:=20=EB=B9=88=20=EC=86=90?= =?UTF-8?q?=ED=8C=A8=EC=9D=B8=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/card/Hand.java | 6 +++++- .../java/blackjack/domain/card/HandTest.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/domain/card/Hand.java b/src/main/java/blackjack/domain/card/Hand.java index be6c7b32dc..affdf3b3fa 100644 --- a/src/main/java/blackjack/domain/card/Hand.java +++ b/src/main/java/blackjack/domain/card/Hand.java @@ -10,7 +10,7 @@ public class Hand { private static final int BLACKJACK_SIZE = 2; private final List cards; - Hand(List cards) { + public Hand(List cards) { this.cards = new ArrayList<>(cards); } @@ -46,4 +46,8 @@ public boolean isBlackjack() { public List getCards() { return Collections.unmodifiableList(cards); } + + public boolean isEmpty() { + return cards.isEmpty(); + } } diff --git a/src/test/java/blackjack/domain/card/HandTest.java b/src/test/java/blackjack/domain/card/HandTest.java index 693a8d4e70..292f011e76 100644 --- a/src/test/java/blackjack/domain/card/HandTest.java +++ b/src/test/java/blackjack/domain/card/HandTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.Collections; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; @@ -109,6 +110,26 @@ void whenOverScore_returnFalse() { assertThat(blackjackHand.isBlackjack()).isFalse(); } + } + + @DisplayName("빈 손패인지 확인할 수 있다.") + @Nested + class EmptyHandTest { + + @DisplayName("아무 카드도 존재하지 않으면 빈 손패이다.") + @Test + void whenEmptyHand_returnTrue() { + Hand emptyHand = new Hand(Collections.emptyList()); + assertThat(emptyHand.isEmpty()).isTrue(); + } + + @DisplayName("카드가 한 장이라도 존재하면 빈 손패가 아니다.") + @Test + void whenCardExists_returnFalse() { + Hand emptyHand = new Hand(List.of(new Card(Value.ACE, Shape.HEART))); + + assertThat(emptyHand.isEmpty()).isFalse(); + } } } From 72369a79e0ad5ba3a75443c18f88319126e84e83 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 17:14:46 +0900 Subject: [PATCH 56/62] =?UTF-8?q?refactor=20(Participant)=20:=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=EC=99=80=20=EA=B4=80=EB=A0=A8=EB=90=9C=20=EC=B1=85?= =?UTF-8?q?=EC=9E=84=EB=93=A4=EC=9D=84=20Hand=20=EB=A1=9C=20=EC=9C=84?= =?UTF-8?q?=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../domain/participant/Participant.java | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 4739d895bd..c6b7d3aca1 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -2,8 +2,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; -import java.util.ArrayList; -import java.util.Collections; +import blackjack.domain.card.Hand; import java.util.List; public abstract class Participant { @@ -11,39 +10,28 @@ public abstract class Participant { protected static final int BLACKJACK_SCORE = 21; private static final int START_CARDS_SIZE = 2; - private final List cards; + private final Hand hand; protected Participant(List cards) { - this.cards = new ArrayList<>(cards); + this.hand = new Hand(cards); } public final int calculateScore() { - int score = getMaxScore(); - int cardIndex = 0; - while (score > BLACKJACK_SCORE && cardIndex < cards.size()) { - Card card = cards.get(cardIndex); - score = score + card.getMinScore() - card.getMaxScore(); - cardIndex++; - } - return score; - } - - private int getMaxScore() { - return cards.stream() - .mapToInt(Card::getMaxScore) - .sum(); + return hand.calculateScore(); } public final boolean isDrawable() { return calculateScore() <= getMaxDrawableScore(); } + // TODO isBlackjack 추가 + public final boolean isBusted() { - return calculateScore() > BLACKJACK_SCORE; + return hand.isBusted(); } - public void drawStartCards(Deck deck) { - if (!cards.isEmpty()) { + public final void drawStartCards(Deck deck) { + if (!hand.isEmpty()) { throw new IllegalStateException("이미 시작 카드를 뽑았습니다."); } for (int i = 0; i < START_CARDS_SIZE; i++) { @@ -55,11 +43,12 @@ public final void add(Card card) { if (!isDrawable()) { throw new IllegalStateException("더 이상 카드를 추가할 수 없습니다."); } - cards.add(card); + hand.add(card); } + // TODO getStartCards() 도입 public final List getCards() { - return Collections.unmodifiableList(cards); + return hand.getCards(); } protected abstract int getMaxDrawableScore(); From be2535a2e5f853648b88e53a5dcb649455be9f2e Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 20:18:33 +0900 Subject: [PATCH 57/62] =?UTF-8?q?feat=20(Dealer)=20:=20=EC=8A=B9=ED=8C=A8?= =?UTF-8?q?=20=EC=A1=B0=EA=B1=B4=EC=97=90=20=EB=B8=94=EB=9E=99=EC=9E=AD=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- README.md | 9 ++-- .../blackjack/domain/participant/Dealer.java | 4 +- .../domain/participant/Participant.java | 4 +- .../domain/participant/DealerTest.java | 44 ++++++++++++++----- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a37241d90d..7d9853dca8 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,12 @@ - 이름은 앞뒤 공백을 가질 수 없다. - 중복된 이름은 가질 수 없다. -### 플레이어 승리 조건 +### 승리 조건 -- 아래의 두 조건을 모두 만족하면 플레이어가 승리한다. - - 카드의 점수 합이 21을 넘기지 않는다. - - 딜러보다 점수가 높거나 딜러의 카드 점수 합이 21을 초과한다. +- 카드 숫자를 합쳐 가능한 21에 가깝게 만들면 이긴다. + - 처음 받은 2장 합쳐 21이 나오는 경우 블랙잭이 되며, 모든 카드조합 중에 가장 강력하다. + - 카드 숫자의 합이 21을 초과하게 되는 순간 '버스트'라고 하며 딜러의 결과에 관계없이 플레이어가 패배한다. + - 딜러와 플레이어의 점수와 블랙잭 여부가 동일한 경우, 딜러가 승리한다. ### 프로그램 진행 순서 diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 21ecfe5bf3..64ad0f3326 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -18,10 +18,10 @@ public Dealer() { } public boolean isWin(Player player) { - if (player.isBusted()) { + if (player.isBusted() || this.isBlackjack()) { return true; } - if (this.isBusted()) { + if (this.isBusted() || player.isBlackjack()) { return false; } return this.calculateScore() >= player.calculateScore(); diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index c6b7d3aca1..6dab9110e4 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -24,7 +24,9 @@ public final boolean isDrawable() { return calculateScore() <= getMaxDrawableScore(); } - // TODO isBlackjack 추가 + public boolean isBlackjack() { + return hand.isBlackjack(); + } public final boolean isBusted() { return hand.isBusted(); diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 64a6e31527..27207294a5 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -24,6 +24,7 @@ class DealerTest { private static final List SCORE_13_WITH_ACE = CardTest.SCORE_13_WITH_ACE; private static final List CARDS_SCORE_16 = CardTest.CARDS_SCORE_16; private static final List CARDS_SCORE_17 = CardTest.CARDS_SCORE_17; + private static final List CARDS_SCORE_21 = CardTest.CARDS_SCORE_21; private static final List BLACKJACK = CardTest.BLACKJACK; private static final List BUSTED = CardTest.BUSTED; private static final Name DEFAULT_NAME = NameTest.DEFAULT_NAME; @@ -113,7 +114,7 @@ void addTest_whenScoreIsOverBound_throwException() { @Nested class IsWinTest { - @DisplayName("플레이어가 21일 넘을 경우, 딜러가 이긴다.") + @DisplayName("플레이어가 21을 넘을 경우, 딜러가 이긴다.") @ParameterizedTest @MethodSource("dealerCards") void whenPlayerBusted_dealerWin(List cards) { @@ -141,25 +142,48 @@ static Stream> playerCards() { return Stream.of(BLACKJACK, CARDS_SCORE_4, CARDS_SCORE_16); } - @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 크다면 플레이어가 이긴다.") + @DisplayName("플레이어만 블랙잭일 경우, 플레이어가 이긴다.") @Test - void whenPlayerScoreIsBiggerThanDealerScore_playerWin() { - Player player = new Player(CARDS_SCORE_17, DEFAULT_NAME); - Dealer dealer = new Dealer(CARDS_SCORE_16); + void whenPlayerOnlyBlackjack_playerWin() { + Player player = new Player(BLACKJACK, DEFAULT_NAME); + Dealer dealer = new Dealer(CARDS_SCORE_21); assertThat(dealer.isWin(player)).isFalse(); } - @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 같다면 딜러가 이긴다.") + @DisplayName("딜러만 블랙잭일 경우, 딜러가 이긴다.") @Test - void whenPlayerScoreIsEqualToDealerScore_dealerWin() { - Player player = new Player(CARDS_SCORE_17, DEFAULT_NAME); - Dealer dealer = new Dealer(CARDS_SCORE_17); + void whenDealerOnlyBlackjack_dealerWin() { + Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); + Dealer dealer = new Dealer(BLACKJACK); + + assertThat(dealer.isWin(player)).isTrue(); + } + + @DisplayName("둘 다 21을 넘지 않을 경우, 플레이어가 딜러의 숫자보다 같다면 딜러가 이긴다.") + @ParameterizedTest + @MethodSource("sameCards") + void whenPlayerScoreIsEqualToDealerScore_dealerWin(List cards) { + Player player = new Player(cards, DEFAULT_NAME); + Dealer dealer = new Dealer(cards); assertThat(dealer.isWin(player)).isTrue(); } - @DisplayName("둘 다 21을 넘기지 않을 경우, 플레이어가 딜러의 숫자보다 작다면 딜러가 이긴다.") + static Stream> sameCards() { + return Stream.of(BLACKJACK, CARDS_SCORE_21, CARDS_SCORE_16); + } + + @DisplayName("둘 다 21보다 작을 경우, 플레이어가 딜러의 숫자보다 크다면 플레이어가 이긴다.") + @Test + void whenPlayerScoreIsBiggerThanDealerScore_playerWin() { + Player player = new Player(CARDS_SCORE_17, DEFAULT_NAME); + Dealer dealer = new Dealer(CARDS_SCORE_16); + + assertThat(dealer.isWin(player)).isFalse(); + } + + @DisplayName("둘 다 21보다 작을 경우, 플레이어가 딜러의 숫자보다 작다면 딜러가 이긴다.") @Test void whenPlayerScoreIsSmallerThanDealerScore_dealerWin() { Player player = new Player(CARDS_SCORE_16, DEFAULT_NAME); From 79068a6845b6fc4574727e46eb7e183d7e31b5e6 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 20:20:10 +0900 Subject: [PATCH 58/62] =?UTF-8?q?refactor=20:=20=EA=B0=80=EB=8F=85?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=B4=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=94=BD=EC=8A=A4=EC=B2=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../java/blackjack/domain/card/CardTest.java | 43 ----------- .../java/blackjack/domain/card/HandTest.java | 32 ++++----- .../domain/fixture/CardsFixture.java | 49 +++++++++++++ .../domain/participant/DealerTest.java | 72 ++++++++++--------- .../domain/participant/NameTest.java | 2 - .../domain/participant/PlayerTest.java | 30 ++++---- 6 files changed, 112 insertions(+), 116 deletions(-) create mode 100644 src/test/java/blackjack/domain/fixture/CardsFixture.java diff --git a/src/test/java/blackjack/domain/card/CardTest.java b/src/test/java/blackjack/domain/card/CardTest.java index eba3cab46c..3790c5041e 100644 --- a/src/test/java/blackjack/domain/card/CardTest.java +++ b/src/test/java/blackjack/domain/card/CardTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; -import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -13,48 +12,6 @@ public class CardTest { - // TODO HandFixture 로 변경 (클래스 분리) - public static final List CARDS_SCORE_4 = List.of( - new Card(Value.TWO, Shape.HEART), - new Card(Value.TWO, Shape.SPADE) - ); - public static final List TWO_ACE = List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.ACE, Shape.SPADE) - ); - public static final List SCORE_13_WITH_ACE = List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.KING, Shape.HEART), - new Card(Value.TWO, Shape.HEART) - ); - public static final List CARDS_SCORE_16 = List.of( - new Card(Value.JACK, Shape.HEART), - new Card(Value.SIX, Shape.HEART) - ); - public static final List CARDS_SCORE_17 = List.of( - new Card(Value.JACK, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART) - ); - public static final List CARDS_SCORE_21 = List.of( - new Card(Value.JACK, Shape.HEART), - new Card(Value.EIGHT, Shape.HEART), - new Card(Value.THREE, Shape.HEART) - ); - public static final List BLACKJACK = List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.KING, Shape.HEART) - ); - public static final List CARDS_SCORE_22 = List.of( - new Card(Value.JACK, Shape.HEART), - new Card(Value.SEVEN, Shape.HEART), - new Card(Value.FIVE, Shape.HEART) - ); - public static final List BUSTED = List.of( - new Card(Value.KING, Shape.DIAMOND), - new Card(Value.QUEEN, Shape.DIAMOND), - new Card(Value.JACK, Shape.DIAMOND) - ); - @DisplayName("카드 값에 따라 점수를 확인할 수 있다") @Nested class CardScoreTest { diff --git a/src/test/java/blackjack/domain/card/HandTest.java b/src/test/java/blackjack/domain/card/HandTest.java index 292f011e76..6ff867df69 100644 --- a/src/test/java/blackjack/domain/card/HandTest.java +++ b/src/test/java/blackjack/domain/card/HandTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import blackjack.domain.fixture.CardsFixture; import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -14,13 +15,6 @@ class HandTest { - private static final List TWO_ACE = CardTest.TWO_ACE; - private static final List SCORE_13_WITH_ACE = CardTest.SCORE_13_WITH_ACE; - private static final List CARDS_SCORE_16 = CardTest.CARDS_SCORE_16; - private static final List CARDS_SCORE_21 = CardTest.CARDS_SCORE_21; - private static final List BLACKJACK = CardTest.BLACKJACK; - private static final List CARDS_SCORE_22 = CardTest.CARDS_SCORE_22; - @DisplayName("점수를 계산할 수 있다.") @ParameterizedTest @MethodSource("cardsAndScore") @@ -31,24 +25,24 @@ void calculateScoreTest(List cards, int expected) { } static Stream cardsAndScore() { - return Stream.of(Arguments.of(BLACKJACK, 21), - Arguments.of(TWO_ACE, 12), - Arguments.of(SCORE_13_WITH_ACE, 13), - Arguments.of(CARDS_SCORE_16, 16)); + return Stream.of(Arguments.of(CardsFixture.BLACKJACK, 21), + Arguments.of(CardsFixture.TWO_ACE, 12), + Arguments.of(CardsFixture.SCORE_13_WITH_ACE, 13), + Arguments.of(CardsFixture.CARDS_SCORE_16, 16)); } @DisplayName("카드를 한 장 뽑는다") @Test void addTest() { - Hand hand = new Hand(CARDS_SCORE_16); + Hand hand = new Hand(CardsFixture.CARDS_SCORE_16); Card additionalCard = new Card(Value.ACE, Shape.HEART); hand.add(additionalCard); assertThat(hand.getCards()) - .containsAll(CARDS_SCORE_16) + .containsAll(CardsFixture.CARDS_SCORE_16) .contains(additionalCard) - .hasSize(CARDS_SCORE_16.size() + 1); + .hasSize(CardsFixture.CARDS_SCORE_16.size() + 1); } @DisplayName("카드의 버스트 상태를 알 수 있다.") @@ -58,7 +52,7 @@ class BustTest { @DisplayName("21점이 넘으면 버스트이다.") @Test void whenBusted_returnTrue() { - Hand bustedHand = new Hand(CARDS_SCORE_22); + Hand bustedHand = new Hand(CardsFixture.CARDS_SCORE_22); assertThat(bustedHand.isBusted()).isTrue(); } @@ -66,7 +60,7 @@ void whenBusted_returnTrue() { @DisplayName("21점 이하 점수는 버스트가 아니다.") @Test void whenNotBusted_returnFalse() { - Hand hand = new Hand(CARDS_SCORE_21); + Hand hand = new Hand(CardsFixture.CARDS_SCORE_21); assertThat(hand.isBusted()).isFalse(); } @@ -79,7 +73,7 @@ class BlackjackTest { @DisplayName("21점이면서 2장의 카드라면 블랙잭이다.") @Test void whenBlackjack_returnTrue() { - Hand blackjackHand = new Hand(BLACKJACK); + Hand blackjackHand = new Hand(CardsFixture.BLACKJACK); assertThat(blackjackHand.isBlackjack()).isTrue(); } @@ -98,7 +92,7 @@ void whenUnderScore_returnFalse() { @DisplayName("21점이지만 3장의 카드라면 블랙잭이 아니다.") @Test void whenOverSize_returnFalse() { - Hand blackjackHand = new Hand(CARDS_SCORE_21); + Hand blackjackHand = new Hand(CardsFixture.CARDS_SCORE_21); assertThat(blackjackHand.isBlackjack()).isFalse(); } @@ -106,7 +100,7 @@ void whenOverSize_returnFalse() { @DisplayName("21점 초과 점수는 블랙잭이 아니다.") @Test void whenOverScore_returnFalse() { - Hand blackjackHand = new Hand(CARDS_SCORE_22); + Hand blackjackHand = new Hand(CardsFixture.CARDS_SCORE_22); assertThat(blackjackHand.isBlackjack()).isFalse(); } diff --git a/src/test/java/blackjack/domain/fixture/CardsFixture.java b/src/test/java/blackjack/domain/fixture/CardsFixture.java new file mode 100644 index 0000000000..c6f671a29b --- /dev/null +++ b/src/test/java/blackjack/domain/fixture/CardsFixture.java @@ -0,0 +1,49 @@ +package blackjack.domain.fixture; + +import blackjack.domain.card.Card; +import blackjack.domain.card.Shape; +import blackjack.domain.card.Value; +import java.util.List; + +public class CardsFixture { + public static final List CARDS_SCORE_4 = List.of( + new Card(Value.TWO, Shape.HEART), + new Card(Value.TWO, Shape.SPADE) + ); + public static final List TWO_ACE = List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.ACE, Shape.SPADE) + ); + public static final List SCORE_13_WITH_ACE = List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ); + public static final List CARDS_SCORE_16 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.SIX, Shape.HEART) + ); + public static final List CARDS_SCORE_17 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART) + ); + public static final List CARDS_SCORE_21 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.EIGHT, Shape.HEART), + new Card(Value.THREE, Shape.HEART) + ); + public static final List BLACKJACK = List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART) + ); + public static final List CARDS_SCORE_22 = List.of( + new Card(Value.JACK, Shape.HEART), + new Card(Value.SEVEN, Shape.HEART), + new Card(Value.FIVE, Shape.HEART) + ); + public static final List BUSTED = List.of( + new Card(Value.KING, Shape.DIAMOND), + new Card(Value.QUEEN, Shape.DIAMOND), + new Card(Value.JACK, Shape.DIAMOND) + ); +} diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 27207294a5..85b20f8f0b 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -4,10 +4,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import blackjack.domain.card.Card; -import blackjack.domain.card.CardTest; import blackjack.domain.card.Deck; import blackjack.domain.card.Shape; import blackjack.domain.card.Value; +import blackjack.domain.fixture.CardsFixture; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; @@ -18,21 +18,12 @@ import org.junit.jupiter.params.provider.MethodSource; class DealerTest { - - private static final List CARDS_SCORE_4 = CardTest.CARDS_SCORE_4; - private static final List TWO_ACE = CardTest.TWO_ACE; - private static final List SCORE_13_WITH_ACE = CardTest.SCORE_13_WITH_ACE; - private static final List CARDS_SCORE_16 = CardTest.CARDS_SCORE_16; - private static final List CARDS_SCORE_17 = CardTest.CARDS_SCORE_17; - private static final List CARDS_SCORE_21 = CardTest.CARDS_SCORE_21; - private static final List BLACKJACK = CardTest.BLACKJACK; - private static final List BUSTED = CardTest.BUSTED; - private static final Name DEFAULT_NAME = NameTest.DEFAULT_NAME; + private static final Name DEFAULT_NAME = new Name("name"); @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnderBound_returnTrue() { - Dealer dealer = new Dealer(CARDS_SCORE_16); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_16); assertThat(dealer.isDrawable()).isTrue(); } @@ -40,7 +31,7 @@ void isDrawableTest_whenScoreIsUnderBound_returnTrue() { @DisplayName("카드의 총 점수가 17을 넘으면, 카드를 더 뽑을 수 없다") @Test void isDrawableTest_whenScoreIsOverBound_returnFalse() { - Dealer dealer = new Dealer(CARDS_SCORE_17); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_17); assertThat(dealer.isDrawable()).isFalse(); } @@ -56,10 +47,10 @@ void calculateScoreTest(List cards, int expected) { static Stream cardsAndScore() { return Stream.of( - Arguments.of(BLACKJACK, 21), - Arguments.of(TWO_ACE, 12), - Arguments.of(SCORE_13_WITH_ACE, 13), - Arguments.of(CARDS_SCORE_16, 16) + Arguments.of(CardsFixture.BLACKJACK, 21), + Arguments.of(CardsFixture.TWO_ACE, 12), + Arguments.of(CardsFixture.SCORE_13_WITH_ACE, 13), + Arguments.of(CardsFixture.CARDS_SCORE_16, 16) ); } @@ -77,7 +68,7 @@ void drawStartCardsTest() { @DisplayName("이미 카드를 가지고 있는 경우, 시작 카드를 뽑을 수 없다.") @Test void drawStartCardsTest_whenAlreadyStarted_throwException() { - Dealer dealer = new Dealer(CARDS_SCORE_16); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_16); Deck deck = Deck.createShuffledDeck(); assertThatThrownBy(() -> dealer.drawStartCards(deck)) @@ -88,13 +79,13 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { @DisplayName("카드의 총 점수가 16을 넘지 않으면, 카드를 한 장 뽑는다") @Test void addTest_whenScoreIsUnderBound() { - Dealer dealer = new Dealer(CARDS_SCORE_16); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_16); Card additionalCard = new Card(Value.ACE, Shape.HEART); dealer.add(additionalCard); assertThat(dealer.getCards()) - .containsAll(CARDS_SCORE_16) + .containsAll(CardsFixture.CARDS_SCORE_16) .contains(additionalCard) .hasSize(3); } @@ -102,7 +93,7 @@ void addTest_whenScoreIsUnderBound() { @DisplayName("카드의 총 점수가 16을 넘으면, 카드를 뽑을 때 예외가 발생한다.") @Test void addTest_whenScoreIsOverBound_throwException() { - Dealer dealer = new Dealer(CARDS_SCORE_17); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_17); Card card = new Card(Value.ACE, Shape.HEART); assertThatThrownBy(() -> dealer.add(card)) @@ -119,34 +110,43 @@ class IsWinTest { @MethodSource("dealerCards") void whenPlayerBusted_dealerWin(List cards) { Dealer dealer = new Dealer(cards); - Player player = new Player(BUSTED, DEFAULT_NAME); + Player player = new Player(CardsFixture.BUSTED, DEFAULT_NAME); assertThat(dealer.isWin(player)).isTrue(); } static Stream> dealerCards() { - return Stream.of(BLACKJACK, CARDS_SCORE_4, CARDS_SCORE_16, BUSTED); + return Stream.of( + CardsFixture.BLACKJACK, + CardsFixture.CARDS_SCORE_4, + CardsFixture.CARDS_SCORE_16, + CardsFixture.BUSTED + ); } @DisplayName("딜러만 21을 넘길 경우, 플레이어가 이긴다.") @ParameterizedTest @MethodSource("playerCards") void whenOnlyDealerBusted_playerWin(List cards) { - Dealer dealer = new Dealer(BUSTED); + Dealer dealer = new Dealer(CardsFixture.BUSTED); Player player = new Player(cards, DEFAULT_NAME); assertThat(dealer.isWin(player)).isFalse(); } static Stream> playerCards() { - return Stream.of(BLACKJACK, CARDS_SCORE_4, CARDS_SCORE_16); + return Stream.of( + CardsFixture.BLACKJACK, + CardsFixture.CARDS_SCORE_4, + CardsFixture.CARDS_SCORE_16 + ); } @DisplayName("플레이어만 블랙잭일 경우, 플레이어가 이긴다.") @Test void whenPlayerOnlyBlackjack_playerWin() { - Player player = new Player(BLACKJACK, DEFAULT_NAME); - Dealer dealer = new Dealer(CARDS_SCORE_21); + Player player = new Player(CardsFixture.BLACKJACK, DEFAULT_NAME); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_21); assertThat(dealer.isWin(player)).isFalse(); } @@ -154,8 +154,8 @@ void whenPlayerOnlyBlackjack_playerWin() { @DisplayName("딜러만 블랙잭일 경우, 딜러가 이긴다.") @Test void whenDealerOnlyBlackjack_dealerWin() { - Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); - Dealer dealer = new Dealer(BLACKJACK); + Player player = new Player(CardsFixture.CARDS_SCORE_21, DEFAULT_NAME); + Dealer dealer = new Dealer(CardsFixture.BLACKJACK); assertThat(dealer.isWin(player)).isTrue(); } @@ -171,14 +171,18 @@ void whenPlayerScoreIsEqualToDealerScore_dealerWin(List cards) { } static Stream> sameCards() { - return Stream.of(BLACKJACK, CARDS_SCORE_21, CARDS_SCORE_16); + return Stream.of( + CardsFixture.BLACKJACK, + CardsFixture.CARDS_SCORE_21, + CardsFixture.CARDS_SCORE_16 + ); } @DisplayName("둘 다 21보다 작을 경우, 플레이어가 딜러의 숫자보다 크다면 플레이어가 이긴다.") @Test void whenPlayerScoreIsBiggerThanDealerScore_playerWin() { - Player player = new Player(CARDS_SCORE_17, DEFAULT_NAME); - Dealer dealer = new Dealer(CARDS_SCORE_16); + Player player = new Player(CardsFixture.CARDS_SCORE_17, DEFAULT_NAME); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_16); assertThat(dealer.isWin(player)).isFalse(); } @@ -186,8 +190,8 @@ void whenPlayerScoreIsBiggerThanDealerScore_playerWin() { @DisplayName("둘 다 21보다 작을 경우, 플레이어가 딜러의 숫자보다 작다면 딜러가 이긴다.") @Test void whenPlayerScoreIsSmallerThanDealerScore_dealerWin() { - Player player = new Player(CARDS_SCORE_16, DEFAULT_NAME); - Dealer dealer = new Dealer(CARDS_SCORE_17); + Player player = new Player(CardsFixture.CARDS_SCORE_16, DEFAULT_NAME); + Dealer dealer = new Dealer(CardsFixture.CARDS_SCORE_17); assertThat(dealer.isWin(player)).isTrue(); } diff --git a/src/test/java/blackjack/domain/participant/NameTest.java b/src/test/java/blackjack/domain/participant/NameTest.java index 973317b0d2..486850bbef 100644 --- a/src/test/java/blackjack/domain/participant/NameTest.java +++ b/src/test/java/blackjack/domain/participant/NameTest.java @@ -10,8 +10,6 @@ class NameTest { - public static final Name DEFAULT_NAME = new Name("name"); - @DisplayName("이름은 적어도 한 글자를 가져야 한다.") @ParameterizedTest @NullAndEmptySource diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 79fe72d6a6..4c1bcafd5e 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -4,10 +4,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import blackjack.domain.card.Card; -import blackjack.domain.card.CardTest; import blackjack.domain.card.Deck; import blackjack.domain.card.Shape; import blackjack.domain.card.Value; +import blackjack.domain.fixture.CardsFixture; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; @@ -18,13 +18,7 @@ class PlayerTest { - private static final List TWO_ACE = CardTest.TWO_ACE; - private static final List SCORE_13_WITH_ACE = CardTest.SCORE_13_WITH_ACE; - private static final List CARDS_SCORE_16 = CardTest.CARDS_SCORE_16; - private static final List CARDS_SCORE_21 = CardTest.CARDS_SCORE_21; - private static final List BLACKJACK = CardTest.BLACKJACK; - private static final List CARDS_SCORE_22 = CardTest.CARDS_SCORE_22; - private static final Name DEFAULT_NAME = NameTest.DEFAULT_NAME; + private static final Name DEFAULT_NAME = new Name("name"); @DisplayName("점수를 계산할 수 있다.") @ParameterizedTest @@ -37,17 +31,17 @@ void calculateScoreTest(List cards, int expected) { static Stream cardsAndScore() { return Stream.of( - Arguments.of(BLACKJACK, 21), - Arguments.of(TWO_ACE, 12), - Arguments.of(SCORE_13_WITH_ACE, 13), - Arguments.of(CARDS_SCORE_16, 16) + Arguments.of(CardsFixture.BLACKJACK, 21), + Arguments.of(CardsFixture.TWO_ACE, 12), + Arguments.of(CardsFixture.SCORE_13_WITH_ACE, 13), + Arguments.of(CardsFixture.CARDS_SCORE_16, 16) ); } @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnderBound_returnTrue() { - Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); + Player player = new Player(CardsFixture.CARDS_SCORE_21, DEFAULT_NAME); assertThat(player.isDrawable()).isTrue(); } @@ -55,7 +49,7 @@ void isDrawableTest_whenScoreIsUnderBound_returnTrue() { @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 더 뽑을 수 없다") @Test void isDrawableTest_whenScoreIsOverBound_returnFalse() { - Player player = new Player(CARDS_SCORE_22, DEFAULT_NAME); + Player player = new Player(CardsFixture.CARDS_SCORE_22, DEFAULT_NAME); assertThat(player.isDrawable()).isFalse(); } @@ -74,7 +68,7 @@ void drawStartCardsTest() { @DisplayName("이미 카드를 가지고 있는 경우, 시작 카드를 뽑을 수 없다.") @Test void drawStartCardsTest_whenAlreadyStarted_throwException() { - Player player = new Player(CARDS_SCORE_16, DEFAULT_NAME); + Player player = new Player(CardsFixture.CARDS_SCORE_16, DEFAULT_NAME); Deck deck = Deck.createShuffledDeck(); assertThatThrownBy(() -> player.drawStartCards(deck)) @@ -85,13 +79,13 @@ void drawStartCardsTest_whenAlreadyStarted_throwException() { @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 한 장 뽑는다") @Test void addTest_whenScoreIsUnderBound() { - Player player = new Player(CARDS_SCORE_21, DEFAULT_NAME); + Player player = new Player(CardsFixture.CARDS_SCORE_21, DEFAULT_NAME); Card additionalCard = new Card(Value.ACE, Shape.HEART); player.add(additionalCard); assertThat(player.getCards()) - .containsAll(CARDS_SCORE_21) + .containsAll(CardsFixture.CARDS_SCORE_21) .contains(additionalCard) .hasSize(4); } @@ -99,7 +93,7 @@ void addTest_whenScoreIsUnderBound() { @DisplayName("카드의 총 점수가 21을 넘으면, 카드를 뽑을 때 예외가 발생한다.") @Test void addTest_whenScoreIsOverBound_throwException() { - Player player = new Player(CARDS_SCORE_22, DEFAULT_NAME); + Player player = new Player(CardsFixture.CARDS_SCORE_22, DEFAULT_NAME); Card card = new Card(Value.ACE, Shape.HEART); assertThatThrownBy(() -> player.add(card)) From f255e57283bb61c51ba2b780023abc303ebb5d2c Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 20:30:01 +0900 Subject: [PATCH 59/62] =?UTF-8?q?refactor=20:=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EA=B7=9C=EC=B9=99=EA=B3=BC=20=EC=A7=81=EA=B2=B0?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EA=B2=BD=EA=B3=84=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=ED=94=BD=EC=8A=A4=EC=B2=98=EC=97=90=EC=84=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- .../java/blackjack/domain/card/HandTest.java | 1 - .../domain/fixture/CardsFixture.java | 5 ---- .../domain/participant/DealerTest.java | 1 - .../domain/participant/PlayerTest.java | 24 ++++++++++++++++++- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/test/java/blackjack/domain/card/HandTest.java b/src/test/java/blackjack/domain/card/HandTest.java index 6ff867df69..e5b09d9274 100644 --- a/src/test/java/blackjack/domain/card/HandTest.java +++ b/src/test/java/blackjack/domain/card/HandTest.java @@ -27,7 +27,6 @@ void calculateScoreTest(List cards, int expected) { static Stream cardsAndScore() { return Stream.of(Arguments.of(CardsFixture.BLACKJACK, 21), Arguments.of(CardsFixture.TWO_ACE, 12), - Arguments.of(CardsFixture.SCORE_13_WITH_ACE, 13), Arguments.of(CardsFixture.CARDS_SCORE_16, 16)); } diff --git a/src/test/java/blackjack/domain/fixture/CardsFixture.java b/src/test/java/blackjack/domain/fixture/CardsFixture.java index c6f671a29b..8005fbde32 100644 --- a/src/test/java/blackjack/domain/fixture/CardsFixture.java +++ b/src/test/java/blackjack/domain/fixture/CardsFixture.java @@ -14,11 +14,6 @@ public class CardsFixture { new Card(Value.ACE, Shape.HEART), new Card(Value.ACE, Shape.SPADE) ); - public static final List SCORE_13_WITH_ACE = List.of( - new Card(Value.ACE, Shape.HEART), - new Card(Value.KING, Shape.HEART), - new Card(Value.TWO, Shape.HEART) - ); public static final List CARDS_SCORE_16 = List.of( new Card(Value.JACK, Shape.HEART), new Card(Value.SIX, Shape.HEART) diff --git a/src/test/java/blackjack/domain/participant/DealerTest.java b/src/test/java/blackjack/domain/participant/DealerTest.java index 85b20f8f0b..f0e911ff9d 100644 --- a/src/test/java/blackjack/domain/participant/DealerTest.java +++ b/src/test/java/blackjack/domain/participant/DealerTest.java @@ -49,7 +49,6 @@ static Stream cardsAndScore() { return Stream.of( Arguments.of(CardsFixture.BLACKJACK, 21), Arguments.of(CardsFixture.TWO_ACE, 12), - Arguments.of(CardsFixture.SCORE_13_WITH_ACE, 13), Arguments.of(CardsFixture.CARDS_SCORE_16, 16) ); } diff --git a/src/test/java/blackjack/domain/participant/PlayerTest.java b/src/test/java/blackjack/domain/participant/PlayerTest.java index 4c1bcafd5e..5eb9cd7190 100644 --- a/src/test/java/blackjack/domain/participant/PlayerTest.java +++ b/src/test/java/blackjack/domain/participant/PlayerTest.java @@ -33,11 +33,33 @@ static Stream cardsAndScore() { return Stream.of( Arguments.of(CardsFixture.BLACKJACK, 21), Arguments.of(CardsFixture.TWO_ACE, 12), - Arguments.of(CardsFixture.SCORE_13_WITH_ACE, 13), Arguments.of(CardsFixture.CARDS_SCORE_16, 16) ); } + @DisplayName("ACE가 11로 계산되었을 때 버스트가 되지 않는다면, ACE를 그대로 계산한다.") + @Test + void calculateScoreTest_usingAceMaxScoreCase() { + Player player = new Player(List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ), DEFAULT_NAME); + + assertThat(player.calculateScore()).isEqualTo(13); + } + + @DisplayName("ACE가 11로 계산되었을 때 버스트가 된다면, ACE를 1로 계산한다.") + @Test + void calculateScoreTest_usingAceMinScoreCase() { + Player player = new Player(List.of( + new Card(Value.ACE, Shape.HEART), + new Card(Value.KING, Shape.HEART), + new Card(Value.TWO, Shape.HEART) + ), DEFAULT_NAME); + + assertThat(player.calculateScore()).isEqualTo(13); + } + @DisplayName("카드의 총 점수가 21을 넘지 않으면, 카드를 더 뽑을 수 있다") @Test void isDrawableTest_whenScoreIsUnderBound_returnTrue() { From 4d88fee4a1cf3d9e7d7d22266535b88f365a3da7 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Sun, 10 Mar 2024 20:47:49 +0900 Subject: [PATCH 60/62] =?UTF-8?q?refactor=20:=20=EC=8B=9C=EC=9E=91=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=EA=B0=80=20=EB=AA=87=20=EA=B0=9C=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A7=80=EB=8A=94=EC=A7=80=EC=9D=98=20=EC=B1=85?= =?UTF-8?q?=EC=9E=84=EC=9D=84=20=EB=B7=B0=EC=97=90=EC=84=9C=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/participant/Dealer.java | 6 ++++++ .../java/blackjack/domain/participant/Participant.java | 7 ++++++- src/main/java/blackjack/domain/participant/Player.java | 6 ++++++ src/main/java/blackjack/view/OutputView.java | 7 ++----- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index 64ad0f3326..f3d56964ca 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -8,6 +8,7 @@ public class Dealer extends Participant { private static final int DRAWABLE_MAX_SCORE = 16; + private static final int START_CARD_SIZE = 1; public Dealer() { super(Collections.emptyList()); @@ -45,4 +46,9 @@ public MatchResultDto match(Players players) { protected int getMaxDrawableScore() { return DRAWABLE_MAX_SCORE; } + + @Override + protected int getStartCardSize() { + return START_CARD_SIZE; + } } diff --git a/src/main/java/blackjack/domain/participant/Participant.java b/src/main/java/blackjack/domain/participant/Participant.java index 6dab9110e4..53e21f9886 100644 --- a/src/main/java/blackjack/domain/participant/Participant.java +++ b/src/main/java/blackjack/domain/participant/Participant.java @@ -48,10 +48,15 @@ public final void add(Card card) { hand.add(card); } - // TODO getStartCards() 도입 + public final List getStartCards() { + return getCards().subList(0, getStartCardSize()); + } + public final List getCards() { return hand.getCards(); } protected abstract int getMaxDrawableScore(); + + protected abstract int getStartCardSize(); } diff --git a/src/main/java/blackjack/domain/participant/Player.java b/src/main/java/blackjack/domain/participant/Player.java index d23d546ef1..a96d63e9e8 100644 --- a/src/main/java/blackjack/domain/participant/Player.java +++ b/src/main/java/blackjack/domain/participant/Player.java @@ -7,6 +7,7 @@ public class Player extends Participant { + private static final int START_CARD_SIZE = 2; private final Name name; Player(List cards, Name name) { @@ -27,6 +28,11 @@ protected int getMaxDrawableScore() { return BLACKJACK_SCORE; } + @Override + protected int getStartCardSize() { + return START_CARD_SIZE; + } + public String getName() { return name.getName(); } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 58aada64b8..28384c86ce 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -30,13 +30,10 @@ public class OutputView { Map.entry(Value.KING, "K") ); - private static final int DEALER_START_CARDS_SIZE = 1; - private static final int PLAYER_START_CARDS_SIZE = 2; - public void printStartStatus(Dealer dealer, Players players) { System.out.println(); System.out.println("딜러와 " + toPrintedFormat(players) + "에게 2장을 나누었습니다."); - printDealerCards(dealer.getCards().subList(0, DEALER_START_CARDS_SIZE)); + printDealerCards(dealer.getStartCards()); System.out.println(); printPlayersCards(players); System.out.println(); @@ -57,7 +54,7 @@ private void printDealerCards(List cards) { private void printPlayersCards(Players players) { for (Player player : players.getPlayers()) { - printPlayerCards(player.getName(), player.getCards().subList(0, PLAYER_START_CARDS_SIZE)); + printPlayerCards(player.getName(), player.getStartCards()); System.out.println(); } } From b9feef4cbc66746bb39ec5778e3a958d001497a9 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 11 Mar 2024 14:57:52 +0900 Subject: [PATCH 61/62] =?UTF-8?q?refactor=20:=20DTO=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9D=84=20=EC=B5=9C=EC=86=8C=ED=99=94=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4,=20=EC=9B=90=EC=8B=9C=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/BlackJackGame.java | 4 +++- .../java/blackjack/domain/participant/Dealer.java | 11 ++++++----- src/main/java/blackjack/dto/MatchResultDto.java | 4 ---- src/main/java/blackjack/view/OutputView.java | 5 ++--- 4 files changed, 11 insertions(+), 13 deletions(-) delete mode 100644 src/main/java/blackjack/dto/MatchResultDto.java diff --git a/src/main/java/blackjack/BlackJackGame.java b/src/main/java/blackjack/BlackJackGame.java index 284c79a9e6..9612c62132 100644 --- a/src/main/java/blackjack/BlackJackGame.java +++ b/src/main/java/blackjack/BlackJackGame.java @@ -50,7 +50,9 @@ private void playTurn(Player player, Deck deck) { private void printResult(Dealer dealer, Players players) { outputView.printEndingStatus(dealer, players); - outputView.printDealerMatchResult(dealer.match(players)); + int winCount = dealer.calculateWinCount(players); + int loseCount = dealer.calculateLoseCount(players); + outputView.printDealerMatchResult(winCount, loseCount); for (Player player : players.getPlayers()) { outputView.printPlayerMatchResult(player.getName(), player.isWin(dealer)); } diff --git a/src/main/java/blackjack/domain/participant/Dealer.java b/src/main/java/blackjack/domain/participant/Dealer.java index f3d56964ca..95d651262f 100644 --- a/src/main/java/blackjack/domain/participant/Dealer.java +++ b/src/main/java/blackjack/domain/participant/Dealer.java @@ -1,7 +1,6 @@ package blackjack.domain.participant; import blackjack.domain.card.Card; -import blackjack.dto.MatchResultDto; import java.util.Collections; import java.util.List; @@ -32,14 +31,16 @@ private boolean isLose(Player player) { return !isWin(player); } - public MatchResultDto match(Players players) { - int winCount = (int) players.getPlayers().stream() + public int calculateWinCount(Players players) { + return (int) players.getPlayers().stream() .filter(this::isWin) .count(); - int loseCount = (int) players.getPlayers().stream() + } + + public int calculateLoseCount(Players players) { + return (int) players.getPlayers().stream() .filter(this::isLose) .count(); - return new MatchResultDto(winCount, loseCount); } @Override diff --git a/src/main/java/blackjack/dto/MatchResultDto.java b/src/main/java/blackjack/dto/MatchResultDto.java deleted file mode 100644 index b17868ac01..0000000000 --- a/src/main/java/blackjack/dto/MatchResultDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package blackjack.dto; - -public record MatchResultDto(int winCount, int loseCount) { -} diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 28384c86ce..c8174e591a 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -6,7 +6,6 @@ import blackjack.domain.participant.Dealer; import blackjack.domain.participant.Player; import blackjack.domain.participant.Players; -import blackjack.dto.MatchResultDto; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -109,9 +108,9 @@ public void printDealerDraw() { System.out.print("딜러는 16이하라 한장의 카드를 더 받았습니다."); } - public void printDealerMatchResult(MatchResultDto matchResult) { + public void printDealerMatchResult(int winCount, int loseCount) { System.out.println("## 최종 승패"); - System.out.printf("딜러 : %d승 %d패%n", matchResult.winCount(), matchResult.loseCount()); + System.out.printf("딜러 : %d승 %d패%n", winCount, loseCount); } public void printPlayerMatchResult(String name, boolean isWin) { From c0f458bc948853cf0f91a8c6edae8a55eb7b6a11 Mon Sep 17 00:00:00 2001 From: "DESKTOP-E5VRH4Q\\cnddk" Date: Mon, 11 Mar 2024 15:46:17 +0900 Subject: [PATCH 62/62] =?UTF-8?q?refactor=20(Hand)=20:=20=EA=B0=80?= =?UTF-8?q?=EB=8F=85=EC=84=B1=20=EA=B0=9C=EC=84=A0=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=A0=90=EC=88=98=20=EA=B3=84=EC=82=B0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: zangsu --- src/main/java/blackjack/domain/card/Card.java | 4 +++ src/main/java/blackjack/domain/card/Hand.java | 32 +++++++++++++------ .../java/blackjack/domain/card/Value.java | 4 +++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java index c6651d338f..416457c064 100644 --- a/src/main/java/blackjack/domain/card/Card.java +++ b/src/main/java/blackjack/domain/card/Card.java @@ -44,4 +44,8 @@ public Value getValue() { public Shape getShape() { return shape; } + + public boolean isAce() { + return value.isAce(); + } } diff --git a/src/main/java/blackjack/domain/card/Hand.java b/src/main/java/blackjack/domain/card/Hand.java index affdf3b3fa..6b07ecb2b0 100644 --- a/src/main/java/blackjack/domain/card/Hand.java +++ b/src/main/java/blackjack/domain/card/Hand.java @@ -8,6 +8,7 @@ public class Hand { private static final int BLACKJACK_SCORE = 21; private static final int BLACKJACK_SIZE = 2; + private final List cards; public Hand(List cards) { @@ -19,22 +20,35 @@ public void add(Card card) { } public int calculateScore() { - int score = getMaxScore(); - int cardIndex = 0; - while (score > BLACKJACK_SCORE && cardIndex < cards.size()) { - Card card = cards.get(cardIndex); - score = score + card.getMinScore() - card.getMaxScore(); - cardIndex++; + int totalMinScore = getMinScore(); + int biggerScore = getBiggerScore(); + + if (biggerScore > BLACKJACK_SCORE) { + return totalMinScore; } - return score; + return biggerScore; } - private int getMaxScore() { + private int getMinScore() { return cards.stream() - .mapToInt(Card::getMaxScore) + .mapToInt(Card::getMinScore) .sum(); } + private int getBiggerScore() { + int score = getMinScore(); + int differenceScore = cards.stream() + .filter(Card::isAce) + .mapToInt(this::calculateDifferenceScore) + .findAny() + .orElse(0); + return score + differenceScore; + } + + private int calculateDifferenceScore(Card card) { + return card.getMaxScore() - card.getMinScore(); + } + public boolean isBusted() { return calculateScore() > BLACKJACK_SCORE; } diff --git a/src/main/java/blackjack/domain/card/Value.java b/src/main/java/blackjack/domain/card/Value.java index ad4e86eaa9..7cd8f2898d 100644 --- a/src/main/java/blackjack/domain/card/Value.java +++ b/src/main/java/blackjack/domain/card/Value.java @@ -30,4 +30,8 @@ public int getMinScore() { public int getMaxScore() { return maxScore; } + + public boolean isAce() { + return this == ACE; + } }