From cc6c638fe3d063c627f2ccbac38fe0ee7b1168ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Tue, 5 Mar 2024 20:27:33 +0900 Subject: [PATCH 01/39] =?UTF-8?q?docs(README):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=9A=94=EA=B5=AC=20=EC=82=AC=ED=95=AD=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- README.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 556099c4de..13782db1ac 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,25 @@ 블랙잭 미션 저장소 -## 우아한테크코스 코드리뷰 +## 기능 요구 사항 + +### 게임 + +-[ ] 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 쪽이 승리한다. +-[ ] 게임을 시작하면 플레이어는 두 장의 카드를 지급 받는다. + -[ ] 이후 플레이어와 딜러의 카드를 출력한다. + -[ ] 단, 딜러의 카드는 하나만 출력한다. +-[ ] 플레이어는 카드의 숫자 합이 21을 초과하지 않는다면 카드를 원하는 만큼 다시 뽑을 수 있다. + -[ ] 새로 받을 때 마다 해당 플레이어의 카드를 출력한다. +-[ ] 플레이어가 카드를 다 받으면 딜러의 카드를 확인한다. +-[ ] 딜러의 카드 합이 16 이하이면 반드시 1장의 카드를 추가로 받아야 한다. + -[ ] 17 이상이면 추가로 받을 수 없다. +-[ ] 딜러와 플레이어의 카드, 결과와 최종 승패를 출력한다. + +### 카드 + +-[ ] 클로버, 스페이드, 하트, 다이아몬드 모양을 가진다. +-[ ] 카드는 2부터 10까지의 숫자와 Ace, King, Queen, Jack으로 이루어져 있다. +-[ ] King, Queen, Jack은 10으로 계산한다. +-[ ] Ace는 1 또는 11로 계산할 수 있다. -- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) From 9c89c6f18274fc149f8ba3978c637c3bc0a16a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Tue, 5 Mar 2024 20:31:43 +0900 Subject: [PATCH 02/39] =?UTF-8?q?feat:=20=EC=B9=B4=EB=93=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=96=91=EA=B3=BC=20=EC=88=AB=EC=9E=90=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20Enum=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- .../blackjack/domain/card/CardNumber.java | 30 +++++++++++++++++++ .../java/blackjack/domain/card/CardShape.java | 15 ++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/main/java/blackjack/domain/card/CardNumber.java create mode 100644 src/main/java/blackjack/domain/card/CardShape.java diff --git a/src/main/java/blackjack/domain/card/CardNumber.java b/src/main/java/blackjack/domain/card/CardNumber.java new file mode 100644 index 0000000000..44b8c54bd2 --- /dev/null +++ b/src/main/java/blackjack/domain/card/CardNumber.java @@ -0,0 +1,30 @@ +package blackjack.domain.card; + +public enum CardNumber { + + ACE("A", 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("J", 10), + QUEEN("Q", 10), + KING("K", 10); + + private final String name; + private final int value; + + CardNumber(String name, int value) { + this.name = name; + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/blackjack/domain/card/CardShape.java b/src/main/java/blackjack/domain/card/CardShape.java new file mode 100644 index 0000000000..82917fadf1 --- /dev/null +++ b/src/main/java/blackjack/domain/card/CardShape.java @@ -0,0 +1,15 @@ +package blackjack.domain.card; + +public enum CardShape { + + HEART("하트"), + CLOVER("클로버"), + SPADE("스페이드"), + DIAMOND("다이아몬드"); + + private final String name; + + CardShape(String name) { + this.name = name; + } +} From b7011cb77452b86b4a3fde83f26fc3532c07e5fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Tue, 5 Mar 2024 20:34:11 +0900 Subject: [PATCH 03/39] =?UTF-8?q?feat(Deck):=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=EB=A5=BC=20=EA=B0=80=EC=A7=80=EB=8A=94=20Dec?= =?UTF-8?q?k=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=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: seokmyungham --- README.md | 6 ++-- src/main/java/blackjack/domain/card/Card.java | 33 +++++++++++++++++++ src/main/java/blackjack/domain/card/Deck.java | 32 ++++++++++++++++++ .../java/blackjack/domain/card/DeckTest.java | 25 ++++++++++++++ 4 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 src/main/java/blackjack/domain/card/Card.java create mode 100644 src/main/java/blackjack/domain/card/Deck.java create mode 100644 src/test/java/blackjack/domain/card/DeckTest.java diff --git a/README.md b/README.md index 13782db1ac..19c8e2218e 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ ### 카드 --[ ] 클로버, 스페이드, 하트, 다이아몬드 모양을 가진다. --[ ] 카드는 2부터 10까지의 숫자와 Ace, King, Queen, Jack으로 이루어져 있다. --[ ] King, Queen, Jack은 10으로 계산한다. +-[x] 클로버, 스페이드, 하트, 다이아몬드 모양을 가진다. +-[x] 카드는 2부터 10까지의 숫자와 Ace, King, Queen, Jack으로 이루어져 있다. +-[x] King, Queen, Jack은 10으로 계산한다. -[ ] Ace는 1 또는 11로 계산할 수 있다. diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java new file mode 100644 index 0000000000..c7e96d839f --- /dev/null +++ b/src/main/java/blackjack/domain/card/Card.java @@ -0,0 +1,33 @@ +package blackjack.domain.card; + +import java.util.Objects; + +public class Card { + + private final CardShape cardShape; + private final CardNumber cardNumber; + + public Card(CardShape cardShape, CardNumber cardNumber) { + this.cardShape = cardShape; + this.cardNumber = cardNumber; + } + + public int getCardNumber() { + return cardNumber.getValue(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Card card = (Card)o; + return cardShape == card.cardShape && cardNumber == card.cardNumber; + } + + @Override + public int hashCode() { + return Objects.hash(cardShape, cardNumber); + } +} diff --git a/src/main/java/blackjack/domain/card/Deck.java b/src/main/java/blackjack/domain/card/Deck.java new file mode 100644 index 0000000000..d19140a943 --- /dev/null +++ b/src/main/java/blackjack/domain/card/Deck.java @@ -0,0 +1,32 @@ +package blackjack.domain.card; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +public class Deck { + + private final LinkedList cards; + + public Deck() { + this.cards = Arrays.stream(CardShape.values()) + .flatMap(cardShape -> Arrays.stream(CardNumber.values()) + .map(number -> new Card(cardShape, number))) + .collect(Collectors.toCollection(LinkedList::new)); + } + + public void shuffle() { + Collections.shuffle(cards); + } + + public Card draw() { + return cards.poll(); + } + + public List getCards() { + return new ArrayList<>(cards); + } +} diff --git a/src/test/java/blackjack/domain/card/DeckTest.java b/src/test/java/blackjack/domain/card/DeckTest.java new file mode 100644 index 0000000000..b501c68b9a --- /dev/null +++ b/src/test/java/blackjack/domain/card/DeckTest.java @@ -0,0 +1,25 @@ +package blackjack.domain.card; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class DeckTest { + + @Test + @DisplayName("카드 덱은 52장의 카드로 이루어져 있다.") + void deckSizeTest() { + Deck deck = new Deck(); + + assertThat(deck.getCards().size()).isEqualTo(52); + } + + @Test + @DisplayName("맨 위의 카드를 한 장 뽑는다.") + void drawTest() { + Deck deck = new Deck(); + + assertThat(deck.draw()).isEqualTo(new Card(CardShape.HEART, CardNumber.ACE)); + } +} From 1ab946fe9aa1d861e22c340e8ae4ba23ca39c8bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 14:49:07 +0900 Subject: [PATCH 04/39] =?UTF-8?q?style(DeckTest):=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=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: seokmyungham --- src/test/java/blackjack/domain/card/DeckTest.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/java/blackjack/domain/card/DeckTest.java b/src/test/java/blackjack/domain/card/DeckTest.java index b501c68b9a..5ce0b7d982 100644 --- a/src/test/java/blackjack/domain/card/DeckTest.java +++ b/src/test/java/blackjack/domain/card/DeckTest.java @@ -2,24 +2,28 @@ import static org.assertj.core.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class DeckTest { + Deck deck; + + @BeforeEach + void setUP() { + deck = new Deck(); + } + @Test @DisplayName("카드 덱은 52장의 카드로 이루어져 있다.") void deckSizeTest() { - Deck deck = new Deck(); - assertThat(deck.getCards().size()).isEqualTo(52); } @Test @DisplayName("맨 위의 카드를 한 장 뽑는다.") void drawTest() { - Deck deck = new Deck(); - assertThat(deck.draw()).isEqualTo(new Card(CardShape.HEART, CardNumber.ACE)); } } From 54db712bddef05496400711ee183742f7cae26da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 14:50:16 +0900 Subject: [PATCH 05/39] =?UTF-8?q?feat(BlackJackGamer):=20=EB=94=9C?= =?UTF-8?q?=EB=9F=AC=EC=99=80=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EC=9D=98=20=EA=B3=B5=ED=86=B5=20=EC=B6=94=EC=83=81=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- README.md | 9 +++- src/main/java/blackjack/domain/card/Card.java | 4 ++ .../domain/gamer/BlackJackGamer.java | 37 ++++++++++++++ .../domain/gamer/BlackJackGamerTest.java | 49 +++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 src/main/java/blackjack/domain/gamer/BlackJackGamer.java create mode 100644 src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java diff --git a/README.md b/README.md index 19c8e2218e..cc0516b974 100644 --- a/README.md +++ b/README.md @@ -22,5 +22,12 @@ -[x] 클로버, 스페이드, 하트, 다이아몬드 모양을 가진다. -[x] 카드는 2부터 10까지의 숫자와 Ace, King, Queen, Jack으로 이루어져 있다. -[x] King, Queen, Jack은 10으로 계산한다. --[ ] Ace는 1 또는 11로 계산할 수 있다. +-[x] ACE는 1 또는 11로 계산할 수 있다. +### 딜러, 플레이어 + +-[ ] 최소 1글자, 최대 5글자의 이름을 가진다. +-[x] ACE 카드를 가지는 경우, 일단 11로 계산한 뒤, 합이 21을 초과하면 1로 계산한다. +-[ ] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. + - [ ] 딜러는 숫자의 합이 16 이하이면 카드를 더 받을 수 있다. + - [ ] 플레이어는 숫자의 합이 21 이하이면 카드를 더 받을 수 있다. diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java index c7e96d839f..d07e4df1e3 100644 --- a/src/main/java/blackjack/domain/card/Card.java +++ b/src/main/java/blackjack/domain/card/Card.java @@ -16,6 +16,10 @@ public int getCardNumber() { return cardNumber.getValue(); } + public boolean isAce() { + return cardNumber == CardNumber.ACE; + } + @Override public boolean equals(Object o) { if (this == o) diff --git a/src/main/java/blackjack/domain/gamer/BlackJackGamer.java b/src/main/java/blackjack/domain/gamer/BlackJackGamer.java new file mode 100644 index 0000000000..0c44dbb43c --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/BlackJackGamer.java @@ -0,0 +1,37 @@ +package blackjack.domain.gamer; + +import java.util.List; + +import blackjack.domain.card.Card; + +public abstract class BlackJackGamer { + + private final List cards; + + public BlackJackGamer(List cards) { + this.cards = cards; + } + + public void addCard(Card card) { + cards.add(card); + } + + /** + * ACE가 포함된 경우, 21 이하이면서 가장 가능한 큰 값으로 계산한다. + */ + public int sumCardNumbers() { + int sum = cards.stream() + .mapToInt(Card::getCardNumber) + .sum(); + int aceCount = (int)cards.stream().filter(Card::isAce).count(); + + for (int i = 0; i < aceCount; i++) { + if (sum > 21) { + sum -= 10; + } + } + return sum; + } + + public abstract boolean canReceiveCard(); +} diff --git a/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java b/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java new file mode 100644 index 0000000000..c847adb404 --- /dev/null +++ b/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java @@ -0,0 +1,49 @@ +package blackjack.domain.gamer; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import blackjack.domain.card.Card; +import blackjack.domain.card.CardNumber; +import blackjack.domain.card.CardShape; + +class BlackJackGamerTest { + + BlackJackGamer player; + + @BeforeEach + void setUP() { + player = new Player(); + } + + @Test + @DisplayName("ACE가 없을때의 숫자 합을 계산한다.") + void sumWithoutAceTest() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + + assertThat(player.sumCardNumbers()).isEqualTo(15); + } + + @Test + @DisplayName("숫자의 합이 21을 초과하는 경우, ACE를 1로 계산한다.") + void sumWithOneAceTest() { + player.addCard(new Card(CardShape.HEART, CardNumber.ACE)); + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.DIAMOND, CardNumber.KING)); + + assertThat(player.sumCardNumbers()).isEqualTo(21); + } + + @Test + @DisplayName("숫자의 합이 21을 초과하지 않으면, ACE를 11로 계산한다.") + void sumWithElevenAceTest() { + player.addCard(new Card(CardShape.HEART, CardNumber.ACE)); + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + + assertThat(player.sumCardNumbers()).isEqualTo(21); + } +} From 1432f2d920cd3a7fb3c9de3612309aecaedec0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 14:55:41 +0900 Subject: [PATCH 06/39] =?UTF-8?q?feat(Dealer):=20BlackJackGamer=EB=A5=BC?= =?UTF-8?q?=20=EC=83=81=EC=86=8D=EB=B0=9B=EB=8A=94=20=EB=94=9C=EB=9F=AC=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1=EA=B3=BC=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9E=AC=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- README.md | 4 +- .../java/blackjack/domain/gamer/Dealer.java | 15 +++++++ .../blackjack/domain/gamer/DealerTest.java | 39 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/main/java/blackjack/domain/gamer/Dealer.java create mode 100644 src/test/java/blackjack/domain/gamer/DealerTest.java diff --git a/README.md b/README.md index cc0516b974..df2d9b02e7 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,6 @@ -[ ] 최소 1글자, 최대 5글자의 이름을 가진다. -[x] ACE 카드를 가지는 경우, 일단 11로 계산한 뒤, 합이 21을 초과하면 1로 계산한다. --[ ] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. - - [ ] 딜러는 숫자의 합이 16 이하이면 카드를 더 받을 수 있다. +-[x] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. + - [x] 딜러는 숫자의 합이 16 이하이면 카드를 더 받을 수 있다. - [ ] 플레이어는 숫자의 합이 21 이하이면 카드를 더 받을 수 있다. diff --git a/src/main/java/blackjack/domain/gamer/Dealer.java b/src/main/java/blackjack/domain/gamer/Dealer.java new file mode 100644 index 0000000000..a69565719a --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/Dealer.java @@ -0,0 +1,15 @@ +package blackjack.domain.gamer; + +import java.util.ArrayList; + +public class Dealer extends BlackJackGamer { + + public Dealer() { + super(new ArrayList<>()); + } + + @Override + public boolean canReceiveCard() { + return sumCardNumbers() <= 16; + } +} diff --git a/src/test/java/blackjack/domain/gamer/DealerTest.java b/src/test/java/blackjack/domain/gamer/DealerTest.java new file mode 100644 index 0000000000..9c98fa3db0 --- /dev/null +++ b/src/test/java/blackjack/domain/gamer/DealerTest.java @@ -0,0 +1,39 @@ +package blackjack.domain.gamer; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import blackjack.domain.card.Card; +import blackjack.domain.card.CardNumber; +import blackjack.domain.card.CardShape; + +class DealerTest { + + Dealer dealer; + + @BeforeEach + void setUP() { + dealer = new Dealer(); + } + + @Test + @DisplayName("카드의 총합이 16 이하이면 카드를 받을 수 있다.") + void receiveCardTest() { + dealer.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + dealer.addCard(new Card(CardShape.HEART, CardNumber.SIX)); + + assertThat(dealer.canReceiveCard()).isTrue(); + } + + @Test + @DisplayName("카드의 총합이 16을 초과하면 카드를 받을 수 없다.") + void cantReceiveCardTest() { + dealer.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + dealer.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(dealer.canReceiveCard()).isFalse(); + } +} From 56af9662c64b1e202ffa8310fca31594233627f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 14:56:00 +0900 Subject: [PATCH 07/39] =?UTF-8?q?feat(Player):=20BlackJackGamer=EB=A5=BC?= =?UTF-8?q?=20=EC=83=81=EC=86=8D=EB=B0=9B=EB=8A=94=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EA=B3=BC=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9E=AC?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- README.md | 2 +- .../java/blackjack/domain/gamer/Player.java | 15 +++++++ .../blackjack/domain/gamer/PlayerTest.java | 40 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/java/blackjack/domain/gamer/Player.java create mode 100644 src/test/java/blackjack/domain/gamer/PlayerTest.java diff --git a/README.md b/README.md index df2d9b02e7..f93db77a99 100644 --- a/README.md +++ b/README.md @@ -30,4 +30,4 @@ -[x] ACE 카드를 가지는 경우, 일단 11로 계산한 뒤, 합이 21을 초과하면 1로 계산한다. -[x] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. - [x] 딜러는 숫자의 합이 16 이하이면 카드를 더 받을 수 있다. - - [ ] 플레이어는 숫자의 합이 21 이하이면 카드를 더 받을 수 있다. + - [x] 플레이어는 숫자의 합이 21 이하이면 카드를 더 받을 수 있다. diff --git a/src/main/java/blackjack/domain/gamer/Player.java b/src/main/java/blackjack/domain/gamer/Player.java new file mode 100644 index 0000000000..3baf3fc5c0 --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/Player.java @@ -0,0 +1,15 @@ +package blackjack.domain.gamer; + +import java.util.ArrayList; + +public class Player extends BlackJackGamer { + + public Player() { + super(new ArrayList<>()); + } + + @Override + public boolean canReceiveCard() { + return sumCardNumbers() <= 21; + } +} diff --git a/src/test/java/blackjack/domain/gamer/PlayerTest.java b/src/test/java/blackjack/domain/gamer/PlayerTest.java new file mode 100644 index 0000000000..5410e8c6d8 --- /dev/null +++ b/src/test/java/blackjack/domain/gamer/PlayerTest.java @@ -0,0 +1,40 @@ +package blackjack.domain.gamer; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import blackjack.domain.card.Card; +import blackjack.domain.card.CardNumber; +import blackjack.domain.card.CardShape; + +class PlayerTest { + + Player player; + + @BeforeEach + void setUP() { + player = new Player(); + } + + @Test + @DisplayName("카드의 총합이 21 이하이면 카드를 받을 수 있다.") + void receiveCardTest() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + + assertThat(player.canReceiveCard()).isTrue(); + } + + @Test + @DisplayName("카드의 총합이 21을 초과하면 카드를 받을 수 없다.") + void cantReceiveCardTest() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.canReceiveCard()).isFalse(); + } +} From af51dfa73df98d62e09e209021e41f39e8d4774a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 16:21:03 +0900 Subject: [PATCH 08/39] =?UTF-8?q?feat(Name):=20=EB=AC=B8=EC=9E=90=EC=97=B4?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=EC=9D=84=20=ED=8F=AC=EC=9E=A5=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- README.md | 2 +- .../blackjack/domain/gamer/BlackJackGamer.java | 4 +++- .../java/blackjack/domain/gamer/Dealer.java | 2 +- src/main/java/blackjack/domain/gamer/Name.java | 12 ++++++++++++ .../java/blackjack/domain/gamer/Player.java | 4 ++-- .../domain/gamer/BlackJackGamerTest.java | 2 +- .../java/blackjack/domain/gamer/NameTest.java | 18 ++++++++++++++++++ .../blackjack/domain/gamer/PlayerTest.java | 2 +- 8 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/main/java/blackjack/domain/gamer/Name.java create mode 100644 src/test/java/blackjack/domain/gamer/NameTest.java diff --git a/README.md b/README.md index f93db77a99..8680d2098b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ ### 딜러, 플레이어 --[ ] 최소 1글자, 최대 5글자의 이름을 가진다. +-[x] 최소 1글자, 최대 5글자의 이름을 가진다. -[x] ACE 카드를 가지는 경우, 일단 11로 계산한 뒤, 합이 21을 초과하면 1로 계산한다. -[x] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. - [x] 딜러는 숫자의 합이 16 이하이면 카드를 더 받을 수 있다. diff --git a/src/main/java/blackjack/domain/gamer/BlackJackGamer.java b/src/main/java/blackjack/domain/gamer/BlackJackGamer.java index 0c44dbb43c..13017b176b 100644 --- a/src/main/java/blackjack/domain/gamer/BlackJackGamer.java +++ b/src/main/java/blackjack/domain/gamer/BlackJackGamer.java @@ -6,9 +6,11 @@ public abstract class BlackJackGamer { + private final Name name; private final List cards; - public BlackJackGamer(List cards) { + public BlackJackGamer(Name name, List cards) { + this.name = name; this.cards = cards; } diff --git a/src/main/java/blackjack/domain/gamer/Dealer.java b/src/main/java/blackjack/domain/gamer/Dealer.java index a69565719a..e3cc143b7f 100644 --- a/src/main/java/blackjack/domain/gamer/Dealer.java +++ b/src/main/java/blackjack/domain/gamer/Dealer.java @@ -5,7 +5,7 @@ public class Dealer extends BlackJackGamer { public Dealer() { - super(new ArrayList<>()); + super(new Name("딜러"), new ArrayList<>()); } @Override diff --git a/src/main/java/blackjack/domain/gamer/Name.java b/src/main/java/blackjack/domain/gamer/Name.java new file mode 100644 index 0000000000..21e6495de9 --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/Name.java @@ -0,0 +1,12 @@ +package blackjack.domain.gamer; + +public record Name(String value) { + + private static final int MAX_NAME_LENGTH = 5; + + public Name { + if (value.isBlank() || value.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("이름의 길이는 최소 1글자부터 최대 5글자까지 가능합니다."); + } + } +} diff --git a/src/main/java/blackjack/domain/gamer/Player.java b/src/main/java/blackjack/domain/gamer/Player.java index 3baf3fc5c0..a79cd529f5 100644 --- a/src/main/java/blackjack/domain/gamer/Player.java +++ b/src/main/java/blackjack/domain/gamer/Player.java @@ -4,8 +4,8 @@ public class Player extends BlackJackGamer { - public Player() { - super(new ArrayList<>()); + public Player(Name name) { + super(name, new ArrayList<>()); } @Override diff --git a/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java b/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java index c847adb404..50b0744c38 100644 --- a/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java +++ b/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java @@ -16,7 +16,7 @@ class BlackJackGamerTest { @BeforeEach void setUP() { - player = new Player(); + player = new Player(new Name("hogi")); } @Test diff --git a/src/test/java/blackjack/domain/gamer/NameTest.java b/src/test/java/blackjack/domain/gamer/NameTest.java new file mode 100644 index 0000000000..6ecf73033d --- /dev/null +++ b/src/test/java/blackjack/domain/gamer/NameTest.java @@ -0,0 +1,18 @@ +package blackjack.domain.gamer; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class NameTest { + + @ParameterizedTest + @ValueSource(strings = {"", "abcdef"}) + @DisplayName("이름의 길이가 0글자이거나, 5글자를 초과하면 예외가 발생된다.") + void nameLengthExceptionTest(String name) { + assertThatThrownBy(() -> new Name(name)) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/blackjack/domain/gamer/PlayerTest.java b/src/test/java/blackjack/domain/gamer/PlayerTest.java index 5410e8c6d8..9b3c894362 100644 --- a/src/test/java/blackjack/domain/gamer/PlayerTest.java +++ b/src/test/java/blackjack/domain/gamer/PlayerTest.java @@ -16,7 +16,7 @@ class PlayerTest { @BeforeEach void setUP() { - player = new Player(); + player = new Player(new Name("hogi")); } @Test From 59f51bc30ab36fd7f4e645fe1452a1729e1e39e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 16:25:40 +0900 Subject: [PATCH 09/39] =?UTF-8?q?feat(Players):=20Player=EC=9D=98=20?= =?UTF-8?q?=EC=9D=BC=EA=B8=89=20=EC=BB=AC=EB=A0=89=EC=85=98=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- README.md | 36 +++++++++-------- .../java/blackjack/domain/gamer/Players.java | 40 +++++++++++++++++++ .../blackjack/domain/gamer/PlayersTest.java | 33 +++++++++++++++ 3 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 src/main/java/blackjack/domain/gamer/Players.java create mode 100644 src/test/java/blackjack/domain/gamer/PlayersTest.java diff --git a/README.md b/README.md index 8680d2098b..1161e0462c 100644 --- a/README.md +++ b/README.md @@ -6,28 +6,30 @@ ### 게임 --[ ] 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 쪽이 승리한다. --[ ] 게임을 시작하면 플레이어는 두 장의 카드를 지급 받는다. - -[ ] 이후 플레이어와 딜러의 카드를 출력한다. - -[ ] 단, 딜러의 카드는 하나만 출력한다. --[ ] 플레이어는 카드의 숫자 합이 21을 초과하지 않는다면 카드를 원하는 만큼 다시 뽑을 수 있다. - -[ ] 새로 받을 때 마다 해당 플레이어의 카드를 출력한다. --[ ] 플레이어가 카드를 다 받으면 딜러의 카드를 확인한다. --[ ] 딜러의 카드 합이 16 이하이면 반드시 1장의 카드를 추가로 받아야 한다. - -[ ] 17 이상이면 추가로 받을 수 없다. --[ ] 딜러와 플레이어의 카드, 결과와 최종 승패를 출력한다. +- [ ] 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 쪽이 승리한다. +- [ ] 게임을 시작하면 플레이어는 두 장의 카드를 지급 받는다. + - [ ] 이후 플레이어와 딜러의 카드를 출력한다. + - [ ] 단, 딜러의 카드는 하나만 출력한다. +- [ ] 플레이어는 카드의 숫자 합이 21을 초과하지 않는다면 카드를 원하는 만큼 다시 뽑을 수 있다. + - [ ] 새로 받을 때 마다 해당 플레이어의 카드를 출력한다. +- [ ] 플레이어가 카드를 다 받으면 딜러의 카드를 확인한다. +- [ ] 딜러의 카드 합이 16 이하이면 반드시 1장의 카드를 추가로 받아야 한다. + - [ ] 17 이상이면 추가로 받을 수 없다. +- [ ] 딜러와 플레이어의 카드, 결과와 최종 승패를 출력한다. ### 카드 --[x] 클로버, 스페이드, 하트, 다이아몬드 모양을 가진다. --[x] 카드는 2부터 10까지의 숫자와 Ace, King, Queen, Jack으로 이루어져 있다. --[x] King, Queen, Jack은 10으로 계산한다. --[x] ACE는 1 또는 11로 계산할 수 있다. +- [x] 클로버, 스페이드, 하트, 다이아몬드 모양을 가진다. +- [x] 카드는 2부터 10까지의 숫자와 Ace, King, Queen, Jack으로 이루어져 있다. +- [x] King, Queen, Jack은 10으로 계산한다. +- [x] ACE는 1 또는 11로 계산할 수 있다. ### 딜러, 플레이어 --[x] 최소 1글자, 최대 5글자의 이름을 가진다. --[x] ACE 카드를 가지는 경우, 일단 11로 계산한 뒤, 합이 21을 초과하면 1로 계산한다. --[x] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. +- [x] 최소 1글자, 최대 5글자의 이름을 가진다. +- [x] ACE 카드를 가지는 경우, 일단 11로 계산한 뒤, 합이 21을 초과하면 1로 계산한다. +- [x] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. - [x] 딜러는 숫자의 합이 16 이하이면 카드를 더 받을 수 있다. - [x] 플레이어는 숫자의 합이 21 이하이면 카드를 더 받을 수 있다. +- [x] 플레이어의 이름은 중복될 수 없다. +- [x] 플레이어는 최소 2명부터 최대 8명까지 가능하다. \ No newline at end of file diff --git a/src/main/java/blackjack/domain/gamer/Players.java b/src/main/java/blackjack/domain/gamer/Players.java new file mode 100644 index 0000000000..6787272238 --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/Players.java @@ -0,0 +1,40 @@ +package blackjack.domain.gamer; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Players { + + private static final int MIN_PLAYER_COUNT = 2; + private static final int MAX_PLAYER_COUNT = 8; + + private final List players; + + public Players(List names) { + validateNames(names); + + this.players = names.stream() + .map(name -> new Player(new Name(name))) + .toList(); + } + + private void validateNames(List names) { + validateDuplicate(names); + validateCount(names.size()); + } + + private void validateCount(int count) { + if (count < MIN_PLAYER_COUNT || count > MAX_PLAYER_COUNT) { + throw new IllegalArgumentException(); + } + } + + private void validateDuplicate(List names) { + Set nonDuplicateNames = new HashSet<>(names); + + if (names.size() != nonDuplicateNames.size()) { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/test/java/blackjack/domain/gamer/PlayersTest.java b/src/test/java/blackjack/domain/gamer/PlayersTest.java new file mode 100644 index 0000000000..b4dbab3b72 --- /dev/null +++ b/src/test/java/blackjack/domain/gamer/PlayersTest.java @@ -0,0 +1,33 @@ +package blackjack.domain.gamer; + +import static java.util.List.*; +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PlayersTest { + + @Test + @DisplayName("플레이어의 이름은 중복을 허용하지 않는다.") + void duplicatePlayerNamesTest() { + assertThatThrownBy(() -> new Players(of("hogi", "sang", "hogi"))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("플레이어는 적어도 2명 이상이어야 한다.") + void minimumPlayerCountTest() { + assertThatThrownBy(() -> new Players(of("a"))) + .isInstanceOf(IllegalArgumentException.class); + + } + + @Test + @DisplayName("플레이어는 최대 8명까지만 가능하다.") + void maximumPlayerCountTest() { + assertThatThrownBy(() -> new Players(of("a", "b", "c", "d", "e", "f", "g", "h", "g"))) + .isInstanceOf(IllegalArgumentException.class); + + } +} From e75ea3bbf903c38db375dd928ff11352824eb187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 17:10:55 +0900 Subject: [PATCH 10/39] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/domain/gamer/Name.java | 2 +- src/main/java/blackjack/domain/gamer/Players.java | 6 ++++-- src/test/java/blackjack/domain/gamer/NameTest.java | 3 ++- src/test/java/blackjack/domain/gamer/PlayersTest.java | 7 ++++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/blackjack/domain/gamer/Name.java b/src/main/java/blackjack/domain/gamer/Name.java index 21e6495de9..2974903b49 100644 --- a/src/main/java/blackjack/domain/gamer/Name.java +++ b/src/main/java/blackjack/domain/gamer/Name.java @@ -6,7 +6,7 @@ public record Name(String value) { public Name { if (value.isBlank() || value.length() > MAX_NAME_LENGTH) { - throw new IllegalArgumentException("이름의 길이는 최소 1글자부터 최대 5글자까지 가능합니다."); + throw new IllegalArgumentException("이름의 길이는 최소 1글자부터 최대 " + MAX_NAME_LENGTH + "글자까지 가능합니다."); } } } diff --git a/src/main/java/blackjack/domain/gamer/Players.java b/src/main/java/blackjack/domain/gamer/Players.java index 6787272238..be90f5986b 100644 --- a/src/main/java/blackjack/domain/gamer/Players.java +++ b/src/main/java/blackjack/domain/gamer/Players.java @@ -26,7 +26,9 @@ private void validateNames(List names) { private void validateCount(int count) { if (count < MIN_PLAYER_COUNT || count > MAX_PLAYER_COUNT) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "플레이어는 최소 " + MIN_PLAYER_COUNT + "명에서 최대 " + MAX_PLAYER_COUNT + "명까지 가능합니다" + ); } } @@ -34,7 +36,7 @@ private void validateDuplicate(List names) { Set nonDuplicateNames = new HashSet<>(names); if (names.size() != nonDuplicateNames.size()) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("이름은 중복될 수 없습니다."); } } } diff --git a/src/test/java/blackjack/domain/gamer/NameTest.java b/src/test/java/blackjack/domain/gamer/NameTest.java index 6ecf73033d..d41537b72b 100644 --- a/src/test/java/blackjack/domain/gamer/NameTest.java +++ b/src/test/java/blackjack/domain/gamer/NameTest.java @@ -13,6 +13,7 @@ public class NameTest { @DisplayName("이름의 길이가 0글자이거나, 5글자를 초과하면 예외가 발생된다.") void nameLengthExceptionTest(String name) { assertThatThrownBy(() -> new Name(name)) - .isInstanceOf(IllegalArgumentException.class); + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("이름의 길이는 최소 1글자부터 최대 5글자까지 가능합니다."); } } diff --git a/src/test/java/blackjack/domain/gamer/PlayersTest.java b/src/test/java/blackjack/domain/gamer/PlayersTest.java index b4dbab3b72..087dad3284 100644 --- a/src/test/java/blackjack/domain/gamer/PlayersTest.java +++ b/src/test/java/blackjack/domain/gamer/PlayersTest.java @@ -19,7 +19,8 @@ void duplicatePlayerNamesTest() { @DisplayName("플레이어는 적어도 2명 이상이어야 한다.") void minimumPlayerCountTest() { assertThatThrownBy(() -> new Players(of("a"))) - .isInstanceOf(IllegalArgumentException.class); + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("플레이어는 최소 2명에서 최대 8명까지 가능합니다"); } @@ -27,7 +28,7 @@ void minimumPlayerCountTest() { @DisplayName("플레이어는 최대 8명까지만 가능하다.") void maximumPlayerCountTest() { assertThatThrownBy(() -> new Players(of("a", "b", "c", "d", "e", "f", "g", "h", "g"))) - .isInstanceOf(IllegalArgumentException.class); - + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("이름은 중복될 수 없습니다."); } } From 939882c368128e30766b143608c8898659b0b6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 17:16:19 +0900 Subject: [PATCH 11/39] =?UTF-8?q?test(NameTest):=20=EC=A0=95=EC=83=81=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=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: seokmyungham --- src/test/java/blackjack/domain/gamer/NameTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test/java/blackjack/domain/gamer/NameTest.java b/src/test/java/blackjack/domain/gamer/NameTest.java index d41537b72b..453eeac6d2 100644 --- a/src/test/java/blackjack/domain/gamer/NameTest.java +++ b/src/test/java/blackjack/domain/gamer/NameTest.java @@ -8,10 +8,17 @@ public class NameTest { + @ParameterizedTest + @ValueSource(strings = {"a", "abcde"}) + @DisplayName("이름의 길이가 1글자에서 5글자인 경우 예외가 발생되지 않는다.") + void validNameLengthTest(String name) { + assertThatCode(() -> new Name(name)).doesNotThrowAnyException(); + } + @ParameterizedTest @ValueSource(strings = {"", "abcdef"}) @DisplayName("이름의 길이가 0글자이거나, 5글자를 초과하면 예외가 발생된다.") - void nameLengthExceptionTest(String name) { + void invalidNameLengthTest(String name) { assertThatThrownBy(() -> new Name(name)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("이름의 길이는 최소 1글자부터 최대 5글자까지 가능합니다."); From f050926f0fbe12ce64a875b30067b5582c9e6c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Wed, 6 Mar 2024 17:22:43 +0900 Subject: [PATCH 12/39] =?UTF-8?q?test(PlayersTest):=20=EC=A0=95=EC=83=81?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=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: seokmyungham --- src/test/java/blackjack/domain/gamer/PlayersTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/blackjack/domain/gamer/PlayersTest.java b/src/test/java/blackjack/domain/gamer/PlayersTest.java index 087dad3284..06ecd10e52 100644 --- a/src/test/java/blackjack/domain/gamer/PlayersTest.java +++ b/src/test/java/blackjack/domain/gamer/PlayersTest.java @@ -3,11 +3,22 @@ import static java.util.List.*; import static org.assertj.core.api.Assertions.*; +import java.util.List; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class PlayersTest { + @Test + @DisplayName("유효한 입력에 대해서는 예외가 발생되지 않는다.") + void validPlayerNamesTest() { + assertThatCode(() -> new Players(List.of("a", "b"))) + .doesNotThrowAnyException(); + assertThatCode(() -> new Players(List.of("a", "b", "c", "d", "e", "f", "g", "h"))) + .doesNotThrowAnyException(); + } + @Test @DisplayName("플레이어의 이름은 중복을 허용하지 않는다.") void duplicatePlayerNamesTest() { From 9b0e50df1c229583c40c11f4b53cf5c732d66e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Thu, 7 Mar 2024 16:55:32 +0900 Subject: [PATCH 13/39] =?UTF-8?q?feat(Player):=20=EB=94=9C=EB=9F=AC?= =?UTF-8?q?=EC=9D=98=20=EC=A0=90=EC=88=98=EB=A5=BC=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=B0=9B=EC=95=84=20=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EC=9D=98=20=EC=8A=B9=ED=8C=A8=20=EC=97=AC=EB=B6=80=EB=A5=BC=20?= =?UTF-8?q?=EA=B2=B0=EC=A0=95=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=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: seokmyungham --- README.md | 12 +++- .../java/blackjack/domain/gamer/Player.java | 13 ++++ .../blackjack/domain/gamer/PlayerTest.java | 59 +++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1161e0462c..eadc72561a 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,20 @@ - [x] King, Queen, Jack은 10으로 계산한다. - [x] ACE는 1 또는 11로 계산할 수 있다. -### 딜러, 플레이어 +### 딜러, 플레이어 공통 - [x] 최소 1글자, 최대 5글자의 이름을 가진다. - [x] ACE 카드를 가지는 경우, 일단 11로 계산한 뒤, 합이 21을 초과하면 1로 계산한다. - [x] 현재 가진 카드 숫자의 합을 기준으로 카드를 더 받을 수 있는지 결정한다. - [x] 딜러는 숫자의 합이 16 이하이면 카드를 더 받을 수 있다. - [x] 플레이어는 숫자의 합이 21 이하이면 카드를 더 받을 수 있다. + +### 플레이어 + - [x] 플레이어의 이름은 중복될 수 없다. -- [x] 플레이어는 최소 2명부터 최대 8명까지 가능하다. \ No newline at end of file +- [x] 플레이어는 최소 2명부터 최대 8명까지 가능하다. +- [x] 딜러의 점수를 입력받아 승,패를 결정한다. + - [x] 플레이어의 점수가 21을 초과하면 딜러의 점수와 무관하게 패배한다. + - [x] 플레이어의 점수가 21 이하이고, 딜러와 동점인 경우 패배한다. + - [x] 플레이어의 점수가 21 이하이고, 딜러의 점수가 21을 초과하면 승리한다. + - [x] 플레이어와 딜러의 점수가 모두 21 이하이고, 딜러의 점수보다 크면 승리한다. diff --git a/src/main/java/blackjack/domain/gamer/Player.java b/src/main/java/blackjack/domain/gamer/Player.java index a79cd529f5..97d385b145 100644 --- a/src/main/java/blackjack/domain/gamer/Player.java +++ b/src/main/java/blackjack/domain/gamer/Player.java @@ -12,4 +12,17 @@ public Player(Name name) { public boolean canReceiveCard() { return sumCardNumbers() <= 21; } + + public boolean isWin(int dealerScore) { + int playerScore = sumCardNumbers(); + + if (playerScore > 21) { + return false; + } + if (dealerScore > 21) { + return true; + } + + return playerScore > dealerScore; + } } diff --git a/src/test/java/blackjack/domain/gamer/PlayerTest.java b/src/test/java/blackjack/domain/gamer/PlayerTest.java index 9b3c894362..7a34ebe5d0 100644 --- a/src/test/java/blackjack/domain/gamer/PlayerTest.java +++ b/src/test/java/blackjack/domain/gamer/PlayerTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import blackjack.domain.card.Card; @@ -37,4 +38,62 @@ void cantReceiveCardTest() { assertThat(player.canReceiveCard()).isFalse(); } + + @Nested + @DisplayName("플레이어가 승리한다.") + class IsWinTest { + + @Test + @DisplayName("플레이어 점수가 21 이하이고, 딜러의 점수보다 큰 경우 승리한다.") + void bustTest() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FOUR)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.isWin(20)).isTrue(); + } + + @Test + @DisplayName("플레이어 점수가 21 이하이고, 딜러의 점수가 21을 초과하면 승리한다.") + void bustTest1() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + + assertThat(player.isWin(22)).isTrue(); + } + } + + @Nested + @DisplayName("플레이어가 패배한다.") + class LoseTest { + + @Test + @DisplayName("점수가 21을 초과하면 딜러의 점수와 무관하게 패배한다") + void bustTest2() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.isWin(21)).isFalse(); + assertThat(player.isWin(22)).isFalse(); + } + + @Test + @DisplayName("플레이어와 딜러의 점수가 모두 21 이하일 때, 딜러의 점수보다 낮으면 패배한다.") + void bustTest3() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.SIX)); + + assertThat(player.isWin(17)).isFalse(); + } + + @Test + @DisplayName("플레이어와 딜러의 점수가 모두 21 이하이고 동점인 경우 플레이어가 패배한다.") + void bustTest4() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.isWin(17)).isFalse(); + } + } } From ae706818c624ea19aa1fb341a262e9e9c80f861f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Thu, 7 Mar 2024 18:07:51 +0900 Subject: [PATCH 14/39] =?UTF-8?q?feat(Hand):=20=EC=B0=B8=EC=97=AC=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EC=B9=B4=EB=93=9C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC?= =?UTF-8?q?=EB=A0=89=EC=85=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- .../java/blackjack/domain/gamer/Hand.java | 35 +++++++++++++ .../domain/gamer/BlackJackGamerTest.java | 49 ------------------ .../java/blackjack/domain/gamer/HandTest.java | 51 +++++++++++++++++++ 3 files changed, 86 insertions(+), 49 deletions(-) create mode 100644 src/main/java/blackjack/domain/gamer/Hand.java delete mode 100644 src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java create mode 100644 src/test/java/blackjack/domain/gamer/HandTest.java diff --git a/src/main/java/blackjack/domain/gamer/Hand.java b/src/main/java/blackjack/domain/gamer/Hand.java new file mode 100644 index 0000000000..8e51f6157d --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/Hand.java @@ -0,0 +1,35 @@ +package blackjack.domain.gamer; + +import java.util.List; + +import blackjack.domain.card.Card; + +public class Hand { + + private final List cards; + + public Hand(List cards) { + this.cards = cards; + } + + public void add(Card card) { + cards.add(card); + } + + /** + * ACE가 포함된 경우, 21 이하이면서 가장 가능한 큰 값으로 계산한다. + */ + public int sum() { + int sum = cards.stream() + .mapToInt(Card::getNumber) + .sum(); + int aceCount = (int)cards.stream().filter(Card::isAce).count(); + + for (int i = 0; i < aceCount; i++) { + if (sum > 21) { + sum -= 10; + } + } + return sum; + } +} diff --git a/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java b/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java deleted file mode 100644 index 50b0744c38..0000000000 --- a/src/test/java/blackjack/domain/gamer/BlackJackGamerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package blackjack.domain.gamer; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import blackjack.domain.card.Card; -import blackjack.domain.card.CardNumber; -import blackjack.domain.card.CardShape; - -class BlackJackGamerTest { - - BlackJackGamer player; - - @BeforeEach - void setUP() { - player = new Player(new Name("hogi")); - } - - @Test - @DisplayName("ACE가 없을때의 숫자 합을 계산한다.") - void sumWithoutAceTest() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); - - assertThat(player.sumCardNumbers()).isEqualTo(15); - } - - @Test - @DisplayName("숫자의 합이 21을 초과하는 경우, ACE를 1로 계산한다.") - void sumWithOneAceTest() { - player.addCard(new Card(CardShape.HEART, CardNumber.ACE)); - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.DIAMOND, CardNumber.KING)); - - assertThat(player.sumCardNumbers()).isEqualTo(21); - } - - @Test - @DisplayName("숫자의 합이 21을 초과하지 않으면, ACE를 11로 계산한다.") - void sumWithElevenAceTest() { - player.addCard(new Card(CardShape.HEART, CardNumber.ACE)); - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - - assertThat(player.sumCardNumbers()).isEqualTo(21); - } -} diff --git a/src/test/java/blackjack/domain/gamer/HandTest.java b/src/test/java/blackjack/domain/gamer/HandTest.java new file mode 100644 index 0000000000..cd554bb672 --- /dev/null +++ b/src/test/java/blackjack/domain/gamer/HandTest.java @@ -0,0 +1,51 @@ +package blackjack.domain.gamer; + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import blackjack.domain.card.Card; +import blackjack.domain.card.CardNumber; +import blackjack.domain.card.CardShape; + +class HandTest { + + Hand hand; + + @Test + @DisplayName("ACE가 없을때의 숫자 합을 계산한다.") + void sumWithoutAceTest() { + hand = new Hand(List.of( + new Card(CardShape.CLOVER, CardNumber.KING), + new Card(CardShape.HEART, CardNumber.FIVE) + )); + + assertThat(hand.sum()).isEqualTo(15); + } + + @Test + @DisplayName("숫자의 합이 21을 초과하는 경우, ACE를 1로 계산한다.") + void sumWithOneAceTest() { + hand = new Hand(List.of( + new Card(CardShape.HEART, CardNumber.ACE), + new Card(CardShape.CLOVER, CardNumber.KING), + new Card(CardShape.DIAMOND, CardNumber.KING) + )); + + assertThat(hand.sum()).isEqualTo(21); + } + + @Test + @DisplayName("숫자의 합이 21을 초과하지 않으면, ACE를 11로 계산한다.") + void sumWithElevenAceTest() { + hand = new Hand(List.of( + new Card(CardShape.HEART, CardNumber.ACE), + new Card(CardShape.CLOVER, CardNumber.KING) + )); + + assertThat(hand.sum()).isEqualTo(21); + } +} From f6afbdcf3dd087209864d9172584b0bf1e16ec09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Thu, 7 Mar 2024 18:12:01 +0900 Subject: [PATCH 15/39] =?UTF-8?q?refactor(BlackjackGamer):=20Hand=EB=A5=BC?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- .../domain/gamer/BlackJackGamer.java | 39 ------------------- .../domain/gamer/BlackjackGamer.java | 28 +++++++++++++ 2 files changed, 28 insertions(+), 39 deletions(-) delete mode 100644 src/main/java/blackjack/domain/gamer/BlackJackGamer.java create mode 100644 src/main/java/blackjack/domain/gamer/BlackjackGamer.java diff --git a/src/main/java/blackjack/domain/gamer/BlackJackGamer.java b/src/main/java/blackjack/domain/gamer/BlackJackGamer.java deleted file mode 100644 index 13017b176b..0000000000 --- a/src/main/java/blackjack/domain/gamer/BlackJackGamer.java +++ /dev/null @@ -1,39 +0,0 @@ -package blackjack.domain.gamer; - -import java.util.List; - -import blackjack.domain.card.Card; - -public abstract class BlackJackGamer { - - private final Name name; - private final List cards; - - public BlackJackGamer(Name name, List cards) { - this.name = name; - this.cards = cards; - } - - public void addCard(Card card) { - cards.add(card); - } - - /** - * ACE가 포함된 경우, 21 이하이면서 가장 가능한 큰 값으로 계산한다. - */ - public int sumCardNumbers() { - int sum = cards.stream() - .mapToInt(Card::getCardNumber) - .sum(); - int aceCount = (int)cards.stream().filter(Card::isAce).count(); - - for (int i = 0; i < aceCount; i++) { - if (sum > 21) { - sum -= 10; - } - } - return sum; - } - - public abstract boolean canReceiveCard(); -} diff --git a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java new file mode 100644 index 0000000000..b6b8c073fc --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java @@ -0,0 +1,28 @@ +package blackjack.domain.gamer; + +import java.util.ArrayList; + +import blackjack.domain.card.Card; +import blackjack.domain.card.Deck; + +public abstract class BlackjackGamer { + + private final Name name; + private final Hand hand; + + public BlackjackGamer(Name name) { + this.name = name; + this.hand = new Hand(new ArrayList<>()); + } + + public abstract boolean canReceiveCard(); + + public void initCard(Deck deck) { + addCard(deck.draw()); + addCard(deck.draw()); + } + + public void addCard(Card card) { + hand.add(card); + } +} From 8d1b095146c9c6fa6e0a3ed8c8ff73a7ff96bb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Thu, 7 Mar 2024 18:16:52 +0900 Subject: [PATCH 16/39] =?UTF-8?q?refactor(Dealer,=20Player):=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=EB=B0=8F=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- .../domain/gamer/BlackjackGamer.java | 22 +++++++++++++++++++ .../java/blackjack/domain/gamer/Dealer.java | 8 +++---- .../java/blackjack/domain/gamer/Player.java | 10 ++++----- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java index b6b8c073fc..f7612cab21 100644 --- a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java +++ b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java @@ -1,9 +1,12 @@ package blackjack.domain.gamer; import java.util.ArrayList; +import java.util.List; import blackjack.domain.card.Card; import blackjack.domain.card.Deck; +import blackjack.dto.CardDto; +import blackjack.dto.GamerResponseDto; public abstract class BlackjackGamer { @@ -25,4 +28,23 @@ public void initCard(Deck deck) { public void addCard(Card card) { hand.add(card); } + + public Card getFirstCard() { + return hand.getFirstCard(); + } + + public int getScore() { + return hand.sum(); + } + + public Name getName() { + return name; + } + + public GamerResponseDto convertGamerToDto() { + String playerName = name.value(); + List gamerHand = hand.convertHandToDto(); + + return new GamerResponseDto(playerName, gamerHand); + } } diff --git a/src/main/java/blackjack/domain/gamer/Dealer.java b/src/main/java/blackjack/domain/gamer/Dealer.java index e3cc143b7f..ca5fead0d5 100644 --- a/src/main/java/blackjack/domain/gamer/Dealer.java +++ b/src/main/java/blackjack/domain/gamer/Dealer.java @@ -1,15 +1,13 @@ package blackjack.domain.gamer; -import java.util.ArrayList; - -public class Dealer extends BlackJackGamer { +public class Dealer extends BlackjackGamer { public Dealer() { - super(new Name("딜러"), new ArrayList<>()); + super(new Name("딜러")); } @Override public boolean canReceiveCard() { - return sumCardNumbers() <= 16; + return getScore() <= 16; } } diff --git a/src/main/java/blackjack/domain/gamer/Player.java b/src/main/java/blackjack/domain/gamer/Player.java index 97d385b145..8099efdcb9 100644 --- a/src/main/java/blackjack/domain/gamer/Player.java +++ b/src/main/java/blackjack/domain/gamer/Player.java @@ -1,20 +1,18 @@ package blackjack.domain.gamer; -import java.util.ArrayList; - -public class Player extends BlackJackGamer { +public class Player extends BlackjackGamer { public Player(Name name) { - super(name, new ArrayList<>()); + super(name); } @Override public boolean canReceiveCard() { - return sumCardNumbers() <= 21; + return getScore() <= 21; } public boolean isWin(int dealerScore) { - int playerScore = sumCardNumbers(); + int playerScore = getScore(); if (playerScore > 21) { return false; From 69e7124d3b37e335fcadbc6013a0aca11a129f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Thu, 7 Mar 2024 18:20:06 +0900 Subject: [PATCH 17/39] =?UTF-8?q?feat(GameResult):=20=EC=8A=B9,=ED=8C=A8?= =?UTF-8?q?=EB=A5=BC=20=ED=91=9C=ED=98=84=ED=95=98=EB=8A=94=20Enum=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- .../java/blackjack/domain/gamer/GameResult.java | 13 +++++++++++++ src/main/java/blackjack/domain/gamer/Player.java | 11 +++++------ .../java/blackjack/domain/gamer/PlayerTest.java | 12 ++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 src/main/java/blackjack/domain/gamer/GameResult.java diff --git a/src/main/java/blackjack/domain/gamer/GameResult.java b/src/main/java/blackjack/domain/gamer/GameResult.java new file mode 100644 index 0000000000..0600b9140e --- /dev/null +++ b/src/main/java/blackjack/domain/gamer/GameResult.java @@ -0,0 +1,13 @@ +package blackjack.domain.gamer; + +public enum GameResult { + + WIN("승"), + LOSE("패"); + + private final String name; + + GameResult(String name) { + this.name = name; + } +} diff --git a/src/main/java/blackjack/domain/gamer/Player.java b/src/main/java/blackjack/domain/gamer/Player.java index 8099efdcb9..e42caa7232 100644 --- a/src/main/java/blackjack/domain/gamer/Player.java +++ b/src/main/java/blackjack/domain/gamer/Player.java @@ -11,16 +11,15 @@ public boolean canReceiveCard() { return getScore() <= 21; } - public boolean isWin(int dealerScore) { + public GameResult isWin(int dealerScore) { int playerScore = getScore(); if (playerScore > 21) { - return false; + return GameResult.LOSE; } - if (dealerScore > 21) { - return true; + if (dealerScore > 21 || playerScore > dealerScore) { + return GameResult.WIN; } - - return playerScore > dealerScore; + return GameResult.LOSE; } } diff --git a/src/test/java/blackjack/domain/gamer/PlayerTest.java b/src/test/java/blackjack/domain/gamer/PlayerTest.java index 7a34ebe5d0..da80d1a12d 100644 --- a/src/test/java/blackjack/domain/gamer/PlayerTest.java +++ b/src/test/java/blackjack/domain/gamer/PlayerTest.java @@ -50,7 +50,7 @@ void bustTest() { player.addCard(new Card(CardShape.HEART, CardNumber.FOUR)); player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); - assertThat(player.isWin(20)).isTrue(); + assertThat(player.isWin(20)).isEqualTo(GameResult.WIN); } @Test @@ -59,7 +59,7 @@ void bustTest1() { player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); - assertThat(player.isWin(22)).isTrue(); + assertThat(player.isWin(22)).isEqualTo(GameResult.WIN); } } @@ -74,8 +74,8 @@ void bustTest2() { player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); - assertThat(player.isWin(21)).isFalse(); - assertThat(player.isWin(22)).isFalse(); + assertThat(player.isWin(21)).isEqualTo(GameResult.LOSE); + assertThat(player.isWin(22)).isEqualTo(GameResult.LOSE); } @Test @@ -84,7 +84,7 @@ void bustTest3() { player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); player.addCard(new Card(CardShape.HEART, CardNumber.SIX)); - assertThat(player.isWin(17)).isFalse(); + assertThat(player.isWin(17)).isEqualTo(GameResult.LOSE); } @Test @@ -93,7 +93,7 @@ void bustTest4() { player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); - assertThat(player.isWin(17)).isFalse(); + assertThat(player.isWin(17)).isEqualTo(GameResult.LOSE); } } } From 1a9df2a6ef8b8f75b45b90d5ca206e9c479cb6d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Thu, 7 Mar 2024 18:31:44 +0900 Subject: [PATCH 18/39] =?UTF-8?q?feat:=20DTO=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B0=81=20=EB=8F=84=EB=A9=94=EC=9D=B8=EC=97=90=20?= =?UTF-8?q?DTO=20=EC=83=9D=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/domain/card/Card.java | 12 +++++++--- .../blackjack/domain/card/CardNumber.java | 4 ++++ .../java/blackjack/domain/card/CardShape.java | 4 ++++ .../domain/gamer/BlackjackGamer.java | 6 ++--- .../java/blackjack/domain/gamer/Dealer.java | 23 +++++++++++++++++++ .../java/blackjack/domain/gamer/Hand.java | 11 +++++++++ src/main/java/blackjack/dto/CardDto.java | 4 ++++ .../blackjack/dto/DealerInitialHandDto.java | 4 ++++ .../java/blackjack/dto/DealerResultDto.java | 4 ++++ src/main/java/blackjack/dto/GamerHandDto.java | 6 +++++ 10 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/main/java/blackjack/dto/CardDto.java create mode 100644 src/main/java/blackjack/dto/DealerInitialHandDto.java create mode 100644 src/main/java/blackjack/dto/DealerResultDto.java create mode 100644 src/main/java/blackjack/dto/GamerHandDto.java diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java index d07e4df1e3..a1a3e72c39 100644 --- a/src/main/java/blackjack/domain/card/Card.java +++ b/src/main/java/blackjack/domain/card/Card.java @@ -2,6 +2,8 @@ import java.util.Objects; +import blackjack.dto.CardDto; + public class Card { private final CardShape cardShape; @@ -12,12 +14,16 @@ public Card(CardShape cardShape, CardNumber cardNumber) { this.cardNumber = cardNumber; } - public int getCardNumber() { + public boolean isAce() { + return cardNumber == CardNumber.ACE; + } + + public int getNumber() { return cardNumber.getValue(); } - public boolean isAce() { - return cardNumber == CardNumber.ACE; + public CardDto convertCardToDto() { + return new CardDto(cardNumber.getName(), cardShape.getName()); } @Override diff --git a/src/main/java/blackjack/domain/card/CardNumber.java b/src/main/java/blackjack/domain/card/CardNumber.java index 44b8c54bd2..abaa843383 100644 --- a/src/main/java/blackjack/domain/card/CardNumber.java +++ b/src/main/java/blackjack/domain/card/CardNumber.java @@ -24,6 +24,10 @@ public enum CardNumber { this.value = value; } + public String getName() { + return name; + } + public int getValue() { return value; } diff --git a/src/main/java/blackjack/domain/card/CardShape.java b/src/main/java/blackjack/domain/card/CardShape.java index 82917fadf1..a2810cd62b 100644 --- a/src/main/java/blackjack/domain/card/CardShape.java +++ b/src/main/java/blackjack/domain/card/CardShape.java @@ -12,4 +12,8 @@ public enum CardShape { CardShape(String name) { this.name = name; } + + public String getName() { + return name; + } } diff --git a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java index f7612cab21..53560e0438 100644 --- a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java +++ b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java @@ -6,7 +6,7 @@ import blackjack.domain.card.Card; import blackjack.domain.card.Deck; import blackjack.dto.CardDto; -import blackjack.dto.GamerResponseDto; +import blackjack.dto.GamerHandDto; public abstract class BlackjackGamer { @@ -41,10 +41,10 @@ public Name getName() { return name; } - public GamerResponseDto convertGamerToDto() { + public GamerHandDto convertGamerToDto() { String playerName = name.value(); List gamerHand = hand.convertHandToDto(); - return new GamerResponseDto(playerName, gamerHand); + return new GamerHandDto(playerName, gamerHand); } } diff --git a/src/main/java/blackjack/domain/gamer/Dealer.java b/src/main/java/blackjack/domain/gamer/Dealer.java index ca5fead0d5..bb85c71718 100644 --- a/src/main/java/blackjack/domain/gamer/Dealer.java +++ b/src/main/java/blackjack/domain/gamer/Dealer.java @@ -1,5 +1,11 @@ package blackjack.domain.gamer; +import java.util.List; + +import blackjack.domain.card.Card; +import blackjack.dto.DealerInitialHandDto; +import blackjack.dto.DealerResultDto; + public class Dealer extends BlackjackGamer { public Dealer() { @@ -10,4 +16,21 @@ public Dealer() { public boolean canReceiveCard() { return getScore() <= 16; } + + public DealerResultDto getResult(List playerResults) { + Name name = getName(); + int winCount = (int)playerResults.stream() + .filter(result -> result == GameResult.WIN) + .count(); + int loseCount = playerResults.size() - winCount; + + return new DealerResultDto(name.value(), winCount, loseCount); + } + + public DealerInitialHandDto convertDealerToDto() { + String dealerName = getName().value(); + Card first = getFirstCard(); + + return new DealerInitialHandDto(dealerName, first.convertCardToDto()); + } } diff --git a/src/main/java/blackjack/domain/gamer/Hand.java b/src/main/java/blackjack/domain/gamer/Hand.java index 8e51f6157d..001521f98a 100644 --- a/src/main/java/blackjack/domain/gamer/Hand.java +++ b/src/main/java/blackjack/domain/gamer/Hand.java @@ -3,6 +3,7 @@ import java.util.List; import blackjack.domain.card.Card; +import blackjack.dto.CardDto; public class Hand { @@ -32,4 +33,14 @@ public int sum() { } return sum; } + + public Card getFirstCard() { + return cards.get(0); + } + + public List convertHandToDto() { + return cards.stream() + .map(Card::convertCardToDto) + .toList(); + } } diff --git a/src/main/java/blackjack/dto/CardDto.java b/src/main/java/blackjack/dto/CardDto.java new file mode 100644 index 0000000000..b52d4df4f0 --- /dev/null +++ b/src/main/java/blackjack/dto/CardDto.java @@ -0,0 +1,4 @@ +package blackjack.dto; + +public record CardDto(String cardNumber, String cardShape) { +} diff --git a/src/main/java/blackjack/dto/DealerInitialHandDto.java b/src/main/java/blackjack/dto/DealerInitialHandDto.java new file mode 100644 index 0000000000..813a3076b0 --- /dev/null +++ b/src/main/java/blackjack/dto/DealerInitialHandDto.java @@ -0,0 +1,4 @@ +package blackjack.dto; + +public record DealerInitialHandDto(String name, CardDto firstCard) { +} diff --git a/src/main/java/blackjack/dto/DealerResultDto.java b/src/main/java/blackjack/dto/DealerResultDto.java new file mode 100644 index 0000000000..72c0cbabbe --- /dev/null +++ b/src/main/java/blackjack/dto/DealerResultDto.java @@ -0,0 +1,4 @@ +package blackjack.dto; + +public record DealerResultDto(String name, int winCount, int loseCount) { +} diff --git a/src/main/java/blackjack/dto/GamerHandDto.java b/src/main/java/blackjack/dto/GamerHandDto.java new file mode 100644 index 0000000000..665fddc294 --- /dev/null +++ b/src/main/java/blackjack/dto/GamerHandDto.java @@ -0,0 +1,6 @@ +package blackjack.dto; + +import java.util.List; + +public record GamerHandDto(String name, List gamerHand) { +} From d74858c0322a517eab7a8eb0be04c66baaefa17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 02:23:59 +0900 Subject: [PATCH 19/39] =?UTF-8?q?refactor(Hand):=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=88=AB=EC=9E=90=EC=9D=98=20=ED=95=A9=EA=B3=84=EB=A5=BC=20?= =?UTF-8?q?=EA=B5=AC=ED=95=98=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=84=B8=EB=B6=84=ED=99=94=20=EB=B0=8F=20=EC=83=81=EC=88=98=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: seokmyungham --- .../domain/gamer/BlackjackGamer.java | 2 +- .../java/blackjack/domain/gamer/Hand.java | 42 +++++++++++++++---- .../java/blackjack/domain/gamer/HandTest.java | 6 +-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java index 53560e0438..830d748655 100644 --- a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java +++ b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java @@ -34,7 +34,7 @@ public Card getFirstCard() { } public int getScore() { - return hand.sum(); + return hand.calculateScore(); } public Name getName() { diff --git a/src/main/java/blackjack/domain/gamer/Hand.java b/src/main/java/blackjack/domain/gamer/Hand.java index 001521f98a..ce7c2ecb15 100644 --- a/src/main/java/blackjack/domain/gamer/Hand.java +++ b/src/main/java/blackjack/domain/gamer/Hand.java @@ -7,6 +7,9 @@ public class Hand { + private static final int BLACKJACK_MAX_SCORE = 21; + private static final int ACE_VALUE_MODIFIER = 10; + private final List cards; public Hand(List cards) { @@ -17,19 +20,42 @@ public void add(Card card) { cards.add(card); } - /** - * ACE가 포함된 경우, 21 이하이면서 가장 가능한 큰 값으로 계산한다. - */ - public int sum() { + public int calculateScore() { int sum = cards.stream() .mapToInt(Card::getNumber) .sum(); - int aceCount = (int)cards.stream().filter(Card::isAce).count(); + + if (hasAce()) { + return adjustSumWithAce(sum); + } + return sum; + } + + private boolean hasAce() { + return cards.stream() + .anyMatch(Card::isAce); + } + + /** + * ACE가 포함된 경우, 21 이하이면서 가장 가능한 큰 값으로 계산한다. + */ + private int adjustSumWithAce(int sum) { + int aceCount = (int)cards.stream() + .filter(Card::isAce) + .count(); for (int i = 0; i < aceCount; i++) { - if (sum > 21) { - sum -= 10; - } + sum = adjust(sum); + } + return sum; + } + + /** + * Ace는 기본적으로 11로 계산되나, 합계가 21을 초과할 경우 1로 계산한다. + */ + private int adjust(int sum) { + if (sum > BLACKJACK_MAX_SCORE) { + sum -= ACE_VALUE_MODIFIER; } return sum; } diff --git a/src/test/java/blackjack/domain/gamer/HandTest.java b/src/test/java/blackjack/domain/gamer/HandTest.java index cd554bb672..9c2bbf6ea4 100644 --- a/src/test/java/blackjack/domain/gamer/HandTest.java +++ b/src/test/java/blackjack/domain/gamer/HandTest.java @@ -23,7 +23,7 @@ void sumWithoutAceTest() { new Card(CardShape.HEART, CardNumber.FIVE) )); - assertThat(hand.sum()).isEqualTo(15); + assertThat(hand.calculateScore()).isEqualTo(15); } @Test @@ -35,7 +35,7 @@ void sumWithOneAceTest() { new Card(CardShape.DIAMOND, CardNumber.KING) )); - assertThat(hand.sum()).isEqualTo(21); + assertThat(hand.calculateScore()).isEqualTo(21); } @Test @@ -46,6 +46,6 @@ void sumWithElevenAceTest() { new Card(CardShape.CLOVER, CardNumber.KING) )); - assertThat(hand.sum()).isEqualTo(21); + assertThat(hand.calculateScore()).isEqualTo(21); } } From 9fd5c3d1fe1707aafad9d802a4c2cb04e6121740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 02:25:51 +0900 Subject: [PATCH 20/39] =?UTF-8?q?style(Dealer):=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20dto=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/domain/gamer/Dealer.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/blackjack/domain/gamer/Dealer.java b/src/main/java/blackjack/domain/gamer/Dealer.java index bb85c71718..c8ab69da7f 100644 --- a/src/main/java/blackjack/domain/gamer/Dealer.java +++ b/src/main/java/blackjack/domain/gamer/Dealer.java @@ -8,26 +8,29 @@ public class Dealer extends BlackjackGamer { + private static final String DEFAULT_DEALER_NAME = "딜러"; + private static final int DEALER_DRAW_THRESHOLD = 16; + public Dealer() { - super(new Name("딜러")); + super(new Name(DEFAULT_DEALER_NAME)); } @Override public boolean canReceiveCard() { - return getScore() <= 16; + return getScore() <= DEALER_DRAW_THRESHOLD; } - public DealerResultDto getResult(List playerResults) { + public DealerResultDto convertDealerToResultDto(List playerResults) { Name name = getName(); int winCount = (int)playerResults.stream() - .filter(result -> result == GameResult.WIN) + .filter(GameResult::isLose) .count(); int loseCount = playerResults.size() - winCount; return new DealerResultDto(name.value(), winCount, loseCount); } - public DealerInitialHandDto convertDealerToDto() { + public DealerInitialHandDto convertDealerToInitialHandDto() { String dealerName = getName().value(); Card first = getFirstCard(); From e0351cfa9e04d3ed8cdadc5cda9663406b2b097f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 02:26:45 +0900 Subject: [PATCH 21/39] =?UTF-8?q?style(Player):=20=EB=A7=A4=EC=A7=81=20?= =?UTF-8?q?=EB=84=98=EB=B2=84=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/domain/gamer/Player.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/blackjack/domain/gamer/Player.java b/src/main/java/blackjack/domain/gamer/Player.java index e42caa7232..4c36a73f22 100644 --- a/src/main/java/blackjack/domain/gamer/Player.java +++ b/src/main/java/blackjack/domain/gamer/Player.java @@ -2,22 +2,24 @@ public class Player extends BlackjackGamer { + private static final int BLACKJACK_MAX_SCORE = 21; + public Player(Name name) { super(name); } @Override public boolean canReceiveCard() { - return getScore() <= 21; + return getScore() <= BLACKJACK_MAX_SCORE; } public GameResult isWin(int dealerScore) { int playerScore = getScore(); - if (playerScore > 21) { + if (playerScore > BLACKJACK_MAX_SCORE) { return GameResult.LOSE; } - if (dealerScore > 21 || playerScore > dealerScore) { + if (dealerScore > BLACKJACK_MAX_SCORE || playerScore > dealerScore) { return GameResult.WIN; } return GameResult.LOSE; From da6b980744a052abba6ffc987f7e3b1242cfa6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 02:39:34 +0900 Subject: [PATCH 22/39] =?UTF-8?q?feat(Players):=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=EC=9D=98=20=ED=8C=A8?= =?UTF-8?q?=EB=A5=BC=20=EC=B4=88=EA=B8=B0=ED=99=94=20=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20dto=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=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: seokmyungham --- .../java/blackjack/domain/gamer/Players.java | 27 +++++++++++++++++++ .../java/blackjack/dto/PlayerResultsDto.java | 9 +++++++ 2 files changed, 36 insertions(+) create mode 100644 src/main/java/blackjack/dto/PlayerResultsDto.java diff --git a/src/main/java/blackjack/domain/gamer/Players.java b/src/main/java/blackjack/domain/gamer/Players.java index be90f5986b..13cc45a92e 100644 --- a/src/main/java/blackjack/domain/gamer/Players.java +++ b/src/main/java/blackjack/domain/gamer/Players.java @@ -1,9 +1,15 @@ package blackjack.domain.gamer; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; +import blackjack.domain.card.Deck; +import blackjack.dto.GamerHandDto; +import blackjack.dto.PlayerResultsDto; + public class Players { private static final int MIN_PLAYER_COUNT = 2; @@ -39,4 +45,25 @@ private void validateDuplicate(List names) { throw new IllegalArgumentException("이름은 중복될 수 없습니다."); } } + + public void initAllPlayersCard(Deck deck) { + players.forEach(player -> player.initCard(deck)); + } + + public List getPlayers() { + return List.copyOf(players); + } + + public List convertPlayersToDto() { + return players.stream() + .map(Player::convertGamerToDto) + .toList(); + } + + public PlayerResultsDto convertPlayersToResultDto(int dealerScore) { + Map resultMap = new LinkedHashMap<>(); + players.forEach(player -> resultMap.put(player.getName(), player.isWin(dealerScore))); + + return new PlayerResultsDto(resultMap); + } } diff --git a/src/main/java/blackjack/dto/PlayerResultsDto.java b/src/main/java/blackjack/dto/PlayerResultsDto.java new file mode 100644 index 0000000000..9969a4ae84 --- /dev/null +++ b/src/main/java/blackjack/dto/PlayerResultsDto.java @@ -0,0 +1,9 @@ +package blackjack.dto; + +import java.util.Map; + +import blackjack.domain.gamer.GameResult; +import blackjack.domain.gamer.Name; + +public record PlayerResultsDto(Map resultMap) { +} From 6f1ef7b9c3d2bb7f4d745978240e65246cf68712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 02:41:08 +0900 Subject: [PATCH 23/39] =?UTF-8?q?feat(GameResult):=20=ED=8C=A8=EB=B0=B0?= =?UTF-8?q?=EC=9D=B8=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20getter=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: seokmyungham --- src/main/java/blackjack/domain/gamer/GameResult.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/blackjack/domain/gamer/GameResult.java b/src/main/java/blackjack/domain/gamer/GameResult.java index 0600b9140e..b1af95a4e1 100644 --- a/src/main/java/blackjack/domain/gamer/GameResult.java +++ b/src/main/java/blackjack/domain/gamer/GameResult.java @@ -10,4 +10,12 @@ public enum GameResult { GameResult(String name) { this.name = name; } + + public boolean isLose() { + return this == LOSE; + } + + public String getName() { + return name; + } } From 23a4321ea215b60f169372639f96527c6764e069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 02:42:49 +0900 Subject: [PATCH 24/39] =?UTF-8?q?feat(InputView):=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=9D=84=20=EB=B0=9B=EC=95=84=EB=93=A4=EC=9D=B4=EB=8A=94=20Inp?= =?UTF-8?q?utView=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/view/InputView.java | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/blackjack/view/InputView.java diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java new file mode 100644 index 0000000000..606f918259 --- /dev/null +++ b/src/main/java/blackjack/view/InputView.java @@ -0,0 +1,24 @@ +package blackjack.view; + +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private final Scanner scanner; + + public InputView() { + scanner = new Scanner(System.in); + } + + public List receivePlayerNames() { + System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); + String input = scanner.nextLine(); + return List.of(input.split(",")); + } + + public String receiveCommand(String name) { + System.out.println(name + "는(은) 한장의 카드를 더 받겠습니까?(예는 y, 아니오: n)"); + return scanner.nextLine(); + } +} From 38f936789589d06e29b0b568a4dcc4741049bf09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 03:25:02 +0900 Subject: [PATCH 25/39] =?UTF-8?q?feat(OutputView):=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EC=9D=84=20=EB=8B=B4=EB=8B=B9=ED=95=98=EB=8A=94=20OutputView?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/view/OutputView.java | 97 ++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/main/java/blackjack/view/OutputView.java diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java new file mode 100644 index 0000000000..e8cebcf143 --- /dev/null +++ b/src/main/java/blackjack/view/OutputView.java @@ -0,0 +1,97 @@ +package blackjack.view; + +import java.util.List; + +import blackjack.dto.CardDto; +import blackjack.dto.DealerInitialHandDto; +import blackjack.dto.DealerResultDto; +import blackjack.dto.GamerHandDto; +import blackjack.dto.PlayerResultsDto; + +public class OutputView { + + public void printInitialHands(DealerInitialHandDto dealerInitialHandDto, List playersInitialHandDto) { + System.out.printf("\n%s와 %s에게 2장을 나누었습니다.\n", dealerInitialHandDto.name(), + joinPlayerNames(playersInitialHandDto)); + + System.out.printf("%s 카드: %s\n", dealerInitialHandDto.name(), formatCardName(dealerInitialHandDto.firstCard())); + printAllPlayerHands(playersInitialHandDto); + } + + private String joinPlayerNames(List playersInitialHandDto) { + return String.join(", ", getPlayerNames(playersInitialHandDto)); + } + + private List getPlayerNames(List playersInitialHandDto) { + return playersInitialHandDto.stream().map(GamerHandDto::name).toList(); + } + + private String formatCardName(CardDto cardDto) { + return cardDto.cardNumber() + cardDto.cardShape(); + } + + private void printAllPlayerHands(List playersInitialHandDto) { + playersInitialHandDto.forEach(this::printPlayerHand); + System.out.println(); + } + + public void printPlayerHand(GamerHandDto playerHandDto) { + System.out.println(buildPlayerHand(playerHandDto)); + } + + private StringBuilder buildPlayerHand(GamerHandDto gamerHandDto) { + StringBuilder stringBuilder = new StringBuilder(); + return stringBuilder + .append(gamerHandDto.name()) + .append(" 카드: ") + .append(joinCardNames(gamerHandDto)); + } + + private String joinCardNames(GamerHandDto gamerHandDto) { + return String.join(", ", getCardNames(gamerHandDto)); + } + + private List getCardNames(GamerHandDto gamerHandDto) { + return gamerHandDto.gamerHand().stream().map(this::formatCardName).toList(); + } + + public void printDealerMessage(String dealerName) { + System.out.printf("\n%s는(은) 16이하라 한장의 카드를 더 받았습니다.\n\n", dealerName); + } + + public void printScore(GamerHandDto gamerHandDto, int score) { + StringBuilder builder = buildPlayerHand(gamerHandDto) + .append(" - ") + .append("결과: ") + .append(score); + System.out.println(builder); + } + + public void printResult(DealerResultDto dealerResultDto, PlayerResultsDto playerResultsDto) { + System.out.println("\n## 최종 승패"); + printDealerResult(dealerResultDto); + printPlayerResults(playerResultsDto); + } + + private void printDealerResult(DealerResultDto dealerResultDto) { + int winCount = dealerResultDto.winCount(); + int loseCount = dealerResultDto.loseCount(); + StringBuilder stringBuilder = new StringBuilder(dealerResultDto.name()).append(": "); + + if (winCount > 0) { + stringBuilder.append(winCount) + .append("승 "); + } + if (loseCount > 0) { + stringBuilder.append(loseCount) + .append("패"); + } + System.out.println(stringBuilder); + } + + private void printPlayerResults(PlayerResultsDto playerResultsDto) { + playerResultsDto.resultMap().forEach((name, result) -> + System.out.println(name.value() + ": " + result.getName()) + ); + } +} From c3443d3376380fded4e659040e369a5c1ebd6835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 03:25:42 +0900 Subject: [PATCH 26/39] =?UTF-8?q?feat(BlackjackController):=20=EB=B8=94?= =?UTF-8?q?=EB=9E=99=EC=9E=AD=20=EA=B2=8C=EC=9E=84=20=ED=9D=90=EB=A6=84?= =?UTF-8?q?=EC=9D=84=20=EC=A0=9C=EC=96=B4=ED=95=98=EB=8A=94=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=81=B4=EB=9E=98=EC=8A=A4=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: seokmyungham --- .../controller/BlackjackController.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/main/java/blackjack/controller/BlackjackController.java diff --git a/src/main/java/blackjack/controller/BlackjackController.java b/src/main/java/blackjack/controller/BlackjackController.java new file mode 100644 index 0000000000..61112eb52a --- /dev/null +++ b/src/main/java/blackjack/controller/BlackjackController.java @@ -0,0 +1,113 @@ +package blackjack.controller; + +import java.util.ArrayList; +import java.util.List; + +import blackjack.domain.card.Deck; +import blackjack.domain.gamer.Dealer; +import blackjack.domain.gamer.GameResult; +import blackjack.domain.gamer.Player; +import blackjack.domain.gamer.Players; +import blackjack.dto.DealerInitialHandDto; +import blackjack.dto.DealerResultDto; +import blackjack.dto.GamerHandDto; +import blackjack.dto.PlayerResultsDto; +import blackjack.view.InputView; +import blackjack.view.OutputView; + +public class BlackjackController { + + private static final String HIT_COMMAND = "y"; + private static final String STAND_COMMAND = "n"; + + private final InputView inputView; + private final OutputView outputView; + + public BlackjackController() { + this.inputView = new InputView(); + this.outputView = new OutputView(); + } + + public void run() { + Players players = getPlayers(); + Dealer dealer = new Dealer(); + Deck deck = new Deck(); + deck.shuffle(); + + setUpInitialHands(players, deck, dealer); + distributeCardToPlayers(players, deck); + distributeCardToDealer(dealer, deck); + printAllGamerScores(dealer, players); + printResult(dealer, players); + } + + private Players getPlayers() { + List playerNames = inputView.receivePlayerNames(); + + return new Players(playerNames); + } + + private void setUpInitialHands(Players players, Deck deck, Dealer dealer) { + players.initAllPlayersCard(deck); + dealer.initCard(deck); + printInitialHands(players, dealer); + } + + private void printInitialHands(Players players, Dealer dealer) { + DealerInitialHandDto dealerInitialHandDto = dealer.convertDealerToInitialHandDto(); + List playersInitialHandDto = players.convertPlayersToDto(); + + outputView.printInitialHands(dealerInitialHandDto, playersInitialHandDto); + } + + private void distributeCardToPlayers(Players players, Deck deck) { + for (Player player : players.getPlayers()) { + distributeCardToPlayer(deck, player); + } + } + + private void distributeCardToPlayer(Deck deck, Player player) { + while (canDistribute(player)) { + player.addCard(deck.draw()); + outputView.printPlayerHand(player.convertGamerToDto()); + } + } + + private boolean canDistribute(Player player) { + return player.canReceiveCard() && HIT_COMMAND.equals(getCommand(player)); + } + + private String getCommand(Player player) { + String command = inputView.receiveCommand(player.getName().value()); + if (HIT_COMMAND.equals(command) || STAND_COMMAND.equals(command)) { + return command; + } + throw new IllegalArgumentException(HIT_COMMAND + " 또는 " + STAND_COMMAND + "만 입력 가능합니다."); + } + + private void distributeCardToDealer(Dealer dealer, Deck deck) { + while (dealer.canReceiveCard()) { + dealer.addCard(deck.draw()); + outputView.printDealerMessage(dealer.getName().value()); + } + } + + private void printAllGamerScores(Dealer dealer, Players players) { + outputView.printScore(dealer.convertGamerToDto(), dealer.getScore()); + printPlayersScores(players); + } + + private void printPlayersScores(Players players) { + for (Player player : players.getPlayers()) { + outputView.printScore(player.convertGamerToDto(), player.getScore()); + } + } + + private void printResult(Dealer dealer, Players players) { + PlayerResultsDto playerResultsDto = players.convertPlayersToResultDto(dealer.getScore()); + List playerResults = new ArrayList<>(playerResultsDto.resultMap().values()); + DealerResultDto dealerResultDto = dealer.convertDealerToResultDto(playerResults); + + outputView.printResult(dealerResultDto, playerResultsDto); + } +} From 74bbc4c69c7354305ba6cc40e35c8901324350c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 03:39:38 +0900 Subject: [PATCH 27/39] =?UTF-8?q?style:=20=EC=B6=9C=EB=A0=A5=20=EC=9A=94?= =?UTF-8?q?=EA=B5=AC=EC=82=AC=ED=95=AD=EC=97=90=20=EB=A7=9E=EC=B6=B0=20?= =?UTF-8?q?=EB=B9=88=20=EC=A4=84=20=EC=B6=9C=EB=A0=A5=20=ED=8F=AC=EB=A7=B7?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/controller/BlackjackController.java | 1 + src/main/java/blackjack/view/OutputView.java | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/controller/BlackjackController.java b/src/main/java/blackjack/controller/BlackjackController.java index 61112eb52a..4d6a8c80d3 100644 --- a/src/main/java/blackjack/controller/BlackjackController.java +++ b/src/main/java/blackjack/controller/BlackjackController.java @@ -93,6 +93,7 @@ private void distributeCardToDealer(Dealer dealer, Deck deck) { } private void printAllGamerScores(Dealer dealer, Players players) { + outputView.printEmptyLine(); outputView.printScore(dealer.convertGamerToDto(), dealer.getScore()); printPlayersScores(players); } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index e8cebcf143..a8a1ab44c9 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -56,7 +56,7 @@ private List getCardNames(GamerHandDto gamerHandDto) { } public void printDealerMessage(String dealerName) { - System.out.printf("\n%s는(은) 16이하라 한장의 카드를 더 받았습니다.\n\n", dealerName); + System.out.printf("\n%s는 16이하라 한장의 카드를 더 받았습니다.\n", dealerName); } public void printScore(GamerHandDto gamerHandDto, int score) { @@ -94,4 +94,8 @@ private void printPlayerResults(PlayerResultsDto playerResultsDto) { System.out.println(name.value() + ": " + result.getName()) ); } + + public void printEmptyLine() { + System.out.println(); + } } From 8250c40ccb5f18972006691a0d167b796033b293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 03:41:26 +0900 Subject: [PATCH 28/39] =?UTF-8?q?feat(Application):=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98?= =?UTF-8?q?=EA=B3=A0=20=ED=98=B8=EC=B6=9C=ED=95=98=EC=97=AC=20=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=EC=9D=84=20=EC=8B=9C=EC=9E=91=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- src/main/java/blackjack/Application.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/blackjack/Application.java diff --git a/src/main/java/blackjack/Application.java b/src/main/java/blackjack/Application.java new file mode 100644 index 0000000000..2ddbf1df98 --- /dev/null +++ b/src/main/java/blackjack/Application.java @@ -0,0 +1,11 @@ +package blackjack; + +import blackjack.controller.BlackjackController; + +public class Application { + + public static void main(String[] args) { + BlackjackController blackjackController = new BlackjackController(); + blackjackController.run(); + } +} From 1b7ead1f958bac4e11ed2fbf9340fc0c475a91f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=A7=84?= Date: Fri, 8 Mar 2024 15:22:32 +0900 Subject: [PATCH 29/39] =?UTF-8?q?docs(README):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=9A=94=EA=B5=AC=20=EC=82=AC=ED=95=AD=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: seokmyungham --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index eadc72561a..e432c782c7 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,15 @@ ### 게임 -- [ ] 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 쪽이 승리한다. -- [ ] 게임을 시작하면 플레이어는 두 장의 카드를 지급 받는다. - - [ ] 이후 플레이어와 딜러의 카드를 출력한다. - - [ ] 단, 딜러의 카드는 하나만 출력한다. -- [ ] 플레이어는 카드의 숫자 합이 21을 초과하지 않는다면 카드를 원하는 만큼 다시 뽑을 수 있다. - - [ ] 새로 받을 때 마다 해당 플레이어의 카드를 출력한다. -- [ ] 플레이어가 카드를 다 받으면 딜러의 카드를 확인한다. -- [ ] 딜러의 카드 합이 16 이하이면 반드시 1장의 카드를 추가로 받아야 한다. - - [ ] 17 이상이면 추가로 받을 수 없다. -- [ ] 딜러와 플레이어의 카드, 결과와 최종 승패를 출력한다. +- [x] 딜러와 플레이어 중 카드의 합이 21 또는 21에 가장 가까운 쪽이 승리한다. +- [x] 게임을 시작하면 플레이어는 두 장의 카드를 지급 받는다. + - [x] 이후 플레이어와 딜러의 카드를 출력한다. + - [x] 단, 딜러의 카드는 하나만 출력한다. +- [x] 플레이어는 카드의 숫자 합이 21을 초과하지 않는다면 카드를 원하는 만큼 다시 뽑을 수 있다. + - [x] 새로 받을 때 마다 해당 플레이어의 카드를 출력한다. +- [x] 플레이어가 카드를 다 받으면 딜러의 카드를 확인한다. +- [x] 딜러의 카드 합이 17 이상이 될 때 까지 카드를 받는다. +- [x] 딜러와 플레이어의 카드, 결과와 최종 승패를 출력한다. ### 카드 From 094a0bf3ee26206021b041614472e94b705ac24b Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Sun, 10 Mar 2024 01:57:12 +0900 Subject: [PATCH 30/39] =?UTF-8?q?refactor(BlackjackController):=20?= =?UTF-8?q?=EB=AA=85=EB=A0=B9=EC=96=B4=20=EC=83=81=EC=88=98=EB=A5=BC=20?= =?UTF-8?q?=EB=B3=84=EB=8F=84=EC=9D=98=20view=20Enum=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BlackjackController.java | 11 +++----- src/main/java/blackjack/view/InputView.java | 5 ++-- .../java/blackjack/view/object/Command.java | 25 +++++++++++++++++++ 3 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 src/main/java/blackjack/view/object/Command.java diff --git a/src/main/java/blackjack/controller/BlackjackController.java b/src/main/java/blackjack/controller/BlackjackController.java index 4d6a8c80d3..38cd5111cc 100644 --- a/src/main/java/blackjack/controller/BlackjackController.java +++ b/src/main/java/blackjack/controller/BlackjackController.java @@ -1,5 +1,6 @@ package blackjack.controller; +import blackjack.view.object.Command; import java.util.ArrayList; import java.util.List; @@ -74,15 +75,11 @@ private void distributeCardToPlayer(Deck deck, Player player) { } private boolean canDistribute(Player player) { - return player.canReceiveCard() && HIT_COMMAND.equals(getCommand(player)); + return player.canReceiveCard() && Command.isHit(getCommand(player)); } - private String getCommand(Player player) { - String command = inputView.receiveCommand(player.getName().value()); - if (HIT_COMMAND.equals(command) || STAND_COMMAND.equals(command)) { - return command; - } - throw new IllegalArgumentException(HIT_COMMAND + " 또는 " + STAND_COMMAND + "만 입력 가능합니다."); + private Command getCommand(Player player) { + return inputView.receiveCommand(player.getName().value()); } private void distributeCardToDealer(Dealer dealer, Deck deck) { diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index 606f918259..6adb3dcefc 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -1,5 +1,6 @@ package blackjack.view; +import blackjack.view.object.Command; import java.util.List; import java.util.Scanner; @@ -17,8 +18,8 @@ public List receivePlayerNames() { return List.of(input.split(",")); } - public String receiveCommand(String name) { + public Command receiveCommand(String name) { System.out.println(name + "는(은) 한장의 카드를 더 받겠습니까?(예는 y, 아니오: n)"); - return scanner.nextLine(); + return Command.convertInputToCommand(scanner.nextLine()); } } diff --git a/src/main/java/blackjack/view/object/Command.java b/src/main/java/blackjack/view/object/Command.java new file mode 100644 index 0000000000..fc7e0ac5cf --- /dev/null +++ b/src/main/java/blackjack/view/object/Command.java @@ -0,0 +1,25 @@ +package blackjack.view.object; + +import java.util.Arrays; + +public enum Command { + HIT("y"), + STAND("n"); + + private final String name; + + Command(String name) { + this.name = name; + } + + public static Command convertInputToCommand(String input) { + return Arrays.stream(values()) + .filter(command -> command.name.equals(input)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("입력과 일치하는 명령어가 존재하지 않습니다.")); + } + + public static boolean isHit(Command command) { + return command == HIT; + } +} From 9397927e03086ae6ee1687094a3ff0a2f3862c77 Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Sun, 10 Mar 2024 10:37:23 +0900 Subject: [PATCH 31/39] =?UTF-8?q?refactor(Card):=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EC=97=90=20=EC=9D=98=EC=A1=B4=EC=A0=81=EC=9D=B8=20CardNumber,?= =?UTF-8?q?=20CardShape=EC=9D=84=20=EC=88=98=EC=A0=95=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?view=20=ED=8C=A8=ED=82=A4=EC=A7=80=EC=97=90=20Enum=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/Card.java | 10 +++-- .../blackjack/domain/card/CardNumber.java | 34 +++++++---------- .../java/blackjack/domain/card/CardShape.java | 18 ++------- .../view/object/CardNumberOutput.java | 37 +++++++++++++++++++ .../view/object/CardShapeOutput.java | 28 ++++++++++++++ 5 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 src/main/java/blackjack/view/object/CardNumberOutput.java create mode 100644 src/main/java/blackjack/view/object/CardShapeOutput.java diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java index a1a3e72c39..78bcbd1f31 100644 --- a/src/main/java/blackjack/domain/card/Card.java +++ b/src/main/java/blackjack/domain/card/Card.java @@ -18,12 +18,16 @@ public boolean isAce() { return cardNumber == CardNumber.ACE; } - public int getNumber() { + public int getNumberValue() { return cardNumber.getValue(); } - public CardDto convertCardToDto() { - return new CardDto(cardNumber.getName(), cardShape.getName()); + public CardShape getCardShape() { + return cardShape; + } + + public CardNumber getCardNumber() { + return cardNumber; } @Override diff --git a/src/main/java/blackjack/domain/card/CardNumber.java b/src/main/java/blackjack/domain/card/CardNumber.java index abaa843383..044a8bb42f 100644 --- a/src/main/java/blackjack/domain/card/CardNumber.java +++ b/src/main/java/blackjack/domain/card/CardNumber.java @@ -2,32 +2,26 @@ public enum CardNumber { - ACE("A", 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("J", 10), - QUEEN("Q", 10), - KING("K", 10); + ACE(11), + 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 String name; private final int value; - CardNumber(String name, int value) { - this.name = name; + CardNumber(int value) { this.value = value; } - public String getName() { - return name; - } - public int getValue() { return value; } diff --git a/src/main/java/blackjack/domain/card/CardShape.java b/src/main/java/blackjack/domain/card/CardShape.java index a2810cd62b..35169f3e95 100644 --- a/src/main/java/blackjack/domain/card/CardShape.java +++ b/src/main/java/blackjack/domain/card/CardShape.java @@ -2,18 +2,8 @@ public enum CardShape { - HEART("하트"), - CLOVER("클로버"), - SPADE("스페이드"), - DIAMOND("다이아몬드"); - - private final String name; - - CardShape(String name) { - this.name = name; - } - - public String getName() { - return name; - } + HEART, + CLOVER, + SPADE, + DIAMOND } diff --git a/src/main/java/blackjack/view/object/CardNumberOutput.java b/src/main/java/blackjack/view/object/CardNumberOutput.java new file mode 100644 index 0000000000..03d4fa840f --- /dev/null +++ b/src/main/java/blackjack/view/object/CardNumberOutput.java @@ -0,0 +1,37 @@ +package blackjack.view.object; + +import blackjack.domain.card.CardNumber; +import java.util.Arrays; + +public enum CardNumberOutput { + + ACE(CardNumber.ACE ,"A"), + TWO(CardNumber.TWO, "2"), + THREE(CardNumber.THREE, "3"), + FOUR(CardNumber.FOUR, "4"), + FIVE(CardNumber.FIVE, "5"), + SIX(CardNumber.SIX, "6"), + SEVEN(CardNumber.SEVEN, "7"), + EIGHT(CardNumber.EIGHT, "8"), + NINE(CardNumber.NINE, "9"), + TEN(CardNumber.TEN, "10"), + JACK(CardNumber.JACK, "J"), + QUEEN(CardNumber.QUEEN, "Q"), + KING(CardNumber.KING, "K"); + + private final CardNumber cardNumber; + private final String output; + + CardNumberOutput(CardNumber cardNumber, String output) { + this.cardNumber = cardNumber; + this.output = output; + } + + public static String convertNumberToOutput(CardNumber cardNumber) { + return Arrays.stream(values()) + .filter(cardNumberOutput -> cardNumberOutput.cardNumber == cardNumber) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 카드 숫자입니다.")) + .output; + } +} diff --git a/src/main/java/blackjack/view/object/CardShapeOutput.java b/src/main/java/blackjack/view/object/CardShapeOutput.java new file mode 100644 index 0000000000..38b0374ce3 --- /dev/null +++ b/src/main/java/blackjack/view/object/CardShapeOutput.java @@ -0,0 +1,28 @@ +package blackjack.view.object; + +import blackjack.domain.card.CardShape; +import java.util.Arrays; + +public enum CardShapeOutput { + + HEART_OUTPUT(CardShape.HEART, "하트"), + CLOVER_OUTPUT(CardShape.CLOVER, "클로버"), + SPADE_OUTPUT(CardShape.SPADE, "스페이드"), + DIAMOND_OUTPUT(CardShape.DIAMOND, "다이아몬드"); + + private final CardShape cardShape; + private final String output; + + CardShapeOutput(CardShape cardShape, String output) { + this.cardShape = cardShape; + this.output = output; + } + + public static String convertShapeToOutput(CardShape cardShape) { + return Arrays.stream(values()) + .filter(cardShapeOutput -> cardShapeOutput.cardShape == cardShape) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 카드 문양입니다.")) + .output; + } +} From 12715f4bbb1081cb125a5384cbcc32e8249cd53c Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 14:45:18 +0900 Subject: [PATCH 32/39] =?UTF-8?q?refactor(GameResult):=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=20=EC=B6=9C=EB=A0=A5=EC=97=90=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=A0=81=EC=9D=B4=EB=8D=98=20=ED=95=84=EB=93=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=EC=97=B4=EC=9D=84=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20?= =?UTF-8?q?view=20enum=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/gamer/GameResult.java | 20 ++++---------- .../view/object/GameResultOutput.java | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 15 deletions(-) create mode 100644 src/main/java/blackjack/view/object/GameResultOutput.java diff --git a/src/main/java/blackjack/domain/gamer/GameResult.java b/src/main/java/blackjack/domain/gamer/GameResult.java index b1af95a4e1..a7d6d08545 100644 --- a/src/main/java/blackjack/domain/gamer/GameResult.java +++ b/src/main/java/blackjack/domain/gamer/GameResult.java @@ -2,20 +2,10 @@ public enum GameResult { - WIN("승"), - LOSE("패"); + WIN, + LOSE; - private final String name; - - GameResult(String name) { - this.name = name; - } - - public boolean isLose() { - return this == LOSE; - } - - public String getName() { - return name; - } + public static boolean isLose(GameResult gameResult) { + return LOSE == gameResult; + } } diff --git a/src/main/java/blackjack/view/object/GameResultOutput.java b/src/main/java/blackjack/view/object/GameResultOutput.java new file mode 100644 index 0000000000..c41a70e3b8 --- /dev/null +++ b/src/main/java/blackjack/view/object/GameResultOutput.java @@ -0,0 +1,26 @@ +package blackjack.view.object; + +import blackjack.domain.gamer.GameResult; +import java.util.Arrays; + +public enum GameResultOutput { + + WIN_OUTPUT(GameResult.WIN, "승"), + LOSE_OUTPUT(GameResult.LOSE, "패"); + + private final GameResult gameResult; + private final String output; + + GameResultOutput(GameResult gameResult, String output) { + this.gameResult = gameResult; + this.output = output; + } + + public static String convertGameResultToOutput(GameResult gameResult) { + return Arrays.stream(values()) + .filter(gameResultOutput -> gameResultOutput.gameResult == gameResult) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("일치하는 게임 결과가 존재하지 않아 문자열을 반환할 수 없습니다.")) + .output; + } +} From 137592307024ec9cfdf3f50d670b34ce63d8634f Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 16:14:51 +0900 Subject: [PATCH 33/39] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=82=B4=EC=97=90=20=EC=A1=B4?= =?UTF-8?q?=EC=9E=AC=ED=95=98=EB=8D=98=20Dto=20=EB=B3=80=ED=99=98=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=84=20Dto=20=EB=82=B4=EB=B6=80=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BlackjackController.java | 190 ++++++++--------- .../domain/gamer/BlackjackGamer.java | 7 +- .../java/blackjack/domain/gamer/Dealer.java | 41 +--- .../java/blackjack/domain/gamer/Hand.java | 104 +++++----- .../java/blackjack/domain/gamer/Players.java | 85 ++++---- src/main/java/blackjack/dto/CardDto.java | 10 +- .../blackjack/dto/DealerInitialHandDto.java | 10 + .../java/blackjack/dto/DealerResultDto.java | 15 +- src/main/java/blackjack/dto/GamerHandDto.java | 15 ++ .../java/blackjack/dto/GamersHandDto.java | 15 ++ .../blackjack/dto/PlayerGameResultsDto.java | 19 ++ .../java/blackjack/dto/PlayerResultsDto.java | 9 - src/main/java/blackjack/view/OutputView.java | 191 +++++++++--------- 13 files changed, 376 insertions(+), 335 deletions(-) create mode 100644 src/main/java/blackjack/dto/GamersHandDto.java create mode 100644 src/main/java/blackjack/dto/PlayerGameResultsDto.java delete mode 100644 src/main/java/blackjack/dto/PlayerResultsDto.java diff --git a/src/main/java/blackjack/controller/BlackjackController.java b/src/main/java/blackjack/controller/BlackjackController.java index 38cd5111cc..feb65f55e8 100644 --- a/src/main/java/blackjack/controller/BlackjackController.java +++ b/src/main/java/blackjack/controller/BlackjackController.java @@ -1,111 +1,111 @@ package blackjack.controller; -import blackjack.view.object.Command; -import java.util.ArrayList; -import java.util.List; - import blackjack.domain.card.Deck; import blackjack.domain.gamer.Dealer; import blackjack.domain.gamer.GameResult; +import blackjack.domain.gamer.Name; import blackjack.domain.gamer.Player; import blackjack.domain.gamer.Players; import blackjack.dto.DealerInitialHandDto; import blackjack.dto.DealerResultDto; import blackjack.dto.GamerHandDto; -import blackjack.dto.PlayerResultsDto; +import blackjack.dto.GamersHandDto; +import blackjack.dto.PlayerGameResultsDto; import blackjack.view.InputView; import blackjack.view.OutputView; +import blackjack.view.object.Command; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class BlackjackController { - private static final String HIT_COMMAND = "y"; - private static final String STAND_COMMAND = "n"; - - private final InputView inputView; - private final OutputView outputView; - - public BlackjackController() { - this.inputView = new InputView(); - this.outputView = new OutputView(); - } - - public void run() { - Players players = getPlayers(); - Dealer dealer = new Dealer(); - Deck deck = new Deck(); - deck.shuffle(); - - setUpInitialHands(players, deck, dealer); - distributeCardToPlayers(players, deck); - distributeCardToDealer(dealer, deck); - printAllGamerScores(dealer, players); - printResult(dealer, players); - } - - private Players getPlayers() { - List playerNames = inputView.receivePlayerNames(); - - return new Players(playerNames); - } - - private void setUpInitialHands(Players players, Deck deck, Dealer dealer) { - players.initAllPlayersCard(deck); - dealer.initCard(deck); - printInitialHands(players, dealer); - } - - private void printInitialHands(Players players, Dealer dealer) { - DealerInitialHandDto dealerInitialHandDto = dealer.convertDealerToInitialHandDto(); - List playersInitialHandDto = players.convertPlayersToDto(); - - outputView.printInitialHands(dealerInitialHandDto, playersInitialHandDto); - } - - private void distributeCardToPlayers(Players players, Deck deck) { - for (Player player : players.getPlayers()) { - distributeCardToPlayer(deck, player); - } - } - - private void distributeCardToPlayer(Deck deck, Player player) { - while (canDistribute(player)) { - player.addCard(deck.draw()); - outputView.printPlayerHand(player.convertGamerToDto()); - } - } - - private boolean canDistribute(Player player) { - return player.canReceiveCard() && Command.isHit(getCommand(player)); - } - - private Command getCommand(Player player) { - return inputView.receiveCommand(player.getName().value()); - } - - private void distributeCardToDealer(Dealer dealer, Deck deck) { - while (dealer.canReceiveCard()) { - dealer.addCard(deck.draw()); - outputView.printDealerMessage(dealer.getName().value()); - } - } - - private void printAllGamerScores(Dealer dealer, Players players) { - outputView.printEmptyLine(); - outputView.printScore(dealer.convertGamerToDto(), dealer.getScore()); - printPlayersScores(players); - } - - private void printPlayersScores(Players players) { - for (Player player : players.getPlayers()) { - outputView.printScore(player.convertGamerToDto(), player.getScore()); - } - } - - private void printResult(Dealer dealer, Players players) { - PlayerResultsDto playerResultsDto = players.convertPlayersToResultDto(dealer.getScore()); - List playerResults = new ArrayList<>(playerResultsDto.resultMap().values()); - DealerResultDto dealerResultDto = dealer.convertDealerToResultDto(playerResults); - - outputView.printResult(dealerResultDto, playerResultsDto); - } + private final InputView inputView; + private final OutputView outputView; + + public BlackjackController() { + this.inputView = new InputView(); + this.outputView = new OutputView(); + } + + public void run() { + Players players = getPlayers(); + Dealer dealer = new Dealer(); + Deck deck = new Deck(); + deck.shuffle(); + + setUpInitialHands(players, deck, dealer); + distributeCardToPlayers(players, deck); + distributeCardToDealer(dealer, deck); + printAllGamerScores(dealer, players); + printResult(dealer, players); + } + + private Players getPlayers() { + List playerNames = inputView.receivePlayerNames(); + + return new Players(playerNames); + } + + private void setUpInitialHands(Players players, Deck deck, Dealer dealer) { + players.initAllPlayersCard(deck); + dealer.initCard(deck); + printInitialHands(players, dealer); + } + + private void printInitialHands(Players players, Dealer dealer) { + DealerInitialHandDto dealerInitialHandDto = DealerInitialHandDto.fromDealer(dealer); + GamersHandDto playersInitialHandDto = GamersHandDto.fromPlayers(players); + + outputView.printInitialHands(dealerInitialHandDto, playersInitialHandDto); + } + + private void distributeCardToPlayers(Players players, Deck deck) { + for (Player player : players.getPlayers()) { + distributeCardToPlayer(deck, player); + } + } + + private void distributeCardToPlayer(Deck deck, Player player) { + while (canDistribute(player)) { + player.addCard(deck.draw()); + outputView.printPlayerHand(GamerHandDto.fromBlackjackGamer(player)); + } + } + + private boolean canDistribute(Player player) { + return player.canReceiveCard() && Command.isHit(getCommand(player)); + } + + private Command getCommand(Player player) { + return inputView.receiveCommand(player.getName().value()); + } + + private void distributeCardToDealer(Dealer dealer, Deck deck) { + while (dealer.canReceiveCard()) { + dealer.addCard(deck.draw()); + outputView.printDealerMessage(dealer.getName().value()); + } + } + + private void printAllGamerScores(Dealer dealer, Players players) { + outputView.printEmptyLine(); + outputView.printScore(GamerHandDto.fromBlackjackGamer(dealer), dealer.getScore()); + printPlayersScores(players); + } + + private void printPlayersScores(Players players) { + for (Player player : players.getPlayers()) { + outputView.printScore(GamerHandDto.fromBlackjackGamer(player), player.getScore()); + } + } + + private void printResult(Dealer dealer, Players players) { + Map playerGameResults = players.collectPlayerGameResults(dealer.getScore()); + PlayerGameResultsDto playerGameResultsDto = PlayerGameResultsDto.fromPlayerGameResults(playerGameResults); + List playerResults = new ArrayList<>(playerGameResultsDto.resultMap().values()); + DealerResultDto dealerResultDto = DealerResultDto.fromPlayerResults(playerResults); + + outputView.printResult(dealerResultDto, playerGameResultsDto); + } } diff --git a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java index 830d748655..efab58e7fe 100644 --- a/src/main/java/blackjack/domain/gamer/BlackjackGamer.java +++ b/src/main/java/blackjack/domain/gamer/BlackjackGamer.java @@ -41,10 +41,7 @@ public Name getName() { return name; } - public GamerHandDto convertGamerToDto() { - String playerName = name.value(); - List gamerHand = hand.convertHandToDto(); - - return new GamerHandDto(playerName, gamerHand); + public Hand getHand() { + return hand; } } diff --git a/src/main/java/blackjack/domain/gamer/Dealer.java b/src/main/java/blackjack/domain/gamer/Dealer.java index c8ab69da7f..a69e016955 100644 --- a/src/main/java/blackjack/domain/gamer/Dealer.java +++ b/src/main/java/blackjack/domain/gamer/Dealer.java @@ -1,39 +1,16 @@ package blackjack.domain.gamer; -import java.util.List; - -import blackjack.domain.card.Card; -import blackjack.dto.DealerInitialHandDto; -import blackjack.dto.DealerResultDto; - public class Dealer extends BlackjackGamer { - private static final String DEFAULT_DEALER_NAME = "딜러"; - private static final int DEALER_DRAW_THRESHOLD = 16; - - public Dealer() { - super(new Name(DEFAULT_DEALER_NAME)); - } - - @Override - public boolean canReceiveCard() { - return getScore() <= DEALER_DRAW_THRESHOLD; - } - - public DealerResultDto convertDealerToResultDto(List playerResults) { - Name name = getName(); - int winCount = (int)playerResults.stream() - .filter(GameResult::isLose) - .count(); - int loseCount = playerResults.size() - winCount; - - return new DealerResultDto(name.value(), winCount, loseCount); - } + private static final String DEFAULT_DEALER_NAME = "딜러"; + private static final int DEALER_DRAW_THRESHOLD = 16; - public DealerInitialHandDto convertDealerToInitialHandDto() { - String dealerName = getName().value(); - Card first = getFirstCard(); + public Dealer() { + super(new Name(DEFAULT_DEALER_NAME)); + } - return new DealerInitialHandDto(dealerName, first.convertCardToDto()); - } + @Override + public boolean canReceiveCard() { + return getScore() <= DEALER_DRAW_THRESHOLD; + } } diff --git a/src/main/java/blackjack/domain/gamer/Hand.java b/src/main/java/blackjack/domain/gamer/Hand.java index ce7c2ecb15..41280fb21e 100644 --- a/src/main/java/blackjack/domain/gamer/Hand.java +++ b/src/main/java/blackjack/domain/gamer/Hand.java @@ -1,72 +1,68 @@ package blackjack.domain.gamer; -import java.util.List; - import blackjack.domain.card.Card; -import blackjack.dto.CardDto; +import java.util.List; public class Hand { - private static final int BLACKJACK_MAX_SCORE = 21; - private static final int ACE_VALUE_MODIFIER = 10; + private static final int BLACKJACK_MAX_SCORE = 21; + private static final int ACE_VALUE_MODIFIER = 10; - private final List cards; + private final List cards; - public Hand(List cards) { - this.cards = cards; - } + public Hand(List cards) { + this.cards = cards; + } - public void add(Card card) { - cards.add(card); - } + public void add(Card card) { + cards.add(card); + } - public int calculateScore() { - int sum = cards.stream() - .mapToInt(Card::getNumber) - .sum(); + public int calculateScore() { + int sum = cards.stream() + .mapToInt(Card::getNumberValue) + .sum(); - if (hasAce()) { - return adjustSumWithAce(sum); - } - return sum; - } + if (hasAce()) { + return adjustSumWithAce(sum); + } + return sum; + } - private boolean hasAce() { - return cards.stream() - .anyMatch(Card::isAce); - } + private boolean hasAce() { + return cards.stream() + .anyMatch(Card::isAce); + } - /** - * ACE가 포함된 경우, 21 이하이면서 가장 가능한 큰 값으로 계산한다. - */ - private int adjustSumWithAce(int sum) { - int aceCount = (int)cards.stream() - .filter(Card::isAce) - .count(); + /** + * ACE가 포함된 경우, 21 이하이면서 가장 가능한 큰 값으로 계산한다. + */ + private int adjustSumWithAce(int sum) { + int aceCount = (int) cards.stream() + .filter(Card::isAce) + .count(); - for (int i = 0; i < aceCount; i++) { - sum = adjust(sum); - } - return sum; - } + for (int i = 0; i < aceCount; i++) { + sum = adjust(sum); + } + return sum; + } - /** - * Ace는 기본적으로 11로 계산되나, 합계가 21을 초과할 경우 1로 계산한다. - */ - private int adjust(int sum) { - if (sum > BLACKJACK_MAX_SCORE) { - sum -= ACE_VALUE_MODIFIER; - } - return sum; - } + /** + * Ace는 기본적으로 11로 계산되나, 합계가 21을 초과할 경우 1로 계산한다. + */ + private int adjust(int sum) { + if (sum > BLACKJACK_MAX_SCORE) { + sum -= ACE_VALUE_MODIFIER; + } + return sum; + } - public Card getFirstCard() { - return cards.get(0); - } + public Card getFirstCard() { + return cards.get(0); + } - public List convertHandToDto() { - return cards.stream() - .map(Card::convertCardToDto) - .toList(); - } + public List getCards() { + return cards; + } } diff --git a/src/main/java/blackjack/domain/gamer/Players.java b/src/main/java/blackjack/domain/gamer/Players.java index 13cc45a92e..eca38b1cd6 100644 --- a/src/main/java/blackjack/domain/gamer/Players.java +++ b/src/main/java/blackjack/domain/gamer/Players.java @@ -1,69 +1,60 @@ package blackjack.domain.gamer; +import blackjack.domain.card.Deck; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; -import blackjack.domain.card.Deck; -import blackjack.dto.GamerHandDto; -import blackjack.dto.PlayerResultsDto; - public class Players { - private static final int MIN_PLAYER_COUNT = 2; - private static final int MAX_PLAYER_COUNT = 8; - - private final List players; + private static final int MIN_PLAYER_COUNT = 2; + private static final int MAX_PLAYER_COUNT = 8; - public Players(List names) { - validateNames(names); + private final List players; - this.players = names.stream() - .map(name -> new Player(new Name(name))) - .toList(); - } + public Players(List names) { + validateNames(names); - private void validateNames(List names) { - validateDuplicate(names); - validateCount(names.size()); - } + this.players = names.stream() + .map(name -> new Player(new Name(name))) + .toList(); + } - private void validateCount(int count) { - if (count < MIN_PLAYER_COUNT || count > MAX_PLAYER_COUNT) { - throw new IllegalArgumentException( - "플레이어는 최소 " + MIN_PLAYER_COUNT + "명에서 최대 " + MAX_PLAYER_COUNT + "명까지 가능합니다" - ); - } - } + private void validateNames(List names) { + validateDuplicate(names); + validateCount(names.size()); + } - private void validateDuplicate(List names) { - Set nonDuplicateNames = new HashSet<>(names); + private void validateCount(int count) { + if (count < MIN_PLAYER_COUNT || count > MAX_PLAYER_COUNT) { + throw new IllegalArgumentException( + "플레이어는 최소 " + MIN_PLAYER_COUNT + "명에서 최대 " + MAX_PLAYER_COUNT + "명까지 가능합니다" + ); + } + } - if (names.size() != nonDuplicateNames.size()) { - throw new IllegalArgumentException("이름은 중복될 수 없습니다."); - } - } + private void validateDuplicate(List names) { + Set nonDuplicateNames = new HashSet<>(names); - public void initAllPlayersCard(Deck deck) { - players.forEach(player -> player.initCard(deck)); - } + if (names.size() != nonDuplicateNames.size()) { + throw new IllegalArgumentException("이름은 중복될 수 없습니다."); + } + } - public List getPlayers() { - return List.copyOf(players); - } + public void initAllPlayersCard(Deck deck) { + players.forEach(player -> player.initCard(deck)); + } - public List convertPlayersToDto() { - return players.stream() - .map(Player::convertGamerToDto) - .toList(); - } + public List getPlayers() { + return List.copyOf(players); + } - public PlayerResultsDto convertPlayersToResultDto(int dealerScore) { - Map resultMap = new LinkedHashMap<>(); - players.forEach(player -> resultMap.put(player.getName(), player.isWin(dealerScore))); + public Map collectPlayerGameResults(int dealerScore) { + Map playerGameResults = new LinkedHashMap<>(); + players.forEach(player -> playerGameResults.put(player.getName(), player.isWin(dealerScore))); - return new PlayerResultsDto(resultMap); - } + return playerGameResults; + } } diff --git a/src/main/java/blackjack/dto/CardDto.java b/src/main/java/blackjack/dto/CardDto.java index b52d4df4f0..274c3a9b63 100644 --- a/src/main/java/blackjack/dto/CardDto.java +++ b/src/main/java/blackjack/dto/CardDto.java @@ -1,4 +1,12 @@ package blackjack.dto; -public record CardDto(String cardNumber, String cardShape) { +import blackjack.domain.card.Card; +import blackjack.domain.card.CardNumber; +import blackjack.domain.card.CardShape; + +public record CardDto(CardNumber cardNumber, CardShape cardShape) { + + public static CardDto fromCard(Card card) { + return new CardDto(card.getCardNumber(), card.getCardShape()); + } } diff --git a/src/main/java/blackjack/dto/DealerInitialHandDto.java b/src/main/java/blackjack/dto/DealerInitialHandDto.java index 813a3076b0..37ef322c18 100644 --- a/src/main/java/blackjack/dto/DealerInitialHandDto.java +++ b/src/main/java/blackjack/dto/DealerInitialHandDto.java @@ -1,4 +1,14 @@ package blackjack.dto; +import blackjack.domain.card.Card; +import blackjack.domain.gamer.Dealer; + public record DealerInitialHandDto(String name, CardDto firstCard) { + + public static DealerInitialHandDto fromDealer(Dealer dealer) { + String dealerName = dealer.getName().value(); + Card first = dealer.getFirstCard(); + + return new DealerInitialHandDto(dealerName, CardDto.fromCard(first)); + } } diff --git a/src/main/java/blackjack/dto/DealerResultDto.java b/src/main/java/blackjack/dto/DealerResultDto.java index 72c0cbabbe..bd1a2fff80 100644 --- a/src/main/java/blackjack/dto/DealerResultDto.java +++ b/src/main/java/blackjack/dto/DealerResultDto.java @@ -1,4 +1,17 @@ package blackjack.dto; -public record DealerResultDto(String name, int winCount, int loseCount) { +import blackjack.domain.gamer.GameResult; +import java.util.List; + +public record DealerResultDto(int winCount, int loseCount) { + + public static DealerResultDto fromPlayerResults(List playerResults) { + int dealerWinCount = (int) playerResults.stream() + .filter(GameResult::isLose) + .count(); + + int dealerLoseCount = playerResults.size() - dealerWinCount; + + return new DealerResultDto(dealerWinCount, dealerLoseCount); + } } diff --git a/src/main/java/blackjack/dto/GamerHandDto.java b/src/main/java/blackjack/dto/GamerHandDto.java index 665fddc294..52da8a1956 100644 --- a/src/main/java/blackjack/dto/GamerHandDto.java +++ b/src/main/java/blackjack/dto/GamerHandDto.java @@ -1,6 +1,21 @@ package blackjack.dto; +import blackjack.domain.gamer.BlackjackGamer; +import blackjack.domain.gamer.Hand; import java.util.List; public record GamerHandDto(String name, List gamerHand) { + + public static GamerHandDto fromBlackjackGamer(BlackjackGamer blackjackGamer) { + String playerName = blackjackGamer.getName().value(); + List gamerHand = convertHandToCardDto(blackjackGamer.getHand()); + + return new GamerHandDto(playerName, gamerHand); + } + + public static List convertHandToCardDto(Hand hand) { + return hand.getCards().stream() + .map(CardDto::fromCard) + .toList(); + } } diff --git a/src/main/java/blackjack/dto/GamersHandDto.java b/src/main/java/blackjack/dto/GamersHandDto.java new file mode 100644 index 0000000000..e63516b98e --- /dev/null +++ b/src/main/java/blackjack/dto/GamersHandDto.java @@ -0,0 +1,15 @@ +package blackjack.dto; + +import blackjack.domain.gamer.Players; +import java.util.List; + +public record GamersHandDto(List gamersHandDto) { + + public static GamersHandDto fromPlayers(Players players) { + List gamerHandDtos = players.getPlayers().stream() + .map(GamerHandDto::fromBlackjackGamer) + .toList(); + + return new GamersHandDto(gamerHandDtos); + } +} diff --git a/src/main/java/blackjack/dto/PlayerGameResultsDto.java b/src/main/java/blackjack/dto/PlayerGameResultsDto.java new file mode 100644 index 0000000000..bacf83827e --- /dev/null +++ b/src/main/java/blackjack/dto/PlayerGameResultsDto.java @@ -0,0 +1,19 @@ +package blackjack.dto; + +import blackjack.domain.gamer.GameResult; +import blackjack.domain.gamer.Name; +import java.util.LinkedHashMap; +import java.util.Map; + +public record PlayerGameResultsDto(Map resultMap) { + + public static PlayerGameResultsDto fromPlayerGameResults(Map playerGameResults) { + Map gameResult = new LinkedHashMap<>(); + + for (Name playerName : playerGameResults.keySet()) { + gameResult.put(playerName.value(), playerGameResults.get(playerName)); + } + + return new PlayerGameResultsDto(gameResult); + } +} diff --git a/src/main/java/blackjack/dto/PlayerResultsDto.java b/src/main/java/blackjack/dto/PlayerResultsDto.java deleted file mode 100644 index 9969a4ae84..0000000000 --- a/src/main/java/blackjack/dto/PlayerResultsDto.java +++ /dev/null @@ -1,9 +0,0 @@ -package blackjack.dto; - -import java.util.Map; - -import blackjack.domain.gamer.GameResult; -import blackjack.domain.gamer.Name; - -public record PlayerResultsDto(Map resultMap) { -} diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index a8a1ab44c9..393e4d9edb 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,101 +1,110 @@ package blackjack.view; -import java.util.List; - import blackjack.dto.CardDto; import blackjack.dto.DealerInitialHandDto; import blackjack.dto.DealerResultDto; import blackjack.dto.GamerHandDto; -import blackjack.dto.PlayerResultsDto; +import blackjack.dto.GamersHandDto; +import blackjack.dto.PlayerGameResultsDto; +import blackjack.view.object.CardNumberOutput; +import blackjack.view.object.CardShapeOutput; +import blackjack.view.object.GameResultOutput; +import java.util.List; public class OutputView { - public void printInitialHands(DealerInitialHandDto dealerInitialHandDto, List playersInitialHandDto) { - System.out.printf("\n%s와 %s에게 2장을 나누었습니다.\n", dealerInitialHandDto.name(), - joinPlayerNames(playersInitialHandDto)); - - System.out.printf("%s 카드: %s\n", dealerInitialHandDto.name(), formatCardName(dealerInitialHandDto.firstCard())); - printAllPlayerHands(playersInitialHandDto); - } - - private String joinPlayerNames(List playersInitialHandDto) { - return String.join(", ", getPlayerNames(playersInitialHandDto)); - } - - private List getPlayerNames(List playersInitialHandDto) { - return playersInitialHandDto.stream().map(GamerHandDto::name).toList(); - } - - private String formatCardName(CardDto cardDto) { - return cardDto.cardNumber() + cardDto.cardShape(); - } - - private void printAllPlayerHands(List playersInitialHandDto) { - playersInitialHandDto.forEach(this::printPlayerHand); - System.out.println(); - } - - public void printPlayerHand(GamerHandDto playerHandDto) { - System.out.println(buildPlayerHand(playerHandDto)); - } - - private StringBuilder buildPlayerHand(GamerHandDto gamerHandDto) { - StringBuilder stringBuilder = new StringBuilder(); - return stringBuilder - .append(gamerHandDto.name()) - .append(" 카드: ") - .append(joinCardNames(gamerHandDto)); - } - - private String joinCardNames(GamerHandDto gamerHandDto) { - return String.join(", ", getCardNames(gamerHandDto)); - } - - private List getCardNames(GamerHandDto gamerHandDto) { - return gamerHandDto.gamerHand().stream().map(this::formatCardName).toList(); - } - - public void printDealerMessage(String dealerName) { - System.out.printf("\n%s는 16이하라 한장의 카드를 더 받았습니다.\n", dealerName); - } - - public void printScore(GamerHandDto gamerHandDto, int score) { - StringBuilder builder = buildPlayerHand(gamerHandDto) - .append(" - ") - .append("결과: ") - .append(score); - System.out.println(builder); - } - - public void printResult(DealerResultDto dealerResultDto, PlayerResultsDto playerResultsDto) { - System.out.println("\n## 최종 승패"); - printDealerResult(dealerResultDto); - printPlayerResults(playerResultsDto); - } - - private void printDealerResult(DealerResultDto dealerResultDto) { - int winCount = dealerResultDto.winCount(); - int loseCount = dealerResultDto.loseCount(); - StringBuilder stringBuilder = new StringBuilder(dealerResultDto.name()).append(": "); - - if (winCount > 0) { - stringBuilder.append(winCount) - .append("승 "); - } - if (loseCount > 0) { - stringBuilder.append(loseCount) - .append("패"); - } - System.out.println(stringBuilder); - } - - private void printPlayerResults(PlayerResultsDto playerResultsDto) { - playerResultsDto.resultMap().forEach((name, result) -> - System.out.println(name.value() + ": " + result.getName()) - ); - } - - public void printEmptyLine() { - System.out.println(); - } + private static final String DEALER_DEFAULT_NAME = "딜러"; + + public void printInitialHands(DealerInitialHandDto dealerInitialHandDto, GamersHandDto playersInitialHandDto) { + System.out.printf("\n%s와 %s에게 2장을 나누었습니다.\n", dealerInitialHandDto.name(), + joinPlayerNames(playersInitialHandDto)); + + System.out.printf("%s 카드: %s\n", dealerInitialHandDto.name(), formatCardName(dealerInitialHandDto.firstCard())); + printAllPlayerHands(playersInitialHandDto); + } + + private String joinPlayerNames(GamersHandDto playersInitialHandDto) { + return String.join(", ", getPlayerNames(playersInitialHandDto)); + } + + private List getPlayerNames(GamersHandDto playersInitialHandDto) { + return playersInitialHandDto.gamersHandDto().stream().map(GamerHandDto::name).toList(); + } + + private String formatCardName(CardDto cardDto) { + return CardNumberOutput.convertNumberToOutput(cardDto.cardNumber()) + CardShapeOutput.convertShapeToOutput( + cardDto.cardShape()); + } + + private void printAllPlayerHands(GamersHandDto playersInitialHandDto) { + playersInitialHandDto.gamersHandDto().forEach(this::printPlayerHand); + System.out.println(); + } + + public void printPlayerHand(GamerHandDto playerHandDto) { + System.out.println(buildPlayerHand(playerHandDto)); + } + + private StringBuilder buildPlayerHand(GamerHandDto gamerHandDto) { + StringBuilder stringBuilder = new StringBuilder(); + return stringBuilder + .append(gamerHandDto.name()) + .append(" 카드: ") + .append(joinCardNames(gamerHandDto)); + } + + private String joinCardNames(GamerHandDto gamerHandDto) { + return String.join(", ", getCardNames(gamerHandDto)); + } + + private List getCardNames(GamerHandDto gamerHandDto) { + return gamerHandDto.gamerHand().stream().map(this::formatCardName).toList(); + } + + public void printDealerMessage(String dealerName) { + System.out.printf("\n%s는 16이하라 한장의 카드를 더 받았습니다.\n", dealerName); + } + + public void printScore(GamerHandDto gamerHandDto, int score) { + StringBuilder builder = buildPlayerHand(gamerHandDto) + .append(" - ") + .append("결과: ") + .append(score); + System.out.println(builder); + } + + public void printResult(DealerResultDto dealerResultDto, PlayerGameResultsDto playerGameResultsDto) { + System.out.println("\n## 최종 승패"); + printDealerResult(dealerResultDto); + printPlayerResults(playerGameResultsDto); + } + + private void printDealerResult(DealerResultDto dealerResultDto) { + int winCount = dealerResultDto.winCount(); + int loseCount = dealerResultDto.loseCount(); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder + .append(DEALER_DEFAULT_NAME) + .append(": "); + + if (winCount > 0) { + stringBuilder.append(winCount) + .append("승 "); + } + if (loseCount > 0) { + stringBuilder.append(loseCount) + .append("패"); + } + System.out.println(stringBuilder); + } + + private void printPlayerResults(PlayerGameResultsDto playerGameResultsDto) { + playerGameResultsDto.resultMap().forEach((name, result) -> + System.out.println(name + ": " + GameResultOutput.convertGameResultToOutput(result)) + ); + } + + public void printEmptyLine() { + System.out.println(); + } } From 16372e101553c26fefccc9c93890913c8a980ae8 Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 17:00:38 +0900 Subject: [PATCH 34/39] =?UTF-8?q?refactor(Deck):=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=AA=A9=EC=A0=81=EC=9D=98=20List=EB=A5=BC?= =?UTF-8?q?=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=EB=A1=9C=20=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EA=B0=9C=EB=B0=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/Deck.java | 44 ++++++++++--------- .../java/blackjack/domain/card/DeckTest.java | 44 ++++++++++++------- 2 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/main/java/blackjack/domain/card/Deck.java b/src/main/java/blackjack/domain/card/Deck.java index d19140a943..430a9aa9d3 100644 --- a/src/main/java/blackjack/domain/card/Deck.java +++ b/src/main/java/blackjack/domain/card/Deck.java @@ -9,24 +9,28 @@ public class Deck { - private final LinkedList cards; - - public Deck() { - this.cards = Arrays.stream(CardShape.values()) - .flatMap(cardShape -> Arrays.stream(CardNumber.values()) - .map(number -> new Card(cardShape, number))) - .collect(Collectors.toCollection(LinkedList::new)); - } - - public void shuffle() { - Collections.shuffle(cards); - } - - public Card draw() { - return cards.poll(); - } - - public List getCards() { - return new ArrayList<>(cards); - } + private final LinkedList cards; + + public Deck() { + this.cards = Arrays.stream(CardShape.values()) + .flatMap(cardShape -> Arrays.stream(CardNumber.values()) + .map(number -> new Card(cardShape, number))) + .collect(Collectors.toCollection(LinkedList::new)); + } + + public Deck(LinkedList cards) { + this.cards = cards; + } + + public void shuffle() { + Collections.shuffle(cards); + } + + public Card draw() { + return cards.poll(); + } + + public List getCards() { + return new ArrayList<>(cards); + } } diff --git a/src/test/java/blackjack/domain/card/DeckTest.java b/src/test/java/blackjack/domain/card/DeckTest.java index 5ce0b7d982..358bd4d9f0 100644 --- a/src/test/java/blackjack/domain/card/DeckTest.java +++ b/src/test/java/blackjack/domain/card/DeckTest.java @@ -1,29 +1,41 @@ package blackjack.domain.card; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.LinkedList; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class DeckTest { - Deck deck; + private Deck mockDeck; + private Deck realDeck; - @BeforeEach - void setUP() { - deck = new Deck(); - } + @BeforeEach + void setUP() { + LinkedList cardList = new LinkedList<>(List.of( + new Card(CardShape.HEART, CardNumber.KING), new Card(CardShape.HEART, CardNumber.QUEEN), + new Card(CardShape.HEART, CardNumber.ACE), new Card(CardShape.HEART, CardNumber.TWO), + new Card(CardShape.DIAMOND, CardNumber.KING), new Card(CardShape.DIAMOND, CardNumber.QUEEN), + new Card(CardShape.DIAMOND, CardNumber.ACE), new Card(CardShape.DIAMOND, CardNumber.TWO))); - @Test - @DisplayName("카드 덱은 52장의 카드로 이루어져 있다.") - void deckSizeTest() { - assertThat(deck.getCards().size()).isEqualTo(52); - } + mockDeck = new Deck(cardList); + realDeck = new Deck(); + } - @Test - @DisplayName("맨 위의 카드를 한 장 뽑는다.") - void drawTest() { - assertThat(deck.draw()).isEqualTo(new Card(CardShape.HEART, CardNumber.ACE)); - } + @Test + @DisplayName("카드 덱은 52장의 카드로 이루어져 있다.") + void deckSizeTest() { + assertThat(realDeck.getCards().size()).isEqualTo(52); + } + + @Test + @DisplayName("맨 위의 카드를 한 장 뽑는다.") + void drawTest() { + assertThat(mockDeck.draw()).isEqualTo(new Card(CardShape.HEART, CardNumber.KING)); + assertThat(mockDeck.draw()).isEqualTo(new Card(CardShape.HEART, CardNumber.QUEEN)); + assertThat(mockDeck.draw()).isEqualTo(new Card(CardShape.HEART, CardNumber.ACE)); + } } From 93c8c4bb70eede142631f80853a8535be24e5fa7 Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 17:01:23 +0900 Subject: [PATCH 35/39] =?UTF-8?q?test(CardTest):=20eqauls&hashCode=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/domain/card/Card.java | 64 +++++++++---------- .../java/blackjack/domain/card/CardTest.java | 19 ++++++ 2 files changed, 51 insertions(+), 32 deletions(-) create mode 100644 src/test/java/blackjack/domain/card/CardTest.java diff --git a/src/main/java/blackjack/domain/card/Card.java b/src/main/java/blackjack/domain/card/Card.java index 78bcbd1f31..8a649540af 100644 --- a/src/main/java/blackjack/domain/card/Card.java +++ b/src/main/java/blackjack/domain/card/Card.java @@ -2,46 +2,46 @@ import java.util.Objects; -import blackjack.dto.CardDto; - public class Card { - private final CardShape cardShape; - private final CardNumber cardNumber; + private final CardShape cardShape; + private final CardNumber cardNumber; - public Card(CardShape cardShape, CardNumber cardNumber) { - this.cardShape = cardShape; - this.cardNumber = cardNumber; - } + public Card(CardShape cardShape, CardNumber cardNumber) { + this.cardShape = cardShape; + this.cardNumber = cardNumber; + } - public boolean isAce() { - return cardNumber == CardNumber.ACE; - } + public boolean isAce() { + return cardNumber == CardNumber.ACE; + } - public int getNumberValue() { - return cardNumber.getValue(); - } + public int getNumberValue() { + return cardNumber.getValue(); + } - public CardShape getCardShape() { - return cardShape; - } + public CardShape getCardShape() { + return cardShape; + } - public CardNumber getCardNumber() { - return cardNumber; - } + public CardNumber getCardNumber() { + return cardNumber; + } - @Override - public boolean equals(Object o) { - if (this == o) + @Override + public boolean equals(Object o) { + if (this == o) { return true; - if (o == null || getClass() != o.getClass()) + } + if (o == null || getClass() != o.getClass()) { return false; - Card card = (Card)o; - return cardShape == card.cardShape && cardNumber == card.cardNumber; - } - - @Override - public int hashCode() { - return Objects.hash(cardShape, cardNumber); - } + } + Card card = (Card) o; + return cardShape == card.cardShape && cardNumber == card.cardNumber; + } + + @Override + public int hashCode() { + return Objects.hash(cardShape, cardNumber); + } } diff --git a/src/test/java/blackjack/domain/card/CardTest.java b/src/test/java/blackjack/domain/card/CardTest.java new file mode 100644 index 0000000000..3cb7939124 --- /dev/null +++ b/src/test/java/blackjack/domain/card/CardTest.java @@ -0,0 +1,19 @@ +package blackjack.domain.card; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Objects; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class CardTest { + + @Test + @DisplayName("equals & hashCode 재정의 테스트") + void equalsTest() { + Card card = new Card(CardShape.HEART, CardNumber.KING); + + assertThat(card).isEqualTo(new Card(CardShape.HEART, CardNumber.KING)); + assertThat(Objects.hash(card)).isEqualTo(Objects.hash(new Card(CardShape.HEART, CardNumber.KING))); + } +} From 1ff95cb239513259754785527fb7232933fff465 Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 17:02:42 +0900 Subject: [PATCH 36/39] =?UTF-8?q?refactor(PlayersTest):=20=EA=B0=80?= =?UTF-8?q?=EB=8F=85=EC=84=B1=20=ED=96=A5=EC=83=81=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/domain/gamer/PlayerTest.java | 180 +++++++++--------- 1 file changed, 92 insertions(+), 88 deletions(-) diff --git a/src/test/java/blackjack/domain/gamer/PlayerTest.java b/src/test/java/blackjack/domain/gamer/PlayerTest.java index da80d1a12d..aa83483545 100644 --- a/src/test/java/blackjack/domain/gamer/PlayerTest.java +++ b/src/test/java/blackjack/domain/gamer/PlayerTest.java @@ -1,99 +1,103 @@ package blackjack.domain.gamer; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import blackjack.domain.card.Card; +import blackjack.domain.card.CardNumber; +import blackjack.domain.card.CardShape; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import blackjack.domain.card.Card; -import blackjack.domain.card.CardNumber; -import blackjack.domain.card.CardShape; - class PlayerTest { - Player player; - - @BeforeEach - void setUP() { - player = new Player(new Name("hogi")); - } - - @Test - @DisplayName("카드의 총합이 21 이하이면 카드를 받을 수 있다.") - void receiveCardTest() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); - - assertThat(player.canReceiveCard()).isTrue(); - } - - @Test - @DisplayName("카드의 총합이 21을 초과하면 카드를 받을 수 없다.") - void cantReceiveCardTest() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); - player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); - - assertThat(player.canReceiveCard()).isFalse(); - } - - @Nested - @DisplayName("플레이어가 승리한다.") - class IsWinTest { - - @Test - @DisplayName("플레이어 점수가 21 이하이고, 딜러의 점수보다 큰 경우 승리한다.") - void bustTest() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.FOUR)); - player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); - - assertThat(player.isWin(20)).isEqualTo(GameResult.WIN); - } - - @Test - @DisplayName("플레이어 점수가 21 이하이고, 딜러의 점수가 21을 초과하면 승리한다.") - void bustTest1() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); - - assertThat(player.isWin(22)).isEqualTo(GameResult.WIN); - } - } - - @Nested - @DisplayName("플레이어가 패배한다.") - class LoseTest { - - @Test - @DisplayName("점수가 21을 초과하면 딜러의 점수와 무관하게 패배한다") - void bustTest2() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); - player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); - - assertThat(player.isWin(21)).isEqualTo(GameResult.LOSE); - assertThat(player.isWin(22)).isEqualTo(GameResult.LOSE); - } - - @Test - @DisplayName("플레이어와 딜러의 점수가 모두 21 이하일 때, 딜러의 점수보다 낮으면 패배한다.") - void bustTest3() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.SIX)); - - assertThat(player.isWin(17)).isEqualTo(GameResult.LOSE); - } - - @Test - @DisplayName("플레이어와 딜러의 점수가 모두 21 이하이고 동점인 경우 플레이어가 패배한다.") - void bustTest4() { - player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); - - assertThat(player.isWin(17)).isEqualTo(GameResult.LOSE); - } - } + Player player; + + @BeforeEach + void setUP() { + player = new Player(new Name("hogi")); + } + + @Nested + @DisplayName("카드를 받는 조건 테스트") + class CanReceiveCardTest { + + @Test + @DisplayName("카드의 총합이 21 이하이면 카드를 받을 수 있다.") + void receiveCardTest() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + + assertThat(player.canReceiveCard()).isTrue(); + } + + @Test + @DisplayName("카드의 총합이 21을 초과하면 카드를 받을 수 없다.") + void cantReceiveCardTest() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.canReceiveCard()).isFalse(); + } + } + + @Nested + @DisplayName("플레이어가 승리하는 경우의 수 테스트") + class IsWinTest { + + @Test + @DisplayName("플레이어 점수가 21 이하이고, 딜러의 점수보다 큰 경우 승리한다.") + void bustTest() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FOUR)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.isWin(20)).isEqualTo(GameResult.WIN); + } + + @Test + @DisplayName("플레이어 점수가 21 이하이고, 딜러의 점수가 21을 초과하면 승리한다.") + void bustTest1() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + + assertThat(player.isWin(22)).isEqualTo(GameResult.WIN); + } + } + + @Nested + @DisplayName("플레이어가 패배하는 경우의 수 테스트") + class LoseTest { + + @Test + @DisplayName("점수가 21을 초과하면 딜러의 점수와 무관하게 패배한다") + void bustTest2() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.isWin(21)).isEqualTo(GameResult.LOSE); + assertThat(player.isWin(22)).isEqualTo(GameResult.LOSE); + } + + @Test + @DisplayName("플레이어와 딜러의 점수가 모두 21 이하일 때, 딜러의 점수보다 낮으면 패배한다.") + void bustTest3() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.SIX)); + + assertThat(player.isWin(17)).isEqualTo(GameResult.LOSE); + } + + @Test + @DisplayName("플레이어와 딜러의 점수가 모두 21 이하이고 동점인 경우 플레이어가 패배한다.") + void bustTest4() { + player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.SEVEN)); + + assertThat(player.isWin(17)).isEqualTo(GameResult.LOSE); + } + } } From ec048b0a145a9aedb8eb435254df35965723b45d Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 17:14:51 +0900 Subject: [PATCH 37/39] =?UTF-8?q?test(PlayersTest):=20=EA=B2=BD=EA=B3=84?= =?UTF-8?q?=20=EA=B0=92=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/blackjack/domain/gamer/PlayerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/blackjack/domain/gamer/PlayerTest.java b/src/test/java/blackjack/domain/gamer/PlayerTest.java index aa83483545..5f1fee38ed 100644 --- a/src/test/java/blackjack/domain/gamer/PlayerTest.java +++ b/src/test/java/blackjack/domain/gamer/PlayerTest.java @@ -27,6 +27,7 @@ class CanReceiveCardTest { @DisplayName("카드의 총합이 21 이하이면 카드를 받을 수 있다.") void receiveCardTest() { player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); + player.addCard(new Card(CardShape.HEART, CardNumber.SIX)); player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); assertThat(player.canReceiveCard()).isTrue(); @@ -61,7 +62,7 @@ void bustTest() { @DisplayName("플레이어 점수가 21 이하이고, 딜러의 점수가 21을 초과하면 승리한다.") void bustTest1() { player.addCard(new Card(CardShape.CLOVER, CardNumber.KING)); - player.addCard(new Card(CardShape.HEART, CardNumber.FIVE)); + player.addCard(new Card(CardShape.HEART, CardNumber.ACE)); assertThat(player.isWin(22)).isEqualTo(GameResult.WIN); } From 6659db223afb0c97ab54604c77cc588664791ab2 Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 17:46:40 +0900 Subject: [PATCH 38/39] =?UTF-8?q?feat(Command):=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EC=9E=85=EB=A0=A5=20=EB=AA=85=EB=A0=B9=EC=96=B4?= =?UTF-8?q?=EB=A5=BC=20=EB=B3=84=EB=8F=84=EC=9D=98=20Enum=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/object/Command.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/blackjack/view/object/Command.java b/src/main/java/blackjack/view/object/Command.java index fc7e0ac5cf..670cdbccf7 100644 --- a/src/main/java/blackjack/view/object/Command.java +++ b/src/main/java/blackjack/view/object/Command.java @@ -3,6 +3,7 @@ import java.util.Arrays; public enum Command { + HIT("y"), STAND("n"); From 8f146b6e34b9102aadd9584a8c2149389b06f572 Mon Sep 17 00:00:00 2001 From: seokmyungham Date: Mon, 11 Mar 2024 17:49:28 +0900 Subject: [PATCH 39/39] =?UTF-8?q?style(Players):=20getter=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EC=9D=98=20=EC=9C=84=EC=B9=98=EB=A5=BC=20?= =?UTF-8?q?=EB=A7=A8=20=EB=B0=91=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 --- src/main/java/blackjack/domain/gamer/Players.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/domain/gamer/Players.java b/src/main/java/blackjack/domain/gamer/Players.java index eca38b1cd6..646b54606b 100644 --- a/src/main/java/blackjack/domain/gamer/Players.java +++ b/src/main/java/blackjack/domain/gamer/Players.java @@ -47,14 +47,14 @@ public void initAllPlayersCard(Deck deck) { players.forEach(player -> player.initCard(deck)); } - public List getPlayers() { - return List.copyOf(players); - } - public Map collectPlayerGameResults(int dealerScore) { Map playerGameResults = new LinkedHashMap<>(); players.forEach(player -> playerGameResults.put(player.getName(), player.isWin(dealerScore))); return playerGameResults; } + + public List getPlayers() { + return List.copyOf(players); + } }