From 143ebe72304c0d63d39b039b459f65aaaa66bea6 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 14:43:21 +0900 Subject: [PATCH 01/85] =?UTF-8?q?docs:=20=EC=BB=A8=EB=B2=A4=EC=85=98=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B8=B0=EB=8A=A5=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=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: donghoony --- README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 556099c4de..3132da7116 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,23 @@ 블랙잭 미션 저장소 -## 우아한테크코스 코드리뷰 +## 페어와 지킬 컨벤션 +1. 클래스 정의 다음 줄은 공백으로 한다. +2. test code에 사용하는 메서드는 `static import`한다. -- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) +## 요구사항 +- [ ] 카드는 모양과 수로 이루어져 있다. + - [ ] 모양으로는 스페이드, 다이아, 하트, 클로버가 있다. + - [ ] 수로는 Ace, King, Queen, Jack과 2 이상 10 이하의 정수가 있다. +- [ ] 카드의 숫자 계산은 카드 숫자를 기본으로 한다. + - [ ] Ace는 1 또는 11로 계산할 수 있다. + - [ ] King, Queen, Jack은 각각 10으로 계산한다. +- [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. +- [ ] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. +- [ ] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. +- [ ] 플레이어의 카드는 모두에게 공개된다. +- [ ] 딜러의 두 번째 카드는 공개되지 않는다. +- [ ] 딜러는 처음에 받은 2장의 합계가 16 이하이면 1장의 카드를 추가로 받는다. +- [ ] 각 플레이어는 딜러와만 승패를 겨룬다. +- [ ] 딜러는 모든 플레이어와 승패를 겨룬다. +- [ ] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 승패를 출력한다. From 21dae3a9450b7f43e21bb95b0bfa09e99cf75075 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 15:06:45 +0900 Subject: [PATCH 02/85] chore: remove gitkeep Co-authored-by: donghoony --- src/main/java/.gitkeep | 0 src/test/java/.gitkeep | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/.gitkeep delete mode 100644 src/test/java/.gitkeep diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 From 1786e9f728c10201491123ee6472b22184fecce1 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 15:07:18 +0900 Subject: [PATCH 03/85] =?UTF-8?q?feat(Card):=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=A0=90=EC=88=98=20=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 10 +++++----- src/main/java/card/Card.java | 16 ++++++++++++++++ src/main/java/card/Number.java | 28 ++++++++++++++++++++++++++++ src/main/java/card/Symbol.java | 9 +++++++++ src/test/java/card/CardTest.java | 16 ++++++++++++++++ 5 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 src/main/java/card/Card.java create mode 100644 src/main/java/card/Number.java create mode 100644 src/main/java/card/Symbol.java create mode 100644 src/test/java/card/CardTest.java diff --git a/README.md b/README.md index 3132da7116..4f9dd7939b 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ 2. test code에 사용하는 메서드는 `static import`한다. ## 요구사항 -- [ ] 카드는 모양과 수로 이루어져 있다. - - [ ] 모양으로는 스페이드, 다이아, 하트, 클로버가 있다. - - [ ] 수로는 Ace, King, Queen, Jack과 2 이상 10 이하의 정수가 있다. -- [ ] 카드의 숫자 계산은 카드 숫자를 기본으로 한다. +- [x] 카드는 모양과 수로 이루어져 있다. + - [x] 모양으로는 스페이드, 다이아, 하트, 클로버가 있다. + - [x] 수로는 Ace, King, Queen, Jack과 2 이상 10 이하의 정수가 있다. +- [x] 카드의 숫자 계산은 카드 숫자를 기본으로 한다. - [ ] Ace는 1 또는 11로 계산할 수 있다. - - [ ] King, Queen, Jack은 각각 10으로 계산한다. + - [x] King, Queen, Jack은 각각 10으로 계산한다. - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. - [ ] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. - [ ] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. diff --git a/src/main/java/card/Card.java b/src/main/java/card/Card.java new file mode 100644 index 0000000000..7c4e5b01d0 --- /dev/null +++ b/src/main/java/card/Card.java @@ -0,0 +1,16 @@ +package card; + +public class Card { + + private final Symbol symbol; + private final Number number; + + public Card(Symbol symbol, Number number) { + this.symbol = symbol; + this.number = number; + } + + int getScore() { + return number.getScore(); + } +} diff --git a/src/main/java/card/Number.java b/src/main/java/card/Number.java new file mode 100644 index 0000000000..98dca0d719 --- /dev/null +++ b/src/main/java/card/Number.java @@ -0,0 +1,28 @@ +package card; + +public enum Number { + + ACE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + TEN(10), + JACK(10), + QUEEN(10), + KING(10); + + private final int score; + + Number(int score) { + this.score = score; + } + + int getScore() { + return this.score; + } +} \ No newline at end of file diff --git a/src/main/java/card/Symbol.java b/src/main/java/card/Symbol.java new file mode 100644 index 0000000000..9678c1ef1c --- /dev/null +++ b/src/main/java/card/Symbol.java @@ -0,0 +1,9 @@ +package card; + +public enum Symbol { + + HEART, + SPADE, + CLOVER, + DIAMOND; +} diff --git a/src/test/java/card/CardTest.java b/src/test/java/card/CardTest.java new file mode 100644 index 0000000000..ab7713183e --- /dev/null +++ b/src/test/java/card/CardTest.java @@ -0,0 +1,16 @@ +package card; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class CardTest { + + @Test + @DisplayName("카드의 점수를 정확하게 계산한다.") + void calculateCardTest() { + Card card = new Card(Symbol.SPADE, Number.ACE); + assertThat(card.getScore()).isEqualTo(1); + } +} From 76ef94b9cac602ded8e446dc060ff034dba354ff Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 15:36:24 +0900 Subject: [PATCH 04/85] =?UTF-8?q?feat(Deck):=20=EB=8D=B1=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=20=ED=95=9C=20=EC=9E=A5=20=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 6 ++++++ src/main/java/card/Card.java | 19 +++++++++++++++++++ src/main/java/card/Deck.java | 18 ++++++++++++++++++ src/test/java/card/DeckTest.java | 26 ++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 src/main/java/card/Deck.java create mode 100644 src/test/java/card/DeckTest.java diff --git a/README.md b/README.md index 4f9dd7939b..b2b9e1a355 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,18 @@ 2. test code에 사용하는 메서드는 `static import`한다. ## 요구사항 +### 카드 - [x] 카드는 모양과 수로 이루어져 있다. - [x] 모양으로는 스페이드, 다이아, 하트, 클로버가 있다. - [x] 수로는 Ace, King, Queen, Jack과 2 이상 10 이하의 정수가 있다. - [x] 카드의 숫자 계산은 카드 숫자를 기본으로 한다. - [ ] Ace는 1 또는 11로 계산할 수 있다. - [x] King, Queen, Jack은 각각 10으로 계산한다. + +### 덱 +- [x] 맨 위의 카드 한 장을 뽑는다. + +--- - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. - [ ] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. - [ ] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. diff --git a/src/main/java/card/Card.java b/src/main/java/card/Card.java index 7c4e5b01d0..68709722d2 100644 --- a/src/main/java/card/Card.java +++ b/src/main/java/card/Card.java @@ -1,5 +1,7 @@ package card; +import java.util.Objects; + public class Card { private final Symbol symbol; @@ -13,4 +15,21 @@ public Card(Symbol symbol, Number number) { int getScore() { return number.getScore(); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Card card = (Card) o; + return symbol == card.symbol && number == card.number; + } + + @Override + public int hashCode() { + return Objects.hash(symbol, number); + } } diff --git a/src/main/java/card/Deck.java b/src/main/java/card/Deck.java new file mode 100644 index 0000000000..2529b4a958 --- /dev/null +++ b/src/main/java/card/Deck.java @@ -0,0 +1,18 @@ +package card; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class Deck { + + private final Queue cards; + + Deck(List cards) { + this.cards = new LinkedList<>(cards); + } + + public Card draw() { + return cards.poll(); + } +} diff --git a/src/test/java/card/DeckTest.java b/src/test/java/card/DeckTest.java new file mode 100644 index 0000000000..374a2063f5 --- /dev/null +++ b/src/test/java/card/DeckTest.java @@ -0,0 +1,26 @@ +package card; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class DeckTest { + + @Test + @DisplayName("덱에서 카드를 뽑는다.") + void createDeckTest() { + // given + List cards = List.of( + new Card(Symbol.HEART, Number.ACE), + new Card(Symbol.CLOVER, Number.EIGHT), + new Card(Symbol.DIAMOND, Number.JACK) + ); + Deck deck = new Deck(cards); + Card expected = new Card(Symbol.HEART, Number.ACE); + // when, then + assertThat(deck.draw()).isEqualTo(expected); + } +} From 3cd8593e1d483b7882519ad79a01851a87ab10a3 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 15:41:16 +0900 Subject: [PATCH 05/85] =?UTF-8?q?feat(Deck):=20=EB=B9=84=EC=96=B4=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EB=8D=B1=EC=97=90=EC=84=9C=20=EB=93=9C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=ED=95=A0=20=EB=95=8C=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 1 + src/main/java/card/Deck.java | 5 ++++- src/test/java/card/DeckTest.java | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b2b9e1a355..f7ab428812 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ ### 덱 - [x] 맨 위의 카드 한 장을 뽑는다. +- [x] 덱에 카드가 없는 경우, 예외를 발생한다. --- - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. diff --git a/src/main/java/card/Deck.java b/src/main/java/card/Deck.java index 2529b4a958..feb4f9f8e6 100644 --- a/src/main/java/card/Deck.java +++ b/src/main/java/card/Deck.java @@ -8,11 +8,14 @@ public class Deck { private final Queue cards; - Deck(List cards) { + public Deck(List cards) { this.cards = new LinkedList<>(cards); } public Card draw() { + if (cards.isEmpty()) { + throw new IllegalStateException("[ERROR] 덱이 비어있습니다."); + } return cards.poll(); } } diff --git a/src/test/java/card/DeckTest.java b/src/test/java/card/DeckTest.java index 374a2063f5..646019d8fa 100644 --- a/src/test/java/card/DeckTest.java +++ b/src/test/java/card/DeckTest.java @@ -6,6 +6,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class DeckTest { @@ -23,4 +24,15 @@ void createDeckTest() { // when, then assertThat(deck.draw()).isEqualTo(expected); } + + @Test + @DisplayName("덱에 카드가 없을 때 뽑는다면 예외를 발생시킨다.") + void emptyDeckDrawTest() { + // given + Deck deck = new Deck(List.of()); + // when, then + assertThatThrownBy(deck::draw) + .isInstanceOf(IllegalStateException.class) + .hasMessage("[ERROR] 덱이 비어있습니다."); + } } From f61ae03146463cda740e4e8248faa8569c43d269 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 15:51:26 +0900 Subject: [PATCH 06/85] =?UTF-8?q?feat(Player):=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=20=EC=A0=90=EC=88=98=20=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 4 ++++ src/main/java/card/Card.java | 2 +- src/main/java/player/Player.java | 26 ++++++++++++++++++++++++++ src/test/java/player/PlayerTest.java | 28 ++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/main/java/player/Player.java create mode 100644 src/test/java/player/PlayerTest.java diff --git a/README.md b/README.md index f7ab428812..3a4945b973 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,10 @@ - [x] 맨 위의 카드 한 장을 뽑는다. - [x] 덱에 카드가 없는 경우, 예외를 발생한다. +### 플레이어 +- [x] 덱에서 카드를 한 장 뽑는다. +- [x] 지금까지 뽑은 카드의 점수를 계산한다. + --- - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. - [ ] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. diff --git a/src/main/java/card/Card.java b/src/main/java/card/Card.java index 68709722d2..6a0b35ac95 100644 --- a/src/main/java/card/Card.java +++ b/src/main/java/card/Card.java @@ -12,7 +12,7 @@ public Card(Symbol symbol, Number number) { this.number = number; } - int getScore() { + public int getScore() { return number.getScore(); } diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java new file mode 100644 index 0000000000..eb8d09698f --- /dev/null +++ b/src/main/java/player/Player.java @@ -0,0 +1,26 @@ +package player; + +import card.Card; +import card.Deck; + +import java.util.ArrayList; +import java.util.List; + +public class Player { + + private final List cards; + + public Player() { + this.cards = new ArrayList<>(); + } + + public void drawCard(Deck deck) { + cards.add(deck.draw()); + } + + public int calculateScore() { + return cards.stream() + .map(Card::getScore) + .reduce(0, Integer::sum); + } +} \ No newline at end of file diff --git a/src/test/java/player/PlayerTest.java b/src/test/java/player/PlayerTest.java new file mode 100644 index 0000000000..6655229ecb --- /dev/null +++ b/src/test/java/player/PlayerTest.java @@ -0,0 +1,28 @@ +package player; + +import card.Card; +import card.Deck; +import card.Number; +import card.Symbol; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class PlayerTest { + + @Test + @DisplayName("플레이어의 점수를 계산한다.") + void calculateScoreTest() { + // given + Player player = new Player(); + Deck deck = new Deck(List.of(new Card(Symbol.SPADE, Number.KING), new Card(Symbol.HEART, Number.EIGHT))); + // when + player.drawCard(deck); + player.drawCard(deck); + // then + assertThat(player.calculateScore()).isEqualTo(18); + } +} From be2c34802cb5eadf32ba04f540f79f600761f861 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 16:31:23 +0900 Subject: [PATCH 07/85] =?UTF-8?q?feat(Dealer):=20=EB=94=9C=EB=9F=AC?= =?UTF-8?q?=EC=9D=98=20=EC=A0=90=EC=88=98=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EB=93=9C=EB=A1=9C=EC=9A=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 5 ++++- src/main/java/player/Dealer.java | 19 ++++++++++++++++ src/test/java/player/DealerTest.java | 33 ++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/main/java/player/Dealer.java create mode 100644 src/test/java/player/DealerTest.java diff --git a/README.md b/README.md index 3a4945b973..feea9804b7 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,16 @@ - [x] 덱에서 카드를 한 장 뽑는다. - [x] 지금까지 뽑은 카드의 점수를 계산한다. +### 딜러 +- [x] 플레이어의 기능을 상속한다. +- [x] 17점 이상이 될 때까지 카드를 계속 뽑는다. + --- - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. - [ ] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. - [ ] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. - [ ] 플레이어의 카드는 모두에게 공개된다. - [ ] 딜러의 두 번째 카드는 공개되지 않는다. -- [ ] 딜러는 처음에 받은 2장의 합계가 16 이하이면 1장의 카드를 추가로 받는다. - [ ] 각 플레이어는 딜러와만 승패를 겨룬다. - [ ] 딜러는 모든 플레이어와 승패를 겨룬다. - [ ] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 승패를 출력한다. diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java new file mode 100644 index 0000000000..2550a867c7 --- /dev/null +++ b/src/main/java/player/Dealer.java @@ -0,0 +1,19 @@ +package player; + +import card.Deck; + +public class Dealer extends Player { + + private static final int MAX_DRAWABLE_SCORE = 16; + + @Override + public void drawCard(Deck deck) { + while (hasDrawableScore()) { + super.drawCard(deck); + } + } + + private boolean hasDrawableScore() { + return calculateScore() <= MAX_DRAWABLE_SCORE; + } +} diff --git a/src/test/java/player/DealerTest.java b/src/test/java/player/DealerTest.java new file mode 100644 index 0000000000..8b793f364e --- /dev/null +++ b/src/test/java/player/DealerTest.java @@ -0,0 +1,33 @@ +package player; + +import card.Card; +import card.Deck; +import card.Number; +import card.Symbol; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class DealerTest { + + @Test + @DisplayName("딜러는 17 이상이 될 때까지 카드를 계속 뽑는다.") + void dealerDrawTest() { + // given + Dealer dealer = new Dealer(); + List cards = List.of( + new Card(Symbol.HEART, Number.JACK), + new Card(Symbol.DIAMOND, Number.SIX), + new Card(Symbol.CLOVER, Number.THREE), + new Card(Symbol.CLOVER, Number.FIVE) + ); + Deck deck = new Deck(cards); + // when + dealer.drawCard(deck); + // then + assertThat(dealer.calculateScore()).isEqualTo(19); + } +} From cc38fcc4d57ac2dd6ad26d451fd01b5ec69f3402 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 16:50:17 +0900 Subject: [PATCH 08/85] =?UTF-8?q?feat(Dealer):=20=EC=A3=BC=EC=96=B4?= =?UTF-8?q?=EC=A7=84=20=EC=A0=90=EC=88=98=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EC=8A=B9=ED=8C=A8=20=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 1 + src/main/java/player/Dealer.java | 5 +++++ src/test/java/player/DealerTest.java | 16 ++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/README.md b/README.md index feea9804b7..6f19a48762 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ ### 딜러 - [x] 플레이어의 기능을 상속한다. - [x] 17점 이상이 될 때까지 카드를 계속 뽑는다. +- [x] 상대의 점수가 주어지면, 자신의 점수와 비교해 승패를 결정한다. --- - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index 2550a867c7..e742040a47 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -16,4 +16,9 @@ public void drawCard(Deck deck) { private boolean hasDrawableScore() { return calculateScore() <= MAX_DRAWABLE_SCORE; } + + public boolean determineResult(int score) { + // TODO: 무승부 처리 + return calculateScore() > score; + } } diff --git a/src/test/java/player/DealerTest.java b/src/test/java/player/DealerTest.java index 8b793f364e..18c9c8f263 100644 --- a/src/test/java/player/DealerTest.java +++ b/src/test/java/player/DealerTest.java @@ -10,6 +10,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; class DealerTest { @@ -30,4 +31,19 @@ void dealerDrawTest() { // then assertThat(dealer.calculateScore()).isEqualTo(19); } + + @Test + @DisplayName("딜러는 플레이어의 점수를 받아 승패를 결정한다") + void determineWinnerTest() { + // given + Dealer dealer = new Dealer(); + List cards = List.of(new Card(Symbol.SPADE, Number.TEN), new Card(Symbol.HEART, Number.KING)); + Deck deck = new Deck(cards); + dealer.drawCard(deck); + // when, then + assertAll( + () -> assertThat(dealer.determineResult(19)).isTrue(), + () -> assertThat(dealer.determineResult(21)).isFalse() + ); + } } From 959c90562756436bbf59bafbec1e13dadefe9c98 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 17:54:39 +0900 Subject: [PATCH 09/85] =?UTF-8?q?feat(Hand):=20Ace=20=EC=A0=90=EC=88=98?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=A0=EB=A6=AC=ED=95=9C=20=EB=B0=A9=ED=96=A5?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기능을 추가하며 클래스 분리 (Player -> Hand) Co-authored-by: donghoony --- README.md | 2 +- src/main/java/card/Card.java | 4 +++ src/main/java/card/Hand.java | 47 +++++++++++++++++++++++++ src/main/java/player/Dealer.java | 15 ++------ src/main/java/player/Player.java | 19 +++-------- src/test/java/card/HandTest.java | 51 ++++++++++++++++++++++++++++ src/test/java/player/DealerTest.java | 19 +++++++++-- src/test/java/player/PlayerTest.java | 23 ------------- 8 files changed, 128 insertions(+), 52 deletions(-) create mode 100644 src/main/java/card/Hand.java create mode 100644 src/test/java/card/HandTest.java diff --git a/README.md b/README.md index 6f19a48762..f106af208e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - [x] 모양으로는 스페이드, 다이아, 하트, 클로버가 있다. - [x] 수로는 Ace, King, Queen, Jack과 2 이상 10 이하의 정수가 있다. - [x] 카드의 숫자 계산은 카드 숫자를 기본으로 한다. - - [ ] Ace는 1 또는 11로 계산할 수 있다. + - [x] Ace는 1 또는 11로 계산할 수 있다. - [x] King, Queen, Jack은 각각 10으로 계산한다. ### 덱 diff --git a/src/main/java/card/Card.java b/src/main/java/card/Card.java index 6a0b35ac95..484e8f45f0 100644 --- a/src/main/java/card/Card.java +++ b/src/main/java/card/Card.java @@ -12,6 +12,10 @@ public Card(Symbol symbol, Number number) { this.number = number; } + public boolean isAce() { + return this.number == Number.ACE; + } + public int getScore() { return number.getScore(); } diff --git a/src/main/java/card/Hand.java b/src/main/java/card/Hand.java new file mode 100644 index 0000000000..7cb36ead3a --- /dev/null +++ b/src/main/java/card/Hand.java @@ -0,0 +1,47 @@ +package card; + +import java.util.ArrayList; +import java.util.List; + +public class Hand { + + private final List cards; + + public Hand() { + this(new ArrayList<>()); + } + + Hand(List cards) { + this.cards = cards; + } + + public int calculateScore() { + int maximumScore = calculateMaximumScore(); + int minimumScore = calculateMinimumScore(); + + if (maximumScore > 21) { + return minimumScore; + } + return maximumScore; + } + + private int calculateMinimumScore() { + return cards.stream() + .map(Card::getScore) + .reduce(0, Integer::sum); + } + + private int calculateMaximumScore() { + int score = calculateMinimumScore(); + boolean isAce = cards.stream().anyMatch(Card::isAce); + + if (isAce) { + return score + 10; + } + return score; + } + + public void addCard(Card card) { + cards.add(card); + } +} diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index e742040a47..e96259cc12 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -1,24 +1,15 @@ package player; -import card.Deck; - public class Dealer extends Player { private static final int MAX_DRAWABLE_SCORE = 16; - @Override - public void drawCard(Deck deck) { - while (hasDrawableScore()) { - super.drawCard(deck); - } - } - - private boolean hasDrawableScore() { - return calculateScore() <= MAX_DRAWABLE_SCORE; + public boolean hasDrawableScore() { + return hand.calculateScore() <= MAX_DRAWABLE_SCORE; } public boolean determineResult(int score) { // TODO: 무승부 처리 - return calculateScore() > score; + return hand.calculateScore() > score; } } diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index eb8d09698f..300d175242 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -1,26 +1,17 @@ package player; -import card.Card; import card.Deck; - -import java.util.ArrayList; -import java.util.List; +import card.Hand; public class Player { - private final List cards; + protected final Hand hand; public Player() { - this.cards = new ArrayList<>(); + this.hand = new Hand(); } public void drawCard(Deck deck) { - cards.add(deck.draw()); - } - - public int calculateScore() { - return cards.stream() - .map(Card::getScore) - .reduce(0, Integer::sum); + hand.addCard(deck.draw()); } -} \ No newline at end of file +} diff --git a/src/test/java/card/HandTest.java b/src/test/java/card/HandTest.java new file mode 100644 index 0000000000..8a44939c19 --- /dev/null +++ b/src/test/java/card/HandTest.java @@ -0,0 +1,51 @@ +package card; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class HandTest { + + @Test + @DisplayName("플레이어의 점수를 계산한다.") + void calculateScoreTest() { + // given + List cards = List.of( + new Card(Symbol.SPADE, Number.KING), + new Card(Symbol.HEART, Number.EIGHT) + ); + Hand hand = new Hand(cards); + // when, then + assertThat(hand.calculateScore()).isEqualTo(18); + } + + @Test + @DisplayName("플레이어의 점수를 계산할 때, Ace의 점수를 유리한 방향(11)으로 결정한다.") + void calculateAceAsElevenTest() { + // given + List cards = List.of( + new Card(Symbol.HEART, Number.TEN), + new Card(Symbol.CLOVER, Number.ACE) + ); + Hand hand = new Hand(cards); + // when, then + assertThat(hand.calculateScore()).isEqualTo(21); + } + + @Test + @DisplayName("플레이어의 점수를 계산할 때, Ace의 점수를 유리한 방향(1)으로 결정한다.") + void calculateAceAsOneTest() { + // given + List cards = List.of( + new Card(Symbol.HEART, Number.TEN), + new Card(Symbol.CLOVER, Number.ACE), + new Card(Symbol.DIAMOND, Number.TEN) + ); + Hand hand = new Hand(cards); + // when, then + assertThat(hand.calculateScore()).isEqualTo(21); + } +} diff --git a/src/test/java/player/DealerTest.java b/src/test/java/player/DealerTest.java index 18c9c8f263..0cb9a02c9e 100644 --- a/src/test/java/player/DealerTest.java +++ b/src/test/java/player/DealerTest.java @@ -28,8 +28,19 @@ void dealerDrawTest() { Deck deck = new Deck(cards); // when dealer.drawCard(deck); + boolean isDrawable1 = dealer.hasDrawableScore(); + + dealer.drawCard(deck); + boolean isDrawable2 = dealer.hasDrawableScore(); + + dealer.drawCard(deck); + boolean isDrawable3 = dealer.hasDrawableScore(); // then - assertThat(dealer.calculateScore()).isEqualTo(19); + assertAll( + () -> assertThat(isDrawable1).isTrue(), + () -> assertThat(isDrawable2).isTrue(), + () -> assertThat(isDrawable3).isFalse() + ); } @Test @@ -37,9 +48,13 @@ void dealerDrawTest() { void determineWinnerTest() { // given Dealer dealer = new Dealer(); - List cards = List.of(new Card(Symbol.SPADE, Number.TEN), new Card(Symbol.HEART, Number.KING)); + List cards = List.of( + new Card(Symbol.SPADE, Number.TEN), + new Card(Symbol.HEART, Number.KING) + ); Deck deck = new Deck(cards); dealer.drawCard(deck); + dealer.drawCard(deck); // when, then assertAll( () -> assertThat(dealer.determineResult(19)).isTrue(), diff --git a/src/test/java/player/PlayerTest.java b/src/test/java/player/PlayerTest.java index 6655229ecb..3c86f51013 100644 --- a/src/test/java/player/PlayerTest.java +++ b/src/test/java/player/PlayerTest.java @@ -1,28 +1,5 @@ package player; -import card.Card; -import card.Deck; -import card.Number; -import card.Symbol; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - class PlayerTest { - @Test - @DisplayName("플레이어의 점수를 계산한다.") - void calculateScoreTest() { - // given - Player player = new Player(); - Deck deck = new Deck(List.of(new Card(Symbol.SPADE, Number.KING), new Card(Symbol.HEART, Number.EIGHT))); - // when - player.drawCard(deck); - player.drawCard(deck); - // then - assertThat(player.calculateScore()).isEqualTo(18); - } } From 4b040931200bd5869ac7b15392a372b9aa1a7f9d Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 20:03:38 +0900 Subject: [PATCH 10/85] =?UTF-8?q?refactor(Player):=20=EB=93=9C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EA=B0=80=EB=8A=A5=20=EC=97=AC=EB=B6=80=20=ED=8C=90?= =?UTF-8?q?=EB=8B=A8=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/player/Dealer.java | 6 ------ src/main/java/player/Player.java | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index e96259cc12..bc72f00e1b 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -2,12 +2,6 @@ public class Dealer extends Player { - private static final int MAX_DRAWABLE_SCORE = 16; - - public boolean hasDrawableScore() { - return hand.calculateScore() <= MAX_DRAWABLE_SCORE; - } - public boolean determineResult(int score) { // TODO: 무승부 처리 return hand.calculateScore() > score; diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index 300d175242..efd5f915ec 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -5,6 +5,8 @@ public class Player { + private static final int MAX_DRAWABLE_SCORE = 16; + protected final Hand hand; public Player() { @@ -14,4 +16,8 @@ public Player() { public void drawCard(Deck deck) { hand.addCard(deck.draw()); } + + public boolean hasDrawableScore() { + return hand.calculateScore() <= MAX_DRAWABLE_SCORE; + } } From a10af0caa4f028768bb846be10da555442dec3d2 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 20:26:10 +0900 Subject: [PATCH 11/85] =?UTF-8?q?feat(Name):=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 5 ++++ src/main/java/player/Name.java | 28 ++++++++++++++++++++++ src/test/java/player/NameTest.java | 37 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/main/java/player/Name.java create mode 100644 src/test/java/player/NameTest.java diff --git a/README.md b/README.md index f106af208e..24b365e705 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,11 @@ - [x] 덱에서 카드를 한 장 뽑는다. - [x] 지금까지 뽑은 카드의 점수를 계산한다. +### 이름 +- [x] 이름은 2글자 이상 5글자 이하이다. +- [x] 이름은 공백으로만 구성될 수 없다. +- [ ] 이름은 중복될 수 없다. + ### 딜러 - [x] 플레이어의 기능을 상속한다. - [x] 17점 이상이 될 때까지 카드를 계속 뽑는다. diff --git a/src/main/java/player/Name.java b/src/main/java/player/Name.java new file mode 100644 index 0000000000..ce8c81148c --- /dev/null +++ b/src/main/java/player/Name.java @@ -0,0 +1,28 @@ +package player; + +public class Name { + + private final String name; + + public Name(String name) { + validateName(name); + this.name = name; + } + + private void validateName(String name) { + validateNonBlankName(name); + validateNameLength(name); + } + + private void validateNameLength(String name) { + if (name.length() < 2 || name.length() > 5) { + throw new IllegalArgumentException("[ERROR] 이름은 2글자 이상 5글자 이하여야 합니다."); + } + } + + private void validateNonBlankName(String name) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("[ERROR] 이름은 공백일 수 없습니다."); + } + } +} diff --git a/src/test/java/player/NameTest.java b/src/test/java/player/NameTest.java new file mode 100644 index 0000000000..0e39e3bd5f --- /dev/null +++ b/src/test/java/player/NameTest.java @@ -0,0 +1,37 @@ +package player; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +class NameTest { + + @ParameterizedTest + @ValueSource(strings = {"12", "12345"}) + @DisplayName("이름이 잘 생성된다.") + void validNameTest(String name) { + assertDoesNotThrow(() -> new Name(name)); + } + + @ParameterizedTest + @NullAndEmptySource + @DisplayName("이름이 공백으로 이루어진 경우 예외를 발생시킨다.") + void blankNameTest(String name) { + assertThatThrownBy(() -> new Name(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이름은 공백일 수 없습니다."); + } + + @ParameterizedTest + @ValueSource(strings = {"a", "abcdef"}) + @DisplayName("이름이 길이 제한을 어기는 경우 예외를 발생시킨다.") + void longNameTest(String name) { + assertThatThrownBy(() -> new Name(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이름은 2글자 이상 5글자 이하여야 합니다."); + } +} From 48dc12da2697c01d47b3164d9a22d4dd6eb09fb1 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 20:53:17 +0900 Subject: [PATCH 12/85] =?UTF-8?q?feat(Players):=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EB=93=A4=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 5 ++- src/main/java/player/Dealer.java | 4 +++ src/main/java/player/Name.java | 2 +- src/main/java/player/Player.java | 4 ++- src/main/java/player/Players.java | 42 ++++++++++++++++++++++ src/test/java/player/PlayersTest.java | 52 +++++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 src/main/java/player/Players.java create mode 100644 src/test/java/player/PlayersTest.java diff --git a/README.md b/README.md index 24b365e705..af4efe3049 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,10 @@ ### 이름 - [x] 이름은 2글자 이상 5글자 이하이다. - [x] 이름은 공백으로만 구성될 수 없다. -- [ ] 이름은 중복될 수 없다. + +### 플레이어들 +- [x] 플레이어들의 이름은 중복될 수 없다. +- [x] 플레이어들의 인원수는 1명 이상 10명 이하이다. ### 딜러 - [x] 플레이어의 기능을 상속한다. diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index bc72f00e1b..28ba1f8e61 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -2,6 +2,10 @@ public class Dealer extends Player { + public Dealer() { + super("딜러"); + } + public boolean determineResult(int score) { // TODO: 무승부 처리 return hand.calculateScore() > score; diff --git a/src/main/java/player/Name.java b/src/main/java/player/Name.java index ce8c81148c..bfe8c12c9b 100644 --- a/src/main/java/player/Name.java +++ b/src/main/java/player/Name.java @@ -4,7 +4,7 @@ public class Name { private final String name; - public Name(String name) { + Name(String name) { validateName(name); this.name = name; } diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index efd5f915ec..57cea777d9 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -7,9 +7,11 @@ public class Player { private static final int MAX_DRAWABLE_SCORE = 16; + private final Name name; protected final Hand hand; - public Player() { + Player(String name) { + this.name = new Name(name); this.hand = new Hand(); } diff --git a/src/main/java/player/Players.java b/src/main/java/player/Players.java new file mode 100644 index 0000000000..83a0e390df --- /dev/null +++ b/src/main/java/player/Players.java @@ -0,0 +1,42 @@ +package player; + +import java.util.List; + +public class Players { + + private final List players; + + public Players(List playerNames) { + validatePlayers(playerNames); + this.players = playerNames.stream() + .map(Player::new) + .toList(); + } + + private void validatePlayers(List playerNames) { + validateNotNull(playerNames); + validateSize(playerNames); + validateUniqueNames(playerNames); + } + + private void validateNotNull(List playerNames) { + if (playerNames == null) { + throw new IllegalArgumentException("[ERROR] 플레이어로 null이 전달되었습니다."); + } + } + + private void validateSize(List playerNames) { + if (playerNames.size() < 1 || playerNames.size() > 10) { + throw new IllegalArgumentException("[ERROR] 플레이어의 수는 1명 이상 10명 이하여야 합니다."); + } + } + + private void validateUniqueNames(List playerNames) { + int distinctNameCount = (int) playerNames.stream() + .distinct() + .count(); + if (distinctNameCount != playerNames.size()) { + throw new IllegalArgumentException("[ERROR] 이름은 중복될 수 없습니다."); + } + } +} diff --git a/src/test/java/player/PlayersTest.java b/src/test/java/player/PlayersTest.java new file mode 100644 index 0000000000..a9c701617b --- /dev/null +++ b/src/test/java/player/PlayersTest.java @@ -0,0 +1,52 @@ +package player; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PlayersTest { + + @Test + @DisplayName("플레이어의 이름이 중복될 경우 예외를 발생시킨다") + void duplicateNameTest() { + // given + List names = List.of("aru", "atto", "aru"); + // when, then + assertThatThrownBy(() -> new Players(names)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이름은 중복될 수 없습니다."); + } + + @Test + @DisplayName("플레이어의 수가 제한을 초과하는 경우 예외를 발생시킨다.") + void exceedingPlayersSizeTest() { + // given + List playerNames = List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"); + // when, then + assertThatThrownBy(() -> new Players(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 플레이어의 수는 1명 이상 10명 이하여야 합니다."); + } + + @Test + @DisplayName("플레이어가 없는 경우 예외를 발생시킨다.") + void emptyPlayersSizeTest() { + // given + List playerNames = List.of(); + // when, then + assertThatThrownBy(() -> new Players(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 플레이어의 수는 1명 이상 10명 이하여야 합니다."); + } + + @Test + @DisplayName("플레이어로 null이 전달되는 경우 예외를 발생시킨다.") + void nullPlayerTest() { + assertThatThrownBy(() -> new Players(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 플레이어로 null이 전달되었습니다."); + } +} From c305c4102cdda75603efd716b5c37fb9bdd2aa2c Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 5 Mar 2024 21:55:08 +0900 Subject: [PATCH 13/85] =?UTF-8?q?feat(View):=20=EC=BD=98=EC=86=94=20?= =?UTF-8?q?=EC=9E=85=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/view/InputView.java | 20 +++++++++++ src/main/java/view/OutputView.java | 54 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/OutputView.java diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000000..f5383e2553 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,20 @@ +package view; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private final Scanner scanner = new Scanner(System.in); + + public List readNames() { + String input = scanner.nextLine(); + String[] names = input.split(","); + return Arrays.stream(names).toList(); + } + + public String readCommand() { + return scanner.nextLine(); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000000..ea9f293ea8 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,54 @@ +package view; + +import java.util.List; + +public class OutputView { + + public void printNamesRequest() { + System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); + } + + public void printInitializeBlackJack(List names) { + System.out.println("딜러와 " + String.join(", ", names) + "에게 2장을 나누었습니다."); + } + + public void printDealerCards(String card) { + System.out.println("딜러: " + card); + } + + public void printPlayerCards(String name, List cards) { + System.out.println(name + "카드: " + String.join(", ", cards)); + } + + public void printDrawMoreCardRequest(String name) { + System.out.println(name + "은(는) 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)"); + } + + public void printDealerDrawCard() { + System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); + } + + public void printDealerCardsWithResult(List cards, int score) { + System.out.println("딜러 카드: " + String.join(", ", cards) + " - 결과: " + score + "점"); + } + + public void printPlayerCardsWithResult(String name, List cards, int score) { + System.out.println(name + " 카드: " + String.join(", ", cards) + " - 결과: " + score + "점"); + } + + public void printResultStart() { + System.out.println("## 최종 승패"); + } + + public void printDealerResult(int winCount, int loseCount) { + System.out.println("딜러: " + winCount + "승 " + loseCount + "패"); + } + + public void printPlayerResult(String name, boolean isWin) { + if (isWin) { + System.out.println(name + ": 승"); + return; + } + System.out.println(name + ": 패"); + } +} From 7ceb8bab60824f8b986efd6f2a1786e8a1d5bd5f Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 6 Mar 2024 14:36:40 +0900 Subject: [PATCH 14/85] =?UTF-8?q?feat(CardDisplay):=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EC=9D=98=20=EB=AA=A8=EC=96=91=EA=B3=BC=20=EC=88=98=EC=9D=98=20?= =?UTF-8?q?=ED=91=9C=ED=98=84=20=EB=B0=A9=EC=8B=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/card/Card.java | 10 ++--- .../java/card/{Symbol.java => Shape.java} | 2 +- src/main/java/view/CardNumberDisplay.java | 37 +++++++++++++++++++ src/main/java/view/CardShapeDisplay.java | 28 ++++++++++++++ src/test/java/card/CardTest.java | 2 +- src/test/java/card/DeckTest.java | 8 ++-- src/test/java/card/HandTest.java | 14 +++---- src/test/java/player/DealerTest.java | 14 +++---- 8 files changed, 90 insertions(+), 25 deletions(-) rename src/main/java/card/{Symbol.java => Shape.java} (75%) create mode 100644 src/main/java/view/CardNumberDisplay.java create mode 100644 src/main/java/view/CardShapeDisplay.java diff --git a/src/main/java/card/Card.java b/src/main/java/card/Card.java index 484e8f45f0..03ed157b68 100644 --- a/src/main/java/card/Card.java +++ b/src/main/java/card/Card.java @@ -4,11 +4,11 @@ public class Card { - private final Symbol symbol; + private final Shape shape; private final Number number; - public Card(Symbol symbol, Number number) { - this.symbol = symbol; + public Card(Shape shape, Number number) { + this.shape = shape; this.number = number; } @@ -29,11 +29,11 @@ public boolean equals(Object o) { return false; } Card card = (Card) o; - return symbol == card.symbol && number == card.number; + return shape == card.shape && number == card.number; } @Override public int hashCode() { - return Objects.hash(symbol, number); + return Objects.hash(shape, number); } } diff --git a/src/main/java/card/Symbol.java b/src/main/java/card/Shape.java similarity index 75% rename from src/main/java/card/Symbol.java rename to src/main/java/card/Shape.java index 9678c1ef1c..b7f2c3dace 100644 --- a/src/main/java/card/Symbol.java +++ b/src/main/java/card/Shape.java @@ -1,6 +1,6 @@ package card; -public enum Symbol { +public enum Shape { HEART, SPADE, diff --git a/src/main/java/view/CardNumberDisplay.java b/src/main/java/view/CardNumberDisplay.java new file mode 100644 index 0000000000..5c2620d47b --- /dev/null +++ b/src/main/java/view/CardNumberDisplay.java @@ -0,0 +1,37 @@ +package view; + +import card.Number; + +import java.util.Arrays; + +public enum CardNumberDisplay { + + ACE(Number.ACE, "A"), + TWO(Number.TWO, "2"), + THREE(Number.THREE, "3"), + FOUR(Number.FOUR, "4"), + FIVE(Number.FIVE, "5"), + SIX(Number.SIX, "6"), + SEVEN(Number.SEVEN, "7"), + EIGHT(Number.EIGHT, "8"), + NINE(Number.NINE, "9"), + TEN(Number.TEN, "10"), + JACK(Number.JACK, "J"), + QUEEN(Number.QUEEN, "Q"), + KING(Number.KING, "K"); + + private final Number number; + private final String display; + + CardNumberDisplay(Number number, String display) { + this.number = number; + this.display = display; + } + + public static CardNumberDisplay fromNumber(Number number) { + return Arrays.stream(CardNumberDisplay.values()) + .filter(displayNumber -> displayNumber.number == number) + .findFirst() + .orElseThrow(); + } +} diff --git a/src/main/java/view/CardShapeDisplay.java b/src/main/java/view/CardShapeDisplay.java new file mode 100644 index 0000000000..3e5ea8a6d3 --- /dev/null +++ b/src/main/java/view/CardShapeDisplay.java @@ -0,0 +1,28 @@ +package view; + +import card.Shape; + +import java.util.Arrays; + +public enum CardShapeDisplay { + + HEART(Shape.HEART, "하트"), + SPADE(Shape.SPADE, "스페이드"), + CLOVER(Shape.CLOVER, "클로버"), + DIAMOND(Shape.DIAMOND, "다이아몬드"); + + private final Shape shape; + private final String display; + + CardShapeDisplay(Shape shape, String display) { + this.shape = shape; + this.display = display; + } + + public static CardShapeDisplay fromShape(Shape shape) { + return Arrays.stream(CardShapeDisplay.values()) + .filter(displayShape -> displayShape.shape == shape) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 모양입니다.")); + } +} diff --git a/src/test/java/card/CardTest.java b/src/test/java/card/CardTest.java index ab7713183e..464033b1b1 100644 --- a/src/test/java/card/CardTest.java +++ b/src/test/java/card/CardTest.java @@ -10,7 +10,7 @@ class CardTest { @Test @DisplayName("카드의 점수를 정확하게 계산한다.") void calculateCardTest() { - Card card = new Card(Symbol.SPADE, Number.ACE); + Card card = new Card(Shape.SPADE, Number.ACE); assertThat(card.getScore()).isEqualTo(1); } } diff --git a/src/test/java/card/DeckTest.java b/src/test/java/card/DeckTest.java index 646019d8fa..ce383486a7 100644 --- a/src/test/java/card/DeckTest.java +++ b/src/test/java/card/DeckTest.java @@ -15,12 +15,12 @@ class DeckTest { void createDeckTest() { // given List cards = List.of( - new Card(Symbol.HEART, Number.ACE), - new Card(Symbol.CLOVER, Number.EIGHT), - new Card(Symbol.DIAMOND, Number.JACK) + new Card(Shape.HEART, Number.ACE), + new Card(Shape.CLOVER, Number.EIGHT), + new Card(Shape.DIAMOND, Number.JACK) ); Deck deck = new Deck(cards); - Card expected = new Card(Symbol.HEART, Number.ACE); + Card expected = new Card(Shape.HEART, Number.ACE); // when, then assertThat(deck.draw()).isEqualTo(expected); } diff --git a/src/test/java/card/HandTest.java b/src/test/java/card/HandTest.java index 8a44939c19..a837dab004 100644 --- a/src/test/java/card/HandTest.java +++ b/src/test/java/card/HandTest.java @@ -14,8 +14,8 @@ public class HandTest { void calculateScoreTest() { // given List cards = List.of( - new Card(Symbol.SPADE, Number.KING), - new Card(Symbol.HEART, Number.EIGHT) + new Card(Shape.SPADE, Number.KING), + new Card(Shape.HEART, Number.EIGHT) ); Hand hand = new Hand(cards); // when, then @@ -27,8 +27,8 @@ void calculateScoreTest() { void calculateAceAsElevenTest() { // given List cards = List.of( - new Card(Symbol.HEART, Number.TEN), - new Card(Symbol.CLOVER, Number.ACE) + new Card(Shape.HEART, Number.TEN), + new Card(Shape.CLOVER, Number.ACE) ); Hand hand = new Hand(cards); // when, then @@ -40,9 +40,9 @@ void calculateAceAsElevenTest() { void calculateAceAsOneTest() { // given List cards = List.of( - new Card(Symbol.HEART, Number.TEN), - new Card(Symbol.CLOVER, Number.ACE), - new Card(Symbol.DIAMOND, Number.TEN) + new Card(Shape.HEART, Number.TEN), + new Card(Shape.CLOVER, Number.ACE), + new Card(Shape.DIAMOND, Number.TEN) ); Hand hand = new Hand(cards); // when, then diff --git a/src/test/java/player/DealerTest.java b/src/test/java/player/DealerTest.java index 0cb9a02c9e..a59fc4821b 100644 --- a/src/test/java/player/DealerTest.java +++ b/src/test/java/player/DealerTest.java @@ -3,7 +3,7 @@ import card.Card; import card.Deck; import card.Number; -import card.Symbol; +import card.Shape; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,10 +20,10 @@ void dealerDrawTest() { // given Dealer dealer = new Dealer(); List cards = List.of( - new Card(Symbol.HEART, Number.JACK), - new Card(Symbol.DIAMOND, Number.SIX), - new Card(Symbol.CLOVER, Number.THREE), - new Card(Symbol.CLOVER, Number.FIVE) + new Card(Shape.HEART, Number.JACK), + new Card(Shape.DIAMOND, Number.SIX), + new Card(Shape.CLOVER, Number.THREE), + new Card(Shape.CLOVER, Number.FIVE) ); Deck deck = new Deck(cards); // when @@ -49,8 +49,8 @@ void determineWinnerTest() { // given Dealer dealer = new Dealer(); List cards = List.of( - new Card(Symbol.SPADE, Number.TEN), - new Card(Symbol.HEART, Number.KING) + new Card(Shape.SPADE, Number.TEN), + new Card(Shape.HEART, Number.KING) ); Deck deck = new Deck(cards); dealer.drawCard(deck); From 9608cafbd3d9bde5f45b50bd43a46c2299bf0ad1 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 6 Mar 2024 16:07:36 +0900 Subject: [PATCH 15/85] =?UTF-8?q?refactor(Player):=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EC=83=81=EC=88=98=20=EC=B6=94=EC=B6=9C=20=EB=B0=8F=20=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EC=A1=B0=EA=B1=B4=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: donghoony --- src/main/java/game/BlackJackGame.java | 6 ++++++ src/main/java/player/Dealer.java | 8 +++++--- src/main/java/player/Player.java | 5 ++--- 3 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 src/main/java/game/BlackJackGame.java diff --git a/src/main/java/game/BlackJackGame.java b/src/main/java/game/BlackJackGame.java new file mode 100644 index 0000000000..483e17c1d1 --- /dev/null +++ b/src/main/java/game/BlackJackGame.java @@ -0,0 +1,6 @@ +package game; + +public class BlackJackGame { + + public static final int BLACKJACK_MAX_SCORE = 21; +} diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index 28ba1f8e61..1a972adb98 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -2,12 +2,14 @@ public class Dealer extends Player { + private static final int MAX_DRAWABLE_SCORE = 16; + public Dealer() { super("딜러"); } - public boolean determineResult(int score) { - // TODO: 무승부 처리 - return hand.calculateScore() > score; + @Override + public boolean hasDrawableScore() { + return hand.calculateScore() <= MAX_DRAWABLE_SCORE; } } diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index 57cea777d9..83cdfe190d 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -2,11 +2,10 @@ import card.Deck; import card.Hand; +import game.BlackJackGame; public class Player { - private static final int MAX_DRAWABLE_SCORE = 16; - private final Name name; protected final Hand hand; @@ -20,6 +19,6 @@ public void drawCard(Deck deck) { } public boolean hasDrawableScore() { - return hand.calculateScore() <= MAX_DRAWABLE_SCORE; + return hand.calculateScore() < BlackJackGame.BLACKJACK_MAX_SCORE; } } From 4ec8b0e89ffb8a9720d2f7ee4366f87cfcedca96 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 6 Mar 2024 16:12:52 +0900 Subject: [PATCH 16/85] =?UTF-8?q?feat(MatchResult):=20=EA=B2=8C=EC=9E=84?= =?UTF-8?q?=20=EA=B2=B0=EA=B3=BC=20=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 8 ++++- src/main/java/game/MatchResult.java | 28 ++++++++++++++++ src/test/java/game/MatchResultTest.java | 43 +++++++++++++++++++++++++ src/test/java/player/DealerTest.java | 19 ----------- 4 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 src/main/java/game/MatchResult.java create mode 100644 src/test/java/game/MatchResultTest.java diff --git a/README.md b/README.md index af4efe3049..b152e82319 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,13 @@ ### 딜러 - [x] 플레이어의 기능을 상속한다. - [x] 17점 이상이 될 때까지 카드를 계속 뽑는다. -- [x] 상대의 점수가 주어지면, 자신의 점수와 비교해 승패를 결정한다. + +### 게임 결과 +- [x] 게임 결과를 아래의 순서대로 올바르게 판단한다. + 1. 플레이어의 점수가 21점을 초과하면 딜러가 승리한다. + 2. 플레이어의 점수가 21점을 초과하지 않으면서 딜러의 점수가 21점을 초과하면 플레이어가 승리한다. + 3. 딜러와 플레이어의 점수를 비교해 승패를 결정한다. + 4. 점수가 같으면 무승부이다. --- - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. diff --git a/src/main/java/game/MatchResult.java b/src/main/java/game/MatchResult.java new file mode 100644 index 0000000000..c68ca42ace --- /dev/null +++ b/src/main/java/game/MatchResult.java @@ -0,0 +1,28 @@ +package game; + +public enum MatchResult { + + DEALER_WIN, + PLAYER_WIN, + TIE; + + public static MatchResult chooseWinner(int playerScore, int dealerScore) { + if (isBurst(playerScore)) { + return DEALER_WIN; + } + if (isBurst(dealerScore)) { + return PLAYER_WIN; + } + if (dealerScore == playerScore) { + return TIE; + } + if (dealerScore > playerScore) { + return DEALER_WIN; + } + return PLAYER_WIN; + } + + private static boolean isBurst(int score) { + return score > BlackJackGame.BLACKJACK_MAX_SCORE; + } +} diff --git a/src/test/java/game/MatchResultTest.java b/src/test/java/game/MatchResultTest.java new file mode 100644 index 0000000000..f197b1eec7 --- /dev/null +++ b/src/test/java/game/MatchResultTest.java @@ -0,0 +1,43 @@ +package game; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +class MatchResultTest { + + @Test + @DisplayName("플레이어의 점수가 21점을 초과하면 딜러가 승리한다.") + void playerBurstTest() { + // when + MatchResult result = MatchResult.chooseWinner(22, 22); + // then + assertThat(result).isEqualTo(MatchResult.DEALER_WIN); + } + + @Test + @DisplayName("플레이어의 점수가 21점 이하이고, 딜러의 점수가 21점을 초과하면 플레이어가 승리한다.") + void dealerBurstTest() { + // when + MatchResult result = MatchResult.chooseWinner(20, 22); + // then + assertThat(result).isEqualTo(MatchResult.PLAYER_WIN); + } + + @Test + @DisplayName("양 쪽 모두 21점 이하일 때, 점수가 높은 사람이 승리한다.") + void comparingScoreTest() { + // when + MatchResult expectPlayerWin = MatchResult.chooseWinner(21, 20); + MatchResult expectTie = MatchResult.chooseWinner(20, 20); + MatchResult expectDealerWin = MatchResult.chooseWinner(20, 21); + // then + assertAll( + () -> assertThat(expectPlayerWin).isEqualTo(MatchResult.PLAYER_WIN), + () -> assertThat(expectTie).isEqualTo(MatchResult.TIE), + () -> assertThat(expectDealerWin).isEqualTo(MatchResult.DEALER_WIN) + ); + } +} \ No newline at end of file diff --git a/src/test/java/player/DealerTest.java b/src/test/java/player/DealerTest.java index a59fc4821b..00d150e620 100644 --- a/src/test/java/player/DealerTest.java +++ b/src/test/java/player/DealerTest.java @@ -42,23 +42,4 @@ void dealerDrawTest() { () -> assertThat(isDrawable3).isFalse() ); } - - @Test - @DisplayName("딜러는 플레이어의 점수를 받아 승패를 결정한다") - void determineWinnerTest() { - // given - Dealer dealer = new Dealer(); - List cards = List.of( - new Card(Shape.SPADE, Number.TEN), - new Card(Shape.HEART, Number.KING) - ); - Deck deck = new Deck(cards); - dealer.drawCard(deck); - dealer.drawCard(deck); - // when, then - assertAll( - () -> assertThat(dealer.determineResult(19)).isTrue(), - () -> assertThat(dealer.determineResult(21)).isFalse() - ); - } } From 25353e0a6723bb432bd7476365355a446639b168 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 6 Mar 2024 16:19:46 +0900 Subject: [PATCH 17/85] =?UTF-8?q?feat(MatchResults):=20=EA=B2=8C=EC=9E=84?= =?UTF-8?q?=20=EA=B2=B0=EA=B3=BC=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 1 + src/main/java/game/MatchResults.java | 25 ++++++++++++++++++++ src/test/java/game/MatchResultsTest.java | 29 ++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/main/java/game/MatchResults.java create mode 100644 src/test/java/game/MatchResultsTest.java diff --git a/README.md b/README.md index b152e82319..a92bef0244 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ 2. 플레이어의 점수가 21점을 초과하지 않으면서 딜러의 점수가 21점을 초과하면 플레이어가 승리한다. 3. 딜러와 플레이어의 점수를 비교해 승패를 결정한다. 4. 점수가 같으면 무승부이다. +- [x] 각 플레이어별 게임 결과를 저장한다. --- - [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. diff --git a/src/main/java/game/MatchResults.java b/src/main/java/game/MatchResults.java new file mode 100644 index 0000000000..d9efe39f4d --- /dev/null +++ b/src/main/java/game/MatchResults.java @@ -0,0 +1,25 @@ +package game; + +import java.util.HashMap; +import java.util.Map; + +public class MatchResults { + + private final Map results; + + public MatchResults() { + this.results = new HashMap<>(); + } + + public void addResult(String playerName, int playerScore, int dealerScore) { + MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); + results.put(playerName, result); + } + + public MatchResult getResultByName(String playerName) { + if (!results.containsKey(playerName)) { + throw new IllegalArgumentException("[ERROR] 존재하지 않는 이름입니다."); + } + return results.get(playerName); + } +} diff --git a/src/test/java/game/MatchResultsTest.java b/src/test/java/game/MatchResultsTest.java new file mode 100644 index 0000000000..cd7c5a9b2c --- /dev/null +++ b/src/test/java/game/MatchResultsTest.java @@ -0,0 +1,29 @@ +package game; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class MatchResultsTest { + + @Test + @DisplayName("이름으로 결과를 올바르게 가져온다.") + void getResultByNameTest() { + MatchResults matchResults = new MatchResults(); + matchResults.addResult("aru", 20, 21); + assertThat(matchResults.getResultByName("aru")).isEqualTo(MatchResult.DEALER_WIN); + } + + @Test + @DisplayName("이름이 존재하지 않는 경우 예외를 발생시킨다.") + void nameNotFoundTest() { + // given + MatchResults matchResults = new MatchResults(); + // when, then + assertThatThrownBy(() -> matchResults.getResultByName("pobi")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 존재하지 않는 이름입니다."); + } +} From 9e6d1f30d0e6a254b68031836fc964a6a1ccf7e0 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 6 Mar 2024 16:27:09 +0900 Subject: [PATCH 18/85] =?UTF-8?q?feat(Deck):=20Shape=EC=99=80=20Number?= =?UTF-8?q?=EC=9D=98=20=EC=A1=B0=ED=95=A9=EC=9C=BC=EB=A1=9C=20=ED=95=9C=20?= =?UTF-8?q?=EC=84=B8=ED=8A=B8=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: donghoony --- src/main/java/card/Deck.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/card/Deck.java b/src/main/java/card/Deck.java index feb4f9f8e6..a65c0dd785 100644 --- a/src/main/java/card/Deck.java +++ b/src/main/java/card/Deck.java @@ -1,5 +1,6 @@ package card; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Queue; @@ -8,6 +9,18 @@ public class Deck { private final Queue cards; + public Deck() { + List initCards = new LinkedList<>(); + // TODO: indent 줄이기, 덱 생성 책임 정하기 + for (Shape shape : Shape.values()) { + for (Number number : Number.values()) { + initCards.add(new Card(shape, number)); + } + } + Collections.shuffle(initCards); + this.cards = new LinkedList<>(initCards); + } + public Deck(List cards) { this.cards = new LinkedList<>(cards); } From 9c16047b1b918c4acc0d348d65f06fbd6928022b Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 6 Mar 2024 17:03:44 +0900 Subject: [PATCH 19/85] =?UTF-8?q?feat(Command):=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=EC=9D=98=20=EB=AA=85=EB=A0=B9=EC=96=B4=20=EB=B3=80?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/game/Command.java | 21 +++++++++++++++++++ src/test/java/game/CommandTest.java | 32 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/main/java/game/Command.java create mode 100644 src/test/java/game/CommandTest.java diff --git a/src/main/java/game/Command.java b/src/main/java/game/Command.java new file mode 100644 index 0000000000..5e1a50feab --- /dev/null +++ b/src/main/java/game/Command.java @@ -0,0 +1,21 @@ +package game; + +import java.util.Arrays; + +public enum Command { + YES("y"), + NO("n"); + + private final String value; + + Command(String value) { + this.value = value; + } + + public static Command from(String value) { + return Arrays.stream(values()) + .filter(command -> command.value.equals(value)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 명령어입니다.")); + } +} diff --git a/src/test/java/game/CommandTest.java b/src/test/java/game/CommandTest.java new file mode 100644 index 0000000000..3a67cd227f --- /dev/null +++ b/src/test/java/game/CommandTest.java @@ -0,0 +1,32 @@ +package game; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +class CommandTest { + + @Test + @DisplayName("명령어를 올바르게 변환한다.") + void convertCommandTest() { + // when + Command yes = Command.from("y"); + Command no = Command.from("n"); + // then + assertAll( + () -> assertThat(yes).isEqualTo(Command.YES), + () -> assertThat(no).isEqualTo(Command.NO) + ); + } + + @Test + @DisplayName("존재하지 않는 명령어가 주어지면 예외를 발생시킨다.") + void commandNotFoundTest() { + assertThatThrownBy(() -> Command.from("hi")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 존재하지 않는 명령어입니다."); + } +} \ No newline at end of file From 25088ec12795c911d920e4168b0ef07b7a5d2f4a Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 11:47:58 +0900 Subject: [PATCH 20/85] =?UTF-8?q?refactor(OutputView):=20=EB=A7=A4?= =?UTF-8?q?=EA=B0=9C=EB=B3=80=EC=88=98=EB=A1=9C=20`Card`=EB=A5=BC=20?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `Card`에 포함되는 모양과 수는 변하지 않고, 불변 객체이므로 그대로 전달 Co-authored-by: donghoony --- src/main/java/card/Card.java | 8 +++++ src/main/java/card/Hand.java | 5 +++ src/main/java/player/Player.java | 4 +++ src/main/java/view/CardNumberDisplay.java | 5 +-- src/main/java/view/CardShapeDisplay.java | 5 +-- src/main/java/view/OutputView.java | 37 ++++++++++++++++++----- 6 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/main/java/card/Card.java b/src/main/java/card/Card.java index 03ed157b68..9fe125e441 100644 --- a/src/main/java/card/Card.java +++ b/src/main/java/card/Card.java @@ -20,6 +20,14 @@ public int getScore() { return number.getScore(); } + public Shape getShape() { + return shape; + } + + public Number getNumber() { + return number; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/src/main/java/card/Hand.java b/src/main/java/card/Hand.java index 7cb36ead3a..fbcda34eb9 100644 --- a/src/main/java/card/Hand.java +++ b/src/main/java/card/Hand.java @@ -1,6 +1,7 @@ package card; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class Hand { @@ -44,4 +45,8 @@ private int calculateMaximumScore() { public void addCard(Card card) { cards.add(card); } + + public List getCards() { + return Collections.unmodifiableList(cards); + } } diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index 83cdfe190d..671710edd2 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -21,4 +21,8 @@ public void drawCard(Deck deck) { public boolean hasDrawableScore() { return hand.calculateScore() < BlackJackGame.BLACKJACK_MAX_SCORE; } + + public List getCards() { + return hand.getCards(); + } } diff --git a/src/main/java/view/CardNumberDisplay.java b/src/main/java/view/CardNumberDisplay.java index 5c2620d47b..c7e3853982 100644 --- a/src/main/java/view/CardNumberDisplay.java +++ b/src/main/java/view/CardNumberDisplay.java @@ -28,10 +28,11 @@ public enum CardNumberDisplay { this.display = display; } - public static CardNumberDisplay fromNumber(Number number) { + public static String fromNumber(Number number) { return Arrays.stream(CardNumberDisplay.values()) .filter(displayNumber -> displayNumber.number == number) .findFirst() - .orElseThrow(); + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 수입니다.")) + .display; } } diff --git a/src/main/java/view/CardShapeDisplay.java b/src/main/java/view/CardShapeDisplay.java index 3e5ea8a6d3..7ab523c25e 100644 --- a/src/main/java/view/CardShapeDisplay.java +++ b/src/main/java/view/CardShapeDisplay.java @@ -19,10 +19,11 @@ public enum CardShapeDisplay { this.display = display; } - public static CardShapeDisplay fromShape(Shape shape) { + public static String fromShape(Shape shape) { return Arrays.stream(CardShapeDisplay.values()) .filter(displayShape -> displayShape.shape == shape) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 모양입니다.")); + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 모양입니다.")) + .display; } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index ea9f293ea8..a66d8571f6 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,5 +1,7 @@ package view; +import card.Card; + import java.util.List; public class OutputView { @@ -12,12 +14,15 @@ public void printInitializeBlackJack(List names) { System.out.println("딜러와 " + String.join(", ", names) + "에게 2장을 나누었습니다."); } - public void printDealerCards(String card) { - System.out.println("딜러: " + card); + public void printDealerFirstCard(Card card) { + System.out.println("딜러: " + convertCard(card)); } - public void printPlayerCards(String name, List cards) { - System.out.println(name + "카드: " + String.join(", ", cards)); + public void printPlayerCards(String name, List cards) { + List convertedCards = cards.stream() + .map(this::convertCard) + .toList(); + System.out.println(name + "카드: " + String.join(", ", convertedCards)); } public void printDrawMoreCardRequest(String name) { @@ -28,12 +33,18 @@ public void printDealerDrawCard() { System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); } - public void printDealerCardsWithResult(List cards, int score) { - System.out.println("딜러 카드: " + String.join(", ", cards) + " - 결과: " + score + "점"); + public void printDealerCardsWithResult(List cards, int score) { + List convertedCards = cards.stream() + .map(this::convertCard) + .toList(); + System.out.println("딜러 카드: " + String.join(", ", convertedCards) + " - 결과: " + score + "점"); } - public void printPlayerCardsWithResult(String name, List cards, int score) { - System.out.println(name + " 카드: " + String.join(", ", cards) + " - 결과: " + score + "점"); + public void printPlayerCardsWithResult(String name, List cards, int score) { + List convertedCards = cards.stream() + .map(this::convertCard) + .toList(); + System.out.println(name + " 카드: " + String.join(", ", convertedCards) + " - 결과: " + score + "점"); } public void printResultStart() { @@ -51,4 +62,14 @@ public void printPlayerResult(String name, boolean isWin) { } System.out.println(name + ": 패"); } + + public void printNewLine() { + System.out.println(); + } + + public String convertCard(Card card) { + String convertedNumber = CardNumberDisplay.fromNumber(card.getNumber()); + String convertedShape = CardShapeDisplay.fromShape(card.getShape()); + return convertedNumber + convertedShape; + } } From de8d257aafa7eb4827c238bd82b9a195ccb03f82 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 11:56:38 +0900 Subject: [PATCH 21/85] =?UTF-8?q?feat(Display):=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EC=9D=98=20=EA=B2=B0=EA=B3=BC=20=ED=91=9C?= =?UTF-8?q?=ED=98=84=20=EB=B0=A9=EC=8B=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/game/MatchResults.java | 7 ++++++ src/main/java/view/OutputView.java | 14 +++++------ src/main/java/view/PlayerResultDisplay.java | 27 +++++++++++++++++++++ src/test/java/game/MatchResultsTest.java | 22 +++++++++++++++++ 4 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 src/main/java/view/PlayerResultDisplay.java diff --git a/src/main/java/game/MatchResults.java b/src/main/java/game/MatchResults.java index d9efe39f4d..e5de42f6ce 100644 --- a/src/main/java/game/MatchResults.java +++ b/src/main/java/game/MatchResults.java @@ -22,4 +22,11 @@ public MatchResult getResultByName(String playerName) { } return results.get(playerName); } + + public int getResultCount(MatchResult result) { + return (int) results.values() + .stream() + .filter(matchResult -> matchResult == result) + .count(); + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index a66d8571f6..a19b9c3b2a 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,6 +1,7 @@ package view; import card.Card; +import game.MatchResult; import java.util.List; @@ -51,16 +52,13 @@ public void printResultStart() { System.out.println("## 최종 승패"); } - public void printDealerResult(int winCount, int loseCount) { - System.out.println("딜러: " + winCount + "승 " + loseCount + "패"); + public void printDealerResult(int winCount, int tieCount, int loseCount) { + System.out.println("딜러: " + winCount + "승 " + tieCount + "무 " + loseCount + "패"); } - public void printPlayerResult(String name, boolean isWin) { - if (isWin) { - System.out.println(name + ": 승"); - return; - } - System.out.println(name + ": 패"); + public void printPlayerResult(String name, MatchResult result) { + String resultDisplay = PlayerResultDisplay.getDisplayByResult(result); + System.out.println(name + ": " + resultDisplay); } public void printNewLine() { diff --git a/src/main/java/view/PlayerResultDisplay.java b/src/main/java/view/PlayerResultDisplay.java new file mode 100644 index 0000000000..031d677e40 --- /dev/null +++ b/src/main/java/view/PlayerResultDisplay.java @@ -0,0 +1,27 @@ +package view; + +import game.MatchResult; + +import java.util.Arrays; + +public enum PlayerResultDisplay { + PLAYER_WIN(MatchResult.PLAYER_WIN, "승"), + PLAYER_LOSE(MatchResult.DEALER_WIN, "패"), + TIE(MatchResult.TIE, "무"); + + private final MatchResult result; + private final String display; + + PlayerResultDisplay(MatchResult result, String display) { + this.result = result; + this.display = display; + } + + public static String getDisplayByResult(MatchResult result) { + return Arrays.stream(values()) + .filter(displayResult -> displayResult.result == result) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 결과입니다.")) + .display; + } +} diff --git a/src/test/java/game/MatchResultsTest.java b/src/test/java/game/MatchResultsTest.java index cd7c5a9b2c..461c674d1a 100644 --- a/src/test/java/game/MatchResultsTest.java +++ b/src/test/java/game/MatchResultsTest.java @@ -5,6 +5,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; public class MatchResultsTest { @@ -26,4 +27,25 @@ void nameNotFoundTest() { .isInstanceOf(IllegalArgumentException.class) .hasMessage("[ERROR] 존재하지 않는 이름입니다."); } + + @Test + @DisplayName("원하는 결과의 개수를 구한다.") + void getDesiredResultCountTest() { + // given + MatchResults matchResults = new MatchResults(); + matchResults.addResult("aru", 10, 20); + matchResults.addResult("pobi", 10, 20); + matchResults.addResult("atto", 10, 10); + matchResults.addResult("jazz", 20, 10); + // when + int playerWinCount = matchResults.getResultCount(MatchResult.PLAYER_WIN); + int tieCount = matchResults.getResultCount(MatchResult.TIE); + int dealerWinCount = matchResults.getResultCount(MatchResult.DEALER_WIN); + // then + assertAll( + () -> assertThat(playerWinCount).isEqualTo(1), + () -> assertThat(tieCount).isEqualTo(1), + () -> assertThat(dealerWinCount).isEqualTo(2) + ); + } } From a1666f102daa89ee9f4d561ae5c57dcf09676b38 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 11:58:07 +0900 Subject: [PATCH 22/85] =?UTF-8?q?feat(BlackJackGame):=20=EA=B2=8C=EC=9E=84?= =?UTF-8?q?=20=ED=9D=90=EB=A6=84=20=EC=A0=9C=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/game/BlackJackGame.java | 79 +++++++++++++++++++++++++++ src/main/java/player/Dealer.java | 6 ++ src/main/java/player/Name.java | 4 ++ src/main/java/player/Player.java | 16 ++++++ src/main/java/player/Players.java | 17 ++++++ 5 files changed, 122 insertions(+) diff --git a/src/main/java/game/BlackJackGame.java b/src/main/java/game/BlackJackGame.java index 483e17c1d1..d5eb2c1b80 100644 --- a/src/main/java/game/BlackJackGame.java +++ b/src/main/java/game/BlackJackGame.java @@ -1,6 +1,85 @@ package game; +import card.Deck; +import player.Dealer; +import player.Player; +import player.Players; +import view.InputView; +import view.OutputView; + +import java.util.List; + public class BlackJackGame { public static final int BLACKJACK_MAX_SCORE = 21; + + private final InputView inputView; + private final OutputView outputView; + private final MatchResults matchResults; + + public BlackJackGame(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + matchResults = new MatchResults(); + } + + public void play() { + Deck deck = new Deck(); + Dealer dealer = new Dealer(); + + outputView.printNamesRequest(); + List names = inputView.readNames(); + Players players = new Players(names); + outputView.printNewLine(); + + players.initDrawCards(deck); + dealer.initDrawCards(deck); + outputView.printInitializeBlackJack(players.getNames()); + outputView.printDealerFirstCard(dealer.getFirstCard()); + for (Player player : players.getPlayers()) { + outputView.printPlayerCards(player.getName(), player.getCards()); + } + outputView.printNewLine(); + + for (Player player : players.getPlayers()) { + while (player.hasDrawableScore()) { + outputView.printDrawMoreCardRequest(player.getName()); + String input = inputView.readCommand(); + Command command = Command.from(input); + if (command == Command.NO) { + break; + } + player.drawCard(deck); + outputView.printPlayerCards(player.getName(), player.getCards()); + } + } + outputView.printNewLine(); + + while (dealer.hasDrawableScore()) { + dealer.drawCard(deck); + outputView.printDealerDrawCard(); + outputView.printNewLine(); + } + + + outputView.printDealerCardsWithResult(dealer.getCards(), dealer.getScore()); + for (Player player : players.getPlayers()) { + outputView.printPlayerCardsWithResult(player.getName(), player.getCards(), player.getScore()); + } + for (Player player : players.getPlayers()) { + matchResults.addResult(player.getName(), player.getScore(), dealer.getScore()); + } + outputView.printNewLine(); + + outputView.printResultStart(); + outputView.printDealerResult( + matchResults.getResultCount(MatchResult.DEALER_WIN), + matchResults.getResultCount(MatchResult.TIE), + matchResults.getResultCount(MatchResult.PLAYER_WIN) + ); + for (Player player : players.getPlayers()) { + String playerName = player.getName(); + outputView.printPlayerResult(playerName, matchResults.getResultByName(playerName)); + } + } } diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index 1a972adb98..a9dd4cfb7f 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -1,5 +1,7 @@ package player; +import card.Card; + public class Dealer extends Player { private static final int MAX_DRAWABLE_SCORE = 16; @@ -12,4 +14,8 @@ public Dealer() { public boolean hasDrawableScore() { return hand.calculateScore() <= MAX_DRAWABLE_SCORE; } + + public Card getFirstCard() { + return getCards().get(0); + } } diff --git a/src/main/java/player/Name.java b/src/main/java/player/Name.java index bfe8c12c9b..16e12dd67a 100644 --- a/src/main/java/player/Name.java +++ b/src/main/java/player/Name.java @@ -25,4 +25,8 @@ private void validateNonBlankName(String name) { throw new IllegalArgumentException("[ERROR] 이름은 공백일 수 없습니다."); } } + + String getName() { + return name; + } } diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index 671710edd2..d9022de2ec 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -1,9 +1,12 @@ package player; +import card.Card; import card.Deck; import card.Hand; import game.BlackJackGame; +import java.util.List; + public class Player { private final Name name; @@ -18,10 +21,23 @@ public void drawCard(Deck deck) { hand.addCard(deck.draw()); } + public void initDrawCards(Deck deck) { + drawCard(deck); + drawCard(deck); + } + public boolean hasDrawableScore() { return hand.calculateScore() < BlackJackGame.BLACKJACK_MAX_SCORE; } + public String getName() { + return name.getName(); + } + + public int getScore() { + return hand.calculateScore(); + } + public List getCards() { return hand.getCards(); } diff --git a/src/main/java/player/Players.java b/src/main/java/player/Players.java index 83a0e390df..5f202e1842 100644 --- a/src/main/java/player/Players.java +++ b/src/main/java/player/Players.java @@ -1,5 +1,8 @@ package player; +import card.Deck; + +import java.util.Collections; import java.util.List; public class Players { @@ -39,4 +42,18 @@ private void validateUniqueNames(List playerNames) { throw new IllegalArgumentException("[ERROR] 이름은 중복될 수 없습니다."); } } + + public void initDrawCards(Deck deck) { + players.forEach(player -> player.initDrawCards(deck)); + } + + public List getNames() { + return players.stream() + .map(Player::getName) + .toList(); + } + + public List getPlayers() { + return Collections.unmodifiableList(players); + } } From fc78badebd70071067e1aec528257a434deda413 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 11:58:29 +0900 Subject: [PATCH 23/85] =?UTF-8?q?feat(BlackJackMain):=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20=EC=8B=A4=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/BlackJackMain.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/BlackJackMain.java diff --git a/src/main/java/BlackJackMain.java b/src/main/java/BlackJackMain.java new file mode 100644 index 0000000000..ee1381c0d0 --- /dev/null +++ b/src/main/java/BlackJackMain.java @@ -0,0 +1,14 @@ +import game.BlackJackGame; +import view.InputView; +import view.OutputView; + +public class BlackJackMain { + + public static void main(String[] args) { + + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + BlackJackGame blackJackGame = new BlackJackGame(inputView, outputView); + blackJackGame.play(); + } +} From a86d39578d8deea8844d00aa8eebbfc9d1e6833c Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 15:30:37 +0900 Subject: [PATCH 24/85] =?UTF-8?q?refactor(BlackJackGame):=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- README.md | 17 +++--- src/main/java/game/BlackJackGame.java | 80 +++++++++++++++++++++------ 2 files changed, 73 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index a92bef0244..68386834ac 100644 --- a/README.md +++ b/README.md @@ -44,11 +44,12 @@ - [x] 각 플레이어별 게임 결과를 저장한다. --- -- [ ] 딜러와 플레이어 중 카드의 합이 21을 초과하지 않으면서 21에 가장 가까운 숫자를 가지는 쪽이 승리한다. -- [ ] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. -- [ ] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. -- [ ] 플레이어의 카드는 모두에게 공개된다. -- [ ] 딜러의 두 번째 카드는 공개되지 않는다. -- [ ] 각 플레이어는 딜러와만 승패를 겨룬다. -- [ ] 딜러는 모든 플레이어와 승패를 겨룬다. -- [ ] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 승패를 출력한다. + +### 게임 흐름 +- [x] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. +- [x] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. +- [x] 플레이어의 카드는 모두에게 공개된다. +- [x] 딜러의 두 번째 카드는 공개되지 않는다. +- [x] 각 플레이어는 딜러와만 승패를 겨룬다. +- [x] 딜러는 모든 플레이어와 승패를 겨룬다. +- [x] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 승패를 확인한다. diff --git a/src/main/java/game/BlackJackGame.java b/src/main/java/game/BlackJackGame.java index d5eb2c1b80..998589262a 100644 --- a/src/main/java/game/BlackJackGame.java +++ b/src/main/java/game/BlackJackGame.java @@ -15,71 +15,119 @@ public class BlackJackGame { private final InputView inputView; private final OutputView outputView; - private final MatchResults matchResults; public BlackJackGame(InputView inputView, OutputView outputView) { this.inputView = inputView; this.outputView = outputView; - matchResults = new MatchResults(); } public void play() { Deck deck = new Deck(); Dealer dealer = new Dealer(); + Players players = createPlayers(); + initGame(deck, dealer, players); + playersDrawMore(deck, players); + dealerDrawMore(deck, dealer); + + showCardResultWithScore(dealer, players); + showMatchResult(dealer, players); + } + + private Players createPlayers() { outputView.printNamesRequest(); List names = inputView.readNames(); Players players = new Players(names); outputView.printNewLine(); + return players; + } + private void initGame(Deck deck, Dealer dealer, Players players) { players.initDrawCards(deck); dealer.initDrawCards(deck); outputView.printInitializeBlackJack(players.getNames()); + showInitCard(dealer, players); + } + + private void showInitCard(Dealer dealer, Players players) { outputView.printDealerFirstCard(dealer.getFirstCard()); + for (Player player : players.getPlayers()) { outputView.printPlayerCards(player.getName(), player.getCards()); } outputView.printNewLine(); + } + private void playersDrawMore(Deck deck, Players players) { for (Player player : players.getPlayers()) { - while (player.hasDrawableScore()) { - outputView.printDrawMoreCardRequest(player.getName()); - String input = inputView.readCommand(); - Command command = Command.from(input); - if (command == Command.NO) { - break; - } - player.drawCard(deck); - outputView.printPlayerCards(player.getName(), player.getCards()); - } + playerDrawMore(deck, player); } outputView.printNewLine(); + } + + private void playerDrawMore(Deck deck, Player player) { + Command command = askPlayerToDrawMore(player); + if (command == Command.NO) { + return; + } + player.drawCard(deck); + outputView.printPlayerCards(player.getName(), player.getCards()); + if (player.hasDrawableScore()) { + playerDrawMore(deck, player); + } + } + + private Command askPlayerToDrawMore(Player player) { + outputView.printDrawMoreCardRequest(player.getName()); + String input = inputView.readCommand(); + return Command.from(input); + } + + private void dealerDrawMore(Deck deck, Dealer dealer) { while (dealer.hasDrawableScore()) { dealer.drawCard(deck); outputView.printDealerDrawCard(); outputView.printNewLine(); } + } - + private void showCardResultWithScore(Dealer dealer, Players players) { outputView.printDealerCardsWithResult(dealer.getCards(), dealer.getScore()); for (Player player : players.getPlayers()) { outputView.printPlayerCardsWithResult(player.getName(), player.getCards(), player.getScore()); } + outputView.printNewLine(); + } + + private void showMatchResult(Dealer dealer, Players players) { + MatchResults matchResults = calculateMatchResults(dealer, players); + outputView.printResultStart(); + showDealerResult(matchResults); + showPlayersResult(players, matchResults); + } + + private MatchResults calculateMatchResults(Dealer dealer, Players players) { + MatchResults matchResults = new MatchResults(); for (Player player : players.getPlayers()) { matchResults.addResult(player.getName(), player.getScore(), dealer.getScore()); } - outputView.printNewLine(); + return matchResults; + } - outputView.printResultStart(); + private void showDealerResult(MatchResults matchResults) { outputView.printDealerResult( matchResults.getResultCount(MatchResult.DEALER_WIN), matchResults.getResultCount(MatchResult.TIE), matchResults.getResultCount(MatchResult.PLAYER_WIN) ); + } + + private void showPlayersResult(Players players, MatchResults matchResults) { for (Player player : players.getPlayers()) { String playerName = player.getName(); - outputView.printPlayerResult(playerName, matchResults.getResultByName(playerName)); + MatchResult result = matchResults.getResultByName(playerName); + outputView.printPlayerResult(playerName, result); } } } From e836cbe90928ac164658d395a3a3ee5bcc08ae7e Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 15:33:40 +0900 Subject: [PATCH 25/85] =?UTF-8?q?refactor(Players):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EB=9E=98=ED=95=91=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `toList`는 변경 불가능한 리스트를 반환하므로 `unmodifiableList` 제거 Co-authored-by: donghoony --- src/main/java/player/Players.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/player/Players.java b/src/main/java/player/Players.java index 5f202e1842..0bcda4bd59 100644 --- a/src/main/java/player/Players.java +++ b/src/main/java/player/Players.java @@ -2,7 +2,6 @@ import card.Deck; -import java.util.Collections; import java.util.List; public class Players { @@ -54,6 +53,6 @@ public List getNames() { } public List getPlayers() { - return Collections.unmodifiableList(players); + return players; } } From 3cbf5c017d75890249d58a639af0a11eea435c92 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 15:45:23 +0900 Subject: [PATCH 26/85] =?UTF-8?q?style(Shape):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=84=B8=EB=AF=B8=EC=BD=9C=EB=A1=A0=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/card/Shape.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/card/Shape.java b/src/main/java/card/Shape.java index b7f2c3dace..6eba3f150e 100644 --- a/src/main/java/card/Shape.java +++ b/src/main/java/card/Shape.java @@ -5,5 +5,5 @@ public enum Shape { HEART, SPADE, CLOVER, - DIAMOND; + DIAMOND } From efad4ef2551ac38fa184429a0a9ec9c6f0fd8c47 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 16:17:47 +0900 Subject: [PATCH 27/85] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/card/Hand.java | 8 ++++++-- src/main/java/player/Name.java | 5 ++++- src/main/java/player/Players.java | 5 ++++- src/main/java/view/InputView.java | 4 +++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/card/Hand.java b/src/main/java/card/Hand.java index fbcda34eb9..460e32cccc 100644 --- a/src/main/java/card/Hand.java +++ b/src/main/java/card/Hand.java @@ -1,11 +1,15 @@ package card; +import game.BlackJackGame; + import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Hand { + private static final int ADDITIONAL_ACE_SCORE = 10; + private final List cards; public Hand() { @@ -20,7 +24,7 @@ public int calculateScore() { int maximumScore = calculateMaximumScore(); int minimumScore = calculateMinimumScore(); - if (maximumScore > 21) { + if (maximumScore > BlackJackGame.BLACKJACK_MAX_SCORE) { return minimumScore; } return maximumScore; @@ -37,7 +41,7 @@ private int calculateMaximumScore() { boolean isAce = cards.stream().anyMatch(Card::isAce); if (isAce) { - return score + 10; + return score + ADDITIONAL_ACE_SCORE; } return score; } diff --git a/src/main/java/player/Name.java b/src/main/java/player/Name.java index 16e12dd67a..a96d695871 100644 --- a/src/main/java/player/Name.java +++ b/src/main/java/player/Name.java @@ -2,6 +2,9 @@ public class Name { + private static final int MIN_NAME_LENGTH = 2; + private static final int MAX_NAME_LENGTH = 5; + private final String name; Name(String name) { @@ -15,7 +18,7 @@ private void validateName(String name) { } private void validateNameLength(String name) { - if (name.length() < 2 || name.length() > 5) { + if (name.length() < MIN_NAME_LENGTH || name.length() > MAX_NAME_LENGTH) { throw new IllegalArgumentException("[ERROR] 이름은 2글자 이상 5글자 이하여야 합니다."); } } diff --git a/src/main/java/player/Players.java b/src/main/java/player/Players.java index 0bcda4bd59..03bf4657d5 100644 --- a/src/main/java/player/Players.java +++ b/src/main/java/player/Players.java @@ -6,6 +6,9 @@ public class Players { + private static final int MIN_PLAYER_COUNT = 1; + private static final int MAX_PLAYER_COUNT = 10; + private final List players; public Players(List playerNames) { @@ -28,7 +31,7 @@ private void validateNotNull(List playerNames) { } private void validateSize(List playerNames) { - if (playerNames.size() < 1 || playerNames.size() > 10) { + if (playerNames.size() < MIN_PLAYER_COUNT || playerNames.size() > MAX_PLAYER_COUNT) { throw new IllegalArgumentException("[ERROR] 플레이어의 수는 1명 이상 10명 이하여야 합니다."); } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index f5383e2553..74f4578c4c 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -6,11 +6,13 @@ public class InputView { + private static final String DELIMITER = ","; + private final Scanner scanner = new Scanner(System.in); public List readNames() { String input = scanner.nextLine(); - String[] names = input.split(","); + String[] names = input.split(DELIMITER); return Arrays.stream(names).toList(); } From 6e0a373a5a9e0b177f234847527d2df0dcb5a6dc Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 16:17:59 +0900 Subject: [PATCH 28/85] =?UTF-8?q?refactor(OutputView):=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/view/OutputView.java | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index a19b9c3b2a..05da3f3d60 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -20,10 +20,7 @@ public void printDealerFirstCard(Card card) { } public void printPlayerCards(String name, List cards) { - List convertedCards = cards.stream() - .map(this::convertCard) - .toList(); - System.out.println(name + "카드: " + String.join(", ", convertedCards)); + System.out.println(name + "카드: " + convertCards(cards)); } public void printDrawMoreCardRequest(String name) { @@ -35,17 +32,11 @@ public void printDealerDrawCard() { } public void printDealerCardsWithResult(List cards, int score) { - List convertedCards = cards.stream() - .map(this::convertCard) - .toList(); - System.out.println("딜러 카드: " + String.join(", ", convertedCards) + " - 결과: " + score + "점"); + System.out.println("딜러 카드: " + convertCards(cards) + " - 결과: " + score + "점"); } public void printPlayerCardsWithResult(String name, List cards, int score) { - List convertedCards = cards.stream() - .map(this::convertCard) - .toList(); - System.out.println(name + " 카드: " + String.join(", ", convertedCards) + " - 결과: " + score + "점"); + System.out.println(name + " 카드: " + convertCards(cards) + " - 결과: " + score + "점"); } public void printResultStart() { @@ -65,9 +56,16 @@ public void printNewLine() { System.out.println(); } - public String convertCard(Card card) { + private String convertCard(Card card) { String convertedNumber = CardNumberDisplay.fromNumber(card.getNumber()); String convertedShape = CardShapeDisplay.fromShape(card.getShape()); return convertedNumber + convertedShape; } + + private String convertCards(List cards) { + List convertedCards = cards.stream() + .map(this::convertCard) + .toList(); + return String.join(", ", convertedCards); + } } From 86c80ac6339f62f4b7ff25df86485dd5d1b75d95 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 17:10:14 +0900 Subject: [PATCH 29/85] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/{card => player}/Hand.java | 3 ++- src/test/java/{card => player}/HandTest.java | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) rename src/main/java/{card => player}/Hand.java (97%) rename src/test/java/{card => player}/HandTest.java (95%) diff --git a/src/main/java/card/Hand.java b/src/main/java/player/Hand.java similarity index 97% rename from src/main/java/card/Hand.java rename to src/main/java/player/Hand.java index 460e32cccc..c13e70c4e1 100644 --- a/src/main/java/card/Hand.java +++ b/src/main/java/player/Hand.java @@ -1,5 +1,6 @@ -package card; +package player; +import card.Card; import game.BlackJackGame; import java.util.ArrayList; diff --git a/src/test/java/card/HandTest.java b/src/test/java/player/HandTest.java similarity index 95% rename from src/test/java/card/HandTest.java rename to src/test/java/player/HandTest.java index a837dab004..970a49dd9a 100644 --- a/src/test/java/card/HandTest.java +++ b/src/test/java/player/HandTest.java @@ -1,5 +1,8 @@ -package card; +package player; +import card.Card; +import card.Number; +import card.Shape; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 3e0e9eedcd8e04500c10193d77b0ca9a811b50c7 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 17:14:50 +0900 Subject: [PATCH 30/85] =?UTF-8?q?test(Player):=20=EB=93=9C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EA=B0=80=EB=8A=A5=20=EC=97=AC=EB=B6=80=20=ED=8C=90?= =?UTF-8?q?=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/player/Dealer.java | 6 +++ src/main/java/player/Player.java | 7 +++- src/test/java/player/DealerTest.java | 55 ++++++++++++++++++---------- src/test/java/player/PlayerTest.java | 41 +++++++++++++++++++++ 4 files changed, 88 insertions(+), 21 deletions(-) diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index a9dd4cfb7f..7774c7cc64 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -2,6 +2,8 @@ import card.Card; +import java.util.List; + public class Dealer extends Player { private static final int MAX_DRAWABLE_SCORE = 16; @@ -10,6 +12,10 @@ public Dealer() { super("딜러"); } + Dealer(Hand hand) { + super("딜러", hand); + } + @Override public boolean hasDrawableScore() { return hand.calculateScore() <= MAX_DRAWABLE_SCORE; diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index d9022de2ec..8469319003 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -2,7 +2,6 @@ import card.Card; import card.Deck; -import card.Hand; import game.BlackJackGame; import java.util.List; @@ -13,8 +12,12 @@ public class Player { protected final Hand hand; Player(String name) { + this(name, new Hand()); + } + + Player(String name, Hand hand) { this.name = new Name(name); - this.hand = new Hand(); + this.hand = hand; } public void drawCard(Deck deck) { diff --git a/src/test/java/player/DealerTest.java b/src/test/java/player/DealerTest.java index 00d150e620..52032e9d8f 100644 --- a/src/test/java/player/DealerTest.java +++ b/src/test/java/player/DealerTest.java @@ -1,7 +1,6 @@ package player; import card.Card; -import card.Deck; import card.Number; import card.Shape; import org.junit.jupiter.api.DisplayName; @@ -10,36 +9,54 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class DealerTest { @Test - @DisplayName("딜러는 17 이상이 될 때까지 카드를 계속 뽑는다.") - void dealerDrawTest() { + @DisplayName("딜러는 16점 이하이면 추가 드로우가 가능하다.") + void ableToDrawTest() { // given - Dealer dealer = new Dealer(); List cards = List.of( new Card(Shape.HEART, Number.JACK), - new Card(Shape.DIAMOND, Number.SIX), - new Card(Shape.CLOVER, Number.THREE), - new Card(Shape.CLOVER, Number.FIVE) + new Card(Shape.DIAMOND, Number.SIX) ); - Deck deck = new Deck(cards); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); // when - dealer.drawCard(deck); - boolean isDrawable1 = dealer.hasDrawableScore(); + boolean isDrawable = dealer.hasDrawableScore(); + // then + assertThat(isDrawable).isTrue(); + } - dealer.drawCard(deck); - boolean isDrawable2 = dealer.hasDrawableScore(); - dealer.drawCard(deck); - boolean isDrawable3 = dealer.hasDrawableScore(); + @Test + @DisplayName("딜러는 16점 초과이면 추가 드로우가 불가능하다.") + void unableToDrawTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Number.JACK), + new Card(Shape.DIAMOND, Number.SEVEN) + ); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); + // when + boolean isDrawable = dealer.hasDrawableScore(); // then - assertAll( - () -> assertThat(isDrawable1).isTrue(), - () -> assertThat(isDrawable2).isTrue(), - () -> assertThat(isDrawable3).isFalse() + assertThat(isDrawable).isFalse(); + } + + @Test + @DisplayName("딜러의 첫 번째 카드를 가져온다.") + void getFirstCardTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Number.JACK), + new Card(Shape.DIAMOND, Number.SEVEN) ); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); + // when, then + assertThat(dealer.getFirstCard()).isEqualTo(new Card(Shape.HEART, Number.JACK)); } } diff --git a/src/test/java/player/PlayerTest.java b/src/test/java/player/PlayerTest.java index 3c86f51013..80bb0952f5 100644 --- a/src/test/java/player/PlayerTest.java +++ b/src/test/java/player/PlayerTest.java @@ -1,5 +1,46 @@ package player; +import card.Card; +import card.Number; +import card.Shape; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + class PlayerTest { + @Test + @DisplayName("플레이어는 21점 미만이면 추가 드로우가 가능하다.") + void ableToDrawTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Number.JACK), + new Card(Shape.DIAMOND, Number.TEN) + ); + Hand hand = new Hand(cards); + Player player = new Player("aru", hand); + // when + boolean isDrawable = player.hasDrawableScore(); + // then + assertThat(isDrawable).isTrue(); + } + + @Test + @DisplayName("플렝이어는 21점 이상이면 추가 드로우가 불가능하다.") + void unableToDrawTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Number.JACK), + new Card(Shape.DIAMOND, Number.ACE) + ); + Hand hand = new Hand(cards); + Player player = new Player("atto", hand); + // when + boolean isDrawable = player.hasDrawableScore(); + // then + assertThat(isDrawable).isFalse(); + } } From 46cc05ca02f6dd1e0205f2b402c9126bc2cebea0 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 17:15:22 +0900 Subject: [PATCH 31/85] =?UTF-8?q?fix(Dealer):=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=EA=B0=80=EC=A7=80=EA=B3=A0=20=EC=9E=88=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=9D=80=20=EA=B2=BD=EC=9A=B0=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/player/Dealer.java | 6 +++++- src/test/java/player/DealerTest.java | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index 7774c7cc64..c4edf30e61 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -22,6 +22,10 @@ public boolean hasDrawableScore() { } public Card getFirstCard() { - return getCards().get(0); + List cards = super.getCards(); + if (cards.isEmpty()) { + throw new IllegalStateException("[ERROR] 딜러가 카드를 가지고 있지 않습니다."); + } + return cards.get(0); } } diff --git a/src/test/java/player/DealerTest.java b/src/test/java/player/DealerTest.java index 52032e9d8f..2c64777f26 100644 --- a/src/test/java/player/DealerTest.java +++ b/src/test/java/player/DealerTest.java @@ -59,4 +59,17 @@ void getFirstCardTest() { // when, then assertThat(dealer.getFirstCard()).isEqualTo(new Card(Shape.HEART, Number.JACK)); } + + @Test + @DisplayName("딜러가 카드를 가지고 있지 않을 때 가져가는 것을 시도하면 예외를 발생시킨다.") + void getFirstCardOnEmptyHandTest() { + // given + List cards = List.of(); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); + // when, then + assertThatThrownBy(dealer::getFirstCard) + .isInstanceOf(IllegalStateException.class) + .hasMessage("[ERROR] 딜러가 카드를 가지고 있지 않습니다."); + } } From 4f27bbdb6e83a6204c219387f671f296dbd9647c Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 17:26:54 +0900 Subject: [PATCH 32/85] =?UTF-8?q?refactor(Deck):=20=EB=8D=B1=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=A0=95=EC=A0=81=20=EB=A9=94=EC=84=9C=EB=93=9C=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: donghoony --- src/main/java/card/Deck.java | 14 +++++++------- src/main/java/game/BlackJackGame.java | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/card/Deck.java b/src/main/java/card/Deck.java index a65c0dd785..11e2b6e847 100644 --- a/src/main/java/card/Deck.java +++ b/src/main/java/card/Deck.java @@ -9,20 +9,20 @@ public class Deck { private final Queue cards; - public Deck() { + Deck(List cards) { + this.cards = new LinkedList<>(cards); + } + + public static Deck createShuffledFullDeck() { List initCards = new LinkedList<>(); - // TODO: indent 줄이기, 덱 생성 책임 정하기 + // TODO: indent 줄이기 for (Shape shape : Shape.values()) { for (Number number : Number.values()) { initCards.add(new Card(shape, number)); } } Collections.shuffle(initCards); - this.cards = new LinkedList<>(initCards); - } - - public Deck(List cards) { - this.cards = new LinkedList<>(cards); + return new Deck(initCards); } public Card draw() { diff --git a/src/main/java/game/BlackJackGame.java b/src/main/java/game/BlackJackGame.java index 998589262a..c4d00b589e 100644 --- a/src/main/java/game/BlackJackGame.java +++ b/src/main/java/game/BlackJackGame.java @@ -22,7 +22,7 @@ public BlackJackGame(InputView inputView, OutputView outputView) { } public void play() { - Deck deck = new Deck(); + Deck deck = Deck.createShuffledFullDeck(); Dealer dealer = new Dealer(); Players players = createPlayers(); From c245b034064b702b5a33f53cbb772c4f9defded9 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 17:27:10 +0900 Subject: [PATCH 33/85] =?UTF-8?q?refactor(Hand):=20=EC=A0=91=EA=B7=BC=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/player/Hand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/player/Hand.java b/src/main/java/player/Hand.java index c13e70c4e1..28d464998f 100644 --- a/src/main/java/player/Hand.java +++ b/src/main/java/player/Hand.java @@ -13,7 +13,7 @@ public class Hand { private final List cards; - public Hand() { + Hand() { this(new ArrayList<>()); } From 70db6d4e516618d6c83fa9a9390cb39b1f4faf4a Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 17:48:58 +0900 Subject: [PATCH 34/85] =?UTF-8?q?refactor(Deck):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/card/Deck.java | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/card/Deck.java b/src/main/java/card/Deck.java index 11e2b6e847..95776c8e78 100644 --- a/src/main/java/card/Deck.java +++ b/src/main/java/card/Deck.java @@ -1,9 +1,6 @@ package card; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; +import java.util.*; public class Deck { @@ -14,15 +11,20 @@ public class Deck { } public static Deck createShuffledFullDeck() { - List initCards = new LinkedList<>(); - // TODO: indent 줄이기 + List cards = new LinkedList<>(); for (Shape shape : Shape.values()) { - for (Number number : Number.values()) { - initCards.add(new Card(shape, number)); - } + cards.addAll(createNumberCardsOf(shape)); } - Collections.shuffle(initCards); - return new Deck(initCards); + Collections.shuffle(cards); + return new Deck(cards); + } + + private static List createNumberCardsOf(Shape shape) { + List cards = new ArrayList<>(); + for (Number number : Number.values()) { + cards.add(new Card(shape, number)); + } + return cards; } public Card draw() { From cace848b284d2572b6991cad63e78d61b6e25728 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 17:56:26 +0900 Subject: [PATCH 35/85] =?UTF-8?q?refactor(Display):=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/view/OutputView.java | 3 +++ src/main/java/view/{ => display}/CardNumberDisplay.java | 2 +- src/main/java/view/{ => display}/CardShapeDisplay.java | 2 +- src/main/java/view/{ => display}/PlayerResultDisplay.java | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) rename src/main/java/view/{ => display}/CardNumberDisplay.java (97%) rename src/main/java/view/{ => display}/CardShapeDisplay.java (97%) rename src/main/java/view/{ => display}/PlayerResultDisplay.java (97%) diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 05da3f3d60..71c87a7cb8 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -2,6 +2,9 @@ import card.Card; import game.MatchResult; +import view.display.CardNumberDisplay; +import view.display.CardShapeDisplay; +import view.display.PlayerResultDisplay; import java.util.List; diff --git a/src/main/java/view/CardNumberDisplay.java b/src/main/java/view/display/CardNumberDisplay.java similarity index 97% rename from src/main/java/view/CardNumberDisplay.java rename to src/main/java/view/display/CardNumberDisplay.java index c7e3853982..77d85914dd 100644 --- a/src/main/java/view/CardNumberDisplay.java +++ b/src/main/java/view/display/CardNumberDisplay.java @@ -1,4 +1,4 @@ -package view; +package view.display; import card.Number; diff --git a/src/main/java/view/CardShapeDisplay.java b/src/main/java/view/display/CardShapeDisplay.java similarity index 97% rename from src/main/java/view/CardShapeDisplay.java rename to src/main/java/view/display/CardShapeDisplay.java index 7ab523c25e..598e578498 100644 --- a/src/main/java/view/CardShapeDisplay.java +++ b/src/main/java/view/display/CardShapeDisplay.java @@ -1,4 +1,4 @@ -package view; +package view.display; import card.Shape; diff --git a/src/main/java/view/PlayerResultDisplay.java b/src/main/java/view/display/PlayerResultDisplay.java similarity index 97% rename from src/main/java/view/PlayerResultDisplay.java rename to src/main/java/view/display/PlayerResultDisplay.java index 031d677e40..25e53780b8 100644 --- a/src/main/java/view/PlayerResultDisplay.java +++ b/src/main/java/view/display/PlayerResultDisplay.java @@ -1,4 +1,4 @@ -package view; +package view.display; import game.MatchResult; From a9577520983a91f4f8b1586d5373d8f69ac0efad Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 19:49:45 +0900 Subject: [PATCH 36/85] =?UTF-8?q?style(Number):=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=81=9D=20=EA=B3=B5=EB=B0=B1=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: donghoony --- src/main/java/card/Number.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/card/Number.java b/src/main/java/card/Number.java index 98dca0d719..e0305aa3e1 100644 --- a/src/main/java/card/Number.java +++ b/src/main/java/card/Number.java @@ -25,4 +25,4 @@ public enum Number { int getScore() { return this.score; } -} \ No newline at end of file +} From d4da75192b2a8ca90e157f144d9614da4ccd9371 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 19:50:23 +0900 Subject: [PATCH 37/85] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EC=88=9C=EC=84=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/player/Dealer.java | 10 +++++----- src/main/java/player/Hand.java | 8 ++++---- src/main/java/player/Player.java | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/player/Dealer.java b/src/main/java/player/Dealer.java index c4edf30e61..c336c88916 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/player/Dealer.java @@ -16,11 +16,6 @@ public Dealer() { super("딜러", hand); } - @Override - public boolean hasDrawableScore() { - return hand.calculateScore() <= MAX_DRAWABLE_SCORE; - } - public Card getFirstCard() { List cards = super.getCards(); if (cards.isEmpty()) { @@ -28,4 +23,9 @@ public Card getFirstCard() { } return cards.get(0); } + + @Override + public boolean hasDrawableScore() { + return hand.calculateScore() <= MAX_DRAWABLE_SCORE; + } } diff --git a/src/main/java/player/Hand.java b/src/main/java/player/Hand.java index 28d464998f..900f2157ba 100644 --- a/src/main/java/player/Hand.java +++ b/src/main/java/player/Hand.java @@ -13,14 +13,14 @@ public class Hand { private final List cards; - Hand() { - this(new ArrayList<>()); - } - Hand(List cards) { this.cards = cards; } + Hand() { + this(new ArrayList<>()); + } + public int calculateScore() { int maximumScore = calculateMaximumScore(); int minimumScore = calculateMinimumScore(); diff --git a/src/main/java/player/Player.java b/src/main/java/player/Player.java index 8469319003..71fc79c5d2 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/player/Player.java @@ -11,15 +11,15 @@ public class Player { private final Name name; protected final Hand hand; - Player(String name) { - this(name, new Hand()); - } - Player(String name, Hand hand) { this.name = new Name(name); this.hand = hand; } + Player(String name) { + this(name, new Hand()); + } + public void drawCard(Deck deck) { hand.addCard(deck.draw()); } From d888faa5792fdfd6820f11088db1dc51d9473496 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 19:56:41 +0900 Subject: [PATCH 38/85] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 컨벤션에 맞게 import 순서 변경 Co-authored-by: donghoony --- .../java/{ => blackjack}/BlackJackMain.java | 8 +++++--- src/main/java/{ => blackjack}/card/Card.java | 2 +- src/main/java/{ => blackjack}/card/Deck.java | 8 ++++++-- .../java/{ => blackjack}/card/Number.java | 2 +- src/main/java/{ => blackjack}/card/Shape.java | 2 +- .../{ => blackjack}/game/BlackJackGame.java | 17 ++++++++--------- .../java/{ => blackjack}/game/Command.java | 2 +- .../{ => blackjack}/game/MatchResult.java | 2 +- .../{ => blackjack}/game/MatchResults.java | 2 +- .../java/{ => blackjack}/player/Dealer.java | 5 ++--- .../java/{ => blackjack}/player/Hand.java | 7 +++---- .../java/{ => blackjack}/player/Name.java | 2 +- .../java/{ => blackjack}/player/Player.java | 9 ++++----- .../java/{ => blackjack}/player/Players.java | 5 ++--- .../java/{ => blackjack}/view/InputView.java | 2 +- .../java/{ => blackjack}/view/OutputView.java | 13 ++++++------- .../view/display/CardNumberDisplay.java | 5 ++--- .../view/display/CardShapeDisplay.java | 5 ++--- .../view/display/PlayerResultDisplay.java | 5 ++--- .../java/{ => blackjack}/card/CardTest.java | 6 +++--- .../java/{ => blackjack}/card/DeckTest.java | 11 +++++------ .../{ => blackjack}/game/CommandTest.java | 8 ++++---- .../{ => blackjack}/game/MatchResultTest.java | 8 ++++---- .../game/MatchResultsTest.java | 8 ++++---- .../{ => blackjack}/player/DealerTest.java | 19 +++++++++---------- .../java/{ => blackjack}/player/HandTest.java | 15 +++++++-------- .../java/{ => blackjack}/player/NameTest.java | 8 ++++---- .../{ => blackjack}/player/PlayerTest.java | 15 +++++++-------- .../{ => blackjack}/player/PlayersTest.java | 9 ++++----- 29 files changed, 101 insertions(+), 109 deletions(-) rename src/main/java/{ => blackjack}/BlackJackMain.java (70%) rename src/main/java/{ => blackjack}/card/Card.java (97%) rename src/main/java/{ => blackjack}/card/Deck.java (84%) rename src/main/java/{ => blackjack}/card/Number.java (93%) rename src/main/java/{ => blackjack}/card/Shape.java (74%) rename src/main/java/{ => blackjack}/game/BlackJackGame.java (95%) rename src/main/java/{ => blackjack}/game/Command.java (95%) rename src/main/java/{ => blackjack}/game/MatchResult.java (96%) rename src/main/java/{ => blackjack}/game/MatchResults.java (97%) rename src/main/java/{ => blackjack}/player/Dealer.java (91%) rename src/main/java/{ => blackjack}/player/Hand.java (92%) rename src/main/java/{ => blackjack}/player/Name.java (97%) rename src/main/java/{ => blackjack}/player/Player.java (86%) rename src/main/java/{ => blackjack}/player/Players.java (97%) rename src/main/java/{ => blackjack}/view/InputView.java (95%) rename src/main/java/{ => blackjack}/view/OutputView.java (91%) rename src/main/java/{ => blackjack}/view/display/CardNumberDisplay.java (94%) rename src/main/java/{ => blackjack}/view/display/CardShapeDisplay.java (92%) rename src/main/java/{ => blackjack}/view/display/PlayerResultDisplay.java (91%) rename src/test/java/{ => blackjack}/card/CardTest.java (94%) rename src/test/java/{ => blackjack}/card/DeckTest.java (97%) rename src/test/java/{ => blackjack}/game/CommandTest.java (97%) rename src/test/java/{ => blackjack}/game/MatchResultTest.java (98%) rename src/test/java/{ => blackjack}/game/MatchResultsTest.java (98%) rename src/test/java/{ => blackjack}/player/DealerTest.java (95%) rename src/test/java/{ => blackjack}/player/HandTest.java (93%) rename src/test/java/{ => blackjack}/player/NameTest.java (98%) rename src/test/java/{ => blackjack}/player/PlayerTest.java (91%) rename src/test/java/{ => blackjack}/player/PlayersTest.java (98%) diff --git a/src/main/java/BlackJackMain.java b/src/main/java/blackjack/BlackJackMain.java similarity index 70% rename from src/main/java/BlackJackMain.java rename to src/main/java/blackjack/BlackJackMain.java index ee1381c0d0..92e542987f 100644 --- a/src/main/java/BlackJackMain.java +++ b/src/main/java/blackjack/BlackJackMain.java @@ -1,6 +1,8 @@ -import game.BlackJackGame; -import view.InputView; -import view.OutputView; +package blackjack; + +import blackjack.game.BlackJackGame; +import blackjack.view.InputView; +import blackjack.view.OutputView; public class BlackJackMain { diff --git a/src/main/java/card/Card.java b/src/main/java/blackjack/card/Card.java similarity index 97% rename from src/main/java/card/Card.java rename to src/main/java/blackjack/card/Card.java index 9fe125e441..f29c4c9153 100644 --- a/src/main/java/card/Card.java +++ b/src/main/java/blackjack/card/Card.java @@ -1,4 +1,4 @@ -package card; +package blackjack.card; import java.util.Objects; diff --git a/src/main/java/card/Deck.java b/src/main/java/blackjack/card/Deck.java similarity index 84% rename from src/main/java/card/Deck.java rename to src/main/java/blackjack/card/Deck.java index 95776c8e78..4eeedf8a17 100644 --- a/src/main/java/card/Deck.java +++ b/src/main/java/blackjack/card/Deck.java @@ -1,6 +1,10 @@ -package card; +package blackjack.card; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; public class Deck { diff --git a/src/main/java/card/Number.java b/src/main/java/blackjack/card/Number.java similarity index 93% rename from src/main/java/card/Number.java rename to src/main/java/blackjack/card/Number.java index e0305aa3e1..2e5e6bdf70 100644 --- a/src/main/java/card/Number.java +++ b/src/main/java/blackjack/card/Number.java @@ -1,4 +1,4 @@ -package card; +package blackjack.card; public enum Number { diff --git a/src/main/java/card/Shape.java b/src/main/java/blackjack/card/Shape.java similarity index 74% rename from src/main/java/card/Shape.java rename to src/main/java/blackjack/card/Shape.java index 6eba3f150e..4ebd32ecc6 100644 --- a/src/main/java/card/Shape.java +++ b/src/main/java/blackjack/card/Shape.java @@ -1,4 +1,4 @@ -package card; +package blackjack.card; public enum Shape { diff --git a/src/main/java/game/BlackJackGame.java b/src/main/java/blackjack/game/BlackJackGame.java similarity index 95% rename from src/main/java/game/BlackJackGame.java rename to src/main/java/blackjack/game/BlackJackGame.java index c4d00b589e..85a21ffd30 100644 --- a/src/main/java/game/BlackJackGame.java +++ b/src/main/java/blackjack/game/BlackJackGame.java @@ -1,12 +1,11 @@ -package game; - -import card.Deck; -import player.Dealer; -import player.Player; -import player.Players; -import view.InputView; -import view.OutputView; - +package blackjack.game; + +import blackjack.card.Deck; +import blackjack.player.Dealer; +import blackjack.player.Player; +import blackjack.player.Players; +import blackjack.view.InputView; +import blackjack.view.OutputView; import java.util.List; public class BlackJackGame { diff --git a/src/main/java/game/Command.java b/src/main/java/blackjack/game/Command.java similarity index 95% rename from src/main/java/game/Command.java rename to src/main/java/blackjack/game/Command.java index 5e1a50feab..c20616f165 100644 --- a/src/main/java/game/Command.java +++ b/src/main/java/blackjack/game/Command.java @@ -1,4 +1,4 @@ -package game; +package blackjack.game; import java.util.Arrays; diff --git a/src/main/java/game/MatchResult.java b/src/main/java/blackjack/game/MatchResult.java similarity index 96% rename from src/main/java/game/MatchResult.java rename to src/main/java/blackjack/game/MatchResult.java index c68ca42ace..fbc12f7264 100644 --- a/src/main/java/game/MatchResult.java +++ b/src/main/java/blackjack/game/MatchResult.java @@ -1,4 +1,4 @@ -package game; +package blackjack.game; public enum MatchResult { diff --git a/src/main/java/game/MatchResults.java b/src/main/java/blackjack/game/MatchResults.java similarity index 97% rename from src/main/java/game/MatchResults.java rename to src/main/java/blackjack/game/MatchResults.java index e5de42f6ce..cfca9fb911 100644 --- a/src/main/java/game/MatchResults.java +++ b/src/main/java/blackjack/game/MatchResults.java @@ -1,4 +1,4 @@ -package game; +package blackjack.game; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/player/Dealer.java b/src/main/java/blackjack/player/Dealer.java similarity index 91% rename from src/main/java/player/Dealer.java rename to src/main/java/blackjack/player/Dealer.java index c336c88916..e920a176b5 100644 --- a/src/main/java/player/Dealer.java +++ b/src/main/java/blackjack/player/Dealer.java @@ -1,7 +1,6 @@ -package player; - -import card.Card; +package blackjack.player; +import blackjack.card.Card; import java.util.List; public class Dealer extends Player { diff --git a/src/main/java/player/Hand.java b/src/main/java/blackjack/player/Hand.java similarity index 92% rename from src/main/java/player/Hand.java rename to src/main/java/blackjack/player/Hand.java index 900f2157ba..db7c1b7aa8 100644 --- a/src/main/java/player/Hand.java +++ b/src/main/java/blackjack/player/Hand.java @@ -1,8 +1,7 @@ -package player; - -import card.Card; -import game.BlackJackGame; +package blackjack.player; +import blackjack.card.Card; +import blackjack.game.BlackJackGame; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/src/main/java/player/Name.java b/src/main/java/blackjack/player/Name.java similarity index 97% rename from src/main/java/player/Name.java rename to src/main/java/blackjack/player/Name.java index a96d695871..1455dbefa9 100644 --- a/src/main/java/player/Name.java +++ b/src/main/java/blackjack/player/Name.java @@ -1,4 +1,4 @@ -package player; +package blackjack.player; public class Name { diff --git a/src/main/java/player/Player.java b/src/main/java/blackjack/player/Player.java similarity index 86% rename from src/main/java/player/Player.java rename to src/main/java/blackjack/player/Player.java index 71fc79c5d2..51064fdcd9 100644 --- a/src/main/java/player/Player.java +++ b/src/main/java/blackjack/player/Player.java @@ -1,9 +1,8 @@ -package player; - -import card.Card; -import card.Deck; -import game.BlackJackGame; +package blackjack.player; +import blackjack.card.Card; +import blackjack.card.Deck; +import blackjack.game.BlackJackGame; import java.util.List; public class Player { diff --git a/src/main/java/player/Players.java b/src/main/java/blackjack/player/Players.java similarity index 97% rename from src/main/java/player/Players.java rename to src/main/java/blackjack/player/Players.java index 03bf4657d5..976651d94b 100644 --- a/src/main/java/player/Players.java +++ b/src/main/java/blackjack/player/Players.java @@ -1,7 +1,6 @@ -package player; - -import card.Deck; +package blackjack.player; +import blackjack.card.Deck; import java.util.List; public class Players { diff --git a/src/main/java/view/InputView.java b/src/main/java/blackjack/view/InputView.java similarity index 95% rename from src/main/java/view/InputView.java rename to src/main/java/blackjack/view/InputView.java index 74f4578c4c..a5d49340e4 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -1,4 +1,4 @@ -package view; +package blackjack.view; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java similarity index 91% rename from src/main/java/view/OutputView.java rename to src/main/java/blackjack/view/OutputView.java index 71c87a7cb8..f692a7fd1a 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,11 +1,10 @@ -package view; - -import card.Card; -import game.MatchResult; -import view.display.CardNumberDisplay; -import view.display.CardShapeDisplay; -import view.display.PlayerResultDisplay; +package blackjack.view; +import blackjack.card.Card; +import blackjack.game.MatchResult; +import blackjack.view.display.CardNumberDisplay; +import blackjack.view.display.CardShapeDisplay; +import blackjack.view.display.PlayerResultDisplay; import java.util.List; public class OutputView { diff --git a/src/main/java/view/display/CardNumberDisplay.java b/src/main/java/blackjack/view/display/CardNumberDisplay.java similarity index 94% rename from src/main/java/view/display/CardNumberDisplay.java rename to src/main/java/blackjack/view/display/CardNumberDisplay.java index 77d85914dd..75ed821008 100644 --- a/src/main/java/view/display/CardNumberDisplay.java +++ b/src/main/java/blackjack/view/display/CardNumberDisplay.java @@ -1,7 +1,6 @@ -package view.display; - -import card.Number; +package blackjack.view.display; +import blackjack.card.Number; import java.util.Arrays; public enum CardNumberDisplay { diff --git a/src/main/java/view/display/CardShapeDisplay.java b/src/main/java/blackjack/view/display/CardShapeDisplay.java similarity index 92% rename from src/main/java/view/display/CardShapeDisplay.java rename to src/main/java/blackjack/view/display/CardShapeDisplay.java index 598e578498..c32f754cf1 100644 --- a/src/main/java/view/display/CardShapeDisplay.java +++ b/src/main/java/blackjack/view/display/CardShapeDisplay.java @@ -1,7 +1,6 @@ -package view.display; - -import card.Shape; +package blackjack.view.display; +import blackjack.card.Shape; import java.util.Arrays; public enum CardShapeDisplay { diff --git a/src/main/java/view/display/PlayerResultDisplay.java b/src/main/java/blackjack/view/display/PlayerResultDisplay.java similarity index 91% rename from src/main/java/view/display/PlayerResultDisplay.java rename to src/main/java/blackjack/view/display/PlayerResultDisplay.java index 25e53780b8..a828c941e0 100644 --- a/src/main/java/view/display/PlayerResultDisplay.java +++ b/src/main/java/blackjack/view/display/PlayerResultDisplay.java @@ -1,7 +1,6 @@ -package view.display; - -import game.MatchResult; +package blackjack.view.display; +import blackjack.game.MatchResult; import java.util.Arrays; public enum PlayerResultDisplay { diff --git a/src/test/java/card/CardTest.java b/src/test/java/blackjack/card/CardTest.java similarity index 94% rename from src/test/java/card/CardTest.java rename to src/test/java/blackjack/card/CardTest.java index 464033b1b1..4eaf03e85f 100644 --- a/src/test/java/card/CardTest.java +++ b/src/test/java/blackjack/card/CardTest.java @@ -1,10 +1,10 @@ -package card; +package blackjack.card; + +import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; - class CardTest { @Test diff --git a/src/test/java/card/DeckTest.java b/src/test/java/blackjack/card/DeckTest.java similarity index 97% rename from src/test/java/card/DeckTest.java rename to src/test/java/blackjack/card/DeckTest.java index ce383486a7..bd76a3ee71 100644 --- a/src/test/java/card/DeckTest.java +++ b/src/test/java/blackjack/card/DeckTest.java @@ -1,13 +1,12 @@ -package card; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.List; +package blackjack.card; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + class DeckTest { @Test diff --git a/src/test/java/game/CommandTest.java b/src/test/java/blackjack/game/CommandTest.java similarity index 97% rename from src/test/java/game/CommandTest.java rename to src/test/java/blackjack/game/CommandTest.java index 3a67cd227f..06f70f0079 100644 --- a/src/test/java/game/CommandTest.java +++ b/src/test/java/blackjack/game/CommandTest.java @@ -1,12 +1,12 @@ -package game; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +package blackjack.game; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + class CommandTest { @Test diff --git a/src/test/java/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java similarity index 98% rename from src/test/java/game/MatchResultTest.java rename to src/test/java/blackjack/game/MatchResultTest.java index f197b1eec7..809e1a8f46 100644 --- a/src/test/java/game/MatchResultTest.java +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -1,11 +1,11 @@ -package game; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +package blackjack.game; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + class MatchResultTest { @Test diff --git a/src/test/java/game/MatchResultsTest.java b/src/test/java/blackjack/game/MatchResultsTest.java similarity index 98% rename from src/test/java/game/MatchResultsTest.java rename to src/test/java/blackjack/game/MatchResultsTest.java index 461c674d1a..878b10898a 100644 --- a/src/test/java/game/MatchResultsTest.java +++ b/src/test/java/blackjack/game/MatchResultsTest.java @@ -1,12 +1,12 @@ -package game; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +package blackjack.game; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + public class MatchResultsTest { @Test diff --git a/src/test/java/player/DealerTest.java b/src/test/java/blackjack/player/DealerTest.java similarity index 95% rename from src/test/java/player/DealerTest.java rename to src/test/java/blackjack/player/DealerTest.java index 2c64777f26..6e392ba738 100644 --- a/src/test/java/player/DealerTest.java +++ b/src/test/java/blackjack/player/DealerTest.java @@ -1,16 +1,15 @@ -package player; - -import card.Card; -import card.Number; -import card.Shape; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.List; +package blackjack.player; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import blackjack.card.Card; +import blackjack.card.Number; +import blackjack.card.Shape; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + class DealerTest { @Test @@ -45,7 +44,7 @@ void unableToDrawTest() { // then assertThat(isDrawable).isFalse(); } - + @Test @DisplayName("딜러의 첫 번째 카드를 가져온다.") void getFirstCardTest() { diff --git a/src/test/java/player/HandTest.java b/src/test/java/blackjack/player/HandTest.java similarity index 93% rename from src/test/java/player/HandTest.java rename to src/test/java/blackjack/player/HandTest.java index 970a49dd9a..b5ad233b20 100644 --- a/src/test/java/player/HandTest.java +++ b/src/test/java/blackjack/player/HandTest.java @@ -1,14 +1,13 @@ -package player; +package blackjack.player; -import card.Card; -import card.Number; -import card.Shape; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import blackjack.card.Card; +import blackjack.card.Number; +import blackjack.card.Shape; import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; public class HandTest { diff --git a/src/test/java/player/NameTest.java b/src/test/java/blackjack/player/NameTest.java similarity index 98% rename from src/test/java/player/NameTest.java rename to src/test/java/blackjack/player/NameTest.java index 0e39e3bd5f..dc205b7b23 100644 --- a/src/test/java/player/NameTest.java +++ b/src/test/java/blackjack/player/NameTest.java @@ -1,13 +1,13 @@ -package player; +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.NullAndEmptySource; import org.junit.jupiter.params.provider.ValueSource; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - class NameTest { @ParameterizedTest diff --git a/src/test/java/player/PlayerTest.java b/src/test/java/blackjack/player/PlayerTest.java similarity index 91% rename from src/test/java/player/PlayerTest.java rename to src/test/java/blackjack/player/PlayerTest.java index 80bb0952f5..cfc787bc1b 100644 --- a/src/test/java/player/PlayerTest.java +++ b/src/test/java/blackjack/player/PlayerTest.java @@ -1,14 +1,13 @@ -package player; +package blackjack.player; -import card.Card; -import card.Number; -import card.Shape; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import blackjack.card.Card; +import blackjack.card.Number; +import blackjack.card.Shape; import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; class PlayerTest { diff --git a/src/test/java/player/PlayersTest.java b/src/test/java/blackjack/player/PlayersTest.java similarity index 98% rename from src/test/java/player/PlayersTest.java rename to src/test/java/blackjack/player/PlayersTest.java index a9c701617b..92bf1268d2 100644 --- a/src/test/java/player/PlayersTest.java +++ b/src/test/java/blackjack/player/PlayersTest.java @@ -1,11 +1,10 @@ -package player; +package blackjack.player; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.List; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; class PlayersTest { From 5729a1d47c2070bb8ad07a9f3c46b91577899306 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 20:03:13 +0900 Subject: [PATCH 39/85] =?UTF-8?q?style:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EA=B0=9C=ED=96=89=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 컨벤션에 맞게 import 순서 변경 Co-authored-by: donghoony --- src/main/java/blackjack/BlackJackMain.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/blackjack/BlackJackMain.java b/src/main/java/blackjack/BlackJackMain.java index 92e542987f..40f5162da6 100644 --- a/src/main/java/blackjack/BlackJackMain.java +++ b/src/main/java/blackjack/BlackJackMain.java @@ -7,7 +7,6 @@ public class BlackJackMain { public static void main(String[] args) { - InputView inputView = new InputView(); OutputView outputView = new OutputView(); BlackJackGame blackJackGame = new BlackJackGame(inputView, outputView); From 1ca43dff24b277ac6f1ea5441f05d5950e4a9068 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 20:25:14 +0900 Subject: [PATCH 40/85] =?UTF-8?q?style(Hand):=20=EA=B0=80=EB=8F=85?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B0=8F=20=EC=A4=84=EB=B0=94=EA=BF=88=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: donghoony --- src/main/java/blackjack/player/Hand.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/blackjack/player/Hand.java b/src/main/java/blackjack/player/Hand.java index db7c1b7aa8..140f4d3264 100644 --- a/src/main/java/blackjack/player/Hand.java +++ b/src/main/java/blackjack/player/Hand.java @@ -21,8 +21,8 @@ public class Hand { } public int calculateScore() { - int maximumScore = calculateMaximumScore(); int minimumScore = calculateMinimumScore(); + int maximumScore = calculateMaximumScore(); if (maximumScore > BlackJackGame.BLACKJACK_MAX_SCORE) { return minimumScore; @@ -38,7 +38,8 @@ private int calculateMinimumScore() { private int calculateMaximumScore() { int score = calculateMinimumScore(); - boolean isAce = cards.stream().anyMatch(Card::isAce); + boolean isAce = cards.stream() + .anyMatch(Card::isAce); if (isAce) { return score + ADDITIONAL_ACE_SCORE; From ce53b0d181bc6bca158865afcb71d95cf005b8ca Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 20:29:25 +0900 Subject: [PATCH 41/85] =?UTF-8?q?refactor(MatchResult):=20=EC=8A=B9?= =?UTF-8?q?=EB=A6=AC=20=EC=A1=B0=EA=B1=B4=20=EB=B3=84=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/blackjack/game/MatchResult.java | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/java/blackjack/game/MatchResult.java b/src/main/java/blackjack/game/MatchResult.java index fbc12f7264..39032ed449 100644 --- a/src/main/java/blackjack/game/MatchResult.java +++ b/src/main/java/blackjack/game/MatchResult.java @@ -7,19 +7,27 @@ public enum MatchResult { TIE; public static MatchResult chooseWinner(int playerScore, int dealerScore) { - if (isBurst(playerScore)) { - return DEALER_WIN; - } - if (isBurst(dealerScore)) { + if (isPlayerWinningCondition(playerScore, dealerScore)) { return PLAYER_WIN; } - if (dealerScore == playerScore) { - return TIE; - } - if (dealerScore > playerScore) { + if (isDealerWinningCondition(playerScore, dealerScore)) { return DEALER_WIN; } - return PLAYER_WIN; + return TIE; + } + + private static boolean isPlayerWinningCondition(int playerScore, int dealerScore) { + if (isBurst(playerScore)) { + return false; + } + return isBurst(dealerScore) || playerScore > dealerScore; + } + + private static boolean isDealerWinningCondition(int playerScore, int dealerScore) { + if (isBurst(playerScore)) { + return true; + } + return !isBurst(dealerScore) && dealerScore > playerScore; } private static boolean isBurst(int score) { From 8969a9ac19a9eb08f0e310d5e56e9699df1c6518 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 20:37:18 +0900 Subject: [PATCH 42/85] =?UTF-8?q?test(MatchResult):=20=EC=8A=B9=EB=A6=AC?= =?UTF-8?q?=20=EC=A1=B0=EA=B1=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- .../java/blackjack/game/MatchResultTest.java | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/test/java/blackjack/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java index 809e1a8f46..5dc818fb78 100644 --- a/src/test/java/blackjack/game/MatchResultTest.java +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -1,43 +1,40 @@ package blackjack.game; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; class MatchResultTest { - @Test - @DisplayName("플레이어의 점수가 21점을 초과하면 딜러가 승리한다.") - void playerBurstTest() { + @ParameterizedTest + @CsvSource(value = {"20, 22", "20, 19", "21, 20"}) + @DisplayName("플레이어가 이기는 경우를 올바르게 판단한다.") + void playerWinningTest(int playerScore, int dealerScore) { // when - MatchResult result = MatchResult.chooseWinner(22, 22); + MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); // then - assertThat(result).isEqualTo(MatchResult.DEALER_WIN); + assertThat(result).isEqualTo(MatchResult.PLAYER_WIN); } - @Test - @DisplayName("플레이어의 점수가 21점 이하이고, 딜러의 점수가 21점을 초과하면 플레이어가 승리한다.") - void dealerBurstTest() { + @ParameterizedTest + @CsvSource(value = {"22, 20", "22, 22", "20, 21", "14, 18"}) + @DisplayName("딜러가 이기는 경우를 올바르게 판단한다.") + void dealerWinningTest(int playerScore, int dealerScore) { // when - MatchResult result = MatchResult.chooseWinner(20, 22); + MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); // then - assertThat(result).isEqualTo(MatchResult.PLAYER_WIN); + assertThat(result).isEqualTo(MatchResult.DEALER_WIN); } - @Test - @DisplayName("양 쪽 모두 21점 이하일 때, 점수가 높은 사람이 승리한다.") - void comparingScoreTest() { + @ParameterizedTest + @CsvSource(value = {"21, 21", "20, 20"}) + @DisplayName("무승부인 경를 올바르게 판단한다.") + void tieTest(int playerScore, int dealerScore) { // when - MatchResult expectPlayerWin = MatchResult.chooseWinner(21, 20); - MatchResult expectTie = MatchResult.chooseWinner(20, 20); - MatchResult expectDealerWin = MatchResult.chooseWinner(20, 21); + MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); // then - assertAll( - () -> assertThat(expectPlayerWin).isEqualTo(MatchResult.PLAYER_WIN), - () -> assertThat(expectTie).isEqualTo(MatchResult.TIE), - () -> assertThat(expectDealerWin).isEqualTo(MatchResult.DEALER_WIN) - ); + assertThat(result).isEqualTo(MatchResult.TIE); } } \ No newline at end of file From 1a0d96e4ece36d39780759f1f641403df2370173 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 20:59:16 +0900 Subject: [PATCH 43/85] =?UTF-8?q?style:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=A0=91=EA=B7=BC=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=EC=9E=90=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/test/java/blackjack/game/MatchResultsTest.java | 2 +- src/test/java/blackjack/player/HandTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/blackjack/game/MatchResultsTest.java b/src/test/java/blackjack/game/MatchResultsTest.java index 878b10898a..40a5972bdd 100644 --- a/src/test/java/blackjack/game/MatchResultsTest.java +++ b/src/test/java/blackjack/game/MatchResultsTest.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -public class MatchResultsTest { +class MatchResultsTest { @Test @DisplayName("이름으로 결과를 올바르게 가져온다.") diff --git a/src/test/java/blackjack/player/HandTest.java b/src/test/java/blackjack/player/HandTest.java index b5ad233b20..1073f3f500 100644 --- a/src/test/java/blackjack/player/HandTest.java +++ b/src/test/java/blackjack/player/HandTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -public class HandTest { +class HandTest { @Test @DisplayName("플레이어의 점수를 계산한다.") From 4d35231712df95593a19a4383606c464c4988e7f Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 7 Mar 2024 20:59:57 +0900 Subject: [PATCH 44/85] =?UTF-8?q?refactor(OutputView):=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=B2=88=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: donghoony --- src/main/java/blackjack/game/BlackJackGame.java | 8 ++++---- src/main/java/blackjack/view/OutputView.java | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/blackjack/game/BlackJackGame.java b/src/main/java/blackjack/game/BlackJackGame.java index 85a21ffd30..2bf57c9431 100644 --- a/src/main/java/blackjack/game/BlackJackGame.java +++ b/src/main/java/blackjack/game/BlackJackGame.java @@ -29,7 +29,7 @@ public void play() { playersDrawMore(deck, players); dealerDrawMore(deck, dealer); - showCardResultWithScore(dealer, players); + showCardsWithScore(dealer, players); showMatchResult(dealer, players); } @@ -91,10 +91,10 @@ private void dealerDrawMore(Deck deck, Dealer dealer) { } } - private void showCardResultWithScore(Dealer dealer, Players players) { - outputView.printDealerCardsWithResult(dealer.getCards(), dealer.getScore()); + private void showCardsWithScore(Dealer dealer, Players players) { + outputView.printDealerCardsWithScore(dealer.getCards(), dealer.getScore()); for (Player player : players.getPlayers()) { - outputView.printPlayerCardsWithResult(player.getName(), player.getCards(), player.getScore()); + outputView.printPlayerCardsWithScore(player.getName(), player.getCards(), player.getScore()); } outputView.printNewLine(); } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index f692a7fd1a..bae37bd11c 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -33,11 +33,11 @@ public void printDealerDrawCard() { System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); } - public void printDealerCardsWithResult(List cards, int score) { - System.out.println("딜러 카드: " + convertCards(cards) + " - 결과: " + score + "점"); + public void printDealerCardsWithScore(List cards, int score) { + printPlayerCardsWithScore("딜러", cards, score); } - public void printPlayerCardsWithResult(String name, List cards, int score) { + public void printPlayerCardsWithScore(String name, List cards, int score) { System.out.println(name + " 카드: " + convertCards(cards) + " - 결과: " + score + "점"); } From 23b3015111947038838cf21e77a36c74a09b6fb5 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Fri, 8 Mar 2024 01:48:42 +0900 Subject: [PATCH 45/85] =?UTF-8?q?style:=20=EA=B0=9C=ED=96=89=20=EB=B0=8F?= =?UTF-8?q?=20=EC=98=A4=ED=83=80=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: donghoony --- src/test/java/blackjack/game/CommandTest.java | 2 +- src/test/java/blackjack/game/MatchResultTest.java | 4 ++-- src/test/java/blackjack/player/DealerTest.java | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/java/blackjack/game/CommandTest.java b/src/test/java/blackjack/game/CommandTest.java index 06f70f0079..6924de65f1 100644 --- a/src/test/java/blackjack/game/CommandTest.java +++ b/src/test/java/blackjack/game/CommandTest.java @@ -29,4 +29,4 @@ void commandNotFoundTest() { .isInstanceOf(IllegalArgumentException.class) .hasMessage("[ERROR] 존재하지 않는 명령어입니다."); } -} \ No newline at end of file +} diff --git a/src/test/java/blackjack/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java index 5dc818fb78..6e4463a92f 100644 --- a/src/test/java/blackjack/game/MatchResultTest.java +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -30,11 +30,11 @@ void dealerWinningTest(int playerScore, int dealerScore) { @ParameterizedTest @CsvSource(value = {"21, 21", "20, 20"}) - @DisplayName("무승부인 경를 올바르게 판단한다.") + @DisplayName("무승부인 경우를 올바르게 판단한다.") void tieTest(int playerScore, int dealerScore) { // when MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); // then assertThat(result).isEqualTo(MatchResult.TIE); } -} \ No newline at end of file +} diff --git a/src/test/java/blackjack/player/DealerTest.java b/src/test/java/blackjack/player/DealerTest.java index 6e392ba738..653649c587 100644 --- a/src/test/java/blackjack/player/DealerTest.java +++ b/src/test/java/blackjack/player/DealerTest.java @@ -28,7 +28,6 @@ void ableToDrawTest() { assertThat(isDrawable).isTrue(); } - @Test @DisplayName("딜러는 16점 초과이면 추가 드로우가 불가능하다.") void unableToDrawTest() { From 0155159f78e64f6b5c00ce1ba85212b7e46dad22 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 17:12:05 +0900 Subject: [PATCH 46/85] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=82=AC=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 68386834ac..7f90631694 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ - [x] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. - [x] 플레이어의 카드는 모두에게 공개된다. - [x] 딜러의 두 번째 카드는 공개되지 않는다. +- [x] 플레이어가 카드를 새로 뽑을 때마다 카드 현황을 공개한다. - [x] 각 플레이어는 딜러와만 승패를 겨룬다. - [x] 딜러는 모든 플레이어와 승패를 겨룬다. - [x] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 승패를 확인한다. From 1800705b4221086bae0df4e15e17aff20c84e0db Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 17:22:12 +0900 Subject: [PATCH 47/85] =?UTF-8?q?refactor(Card):=20this=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20=EC=9D=BC=EA=B4=80=EC=84=B1=20=EA=B3=A0=EB=A0=A4?= =?UTF-8?q?=ED=95=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 파라미터와 구분이 되지 않는 경우만 사용 --- src/main/java/blackjack/card/Card.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/card/Card.java b/src/main/java/blackjack/card/Card.java index f29c4c9153..c9376c6723 100644 --- a/src/main/java/blackjack/card/Card.java +++ b/src/main/java/blackjack/card/Card.java @@ -13,7 +13,7 @@ public Card(Shape shape, Number number) { } public boolean isAce() { - return this.number == Number.ACE; + return number == Number.ACE; } public int getScore() { From 76bed3c0061de337336b0d578a33f0491b367e76 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 17:47:41 +0900 Subject: [PATCH 48/85] =?UTF-8?q?refactor(InputView):=20=EC=83=81=EC=88=98?= =?UTF-8?q?=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 --- src/main/java/blackjack/view/InputView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index a5d49340e4..ea46be171b 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -6,13 +6,13 @@ public class InputView { - private static final String DELIMITER = ","; + private static final String NAME_DELIMITER = ","; private final Scanner scanner = new Scanner(System.in); public List readNames() { String input = scanner.nextLine(); - String[] names = input.split(DELIMITER); + String[] names = input.split(NAME_DELIMITER); return Arrays.stream(names).toList(); } From 33d82371f2ed32c2eeccde279ee35208b8acb7f4 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 17:49:05 +0900 Subject: [PATCH 49/85] =?UTF-8?q?refactor(Display):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=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 --- src/main/java/blackjack/view/OutputView.java | 4 ++-- src/main/java/blackjack/view/display/CardNumberDisplay.java | 2 +- src/main/java/blackjack/view/display/CardShapeDisplay.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index bae37bd11c..3310fe5084 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -59,8 +59,8 @@ public void printNewLine() { } private String convertCard(Card card) { - String convertedNumber = CardNumberDisplay.fromNumber(card.getNumber()); - String convertedShape = CardShapeDisplay.fromShape(card.getShape()); + String convertedNumber = CardNumberDisplay.getDisplayByNumber(card.getNumber()); + String convertedShape = CardShapeDisplay.getDisplayByShape(card.getShape()); return convertedNumber + convertedShape; } diff --git a/src/main/java/blackjack/view/display/CardNumberDisplay.java b/src/main/java/blackjack/view/display/CardNumberDisplay.java index 75ed821008..2762ec4975 100644 --- a/src/main/java/blackjack/view/display/CardNumberDisplay.java +++ b/src/main/java/blackjack/view/display/CardNumberDisplay.java @@ -27,7 +27,7 @@ public enum CardNumberDisplay { this.display = display; } - public static String fromNumber(Number number) { + public static String getDisplayByNumber(Number number) { return Arrays.stream(CardNumberDisplay.values()) .filter(displayNumber -> displayNumber.number == number) .findFirst() diff --git a/src/main/java/blackjack/view/display/CardShapeDisplay.java b/src/main/java/blackjack/view/display/CardShapeDisplay.java index c32f754cf1..fbe580073c 100644 --- a/src/main/java/blackjack/view/display/CardShapeDisplay.java +++ b/src/main/java/blackjack/view/display/CardShapeDisplay.java @@ -18,7 +18,7 @@ public enum CardShapeDisplay { this.display = display; } - public static String fromShape(Shape shape) { + public static String getDisplayByShape(Shape shape) { return Arrays.stream(CardShapeDisplay.values()) .filter(displayShape -> displayShape.shape == shape) .findFirst() From 1f5d1ff77181762d0d581310fcc36de7dca4f1e9 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 19:30:25 +0900 Subject: [PATCH 50/85] =?UTF-8?q?test(Card):=20=EC=97=90=EC=9D=B4=EC=8A=A4?= =?UTF-8?q?=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/blackjack/card/CardTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/blackjack/card/CardTest.java b/src/test/java/blackjack/card/CardTest.java index 4eaf03e85f..557d214883 100644 --- a/src/test/java/blackjack/card/CardTest.java +++ b/src/test/java/blackjack/card/CardTest.java @@ -1,6 +1,7 @@ package blackjack.card; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -13,4 +14,16 @@ void calculateCardTest() { Card card = new Card(Shape.SPADE, Number.ACE); assertThat(card.getScore()).isEqualTo(1); } + + @Test + @DisplayName("카드가 에이스인지 확인한다.") + void isAceTest() { + Card aceCard = new Card(Shape.HEART, Number.ACE); + Card nonAceCard = new Card(Shape.CLOVER, Number.JACK); + + assertAll( + () -> assertThat(aceCard.isAce()).isTrue(), + () -> assertThat(nonAceCard.isAce()).isFalse() + ); + } } From eb15bf08ccf3b788a1a9c8275d8b49da26b1f6de Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 19:51:48 +0900 Subject: [PATCH 51/85] =?UTF-8?q?refactor(Hand):=20=EC=A0=90=EC=88=98=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Hand.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/blackjack/player/Hand.java b/src/main/java/blackjack/player/Hand.java index 140f4d3264..0a8d289d01 100644 --- a/src/main/java/blackjack/player/Hand.java +++ b/src/main/java/blackjack/player/Hand.java @@ -22,12 +22,10 @@ public class Hand { public int calculateScore() { int minimumScore = calculateMinimumScore(); - int maximumScore = calculateMaximumScore(); - - if (maximumScore > BlackJackGame.BLACKJACK_MAX_SCORE) { + if (!hasAce()) { return minimumScore; } - return maximumScore; + return changeToMaximumScore(minimumScore); } private int calculateMinimumScore() { @@ -36,15 +34,17 @@ private int calculateMinimumScore() { .reduce(0, Integer::sum); } - private int calculateMaximumScore() { - int score = calculateMinimumScore(); - boolean isAce = cards.stream() + private boolean hasAce() { + return cards.stream() .anyMatch(Card::isAce); + } - if (isAce) { - return score + ADDITIONAL_ACE_SCORE; + private int changeToMaximumScore(int minimumScore) { + int maximumScore = minimumScore + ADDITIONAL_ACE_SCORE; + if (maximumScore <= BlackJackGame.BLACKJACK_MAX_SCORE) { + return maximumScore; } - return score; + return minimumScore; } public void addCard(Card card) { From cf27355bcea7807f2a5d2fc1cf63059b22589bc5 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 20:04:19 +0900 Subject: [PATCH 52/85] =?UTF-8?q?refactor:=20=EB=93=9C=EB=A1=9C=EC=9A=B0?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/game/BlackJackGame.java | 26 +++++++++---------- src/main/java/blackjack/player/Player.java | 2 +- src/main/java/blackjack/player/Players.java | 4 +-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/blackjack/game/BlackJackGame.java b/src/main/java/blackjack/game/BlackJackGame.java index 2bf57c9431..81fd5c9dd1 100644 --- a/src/main/java/blackjack/game/BlackJackGame.java +++ b/src/main/java/blackjack/game/BlackJackGame.java @@ -25,9 +25,9 @@ public void play() { Dealer dealer = new Dealer(); Players players = createPlayers(); - initGame(deck, dealer, players); - playersDrawMore(deck, players); - dealerDrawMore(deck, dealer); + initializeGame(deck, dealer, players); + proceedPlayersTurn(deck, players); + proceedDealerTurn(deck, dealer); showCardsWithScore(dealer, players); showMatchResult(dealer, players); @@ -41,14 +41,14 @@ private Players createPlayers() { return players; } - private void initGame(Deck deck, Dealer dealer, Players players) { - players.initDrawCards(deck); - dealer.initDrawCards(deck); + private void initializeGame(Deck deck, Dealer dealer, Players players) { + players.doInitialDraw(deck); + dealer.doInitialDraw(deck); outputView.printInitializeBlackJack(players.getNames()); - showInitCard(dealer, players); + showInitialCard(dealer, players); } - private void showInitCard(Dealer dealer, Players players) { + private void showInitialCard(Dealer dealer, Players players) { outputView.printDealerFirstCard(dealer.getFirstCard()); for (Player player : players.getPlayers()) { @@ -57,14 +57,14 @@ private void showInitCard(Dealer dealer, Players players) { outputView.printNewLine(); } - private void playersDrawMore(Deck deck, Players players) { + private void proceedPlayersTurn(Deck deck, Players players) { for (Player player : players.getPlayers()) { - playerDrawMore(deck, player); + proceedPlayerTurn(deck, player); } outputView.printNewLine(); } - private void playerDrawMore(Deck deck, Player player) { + private void proceedPlayerTurn(Deck deck, Player player) { Command command = askPlayerToDrawMore(player); if (command == Command.NO) { return; @@ -73,7 +73,7 @@ private void playerDrawMore(Deck deck, Player player) { outputView.printPlayerCards(player.getName(), player.getCards()); if (player.hasDrawableScore()) { - playerDrawMore(deck, player); + proceedPlayerTurn(deck, player); } } @@ -83,7 +83,7 @@ private Command askPlayerToDrawMore(Player player) { return Command.from(input); } - private void dealerDrawMore(Deck deck, Dealer dealer) { + private void proceedDealerTurn(Deck deck, Dealer dealer) { while (dealer.hasDrawableScore()) { dealer.drawCard(deck); outputView.printDealerDrawCard(); diff --git a/src/main/java/blackjack/player/Player.java b/src/main/java/blackjack/player/Player.java index 51064fdcd9..4a86ac4991 100644 --- a/src/main/java/blackjack/player/Player.java +++ b/src/main/java/blackjack/player/Player.java @@ -23,7 +23,7 @@ public void drawCard(Deck deck) { hand.addCard(deck.draw()); } - public void initDrawCards(Deck deck) { + public void doInitialDraw(Deck deck) { drawCard(deck); drawCard(deck); } diff --git a/src/main/java/blackjack/player/Players.java b/src/main/java/blackjack/player/Players.java index 976651d94b..8592dcdd04 100644 --- a/src/main/java/blackjack/player/Players.java +++ b/src/main/java/blackjack/player/Players.java @@ -44,8 +44,8 @@ private void validateUniqueNames(List playerNames) { } } - public void initDrawCards(Deck deck) { - players.forEach(player -> player.initDrawCards(deck)); + public void doInitialDraw(Deck deck) { + players.forEach(player -> player.doInitialDraw(deck)); } public List getNames() { From 543e4a1a3361f9ae86ef7e6b5f4410e8dca629db Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 20:17:20 +0900 Subject: [PATCH 53/85] =?UTF-8?q?refactor(Command):=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=82=B4=EB=B6=80=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20No=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/game/BlackJackGame.java | 2 +- src/main/java/blackjack/game/Command.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/game/BlackJackGame.java b/src/main/java/blackjack/game/BlackJackGame.java index 81fd5c9dd1..448ee346c9 100644 --- a/src/main/java/blackjack/game/BlackJackGame.java +++ b/src/main/java/blackjack/game/BlackJackGame.java @@ -66,7 +66,7 @@ private void proceedPlayersTurn(Deck deck, Players players) { private void proceedPlayerTurn(Deck deck, Player player) { Command command = askPlayerToDrawMore(player); - if (command == Command.NO) { + if (command.isNo()) { return; } player.drawCard(deck); diff --git a/src/main/java/blackjack/game/Command.java b/src/main/java/blackjack/game/Command.java index c20616f165..1dcece9cbf 100644 --- a/src/main/java/blackjack/game/Command.java +++ b/src/main/java/blackjack/game/Command.java @@ -1,6 +1,7 @@ package blackjack.game; import java.util.Arrays; +import java.util.Objects; public enum Command { YES("y"), @@ -18,4 +19,8 @@ public static Command from(String value) { .findFirst() .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 명령어입니다.")); } + + public boolean isNo() { + return Objects.equals(value, Command.NO.value); + } } From 8c510c9283d720fd296b0882b42fc9e6cb75de0c Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 20:39:31 +0900 Subject: [PATCH 54/85] =?UTF-8?q?refactor(Rank):=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/card/Card.java | 18 ++++----- src/main/java/blackjack/card/Deck.java | 4 +- .../blackjack/card/{Number.java => Rank.java} | 4 +- src/main/java/blackjack/view/OutputView.java | 6 +-- .../view/display/CardNumberDisplay.java | 37 ------------------- .../view/display/CardRankDisplay.java | 37 +++++++++++++++++++ src/test/java/blackjack/card/CardTest.java | 6 +-- src/test/java/blackjack/card/DeckTest.java | 8 ++-- .../java/blackjack/player/DealerTest.java | 16 ++++---- src/test/java/blackjack/player/HandTest.java | 16 ++++---- .../java/blackjack/player/PlayerTest.java | 10 ++--- 11 files changed, 81 insertions(+), 81 deletions(-) rename src/main/java/blackjack/card/{Number.java => Rank.java} (87%) delete mode 100644 src/main/java/blackjack/view/display/CardNumberDisplay.java create mode 100644 src/main/java/blackjack/view/display/CardRankDisplay.java diff --git a/src/main/java/blackjack/card/Card.java b/src/main/java/blackjack/card/Card.java index c9376c6723..438e7dc4fb 100644 --- a/src/main/java/blackjack/card/Card.java +++ b/src/main/java/blackjack/card/Card.java @@ -5,27 +5,27 @@ public class Card { private final Shape shape; - private final Number number; + private final Rank rank; - public Card(Shape shape, Number number) { + public Card(Shape shape, Rank rank) { this.shape = shape; - this.number = number; + this.rank = rank; } public boolean isAce() { - return number == Number.ACE; + return rank == Rank.ACE; } public int getScore() { - return number.getScore(); + return rank.getScore(); } public Shape getShape() { return shape; } - public Number getNumber() { - return number; + public Rank getRank() { + return rank; } @Override @@ -37,11 +37,11 @@ public boolean equals(Object o) { return false; } Card card = (Card) o; - return shape == card.shape && number == card.number; + return shape == card.shape && rank == card.rank; } @Override public int hashCode() { - return Objects.hash(shape, number); + return Objects.hash(shape, rank); } } diff --git a/src/main/java/blackjack/card/Deck.java b/src/main/java/blackjack/card/Deck.java index 4eeedf8a17..50f4ccd6b2 100644 --- a/src/main/java/blackjack/card/Deck.java +++ b/src/main/java/blackjack/card/Deck.java @@ -25,8 +25,8 @@ public static Deck createShuffledFullDeck() { private static List createNumberCardsOf(Shape shape) { List cards = new ArrayList<>(); - for (Number number : Number.values()) { - cards.add(new Card(shape, number)); + for (Rank rank : Rank.values()) { + cards.add(new Card(shape, rank)); } return cards; } diff --git a/src/main/java/blackjack/card/Number.java b/src/main/java/blackjack/card/Rank.java similarity index 87% rename from src/main/java/blackjack/card/Number.java rename to src/main/java/blackjack/card/Rank.java index 2e5e6bdf70..f430ebdddc 100644 --- a/src/main/java/blackjack/card/Number.java +++ b/src/main/java/blackjack/card/Rank.java @@ -1,6 +1,6 @@ package blackjack.card; -public enum Number { +public enum Rank { ACE(1), TWO(2), @@ -18,7 +18,7 @@ public enum Number { private final int score; - Number(int score) { + Rank(int score) { this.score = score; } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 3310fe5084..ad62522533 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -2,7 +2,7 @@ import blackjack.card.Card; import blackjack.game.MatchResult; -import blackjack.view.display.CardNumberDisplay; +import blackjack.view.display.CardRankDisplay; import blackjack.view.display.CardShapeDisplay; import blackjack.view.display.PlayerResultDisplay; import java.util.List; @@ -59,9 +59,9 @@ public void printNewLine() { } private String convertCard(Card card) { - String convertedNumber = CardNumberDisplay.getDisplayByNumber(card.getNumber()); + String convertedRank = CardRankDisplay.getDisplayByRank(card.getRank()); String convertedShape = CardShapeDisplay.getDisplayByShape(card.getShape()); - return convertedNumber + convertedShape; + return convertedRank + convertedShape; } private String convertCards(List cards) { diff --git a/src/main/java/blackjack/view/display/CardNumberDisplay.java b/src/main/java/blackjack/view/display/CardNumberDisplay.java deleted file mode 100644 index 2762ec4975..0000000000 --- a/src/main/java/blackjack/view/display/CardNumberDisplay.java +++ /dev/null @@ -1,37 +0,0 @@ -package blackjack.view.display; - -import blackjack.card.Number; -import java.util.Arrays; - -public enum CardNumberDisplay { - - ACE(Number.ACE, "A"), - TWO(Number.TWO, "2"), - THREE(Number.THREE, "3"), - FOUR(Number.FOUR, "4"), - FIVE(Number.FIVE, "5"), - SIX(Number.SIX, "6"), - SEVEN(Number.SEVEN, "7"), - EIGHT(Number.EIGHT, "8"), - NINE(Number.NINE, "9"), - TEN(Number.TEN, "10"), - JACK(Number.JACK, "J"), - QUEEN(Number.QUEEN, "Q"), - KING(Number.KING, "K"); - - private final Number number; - private final String display; - - CardNumberDisplay(Number number, String display) { - this.number = number; - this.display = display; - } - - public static String getDisplayByNumber(Number number) { - return Arrays.stream(CardNumberDisplay.values()) - .filter(displayNumber -> displayNumber.number == number) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 수입니다.")) - .display; - } -} diff --git a/src/main/java/blackjack/view/display/CardRankDisplay.java b/src/main/java/blackjack/view/display/CardRankDisplay.java new file mode 100644 index 0000000000..597d2522ae --- /dev/null +++ b/src/main/java/blackjack/view/display/CardRankDisplay.java @@ -0,0 +1,37 @@ +package blackjack.view.display; + +import blackjack.card.Rank; +import java.util.Arrays; + +public enum CardRankDisplay { + + ACE(Rank.ACE, "A"), + TWO(Rank.TWO, "2"), + THREE(Rank.THREE, "3"), + FOUR(Rank.FOUR, "4"), + FIVE(Rank.FIVE, "5"), + SIX(Rank.SIX, "6"), + SEVEN(Rank.SEVEN, "7"), + EIGHT(Rank.EIGHT, "8"), + NINE(Rank.NINE, "9"), + TEN(Rank.TEN, "10"), + JACK(Rank.JACK, "J"), + QUEEN(Rank.QUEEN, "Q"), + KING(Rank.KING, "K"); + + private final Rank rank; + private final String display; + + CardRankDisplay(Rank rank, String display) { + this.rank = rank; + this.display = display; + } + + public static String getDisplayByRank(Rank rank) { + return Arrays.stream(CardRankDisplay.values()) + .filter(displayNumber -> displayNumber.rank == rank) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 수입니다.")) + .display; + } +} diff --git a/src/test/java/blackjack/card/CardTest.java b/src/test/java/blackjack/card/CardTest.java index 557d214883..f13a1c7e4b 100644 --- a/src/test/java/blackjack/card/CardTest.java +++ b/src/test/java/blackjack/card/CardTest.java @@ -11,15 +11,15 @@ class CardTest { @Test @DisplayName("카드의 점수를 정확하게 계산한다.") void calculateCardTest() { - Card card = new Card(Shape.SPADE, Number.ACE); + Card card = new Card(Shape.SPADE, Rank.ACE); assertThat(card.getScore()).isEqualTo(1); } @Test @DisplayName("카드가 에이스인지 확인한다.") void isAceTest() { - Card aceCard = new Card(Shape.HEART, Number.ACE); - Card nonAceCard = new Card(Shape.CLOVER, Number.JACK); + Card aceCard = new Card(Shape.HEART, Rank.ACE); + Card nonAceCard = new Card(Shape.CLOVER, Rank.JACK); assertAll( () -> assertThat(aceCard.isAce()).isTrue(), diff --git a/src/test/java/blackjack/card/DeckTest.java b/src/test/java/blackjack/card/DeckTest.java index bd76a3ee71..50c9e25f8e 100644 --- a/src/test/java/blackjack/card/DeckTest.java +++ b/src/test/java/blackjack/card/DeckTest.java @@ -14,12 +14,12 @@ class DeckTest { void createDeckTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.ACE), - new Card(Shape.CLOVER, Number.EIGHT), - new Card(Shape.DIAMOND, Number.JACK) + new Card(Shape.HEART, Rank.ACE), + new Card(Shape.CLOVER, Rank.EIGHT), + new Card(Shape.DIAMOND, Rank.JACK) ); Deck deck = new Deck(cards); - Card expected = new Card(Shape.HEART, Number.ACE); + Card expected = new Card(Shape.HEART, Rank.ACE); // when, then assertThat(deck.draw()).isEqualTo(expected); } diff --git a/src/test/java/blackjack/player/DealerTest.java b/src/test/java/blackjack/player/DealerTest.java index 653649c587..d9897d57b5 100644 --- a/src/test/java/blackjack/player/DealerTest.java +++ b/src/test/java/blackjack/player/DealerTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import blackjack.card.Card; -import blackjack.card.Number; +import blackjack.card.Rank; import blackjack.card.Shape; import java.util.List; import org.junit.jupiter.api.DisplayName; @@ -17,8 +17,8 @@ class DealerTest { void ableToDrawTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.JACK), - new Card(Shape.DIAMOND, Number.SIX) + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.SIX) ); Hand hand = new Hand(cards); Dealer dealer = new Dealer(hand); @@ -33,8 +33,8 @@ void ableToDrawTest() { void unableToDrawTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.JACK), - new Card(Shape.DIAMOND, Number.SEVEN) + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.SEVEN) ); Hand hand = new Hand(cards); Dealer dealer = new Dealer(hand); @@ -49,13 +49,13 @@ void unableToDrawTest() { void getFirstCardTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.JACK), - new Card(Shape.DIAMOND, Number.SEVEN) + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.SEVEN) ); Hand hand = new Hand(cards); Dealer dealer = new Dealer(hand); // when, then - assertThat(dealer.getFirstCard()).isEqualTo(new Card(Shape.HEART, Number.JACK)); + assertThat(dealer.getFirstCard()).isEqualTo(new Card(Shape.HEART, Rank.JACK)); } @Test diff --git a/src/test/java/blackjack/player/HandTest.java b/src/test/java/blackjack/player/HandTest.java index 1073f3f500..5a7e511b10 100644 --- a/src/test/java/blackjack/player/HandTest.java +++ b/src/test/java/blackjack/player/HandTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import blackjack.card.Card; -import blackjack.card.Number; +import blackjack.card.Rank; import blackjack.card.Shape; import java.util.List; import org.junit.jupiter.api.DisplayName; @@ -16,8 +16,8 @@ class HandTest { void calculateScoreTest() { // given List cards = List.of( - new Card(Shape.SPADE, Number.KING), - new Card(Shape.HEART, Number.EIGHT) + new Card(Shape.SPADE, Rank.KING), + new Card(Shape.HEART, Rank.EIGHT) ); Hand hand = new Hand(cards); // when, then @@ -29,8 +29,8 @@ void calculateScoreTest() { void calculateAceAsElevenTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.TEN), - new Card(Shape.CLOVER, Number.ACE) + new Card(Shape.HEART, Rank.TEN), + new Card(Shape.CLOVER, Rank.ACE) ); Hand hand = new Hand(cards); // when, then @@ -42,9 +42,9 @@ void calculateAceAsElevenTest() { void calculateAceAsOneTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.TEN), - new Card(Shape.CLOVER, Number.ACE), - new Card(Shape.DIAMOND, Number.TEN) + new Card(Shape.HEART, Rank.TEN), + new Card(Shape.CLOVER, Rank.ACE), + new Card(Shape.DIAMOND, Rank.TEN) ); Hand hand = new Hand(cards); // when, then diff --git a/src/test/java/blackjack/player/PlayerTest.java b/src/test/java/blackjack/player/PlayerTest.java index cfc787bc1b..3e996c6975 100644 --- a/src/test/java/blackjack/player/PlayerTest.java +++ b/src/test/java/blackjack/player/PlayerTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import blackjack.card.Card; -import blackjack.card.Number; +import blackjack.card.Rank; import blackjack.card.Shape; import java.util.List; import org.junit.jupiter.api.DisplayName; @@ -16,8 +16,8 @@ class PlayerTest { void ableToDrawTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.JACK), - new Card(Shape.DIAMOND, Number.TEN) + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.TEN) ); Hand hand = new Hand(cards); Player player = new Player("aru", hand); @@ -32,8 +32,8 @@ void ableToDrawTest() { void unableToDrawTest() { // given List cards = List.of( - new Card(Shape.HEART, Number.JACK), - new Card(Shape.DIAMOND, Number.ACE) + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.ACE) ); Hand hand = new Hand(cards); Player player = new Player("atto", hand); From 429555c1dddc07ab2e2a357089777116b47b7a5c Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 20:44:58 +0900 Subject: [PATCH 55/85] =?UTF-8?q?refactor(MatchResult):=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/game/MatchResult.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/game/MatchResult.java b/src/main/java/blackjack/game/MatchResult.java index 39032ed449..756177d0cb 100644 --- a/src/main/java/blackjack/game/MatchResult.java +++ b/src/main/java/blackjack/game/MatchResult.java @@ -17,20 +17,21 @@ public static MatchResult chooseWinner(int playerScore, int dealerScore) { } private static boolean isPlayerWinningCondition(int playerScore, int dealerScore) { - if (isBurst(playerScore)) { + if (isBust(playerScore)) { return false; } - return isBurst(dealerScore) || playerScore > dealerScore; + return isBust(dealerScore) || playerScore > dealerScore; } private static boolean isDealerWinningCondition(int playerScore, int dealerScore) { - if (isBurst(playerScore)) { + if (isBust(playerScore)) { return true; } - return !isBurst(dealerScore) && dealerScore > playerScore; + return !isBust(dealerScore) && dealerScore > playerScore; } private static boolean isBurst(int score) { + private static boolean isBust(int score) { return score > BlackJackGame.BLACKJACK_MAX_SCORE; } } From 7622c5f91f92ac2910697baafeab4205906ed8d4 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 20:48:32 +0900 Subject: [PATCH 56/85] =?UTF-8?q?refactor(Players):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Players.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/player/Players.java b/src/main/java/blackjack/player/Players.java index 8592dcdd04..f1eb33b944 100644 --- a/src/main/java/blackjack/player/Players.java +++ b/src/main/java/blackjack/player/Players.java @@ -2,6 +2,7 @@ import blackjack.card.Deck; import java.util.List; +import java.util.Set; public class Players { @@ -36,10 +37,7 @@ private void validateSize(List playerNames) { } private void validateUniqueNames(List playerNames) { - int distinctNameCount = (int) playerNames.stream() - .distinct() - .count(); - if (distinctNameCount != playerNames.size()) { + if (Set.copyOf(playerNames).size() != playerNames.size()) { throw new IllegalArgumentException("[ERROR] 이름은 중복될 수 없습니다."); } } From 560a034b0fc4d684baea434f5f51e99571f975c6 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 21:21:06 +0900 Subject: [PATCH 57/85] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=EC=97=90=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Name.java | 4 +++- src/main/java/blackjack/player/Players.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/blackjack/player/Name.java b/src/main/java/blackjack/player/Name.java index 1455dbefa9..93a4bf79fe 100644 --- a/src/main/java/blackjack/player/Name.java +++ b/src/main/java/blackjack/player/Name.java @@ -19,7 +19,9 @@ private void validateName(String name) { private void validateNameLength(String name) { if (name.length() < MIN_NAME_LENGTH || name.length() > MAX_NAME_LENGTH) { - throw new IllegalArgumentException("[ERROR] 이름은 2글자 이상 5글자 이하여야 합니다."); + throw new IllegalArgumentException( + "[ERROR] 이름은 " + MIN_NAME_LENGTH + "글자 이상 " + MAX_NAME_LENGTH + "글자 이하여야 합니다." + ); } } diff --git a/src/main/java/blackjack/player/Players.java b/src/main/java/blackjack/player/Players.java index f1eb33b944..ed18881912 100644 --- a/src/main/java/blackjack/player/Players.java +++ b/src/main/java/blackjack/player/Players.java @@ -32,7 +32,9 @@ private void validateNotNull(List playerNames) { private void validateSize(List playerNames) { if (playerNames.size() < MIN_PLAYER_COUNT || playerNames.size() > MAX_PLAYER_COUNT) { - throw new IllegalArgumentException("[ERROR] 플레이어의 수는 1명 이상 10명 이하여야 합니다."); + throw new IllegalArgumentException( + "[ERROR] 플레이어의 수는 " + MIN_PLAYER_COUNT + "명 이상 " + MAX_PLAYER_COUNT + "명 이하여야 합니다." + ); } } From 948d5698403a6ca57560086be4ab51a0c559ea53 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Mon, 11 Mar 2024 21:29:24 +0900 Subject: [PATCH 58/85] =?UTF-8?q?refactor:=20=EC=83=81=ED=98=B8=20?= =?UTF-8?q?=EC=B0=B8=EC=A1=B0=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 도메인에서 컨트롤러 참조하지 않게 수정 --- src/main/java/blackjack/game/BlackJackGame.java | 2 -- src/main/java/blackjack/game/MatchResult.java | 5 +++-- src/main/java/blackjack/player/Hand.java | 4 ++-- src/main/java/blackjack/player/Player.java | 5 +++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/blackjack/game/BlackJackGame.java b/src/main/java/blackjack/game/BlackJackGame.java index 448ee346c9..473bc42d0d 100644 --- a/src/main/java/blackjack/game/BlackJackGame.java +++ b/src/main/java/blackjack/game/BlackJackGame.java @@ -10,8 +10,6 @@ public class BlackJackGame { - public static final int BLACKJACK_MAX_SCORE = 21; - private final InputView inputView; private final OutputView outputView; diff --git a/src/main/java/blackjack/game/MatchResult.java b/src/main/java/blackjack/game/MatchResult.java index 756177d0cb..3ead44427c 100644 --- a/src/main/java/blackjack/game/MatchResult.java +++ b/src/main/java/blackjack/game/MatchResult.java @@ -6,6 +6,8 @@ public enum MatchResult { PLAYER_WIN, TIE; + private static final int BLACKJACK_MAX_SCORE = 21; + public static MatchResult chooseWinner(int playerScore, int dealerScore) { if (isPlayerWinningCondition(playerScore, dealerScore)) { return PLAYER_WIN; @@ -30,8 +32,7 @@ private static boolean isDealerWinningCondition(int playerScore, int dealerScore return !isBust(dealerScore) && dealerScore > playerScore; } - private static boolean isBurst(int score) { private static boolean isBust(int score) { - return score > BlackJackGame.BLACKJACK_MAX_SCORE; + return score > BLACKJACK_MAX_SCORE; } } diff --git a/src/main/java/blackjack/player/Hand.java b/src/main/java/blackjack/player/Hand.java index 0a8d289d01..398770c6ef 100644 --- a/src/main/java/blackjack/player/Hand.java +++ b/src/main/java/blackjack/player/Hand.java @@ -1,13 +1,13 @@ package blackjack.player; import blackjack.card.Card; -import blackjack.game.BlackJackGame; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Hand { + private static final int BLACKJACK_MAX_SCORE = 21; private static final int ADDITIONAL_ACE_SCORE = 10; private final List cards; @@ -41,7 +41,7 @@ private boolean hasAce() { private int changeToMaximumScore(int minimumScore) { int maximumScore = minimumScore + ADDITIONAL_ACE_SCORE; - if (maximumScore <= BlackJackGame.BLACKJACK_MAX_SCORE) { + if (maximumScore <= BLACKJACK_MAX_SCORE) { return maximumScore; } return minimumScore; diff --git a/src/main/java/blackjack/player/Player.java b/src/main/java/blackjack/player/Player.java index 4a86ac4991..9393372cfd 100644 --- a/src/main/java/blackjack/player/Player.java +++ b/src/main/java/blackjack/player/Player.java @@ -2,11 +2,12 @@ import blackjack.card.Card; import blackjack.card.Deck; -import blackjack.game.BlackJackGame; import java.util.List; public class Player { + private static final int BLACKJACK_MAX_SCORE = 21; + private final Name name; protected final Hand hand; @@ -29,7 +30,7 @@ public void doInitialDraw(Deck deck) { } public boolean hasDrawableScore() { - return hand.calculateScore() < BlackJackGame.BLACKJACK_MAX_SCORE; + return hand.calculateScore() < BLACKJACK_MAX_SCORE; } public String getName() { From b3cc95c58363644230dfe5a3de82b799ba16fff6 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Tue, 12 Mar 2024 13:50:19 +0900 Subject: [PATCH 59/85] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=EC=8B=9C=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=ED=9B=84=20=EC=A2=85=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/BlackJackMain.java | 6 +++++- src/main/java/blackjack/view/OutputView.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/BlackJackMain.java b/src/main/java/blackjack/BlackJackMain.java index 40f5162da6..9be8abc104 100644 --- a/src/main/java/blackjack/BlackJackMain.java +++ b/src/main/java/blackjack/BlackJackMain.java @@ -10,6 +10,10 @@ public static void main(String[] args) { InputView inputView = new InputView(); OutputView outputView = new OutputView(); BlackJackGame blackJackGame = new BlackJackGame(inputView, outputView); - blackJackGame.play(); + try { + blackJackGame.play(); + } catch (Exception e) { + outputView.printExceptionMessage(e); + } } } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index ad62522533..0518edac08 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -70,4 +70,8 @@ private String convertCards(List cards) { .toList(); return String.join(", ", convertedCards); } + + public void printExceptionMessage(Exception e) { + System.out.println(e.getMessage()); + } } From b9c066576ce91bbb428cb875a663ba18c14d51ce Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 13 Mar 2024 13:57:46 +0900 Subject: [PATCH 60/85] =?UTF-8?q?refactor(Display):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=A6=AC=ED=84=B4=20=ED=83=80=EC=9E=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/OutputView.java | 6 +++--- .../java/blackjack/view/display/CardRankDisplay.java | 9 ++++++--- .../java/blackjack/view/display/CardShapeDisplay.java | 9 ++++++--- .../java/blackjack/view/display/PlayerResultDisplay.java | 9 ++++++--- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 0518edac08..467674826c 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -50,7 +50,7 @@ public void printDealerResult(int winCount, int tieCount, int loseCount) { } public void printPlayerResult(String name, MatchResult result) { - String resultDisplay = PlayerResultDisplay.getDisplayByResult(result); + String resultDisplay = PlayerResultDisplay.getDisplayByResult(result).getDisplay(); System.out.println(name + ": " + resultDisplay); } @@ -59,8 +59,8 @@ public void printNewLine() { } private String convertCard(Card card) { - String convertedRank = CardRankDisplay.getDisplayByRank(card.getRank()); - String convertedShape = CardShapeDisplay.getDisplayByShape(card.getShape()); + String convertedRank = CardRankDisplay.getDisplayByRank(card.getRank()).getDisplay(); + String convertedShape = CardShapeDisplay.getDisplayByShape(card.getShape()).getDisplay(); return convertedRank + convertedShape; } diff --git a/src/main/java/blackjack/view/display/CardRankDisplay.java b/src/main/java/blackjack/view/display/CardRankDisplay.java index 597d2522ae..e23a8c0638 100644 --- a/src/main/java/blackjack/view/display/CardRankDisplay.java +++ b/src/main/java/blackjack/view/display/CardRankDisplay.java @@ -27,11 +27,14 @@ public enum CardRankDisplay { this.display = display; } - public static String getDisplayByRank(Rank rank) { + public static CardRankDisplay getDisplayByRank(Rank rank) { return Arrays.stream(CardRankDisplay.values()) .filter(displayNumber -> displayNumber.rank == rank) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 수입니다.")) - .display; + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 수입니다.")); + } + + public String getDisplay() { + return display; } } diff --git a/src/main/java/blackjack/view/display/CardShapeDisplay.java b/src/main/java/blackjack/view/display/CardShapeDisplay.java index fbe580073c..91226a4223 100644 --- a/src/main/java/blackjack/view/display/CardShapeDisplay.java +++ b/src/main/java/blackjack/view/display/CardShapeDisplay.java @@ -18,11 +18,14 @@ public enum CardShapeDisplay { this.display = display; } - public static String getDisplayByShape(Shape shape) { + public static CardShapeDisplay getDisplayByShape(Shape shape) { return Arrays.stream(CardShapeDisplay.values()) .filter(displayShape -> displayShape.shape == shape) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 모양입니다.")) - .display; + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 모양입니다.")); + } + + public String getDisplay() { + return display; } } diff --git a/src/main/java/blackjack/view/display/PlayerResultDisplay.java b/src/main/java/blackjack/view/display/PlayerResultDisplay.java index a828c941e0..ba320eb162 100644 --- a/src/main/java/blackjack/view/display/PlayerResultDisplay.java +++ b/src/main/java/blackjack/view/display/PlayerResultDisplay.java @@ -16,11 +16,14 @@ public enum PlayerResultDisplay { this.display = display; } - public static String getDisplayByResult(MatchResult result) { + public static PlayerResultDisplay getDisplayByResult(MatchResult result) { return Arrays.stream(values()) .filter(displayResult -> displayResult.result == result) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 결과입니다.")) - .display; + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 결과입니다.")); + } + + public String getDisplay() { + return display; } } From 5c8c80da6183775ff7f607ac33c42360fcfe3f1c Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 13 Mar 2024 13:58:35 +0900 Subject: [PATCH 61/85] =?UTF-8?q?refactor(OutputView):=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/OutputView.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 467674826c..4280c906fb 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -9,12 +9,15 @@ public class OutputView { + private static final String NAME_SEPARATOR = ", "; + private static final String CARD_SEPARATOR = ", "; + public void printNamesRequest() { System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); } public void printInitializeBlackJack(List names) { - System.out.println("딜러와 " + String.join(", ", names) + "에게 2장을 나누었습니다."); + System.out.println("딜러와 " + String.join(NAME_SEPARATOR, names) + "에게 2장을 나누었습니다."); } public void printDealerFirstCard(Card card) { @@ -68,7 +71,7 @@ private String convertCards(List cards) { List convertedCards = cards.stream() .map(this::convertCard) .toList(); - return String.join(", ", convertedCards); + return String.join(CARD_SEPARATOR, convertedCards); } public void printExceptionMessage(Exception e) { From 61950f8431a38bd48f143986750683b5f651b020 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 13 Mar 2024 22:49:26 +0900 Subject: [PATCH 62/85] =?UTF-8?q?feat(Score):=20=EC=A0=90=EC=88=98=20?= =?UTF-8?q?=EB=8D=A7=EC=85=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Score.java | 18 ++++++++++++++++++ src/test/java/blackjack/player/ScoreTest.java | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/main/java/blackjack/player/Score.java create mode 100644 src/test/java/blackjack/player/ScoreTest.java diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java new file mode 100644 index 0000000000..2d12bf24e5 --- /dev/null +++ b/src/main/java/blackjack/player/Score.java @@ -0,0 +1,18 @@ +package blackjack.player; + +public class Score { + + private int score; + + public Score(int score) { + this.score = score; + } + + public Score add(int score) { + return add(new Score(score)); + } + + public Score add(Score other) { + return new Score(this.score + other.score); + } +} diff --git a/src/test/java/blackjack/player/ScoreTest.java b/src/test/java/blackjack/player/ScoreTest.java new file mode 100644 index 0000000000..4b6f86678f --- /dev/null +++ b/src/test/java/blackjack/player/ScoreTest.java @@ -0,0 +1,17 @@ +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class ScoreTest { + + @Test + @DisplayName("점수를 더할 수 있다.") + void addScoreTest() { + Score score = new Score(2); + + assertThat(score.add(3)).isEqualTo(new Score(5)); + } +} From a1b1c15173c514a2dcf0e500da1b9c420d88e08d Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 13 Mar 2024 22:51:01 +0900 Subject: [PATCH 63/85] =?UTF-8?q?feat(Score):=20=EB=B2=84=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=97=AC=EB=B6=80=20=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Score.java | 10 ++++++++ src/test/java/blackjack/player/ScoreTest.java | 25 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java index 2d12bf24e5..38b4e5d216 100644 --- a/src/main/java/blackjack/player/Score.java +++ b/src/main/java/blackjack/player/Score.java @@ -2,6 +2,8 @@ public class Score { + private static final int BLACKJACK = 21; + private int score; public Score(int score) { @@ -15,4 +17,12 @@ public Score add(int score) { public Score add(Score other) { return new Score(this.score + other.score); } + + public boolean isBust() { + return score > BLACKJACK; + } + + public boolean isNotBust() { + return !isBust(); + } } diff --git a/src/test/java/blackjack/player/ScoreTest.java b/src/test/java/blackjack/player/ScoreTest.java index 4b6f86678f..d1d4500707 100644 --- a/src/test/java/blackjack/player/ScoreTest.java +++ b/src/test/java/blackjack/player/ScoreTest.java @@ -1,6 +1,7 @@ package blackjack.player; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -14,4 +15,28 @@ void addScoreTest() { assertThat(score.add(3)).isEqualTo(new Score(5)); } + + @Test + @DisplayName("점수가 버스트인지 판단한다.") + void isBustTest() { + Score bustScore = new Score(22); + Score notBustScore = new Score(21); + + assertAll( + () -> assertThat(bustScore.isBust()).isTrue(), + () -> assertThat(notBustScore.isBust()).isFalse() + ); + } + + @Test + @DisplayName("점수가 버스트인지 판단한다.") + void isNotBustTest() { + Score bustScore = new Score(22); + Score notBustScore = new Score(21); + + assertAll( + () -> assertThat(bustScore.isNotBust()).isFalse(), + () -> assertThat(notBustScore.isNotBust()).isTrue() + ); + } } From 3e1c8f808d39884f4ba9bf952e04285d00658776 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 13 Mar 2024 22:52:55 +0900 Subject: [PATCH 64/85] =?UTF-8?q?feat(Score):=20=EC=A0=90=EC=88=98=20?= =?UTF-8?q?=EB=8C=80=EC=86=8C=20=EB=B9=84=EA=B5=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Score.java | 8 +++++++ src/test/java/blackjack/player/ScoreTest.java | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java index 38b4e5d216..78592e1c93 100644 --- a/src/main/java/blackjack/player/Score.java +++ b/src/main/java/blackjack/player/Score.java @@ -25,4 +25,12 @@ public boolean isBust() { public boolean isNotBust() { return !isBust(); } + + public boolean isLargerThan(Score other) { + return this.score > other.score; + } + + public boolean isSmallerOrEqual(Score other) { + return !isLargerThan(other); + } } diff --git a/src/test/java/blackjack/player/ScoreTest.java b/src/test/java/blackjack/player/ScoreTest.java index d1d4500707..74214a5e55 100644 --- a/src/test/java/blackjack/player/ScoreTest.java +++ b/src/test/java/blackjack/player/ScoreTest.java @@ -39,4 +39,26 @@ void isNotBustTest() { () -> assertThat(notBustScore.isNotBust()).isTrue() ); } + + @Test + @DisplayName("점수의 대소비교가 가능하다.") + void isLargerThanTest() { + Score score = new Score(15); + + assertAll( + () -> assertThat(score.isLargerThan(new Score(14))).isTrue(), + () -> assertThat(score.isLargerThan(new Score(16))).isFalse() + ); + } + + @Test + @DisplayName("점수의 대소비교가 가능하다.") + void isSmallerThanEqualTest() { + Score score = new Score(15); + + assertAll( + () -> assertThat(score.isSmallerOrEqual(new Score(14))).isFalse(), + () -> assertThat(score.isSmallerOrEqual(new Score(16))).isTrue() + ); + } } From c99ed8e52f316dbffa31153814886eb2998f86b2 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 13 Mar 2024 22:53:59 +0900 Subject: [PATCH 65/85] =?UTF-8?q?feat(Score):=20=EC=97=90=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EB=B3=B4=EC=A0=95=20=EC=A0=90=EC=88=98=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Score.java | 9 +++++++++ src/test/java/blackjack/player/ScoreTest.java | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java index 78592e1c93..3ac2219681 100644 --- a/src/main/java/blackjack/player/Score.java +++ b/src/main/java/blackjack/player/Score.java @@ -3,6 +3,7 @@ public class Score { private static final int BLACKJACK = 21; + private static final int ADDITIONAL_ACE = 10; private int score; @@ -33,4 +34,12 @@ public boolean isLargerThan(Score other) { public boolean isSmallerOrEqual(Score other) { return !isLargerThan(other); } + + public Score changeToLargeAceScore() { + Score largeAceScore = add(ADDITIONAL_ACE); + if (largeAceScore.isBust()) { + return this; + } + return largeAceScore; + } } diff --git a/src/test/java/blackjack/player/ScoreTest.java b/src/test/java/blackjack/player/ScoreTest.java index 74214a5e55..4e307cef6f 100644 --- a/src/test/java/blackjack/player/ScoreTest.java +++ b/src/test/java/blackjack/player/ScoreTest.java @@ -61,4 +61,16 @@ void isSmallerThanEqualTest() { () -> assertThat(score.isSmallerOrEqual(new Score(16))).isTrue() ); } + + @Test + @DisplayName("보정된 에이스 점수를 계산한다.") + void changeToLargeAceTest() { + Score canChangeScore = new Score(11); + Score cantChangeScore = new Score(12); + + assertAll( + () -> assertThat(canChangeScore.changeToLargeAceScore()).isEqualTo(new Score(21)), + () -> assertThat(cantChangeScore.changeToLargeAceScore()).isEqualTo(new Score(12)) + ); + } } From c551c570b171b15be1c122d5f9da0cdec2a57cb1 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Wed, 13 Mar 2024 22:57:33 +0900 Subject: [PATCH 66/85] =?UTF-8?q?refactor:=20Score=20=EC=9D=B4=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Player의 Hand 접근제한자 변경 --- src/main/java/blackjack/card/Card.java | 3 ++- src/main/java/blackjack/card/Rank.java | 8 ++++--- src/main/java/blackjack/game/MatchResult.java | 22 ++++++++---------- .../java/blackjack/game/MatchResults.java | 3 ++- src/main/java/blackjack/player/Dealer.java | 2 +- src/main/java/blackjack/player/Hand.java | 21 ++++------------- src/main/java/blackjack/player/Player.java | 8 +++---- src/main/java/blackjack/player/Score.java | 23 +++++++++++++++++++ src/main/java/blackjack/view/OutputView.java | 7 +++--- src/test/java/blackjack/card/CardTest.java | 3 ++- .../java/blackjack/game/MatchResultTest.java | 7 +++--- .../java/blackjack/game/MatchResultsTest.java | 11 +++++---- src/test/java/blackjack/player/HandTest.java | 6 ++--- .../java/blackjack/player/PlayerTest.java | 5 ++-- 14 files changed, 72 insertions(+), 57 deletions(-) diff --git a/src/main/java/blackjack/card/Card.java b/src/main/java/blackjack/card/Card.java index 438e7dc4fb..0c0992c14b 100644 --- a/src/main/java/blackjack/card/Card.java +++ b/src/main/java/blackjack/card/Card.java @@ -1,5 +1,6 @@ package blackjack.card; +import blackjack.player.Score; import java.util.Objects; public class Card { @@ -16,7 +17,7 @@ public boolean isAce() { return rank == Rank.ACE; } - public int getScore() { + public Score getScore() { return rank.getScore(); } diff --git a/src/main/java/blackjack/card/Rank.java b/src/main/java/blackjack/card/Rank.java index f430ebdddc..826c73b8cd 100644 --- a/src/main/java/blackjack/card/Rank.java +++ b/src/main/java/blackjack/card/Rank.java @@ -1,5 +1,7 @@ package blackjack.card; +import blackjack.player.Score; + public enum Rank { ACE(1), @@ -16,13 +18,13 @@ public enum Rank { QUEEN(10), KING(10); - private final int score; + private final Score score; Rank(int score) { - this.score = score; + this.score = new Score(score); } - int getScore() { + Score getScore() { return this.score; } } diff --git a/src/main/java/blackjack/game/MatchResult.java b/src/main/java/blackjack/game/MatchResult.java index 3ead44427c..e5dd19c827 100644 --- a/src/main/java/blackjack/game/MatchResult.java +++ b/src/main/java/blackjack/game/MatchResult.java @@ -1,14 +1,14 @@ package blackjack.game; +import blackjack.player.Score; + public enum MatchResult { DEALER_WIN, PLAYER_WIN, TIE; - private static final int BLACKJACK_MAX_SCORE = 21; - - public static MatchResult chooseWinner(int playerScore, int dealerScore) { + public static MatchResult chooseWinner(Score playerScore, Score dealerScore) { if (isPlayerWinningCondition(playerScore, dealerScore)) { return PLAYER_WIN; } @@ -18,21 +18,17 @@ public static MatchResult chooseWinner(int playerScore, int dealerScore) { return TIE; } - private static boolean isPlayerWinningCondition(int playerScore, int dealerScore) { - if (isBust(playerScore)) { + private static boolean isPlayerWinningCondition(Score playerScore, Score dealerScore) { + if (playerScore.isBust()) { return false; } - return isBust(dealerScore) || playerScore > dealerScore; + return dealerScore.isBust() || playerScore.isLargerThan(dealerScore); } - private static boolean isDealerWinningCondition(int playerScore, int dealerScore) { - if (isBust(playerScore)) { + private static boolean isDealerWinningCondition(Score playerScore, Score dealerScore) { + if (playerScore.isBust()) { return true; } - return !isBust(dealerScore) && dealerScore > playerScore; - } - - private static boolean isBust(int score) { - return score > BLACKJACK_MAX_SCORE; + return dealerScore.isNotBust() && dealerScore.isLargerThan(playerScore); } } diff --git a/src/main/java/blackjack/game/MatchResults.java b/src/main/java/blackjack/game/MatchResults.java index cfca9fb911..6446f6656e 100644 --- a/src/main/java/blackjack/game/MatchResults.java +++ b/src/main/java/blackjack/game/MatchResults.java @@ -1,5 +1,6 @@ package blackjack.game; +import blackjack.player.Score; import java.util.HashMap; import java.util.Map; @@ -11,7 +12,7 @@ public MatchResults() { this.results = new HashMap<>(); } - public void addResult(String playerName, int playerScore, int dealerScore) { + public void addResult(String playerName, Score playerScore, Score dealerScore) { MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); results.put(playerName, result); } diff --git a/src/main/java/blackjack/player/Dealer.java b/src/main/java/blackjack/player/Dealer.java index e920a176b5..9048af8b55 100644 --- a/src/main/java/blackjack/player/Dealer.java +++ b/src/main/java/blackjack/player/Dealer.java @@ -25,6 +25,6 @@ public Card getFirstCard() { @Override public boolean hasDrawableScore() { - return hand.calculateScore() <= MAX_DRAWABLE_SCORE; + return getScore().isSmallerOrEqual(new Score(MAX_DRAWABLE_SCORE)); } } diff --git a/src/main/java/blackjack/player/Hand.java b/src/main/java/blackjack/player/Hand.java index 398770c6ef..ac3acbdaed 100644 --- a/src/main/java/blackjack/player/Hand.java +++ b/src/main/java/blackjack/player/Hand.java @@ -7,9 +7,6 @@ public class Hand { - private static final int BLACKJACK_MAX_SCORE = 21; - private static final int ADDITIONAL_ACE_SCORE = 10; - private final List cards; Hand(List cards) { @@ -20,18 +17,18 @@ public class Hand { this(new ArrayList<>()); } - public int calculateScore() { - int minimumScore = calculateMinimumScore(); + public Score calculateScore() { + Score minimumScore = calculateMinimumScore(); if (!hasAce()) { return minimumScore; } - return changeToMaximumScore(minimumScore); + return minimumScore.changeToLargeAceScore(); } - private int calculateMinimumScore() { + private Score calculateMinimumScore() { return cards.stream() .map(Card::getScore) - .reduce(0, Integer::sum); + .reduce(new Score(0), Score::add); } private boolean hasAce() { @@ -39,14 +36,6 @@ private boolean hasAce() { .anyMatch(Card::isAce); } - private int changeToMaximumScore(int minimumScore) { - int maximumScore = minimumScore + ADDITIONAL_ACE_SCORE; - if (maximumScore <= BLACKJACK_MAX_SCORE) { - return maximumScore; - } - return minimumScore; - } - public void addCard(Card card) { cards.add(card); } diff --git a/src/main/java/blackjack/player/Player.java b/src/main/java/blackjack/player/Player.java index 9393372cfd..e61fde1b2d 100644 --- a/src/main/java/blackjack/player/Player.java +++ b/src/main/java/blackjack/player/Player.java @@ -6,10 +6,8 @@ public class Player { - private static final int BLACKJACK_MAX_SCORE = 21; - private final Name name; - protected final Hand hand; + private final Hand hand; Player(String name, Hand hand) { this.name = new Name(name); @@ -30,14 +28,14 @@ public void doInitialDraw(Deck deck) { } public boolean hasDrawableScore() { - return hand.calculateScore() < BLACKJACK_MAX_SCORE; + return hand.calculateScore().isNotBust(); } public String getName() { return name.getName(); } - public int getScore() { + public Score getScore() { return hand.calculateScore(); } diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java index 3ac2219681..bd857c6e5c 100644 --- a/src/main/java/blackjack/player/Score.java +++ b/src/main/java/blackjack/player/Score.java @@ -1,5 +1,7 @@ package blackjack.player; +import java.util.Objects; + public class Score { private static final int BLACKJACK = 21; @@ -42,4 +44,25 @@ public Score changeToLargeAceScore() { } return largeAceScore; } + + public int getScore() { + return score; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Score score1 = (Score) o; + return score == score1.score; + } + + @Override + public int hashCode() { + return Objects.hash(score); + } } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 4280c906fb..62f42f5d44 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -2,6 +2,7 @@ import blackjack.card.Card; import blackjack.game.MatchResult; +import blackjack.player.Score; import blackjack.view.display.CardRankDisplay; import blackjack.view.display.CardShapeDisplay; import blackjack.view.display.PlayerResultDisplay; @@ -36,12 +37,12 @@ public void printDealerDrawCard() { System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); } - public void printDealerCardsWithScore(List cards, int score) { + public void printDealerCardsWithScore(List cards, Score score) { printPlayerCardsWithScore("딜러", cards, score); } - public void printPlayerCardsWithScore(String name, List cards, int score) { - System.out.println(name + " 카드: " + convertCards(cards) + " - 결과: " + score + "점"); + public void printPlayerCardsWithScore(String name, List cards, Score score) { + System.out.println(name + " 카드: " + convertCards(cards) + " - 결과: " + score.getScore() + "점"); } public void printResultStart() { diff --git a/src/test/java/blackjack/card/CardTest.java b/src/test/java/blackjack/card/CardTest.java index f13a1c7e4b..eca88ade62 100644 --- a/src/test/java/blackjack/card/CardTest.java +++ b/src/test/java/blackjack/card/CardTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import blackjack.player.Score; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -12,7 +13,7 @@ class CardTest { @DisplayName("카드의 점수를 정확하게 계산한다.") void calculateCardTest() { Card card = new Card(Shape.SPADE, Rank.ACE); - assertThat(card.getScore()).isEqualTo(1); + assertThat(card.getScore()).isEqualTo(new Score(1)); } @Test diff --git a/src/test/java/blackjack/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java index 6e4463a92f..b5236a1a4c 100644 --- a/src/test/java/blackjack/game/MatchResultTest.java +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import blackjack.player.Score; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -13,7 +14,7 @@ class MatchResultTest { @DisplayName("플레이어가 이기는 경우를 올바르게 판단한다.") void playerWinningTest(int playerScore, int dealerScore) { // when - MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); + MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); // then assertThat(result).isEqualTo(MatchResult.PLAYER_WIN); } @@ -23,7 +24,7 @@ void playerWinningTest(int playerScore, int dealerScore) { @DisplayName("딜러가 이기는 경우를 올바르게 판단한다.") void dealerWinningTest(int playerScore, int dealerScore) { // when - MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); + MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); // then assertThat(result).isEqualTo(MatchResult.DEALER_WIN); } @@ -33,7 +34,7 @@ void dealerWinningTest(int playerScore, int dealerScore) { @DisplayName("무승부인 경우를 올바르게 판단한다.") void tieTest(int playerScore, int dealerScore) { // when - MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); + MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); // then assertThat(result).isEqualTo(MatchResult.TIE); } diff --git a/src/test/java/blackjack/game/MatchResultsTest.java b/src/test/java/blackjack/game/MatchResultsTest.java index 40a5972bdd..5b3c999b09 100644 --- a/src/test/java/blackjack/game/MatchResultsTest.java +++ b/src/test/java/blackjack/game/MatchResultsTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; +import blackjack.player.Score; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -13,7 +14,7 @@ class MatchResultsTest { @DisplayName("이름으로 결과를 올바르게 가져온다.") void getResultByNameTest() { MatchResults matchResults = new MatchResults(); - matchResults.addResult("aru", 20, 21); + matchResults.addResult("aru", new Score(20), new Score(21)); assertThat(matchResults.getResultByName("aru")).isEqualTo(MatchResult.DEALER_WIN); } @@ -33,10 +34,10 @@ void nameNotFoundTest() { void getDesiredResultCountTest() { // given MatchResults matchResults = new MatchResults(); - matchResults.addResult("aru", 10, 20); - matchResults.addResult("pobi", 10, 20); - matchResults.addResult("atto", 10, 10); - matchResults.addResult("jazz", 20, 10); + matchResults.addResult("aru", new Score(10), new Score(20)); + matchResults.addResult("pobi", new Score(10), new Score(20)); + matchResults.addResult("atto", new Score(10), new Score(10)); + matchResults.addResult("jazz", new Score(20), new Score(10)); // when int playerWinCount = matchResults.getResultCount(MatchResult.PLAYER_WIN); int tieCount = matchResults.getResultCount(MatchResult.TIE); diff --git a/src/test/java/blackjack/player/HandTest.java b/src/test/java/blackjack/player/HandTest.java index 5a7e511b10..7e0b01b150 100644 --- a/src/test/java/blackjack/player/HandTest.java +++ b/src/test/java/blackjack/player/HandTest.java @@ -21,7 +21,7 @@ void calculateScoreTest() { ); Hand hand = new Hand(cards); // when, then - assertThat(hand.calculateScore()).isEqualTo(18); + assertThat(hand.calculateScore()).isEqualTo(new Score(18)); } @Test @@ -34,7 +34,7 @@ void calculateAceAsElevenTest() { ); Hand hand = new Hand(cards); // when, then - assertThat(hand.calculateScore()).isEqualTo(21); + assertThat(hand.calculateScore()).isEqualTo(new Score(21)); } @Test @@ -48,6 +48,6 @@ void calculateAceAsOneTest() { ); Hand hand = new Hand(cards); // when, then - assertThat(hand.calculateScore()).isEqualTo(21); + assertThat(hand.calculateScore()).isEqualTo(new Score(21)); } } diff --git a/src/test/java/blackjack/player/PlayerTest.java b/src/test/java/blackjack/player/PlayerTest.java index 3e996c6975..140bca5001 100644 --- a/src/test/java/blackjack/player/PlayerTest.java +++ b/src/test/java/blackjack/player/PlayerTest.java @@ -28,12 +28,13 @@ void ableToDrawTest() { } @Test - @DisplayName("플렝이어는 21점 이상이면 추가 드로우가 불가능하다.") + @DisplayName("플렝이어는 21점 초과이면 추가 드로우가 불가능하다.") void unableToDrawTest() { // given List cards = List.of( new Card(Shape.HEART, Rank.JACK), - new Card(Shape.DIAMOND, Rank.ACE) + new Card(Shape.DIAMOND, Rank.TEN), + new Card(Shape.DIAMOND, Rank.TWO) ); Hand hand = new Hand(cards); Player player = new Player("atto", hand); From 28dd3a139f3393a03dee81f8bacdf5d52ce0e3f6 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 14 Mar 2024 01:22:35 +0900 Subject: [PATCH 67/85] =?UTF-8?q?test(Deck):=20=EB=8D=B1=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 --- src/main/java/blackjack/card/Deck.java | 6 +++++- src/test/java/blackjack/card/DeckTest.java | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/blackjack/card/Deck.java b/src/main/java/blackjack/card/Deck.java index 50f4ccd6b2..9ed021cc26 100644 --- a/src/main/java/blackjack/card/Deck.java +++ b/src/main/java/blackjack/card/Deck.java @@ -23,7 +23,7 @@ public static Deck createShuffledFullDeck() { return new Deck(cards); } - private static List createNumberCardsOf(Shape shape) { + static List createNumberCardsOf(Shape shape) { List cards = new ArrayList<>(); for (Rank rank : Rank.values()) { cards.add(new Card(shape, rank)); @@ -37,4 +37,8 @@ public Card draw() { } return cards.poll(); } + + int size() { + return cards.size(); + } } diff --git a/src/test/java/blackjack/card/DeckTest.java b/src/test/java/blackjack/card/DeckTest.java index 50c9e25f8e..0ff6dab591 100644 --- a/src/test/java/blackjack/card/DeckTest.java +++ b/src/test/java/blackjack/card/DeckTest.java @@ -34,4 +34,18 @@ void emptyDeckDrawTest() { .isInstanceOf(IllegalStateException.class) .hasMessage("[ERROR] 덱이 비어있습니다."); } + + @Test + @DisplayName("원하는 모양의 카드 전체가 생성된다.") + void createNumberCardsOfShapeTest() { + assertThat(Deck.createNumberCardsOf(Shape.CLOVER).size()).isEqualTo(13); + } + + @Test + @DisplayName("카드 전체가 생성된다.") + void createFullDeckTest() { + Deck deck = Deck.createShuffledFullDeck(); + + assertThat(deck.size()).isEqualTo(52); + } } From dc1689886b1b9ffd4fb3f5a678b833a15b11a478 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Thu, 14 Mar 2024 11:03:17 +0900 Subject: [PATCH 68/85] =?UTF-8?q?refactor(Score):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B2=88=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Dealer.java | 2 +- src/main/java/blackjack/player/Score.java | 2 +- src/test/java/blackjack/player/ScoreTest.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/blackjack/player/Dealer.java b/src/main/java/blackjack/player/Dealer.java index 9048af8b55..76c67ec1de 100644 --- a/src/main/java/blackjack/player/Dealer.java +++ b/src/main/java/blackjack/player/Dealer.java @@ -25,6 +25,6 @@ public Card getFirstCard() { @Override public boolean hasDrawableScore() { - return getScore().isSmallerOrEqual(new Score(MAX_DRAWABLE_SCORE)); + return getScore().isSmallerThanOrEqualTo(new Score(MAX_DRAWABLE_SCORE)); } } diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java index bd857c6e5c..3ee3d2dfc4 100644 --- a/src/main/java/blackjack/player/Score.java +++ b/src/main/java/blackjack/player/Score.java @@ -33,7 +33,7 @@ public boolean isLargerThan(Score other) { return this.score > other.score; } - public boolean isSmallerOrEqual(Score other) { + public boolean isSmallerThanOrEqualTo(Score other) { return !isLargerThan(other); } diff --git a/src/test/java/blackjack/player/ScoreTest.java b/src/test/java/blackjack/player/ScoreTest.java index 4e307cef6f..c3141344aa 100644 --- a/src/test/java/blackjack/player/ScoreTest.java +++ b/src/test/java/blackjack/player/ScoreTest.java @@ -57,8 +57,8 @@ void isSmallerThanEqualTest() { Score score = new Score(15); assertAll( - () -> assertThat(score.isSmallerOrEqual(new Score(14))).isFalse(), - () -> assertThat(score.isSmallerOrEqual(new Score(16))).isTrue() + () -> assertThat(score.isSmallerThanOrEqualTo(new Score(14))).isFalse(), + () -> assertThat(score.isSmallerThanOrEqualTo(new Score(16))).isTrue() ); } From a8150b929d12034c847a752cd3b4fa4c7f656dc7 Mon Sep 17 00:00:00 2001 From: hyxrxn <89867757+hyxrxn@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:59:14 +0900 Subject: [PATCH 69/85] =?UTF-8?q?[=EB=B8=94=EB=9E=99=EC=9E=AD=20-=201?= =?UTF-8?q?=EB=8B=A8=EA=B3=84]=20=EC=95=84=ED=86=A0(=EC=9D=B4=ED=98=9C?= =?UTF-8?q?=EB=A6=B0)=20=EB=AF=B8=EC=85=98=20=EC=A0=9C=EC=B6=9C=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.=20(#593)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: 컨벤션 및 기능 요구사항 작성 Co-authored-by: donghoony * chore: remove gitkeep Co-authored-by: donghoony * feat(Card): 카드 점수 계산 Co-authored-by: donghoony * feat(Deck): 덱에서 카드 한 장 드로우 Co-authored-by: donghoony * feat(Deck): 비어있는 덱에서 드로우할 때 예외 처리 Co-authored-by: donghoony * feat(Player): 플레이어 점수 계산 Co-authored-by: donghoony * feat(Dealer): 딜러의 점수에 따른 카드 드로우 Co-authored-by: donghoony * feat(Dealer): 주어진 점수에 따른 승패 판단 Co-authored-by: donghoony * feat(Hand): Ace 점수를 유리한 방향으로 계산 - 기능을 추가하며 클래스 분리 (Player -> Hand) Co-authored-by: donghoony * refactor(Player): 드로우 가능 여부 판단 메서드 위치 변경 Co-authored-by: donghoony * feat(Name): 이름 생성 및 검증 Co-authored-by: donghoony * feat(Players): 플레이어들 생성 및 검증 Co-authored-by: donghoony * feat(View): 콘솔 입출력 Co-authored-by: donghoony * feat(CardDisplay): 카드의 모양과 수의 표현 방식 설정 Co-authored-by: donghoony * refactor(Player): 게임 상수 추출 및 드로우 조건 수정 Co-authored-by: donghoony * feat(MatchResult): 게임 결과 판단 Co-authored-by: donghoony * feat(MatchResults): 게임 결과 저장 Co-authored-by: donghoony * feat(Deck): Shape와 Number의 조합으로 한 세트 생성 Co-authored-by: donghoony * feat(Command): 사용자의 명령어 변환 Co-authored-by: donghoony * refactor(OutputView): 매개변수로 `Card`를 받도록 수정 - `Card`에 포함되는 모양과 수는 변하지 않고, 불변 객체이므로 그대로 전달 Co-authored-by: donghoony * feat(Display): 플레이어의 결과 표현 방식 설정 Co-authored-by: donghoony * feat(BlackJackGame): 게임 흐름 제어 Co-authored-by: donghoony * feat(BlackJackMain): 의존성 설정 및 실행 Co-authored-by: donghoony * refactor(BlackJackGame): 메서드 분리 Co-authored-by: donghoony * refactor(Players): 불필요한 래핑 제거 - `toList`는 변경 불가능한 리스트를 반환하므로 `unmodifiableList` 제거 Co-authored-by: donghoony * style(Shape): 불필요한 세미콜론 제거 Co-authored-by: donghoony * refactor: 상수 추출 Co-authored-by: donghoony * refactor(OutputView): 메서드 분리 Co-authored-by: donghoony * refactor: 패키지 이동 Co-authored-by: donghoony * test(Player): 드로우 가능 여부 판단 Co-authored-by: donghoony * fix(Dealer): 카드를 가지고 있지 않은 경우 예외 처리 Co-authored-by: donghoony * refactor(Deck): 덱 생성 정적 메서드 추가 Co-authored-by: donghoony * refactor(Hand): 접근 제한자 변경 Co-authored-by: donghoony * refactor(Deck): 메서드 분리 Co-authored-by: donghoony * refactor(Display): 패키지 분리 Co-authored-by: donghoony * style(Number): 파일 끝 공백 추가 Co-authored-by: donghoony * refactor: 메서드 순서 변경 Co-authored-by: donghoony * refactor: 패키지 이동 - 컨벤션에 맞게 import 순서 변경 Co-authored-by: donghoony * style: 불필요한 개행 삭제 - 컨벤션에 맞게 import 순서 변경 Co-authored-by: donghoony * style(Hand): 가독성을 위한 변수 위치 및 줄바꿈 수정 Co-authored-by: donghoony * refactor(MatchResult): 승리 조건 별 메서드 분리 Co-authored-by: donghoony * test(MatchResult): 승리 조건 테스트 데이터 보강 Co-authored-by: donghoony * style: 테스트 클래스 접근제한자 삭제 Co-authored-by: donghoony * refactor(OutputView): 중복 코드 제거 및 메서드명 번경 Co-authored-by: donghoony * style: 개행 및 오타 수정 Co-authored-by: donghoony * docs: 기능 구현 사항 추가 * refactor(Card): this 사용 일관성 고려해 수정 - 파라미터와 구분이 되지 않는 경우만 사용 * refactor(InputView): 상수명 수정 * refactor(Display): 메서드명 수정 * test(Card): 에이스 여부 확인 * refactor(Hand): 점수 계산 로직 수정 * refactor: 드로우 관련 메서드명 변경 * refactor(Command): 클래스 내부 메서드로 No 여부 확인 * refactor(Rank): 클래스명 변경 * refactor(MatchResult): 메서드명 변경 * refactor(Players): 메서드 간소화 * refactor: 예외 메시지에서 상수 사용 * refactor: 상호 참조 제외 - 도메인에서 컨트롤러 참조하지 않게 수정 * refactor: 예외 발생시 메시지 출력 후 종료 * refactor(Display): 메서드 리턴 타입 변경 * refactor(OutputView): 상수 추출 * feat(Score): 점수 덧셈 * feat(Score): 버스트 여부 판단 * feat(Score): 점수 대소 비교 * feat(Score): 에이스 보정 점수 계산 * refactor: Score 이용 - Player의 Hand 접근제한자 변경 * test(Deck): 덱 생성 * refactor(Score): 메서드명 번경 --------- Co-authored-by: donghoony --- README.md | 53 ++++++- src/main/java/.gitkeep | 0 src/main/java/blackjack/BlackJackMain.java | 19 +++ src/main/java/blackjack/card/Card.java | 48 +++++++ src/main/java/blackjack/card/Deck.java | 44 ++++++ src/main/java/blackjack/card/Rank.java | 30 ++++ src/main/java/blackjack/card/Shape.java | 9 ++ .../java/blackjack/game/BlackJackGame.java | 130 ++++++++++++++++++ src/main/java/blackjack/game/Command.java | 26 ++++ src/main/java/blackjack/game/MatchResult.java | 34 +++++ .../java/blackjack/game/MatchResults.java | 33 +++++ src/main/java/blackjack/player/Dealer.java | 30 ++++ src/main/java/blackjack/player/Hand.java | 46 +++++++ src/main/java/blackjack/player/Name.java | 37 +++++ src/main/java/blackjack/player/Player.java | 45 ++++++ src/main/java/blackjack/player/Players.java | 60 ++++++++ src/main/java/blackjack/player/Score.java | 68 +++++++++ src/main/java/blackjack/view/InputView.java | 22 +++ src/main/java/blackjack/view/OutputView.java | 81 +++++++++++ .../view/display/CardRankDisplay.java | 40 ++++++ .../view/display/CardShapeDisplay.java | 31 +++++ .../view/display/PlayerResultDisplay.java | 29 ++++ src/test/java/.gitkeep | 0 src/test/java/blackjack/card/CardTest.java | 30 ++++ src/test/java/blackjack/card/DeckTest.java | 51 +++++++ src/test/java/blackjack/game/CommandTest.java | 32 +++++ .../java/blackjack/game/MatchResultTest.java | 41 ++++++ .../java/blackjack/game/MatchResultsTest.java | 52 +++++++ .../java/blackjack/player/DealerTest.java | 73 ++++++++++ src/test/java/blackjack/player/HandTest.java | 53 +++++++ src/test/java/blackjack/player/NameTest.java | 37 +++++ .../java/blackjack/player/PlayerTest.java | 46 +++++++ .../java/blackjack/player/PlayersTest.java | 51 +++++++ src/test/java/blackjack/player/ScoreTest.java | 76 ++++++++++ 34 files changed, 1455 insertions(+), 2 deletions(-) delete mode 100644 src/main/java/.gitkeep create mode 100644 src/main/java/blackjack/BlackJackMain.java create mode 100644 src/main/java/blackjack/card/Card.java create mode 100644 src/main/java/blackjack/card/Deck.java create mode 100644 src/main/java/blackjack/card/Rank.java create mode 100644 src/main/java/blackjack/card/Shape.java create mode 100644 src/main/java/blackjack/game/BlackJackGame.java create mode 100644 src/main/java/blackjack/game/Command.java create mode 100644 src/main/java/blackjack/game/MatchResult.java create mode 100644 src/main/java/blackjack/game/MatchResults.java create mode 100644 src/main/java/blackjack/player/Dealer.java create mode 100644 src/main/java/blackjack/player/Hand.java create mode 100644 src/main/java/blackjack/player/Name.java create mode 100644 src/main/java/blackjack/player/Player.java create mode 100644 src/main/java/blackjack/player/Players.java create mode 100644 src/main/java/blackjack/player/Score.java create mode 100644 src/main/java/blackjack/view/InputView.java create mode 100644 src/main/java/blackjack/view/OutputView.java create mode 100644 src/main/java/blackjack/view/display/CardRankDisplay.java create mode 100644 src/main/java/blackjack/view/display/CardShapeDisplay.java create mode 100644 src/main/java/blackjack/view/display/PlayerResultDisplay.java delete mode 100644 src/test/java/.gitkeep create mode 100644 src/test/java/blackjack/card/CardTest.java create mode 100644 src/test/java/blackjack/card/DeckTest.java create mode 100644 src/test/java/blackjack/game/CommandTest.java create mode 100644 src/test/java/blackjack/game/MatchResultTest.java create mode 100644 src/test/java/blackjack/game/MatchResultsTest.java create mode 100644 src/test/java/blackjack/player/DealerTest.java create mode 100644 src/test/java/blackjack/player/HandTest.java create mode 100644 src/test/java/blackjack/player/NameTest.java create mode 100644 src/test/java/blackjack/player/PlayerTest.java create mode 100644 src/test/java/blackjack/player/PlayersTest.java create mode 100644 src/test/java/blackjack/player/ScoreTest.java diff --git a/README.md b/README.md index 556099c4de..7f90631694 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,55 @@ 블랙잭 미션 저장소 -## 우아한테크코스 코드리뷰 +## 페어와 지킬 컨벤션 +1. 클래스 정의 다음 줄은 공백으로 한다. +2. test code에 사용하는 메서드는 `static import`한다. -- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) +## 요구사항 +### 카드 +- [x] 카드는 모양과 수로 이루어져 있다. + - [x] 모양으로는 스페이드, 다이아, 하트, 클로버가 있다. + - [x] 수로는 Ace, King, Queen, Jack과 2 이상 10 이하의 정수가 있다. +- [x] 카드의 숫자 계산은 카드 숫자를 기본으로 한다. + - [x] Ace는 1 또는 11로 계산할 수 있다. + - [x] King, Queen, Jack은 각각 10으로 계산한다. + +### 덱 +- [x] 맨 위의 카드 한 장을 뽑는다. +- [x] 덱에 카드가 없는 경우, 예외를 발생한다. + +### 플레이어 +- [x] 덱에서 카드를 한 장 뽑는다. +- [x] 지금까지 뽑은 카드의 점수를 계산한다. + +### 이름 +- [x] 이름은 2글자 이상 5글자 이하이다. +- [x] 이름은 공백으로만 구성될 수 없다. + +### 플레이어들 +- [x] 플레이어들의 이름은 중복될 수 없다. +- [x] 플레이어들의 인원수는 1명 이상 10명 이하이다. + +### 딜러 +- [x] 플레이어의 기능을 상속한다. +- [x] 17점 이상이 될 때까지 카드를 계속 뽑는다. + +### 게임 결과 +- [x] 게임 결과를 아래의 순서대로 올바르게 판단한다. + 1. 플레이어의 점수가 21점을 초과하면 딜러가 승리한다. + 2. 플레이어의 점수가 21점을 초과하지 않으면서 딜러의 점수가 21점을 초과하면 플레이어가 승리한다. + 3. 딜러와 플레이어의 점수를 비교해 승패를 결정한다. + 4. 점수가 같으면 무승부이다. +- [x] 각 플레이어별 게임 결과를 저장한다. + +--- + +### 게임 흐름 +- [x] (hit, stand) 21을 넘지 않을 경우 원한다면 카드를 계속 뽑을 수 있다. +- [x] 게임이 시작할 때 딜러와 플레이어는 두 장의 카드를 지급 받는다. +- [x] 플레이어의 카드는 모두에게 공개된다. +- [x] 딜러의 두 번째 카드는 공개되지 않는다. +- [x] 플레이어가 카드를 새로 뽑을 때마다 카드 현황을 공개한다. +- [x] 각 플레이어는 딜러와만 승패를 겨룬다. +- [x] 딜러는 모든 플레이어와 승패를 겨룬다. +- [x] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 승패를 확인한다. diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/blackjack/BlackJackMain.java b/src/main/java/blackjack/BlackJackMain.java new file mode 100644 index 0000000000..9be8abc104 --- /dev/null +++ b/src/main/java/blackjack/BlackJackMain.java @@ -0,0 +1,19 @@ +package blackjack; + +import blackjack.game.BlackJackGame; +import blackjack.view.InputView; +import blackjack.view.OutputView; + +public class BlackJackMain { + + public static void main(String[] args) { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + BlackJackGame blackJackGame = new BlackJackGame(inputView, outputView); + try { + blackJackGame.play(); + } catch (Exception e) { + outputView.printExceptionMessage(e); + } + } +} diff --git a/src/main/java/blackjack/card/Card.java b/src/main/java/blackjack/card/Card.java new file mode 100644 index 0000000000..0c0992c14b --- /dev/null +++ b/src/main/java/blackjack/card/Card.java @@ -0,0 +1,48 @@ +package blackjack.card; + +import blackjack.player.Score; +import java.util.Objects; + +public class Card { + + private final Shape shape; + private final Rank rank; + + public Card(Shape shape, Rank rank) { + this.shape = shape; + this.rank = rank; + } + + public boolean isAce() { + return rank == Rank.ACE; + } + + public Score getScore() { + return rank.getScore(); + } + + public Shape getShape() { + return shape; + } + + public Rank getRank() { + return rank; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Card card = (Card) o; + return shape == card.shape && rank == card.rank; + } + + @Override + public int hashCode() { + return Objects.hash(shape, rank); + } +} diff --git a/src/main/java/blackjack/card/Deck.java b/src/main/java/blackjack/card/Deck.java new file mode 100644 index 0000000000..9ed021cc26 --- /dev/null +++ b/src/main/java/blackjack/card/Deck.java @@ -0,0 +1,44 @@ +package blackjack.card; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class Deck { + + private final Queue cards; + + Deck(List cards) { + this.cards = new LinkedList<>(cards); + } + + public static Deck createShuffledFullDeck() { + List cards = new LinkedList<>(); + for (Shape shape : Shape.values()) { + cards.addAll(createNumberCardsOf(shape)); + } + Collections.shuffle(cards); + return new Deck(cards); + } + + static List createNumberCardsOf(Shape shape) { + List cards = new ArrayList<>(); + for (Rank rank : Rank.values()) { + cards.add(new Card(shape, rank)); + } + return cards; + } + + public Card draw() { + if (cards.isEmpty()) { + throw new IllegalStateException("[ERROR] 덱이 비어있습니다."); + } + return cards.poll(); + } + + int size() { + return cards.size(); + } +} diff --git a/src/main/java/blackjack/card/Rank.java b/src/main/java/blackjack/card/Rank.java new file mode 100644 index 0000000000..826c73b8cd --- /dev/null +++ b/src/main/java/blackjack/card/Rank.java @@ -0,0 +1,30 @@ +package blackjack.card; + +import blackjack.player.Score; + +public enum Rank { + + ACE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + TEN(10), + JACK(10), + QUEEN(10), + KING(10); + + private final Score score; + + Rank(int score) { + this.score = new Score(score); + } + + Score getScore() { + return this.score; + } +} diff --git a/src/main/java/blackjack/card/Shape.java b/src/main/java/blackjack/card/Shape.java new file mode 100644 index 0000000000..4ebd32ecc6 --- /dev/null +++ b/src/main/java/blackjack/card/Shape.java @@ -0,0 +1,9 @@ +package blackjack.card; + +public enum Shape { + + HEART, + SPADE, + CLOVER, + DIAMOND +} diff --git a/src/main/java/blackjack/game/BlackJackGame.java b/src/main/java/blackjack/game/BlackJackGame.java new file mode 100644 index 0000000000..473bc42d0d --- /dev/null +++ b/src/main/java/blackjack/game/BlackJackGame.java @@ -0,0 +1,130 @@ +package blackjack.game; + +import blackjack.card.Deck; +import blackjack.player.Dealer; +import blackjack.player.Player; +import blackjack.player.Players; +import blackjack.view.InputView; +import blackjack.view.OutputView; +import java.util.List; + +public class BlackJackGame { + + private final InputView inputView; + private final OutputView outputView; + + public BlackJackGame(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void play() { + Deck deck = Deck.createShuffledFullDeck(); + Dealer dealer = new Dealer(); + + Players players = createPlayers(); + initializeGame(deck, dealer, players); + proceedPlayersTurn(deck, players); + proceedDealerTurn(deck, dealer); + + showCardsWithScore(dealer, players); + showMatchResult(dealer, players); + } + + private Players createPlayers() { + outputView.printNamesRequest(); + List names = inputView.readNames(); + Players players = new Players(names); + outputView.printNewLine(); + return players; + } + + private void initializeGame(Deck deck, Dealer dealer, Players players) { + players.doInitialDraw(deck); + dealer.doInitialDraw(deck); + outputView.printInitializeBlackJack(players.getNames()); + showInitialCard(dealer, players); + } + + private void showInitialCard(Dealer dealer, Players players) { + outputView.printDealerFirstCard(dealer.getFirstCard()); + + for (Player player : players.getPlayers()) { + outputView.printPlayerCards(player.getName(), player.getCards()); + } + outputView.printNewLine(); + } + + private void proceedPlayersTurn(Deck deck, Players players) { + for (Player player : players.getPlayers()) { + proceedPlayerTurn(deck, player); + } + outputView.printNewLine(); + } + + private void proceedPlayerTurn(Deck deck, Player player) { + Command command = askPlayerToDrawMore(player); + if (command.isNo()) { + return; + } + player.drawCard(deck); + outputView.printPlayerCards(player.getName(), player.getCards()); + + if (player.hasDrawableScore()) { + proceedPlayerTurn(deck, player); + } + } + + private Command askPlayerToDrawMore(Player player) { + outputView.printDrawMoreCardRequest(player.getName()); + String input = inputView.readCommand(); + return Command.from(input); + } + + private void proceedDealerTurn(Deck deck, Dealer dealer) { + while (dealer.hasDrawableScore()) { + dealer.drawCard(deck); + outputView.printDealerDrawCard(); + outputView.printNewLine(); + } + } + + private void showCardsWithScore(Dealer dealer, Players players) { + outputView.printDealerCardsWithScore(dealer.getCards(), dealer.getScore()); + for (Player player : players.getPlayers()) { + outputView.printPlayerCardsWithScore(player.getName(), player.getCards(), player.getScore()); + } + outputView.printNewLine(); + } + + private void showMatchResult(Dealer dealer, Players players) { + MatchResults matchResults = calculateMatchResults(dealer, players); + outputView.printResultStart(); + showDealerResult(matchResults); + showPlayersResult(players, matchResults); + } + + private MatchResults calculateMatchResults(Dealer dealer, Players players) { + MatchResults matchResults = new MatchResults(); + for (Player player : players.getPlayers()) { + matchResults.addResult(player.getName(), player.getScore(), dealer.getScore()); + } + return matchResults; + } + + private void showDealerResult(MatchResults matchResults) { + outputView.printDealerResult( + matchResults.getResultCount(MatchResult.DEALER_WIN), + matchResults.getResultCount(MatchResult.TIE), + matchResults.getResultCount(MatchResult.PLAYER_WIN) + ); + } + + private void showPlayersResult(Players players, MatchResults matchResults) { + for (Player player : players.getPlayers()) { + String playerName = player.getName(); + MatchResult result = matchResults.getResultByName(playerName); + outputView.printPlayerResult(playerName, result); + } + } +} diff --git a/src/main/java/blackjack/game/Command.java b/src/main/java/blackjack/game/Command.java new file mode 100644 index 0000000000..1dcece9cbf --- /dev/null +++ b/src/main/java/blackjack/game/Command.java @@ -0,0 +1,26 @@ +package blackjack.game; + +import java.util.Arrays; +import java.util.Objects; + +public enum Command { + YES("y"), + NO("n"); + + private final String value; + + Command(String value) { + this.value = value; + } + + public static Command from(String value) { + return Arrays.stream(values()) + .filter(command -> command.value.equals(value)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 명령어입니다.")); + } + + public boolean isNo() { + return Objects.equals(value, Command.NO.value); + } +} diff --git a/src/main/java/blackjack/game/MatchResult.java b/src/main/java/blackjack/game/MatchResult.java new file mode 100644 index 0000000000..e5dd19c827 --- /dev/null +++ b/src/main/java/blackjack/game/MatchResult.java @@ -0,0 +1,34 @@ +package blackjack.game; + +import blackjack.player.Score; + +public enum MatchResult { + + DEALER_WIN, + PLAYER_WIN, + TIE; + + public static MatchResult chooseWinner(Score playerScore, Score dealerScore) { + if (isPlayerWinningCondition(playerScore, dealerScore)) { + return PLAYER_WIN; + } + if (isDealerWinningCondition(playerScore, dealerScore)) { + return DEALER_WIN; + } + return TIE; + } + + private static boolean isPlayerWinningCondition(Score playerScore, Score dealerScore) { + if (playerScore.isBust()) { + return false; + } + return dealerScore.isBust() || playerScore.isLargerThan(dealerScore); + } + + private static boolean isDealerWinningCondition(Score playerScore, Score dealerScore) { + if (playerScore.isBust()) { + return true; + } + return dealerScore.isNotBust() && dealerScore.isLargerThan(playerScore); + } +} diff --git a/src/main/java/blackjack/game/MatchResults.java b/src/main/java/blackjack/game/MatchResults.java new file mode 100644 index 0000000000..6446f6656e --- /dev/null +++ b/src/main/java/blackjack/game/MatchResults.java @@ -0,0 +1,33 @@ +package blackjack.game; + +import blackjack.player.Score; +import java.util.HashMap; +import java.util.Map; + +public class MatchResults { + + private final Map results; + + public MatchResults() { + this.results = new HashMap<>(); + } + + public void addResult(String playerName, Score playerScore, Score dealerScore) { + MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); + results.put(playerName, result); + } + + public MatchResult getResultByName(String playerName) { + if (!results.containsKey(playerName)) { + throw new IllegalArgumentException("[ERROR] 존재하지 않는 이름입니다."); + } + return results.get(playerName); + } + + public int getResultCount(MatchResult result) { + return (int) results.values() + .stream() + .filter(matchResult -> matchResult == result) + .count(); + } +} diff --git a/src/main/java/blackjack/player/Dealer.java b/src/main/java/blackjack/player/Dealer.java new file mode 100644 index 0000000000..76c67ec1de --- /dev/null +++ b/src/main/java/blackjack/player/Dealer.java @@ -0,0 +1,30 @@ +package blackjack.player; + +import blackjack.card.Card; +import java.util.List; + +public class Dealer extends Player { + + private static final int MAX_DRAWABLE_SCORE = 16; + + public Dealer() { + super("딜러"); + } + + Dealer(Hand hand) { + super("딜러", hand); + } + + public Card getFirstCard() { + List cards = super.getCards(); + if (cards.isEmpty()) { + throw new IllegalStateException("[ERROR] 딜러가 카드를 가지고 있지 않습니다."); + } + return cards.get(0); + } + + @Override + public boolean hasDrawableScore() { + return getScore().isSmallerThanOrEqualTo(new Score(MAX_DRAWABLE_SCORE)); + } +} diff --git a/src/main/java/blackjack/player/Hand.java b/src/main/java/blackjack/player/Hand.java new file mode 100644 index 0000000000..ac3acbdaed --- /dev/null +++ b/src/main/java/blackjack/player/Hand.java @@ -0,0 +1,46 @@ +package blackjack.player; + +import blackjack.card.Card; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Hand { + + private final List cards; + + Hand(List cards) { + this.cards = cards; + } + + Hand() { + this(new ArrayList<>()); + } + + public Score calculateScore() { + Score minimumScore = calculateMinimumScore(); + if (!hasAce()) { + return minimumScore; + } + return minimumScore.changeToLargeAceScore(); + } + + private Score calculateMinimumScore() { + return cards.stream() + .map(Card::getScore) + .reduce(new Score(0), Score::add); + } + + private boolean hasAce() { + return cards.stream() + .anyMatch(Card::isAce); + } + + public void addCard(Card card) { + cards.add(card); + } + + public List getCards() { + return Collections.unmodifiableList(cards); + } +} diff --git a/src/main/java/blackjack/player/Name.java b/src/main/java/blackjack/player/Name.java new file mode 100644 index 0000000000..93a4bf79fe --- /dev/null +++ b/src/main/java/blackjack/player/Name.java @@ -0,0 +1,37 @@ +package blackjack.player; + +public class Name { + + private static final int MIN_NAME_LENGTH = 2; + private static final int MAX_NAME_LENGTH = 5; + + private final String name; + + Name(String name) { + validateName(name); + this.name = name; + } + + private void validateName(String name) { + validateNonBlankName(name); + validateNameLength(name); + } + + private void validateNameLength(String name) { + if (name.length() < MIN_NAME_LENGTH || name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException( + "[ERROR] 이름은 " + MIN_NAME_LENGTH + "글자 이상 " + MAX_NAME_LENGTH + "글자 이하여야 합니다." + ); + } + } + + private void validateNonBlankName(String name) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("[ERROR] 이름은 공백일 수 없습니다."); + } + } + + String getName() { + return name; + } +} diff --git a/src/main/java/blackjack/player/Player.java b/src/main/java/blackjack/player/Player.java new file mode 100644 index 0000000000..e61fde1b2d --- /dev/null +++ b/src/main/java/blackjack/player/Player.java @@ -0,0 +1,45 @@ +package blackjack.player; + +import blackjack.card.Card; +import blackjack.card.Deck; +import java.util.List; + +public class Player { + + private final Name name; + private final Hand hand; + + Player(String name, Hand hand) { + this.name = new Name(name); + this.hand = hand; + } + + Player(String name) { + this(name, new Hand()); + } + + public void drawCard(Deck deck) { + hand.addCard(deck.draw()); + } + + public void doInitialDraw(Deck deck) { + drawCard(deck); + drawCard(deck); + } + + public boolean hasDrawableScore() { + return hand.calculateScore().isNotBust(); + } + + public String getName() { + return name.getName(); + } + + public Score getScore() { + return hand.calculateScore(); + } + + public List getCards() { + return hand.getCards(); + } +} diff --git a/src/main/java/blackjack/player/Players.java b/src/main/java/blackjack/player/Players.java new file mode 100644 index 0000000000..ed18881912 --- /dev/null +++ b/src/main/java/blackjack/player/Players.java @@ -0,0 +1,60 @@ +package blackjack.player; + +import blackjack.card.Deck; +import java.util.List; +import java.util.Set; + +public class Players { + + private static final int MIN_PLAYER_COUNT = 1; + private static final int MAX_PLAYER_COUNT = 10; + + private final List players; + + public Players(List playerNames) { + validatePlayers(playerNames); + this.players = playerNames.stream() + .map(Player::new) + .toList(); + } + + private void validatePlayers(List playerNames) { + validateNotNull(playerNames); + validateSize(playerNames); + validateUniqueNames(playerNames); + } + + private void validateNotNull(List playerNames) { + if (playerNames == null) { + throw new IllegalArgumentException("[ERROR] 플레이어로 null이 전달되었습니다."); + } + } + + private void validateSize(List playerNames) { + if (playerNames.size() < MIN_PLAYER_COUNT || playerNames.size() > MAX_PLAYER_COUNT) { + throw new IllegalArgumentException( + "[ERROR] 플레이어의 수는 " + MIN_PLAYER_COUNT + "명 이상 " + MAX_PLAYER_COUNT + "명 이하여야 합니다." + ); + } + } + + private void validateUniqueNames(List playerNames) { + if (Set.copyOf(playerNames).size() != playerNames.size()) { + throw new IllegalArgumentException("[ERROR] 이름은 중복될 수 없습니다."); + } + } + + public void doInitialDraw(Deck deck) { + players.forEach(player -> player.doInitialDraw(deck)); + } + + public List getNames() { + return players.stream() + .map(Player::getName) + .toList(); + } + + public List getPlayers() { + return players; + } +} diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java new file mode 100644 index 0000000000..3ee3d2dfc4 --- /dev/null +++ b/src/main/java/blackjack/player/Score.java @@ -0,0 +1,68 @@ +package blackjack.player; + +import java.util.Objects; + +public class Score { + + private static final int BLACKJACK = 21; + private static final int ADDITIONAL_ACE = 10; + + private int score; + + public Score(int score) { + this.score = score; + } + + public Score add(int score) { + return add(new Score(score)); + } + + public Score add(Score other) { + return new Score(this.score + other.score); + } + + public boolean isBust() { + return score > BLACKJACK; + } + + public boolean isNotBust() { + return !isBust(); + } + + public boolean isLargerThan(Score other) { + return this.score > other.score; + } + + public boolean isSmallerThanOrEqualTo(Score other) { + return !isLargerThan(other); + } + + public Score changeToLargeAceScore() { + Score largeAceScore = add(ADDITIONAL_ACE); + if (largeAceScore.isBust()) { + return this; + } + return largeAceScore; + } + + public int getScore() { + return score; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Score score1 = (Score) o; + return score == score1.score; + } + + @Override + public int hashCode() { + return Objects.hash(score); + } +} diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java new file mode 100644 index 0000000000..ea46be171b --- /dev/null +++ b/src/main/java/blackjack/view/InputView.java @@ -0,0 +1,22 @@ +package blackjack.view; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private static final String NAME_DELIMITER = ","; + + private final Scanner scanner = new Scanner(System.in); + + public List readNames() { + String input = scanner.nextLine(); + String[] names = input.split(NAME_DELIMITER); + return Arrays.stream(names).toList(); + } + + public String readCommand() { + return scanner.nextLine(); + } +} diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java new file mode 100644 index 0000000000..62f42f5d44 --- /dev/null +++ b/src/main/java/blackjack/view/OutputView.java @@ -0,0 +1,81 @@ +package blackjack.view; + +import blackjack.card.Card; +import blackjack.game.MatchResult; +import blackjack.player.Score; +import blackjack.view.display.CardRankDisplay; +import blackjack.view.display.CardShapeDisplay; +import blackjack.view.display.PlayerResultDisplay; +import java.util.List; + +public class OutputView { + + private static final String NAME_SEPARATOR = ", "; + private static final String CARD_SEPARATOR = ", "; + + public void printNamesRequest() { + System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); + } + + public void printInitializeBlackJack(List names) { + System.out.println("딜러와 " + String.join(NAME_SEPARATOR, names) + "에게 2장을 나누었습니다."); + } + + public void printDealerFirstCard(Card card) { + System.out.println("딜러: " + convertCard(card)); + } + + public void printPlayerCards(String name, List cards) { + System.out.println(name + "카드: " + convertCards(cards)); + } + + public void printDrawMoreCardRequest(String name) { + System.out.println(name + "은(는) 한장의 카드를 더 받겠습니까?(예는 y, 아니오는 n)"); + } + + public void printDealerDrawCard() { + System.out.println("딜러는 16이하라 한장의 카드를 더 받았습니다."); + } + + public void printDealerCardsWithScore(List cards, Score score) { + printPlayerCardsWithScore("딜러", cards, score); + } + + public void printPlayerCardsWithScore(String name, List cards, Score score) { + System.out.println(name + " 카드: " + convertCards(cards) + " - 결과: " + score.getScore() + "점"); + } + + public void printResultStart() { + System.out.println("## 최종 승패"); + } + + public void printDealerResult(int winCount, int tieCount, int loseCount) { + System.out.println("딜러: " + winCount + "승 " + tieCount + "무 " + loseCount + "패"); + } + + public void printPlayerResult(String name, MatchResult result) { + String resultDisplay = PlayerResultDisplay.getDisplayByResult(result).getDisplay(); + System.out.println(name + ": " + resultDisplay); + } + + public void printNewLine() { + System.out.println(); + } + + private String convertCard(Card card) { + String convertedRank = CardRankDisplay.getDisplayByRank(card.getRank()).getDisplay(); + String convertedShape = CardShapeDisplay.getDisplayByShape(card.getShape()).getDisplay(); + return convertedRank + convertedShape; + } + + private String convertCards(List cards) { + List convertedCards = cards.stream() + .map(this::convertCard) + .toList(); + return String.join(CARD_SEPARATOR, convertedCards); + } + + public void printExceptionMessage(Exception e) { + System.out.println(e.getMessage()); + } +} diff --git a/src/main/java/blackjack/view/display/CardRankDisplay.java b/src/main/java/blackjack/view/display/CardRankDisplay.java new file mode 100644 index 0000000000..e23a8c0638 --- /dev/null +++ b/src/main/java/blackjack/view/display/CardRankDisplay.java @@ -0,0 +1,40 @@ +package blackjack.view.display; + +import blackjack.card.Rank; +import java.util.Arrays; + +public enum CardRankDisplay { + + ACE(Rank.ACE, "A"), + TWO(Rank.TWO, "2"), + THREE(Rank.THREE, "3"), + FOUR(Rank.FOUR, "4"), + FIVE(Rank.FIVE, "5"), + SIX(Rank.SIX, "6"), + SEVEN(Rank.SEVEN, "7"), + EIGHT(Rank.EIGHT, "8"), + NINE(Rank.NINE, "9"), + TEN(Rank.TEN, "10"), + JACK(Rank.JACK, "J"), + QUEEN(Rank.QUEEN, "Q"), + KING(Rank.KING, "K"); + + private final Rank rank; + private final String display; + + CardRankDisplay(Rank rank, String display) { + this.rank = rank; + this.display = display; + } + + public static CardRankDisplay getDisplayByRank(Rank rank) { + return Arrays.stream(CardRankDisplay.values()) + .filter(displayNumber -> displayNumber.rank == rank) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 수입니다.")); + } + + public String getDisplay() { + return display; + } +} diff --git a/src/main/java/blackjack/view/display/CardShapeDisplay.java b/src/main/java/blackjack/view/display/CardShapeDisplay.java new file mode 100644 index 0000000000..91226a4223 --- /dev/null +++ b/src/main/java/blackjack/view/display/CardShapeDisplay.java @@ -0,0 +1,31 @@ +package blackjack.view.display; + +import blackjack.card.Shape; +import java.util.Arrays; + +public enum CardShapeDisplay { + + HEART(Shape.HEART, "하트"), + SPADE(Shape.SPADE, "스페이드"), + CLOVER(Shape.CLOVER, "클로버"), + DIAMOND(Shape.DIAMOND, "다이아몬드"); + + private final Shape shape; + private final String display; + + CardShapeDisplay(Shape shape, String display) { + this.shape = shape; + this.display = display; + } + + public static CardShapeDisplay getDisplayByShape(Shape shape) { + return Arrays.stream(CardShapeDisplay.values()) + .filter(displayShape -> displayShape.shape == shape) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 모양입니다.")); + } + + public String getDisplay() { + return display; + } +} diff --git a/src/main/java/blackjack/view/display/PlayerResultDisplay.java b/src/main/java/blackjack/view/display/PlayerResultDisplay.java new file mode 100644 index 0000000000..ba320eb162 --- /dev/null +++ b/src/main/java/blackjack/view/display/PlayerResultDisplay.java @@ -0,0 +1,29 @@ +package blackjack.view.display; + +import blackjack.game.MatchResult; +import java.util.Arrays; + +public enum PlayerResultDisplay { + PLAYER_WIN(MatchResult.PLAYER_WIN, "승"), + PLAYER_LOSE(MatchResult.DEALER_WIN, "패"), + TIE(MatchResult.TIE, "무"); + + private final MatchResult result; + private final String display; + + PlayerResultDisplay(MatchResult result, String display) { + this.result = result; + this.display = display; + } + + public static PlayerResultDisplay getDisplayByResult(MatchResult result) { + return Arrays.stream(values()) + .filter(displayResult -> displayResult.result == result) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("[ERROR] 존재하지 않는 결과입니다.")); + } + + public String getDisplay() { + return display; + } +} diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/blackjack/card/CardTest.java b/src/test/java/blackjack/card/CardTest.java new file mode 100644 index 0000000000..eca88ade62 --- /dev/null +++ b/src/test/java/blackjack/card/CardTest.java @@ -0,0 +1,30 @@ +package blackjack.card; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import blackjack.player.Score; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class CardTest { + + @Test + @DisplayName("카드의 점수를 정확하게 계산한다.") + void calculateCardTest() { + Card card = new Card(Shape.SPADE, Rank.ACE); + assertThat(card.getScore()).isEqualTo(new Score(1)); + } + + @Test + @DisplayName("카드가 에이스인지 확인한다.") + void isAceTest() { + Card aceCard = new Card(Shape.HEART, Rank.ACE); + Card nonAceCard = new Card(Shape.CLOVER, Rank.JACK); + + assertAll( + () -> assertThat(aceCard.isAce()).isTrue(), + () -> assertThat(nonAceCard.isAce()).isFalse() + ); + } +} diff --git a/src/test/java/blackjack/card/DeckTest.java b/src/test/java/blackjack/card/DeckTest.java new file mode 100644 index 0000000000..0ff6dab591 --- /dev/null +++ b/src/test/java/blackjack/card/DeckTest.java @@ -0,0 +1,51 @@ +package blackjack.card; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class DeckTest { + + @Test + @DisplayName("덱에서 카드를 뽑는다.") + void createDeckTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.ACE), + new Card(Shape.CLOVER, Rank.EIGHT), + new Card(Shape.DIAMOND, Rank.JACK) + ); + Deck deck = new Deck(cards); + Card expected = new Card(Shape.HEART, Rank.ACE); + // when, then + assertThat(deck.draw()).isEqualTo(expected); + } + + @Test + @DisplayName("덱에 카드가 없을 때 뽑는다면 예외를 발생시킨다.") + void emptyDeckDrawTest() { + // given + Deck deck = new Deck(List.of()); + // when, then + assertThatThrownBy(deck::draw) + .isInstanceOf(IllegalStateException.class) + .hasMessage("[ERROR] 덱이 비어있습니다."); + } + + @Test + @DisplayName("원하는 모양의 카드 전체가 생성된다.") + void createNumberCardsOfShapeTest() { + assertThat(Deck.createNumberCardsOf(Shape.CLOVER).size()).isEqualTo(13); + } + + @Test + @DisplayName("카드 전체가 생성된다.") + void createFullDeckTest() { + Deck deck = Deck.createShuffledFullDeck(); + + assertThat(deck.size()).isEqualTo(52); + } +} diff --git a/src/test/java/blackjack/game/CommandTest.java b/src/test/java/blackjack/game/CommandTest.java new file mode 100644 index 0000000000..6924de65f1 --- /dev/null +++ b/src/test/java/blackjack/game/CommandTest.java @@ -0,0 +1,32 @@ +package blackjack.game; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class CommandTest { + + @Test + @DisplayName("명령어를 올바르게 변환한다.") + void convertCommandTest() { + // when + Command yes = Command.from("y"); + Command no = Command.from("n"); + // then + assertAll( + () -> assertThat(yes).isEqualTo(Command.YES), + () -> assertThat(no).isEqualTo(Command.NO) + ); + } + + @Test + @DisplayName("존재하지 않는 명령어가 주어지면 예외를 발생시킨다.") + void commandNotFoundTest() { + assertThatThrownBy(() -> Command.from("hi")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 존재하지 않는 명령어입니다."); + } +} diff --git a/src/test/java/blackjack/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java new file mode 100644 index 0000000000..b5236a1a4c --- /dev/null +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -0,0 +1,41 @@ +package blackjack.game; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.player.Score; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class MatchResultTest { + + @ParameterizedTest + @CsvSource(value = {"20, 22", "20, 19", "21, 20"}) + @DisplayName("플레이어가 이기는 경우를 올바르게 판단한다.") + void playerWinningTest(int playerScore, int dealerScore) { + // when + MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); + // then + assertThat(result).isEqualTo(MatchResult.PLAYER_WIN); + } + + @ParameterizedTest + @CsvSource(value = {"22, 20", "22, 22", "20, 21", "14, 18"}) + @DisplayName("딜러가 이기는 경우를 올바르게 판단한다.") + void dealerWinningTest(int playerScore, int dealerScore) { + // when + MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); + // then + assertThat(result).isEqualTo(MatchResult.DEALER_WIN); + } + + @ParameterizedTest + @CsvSource(value = {"21, 21", "20, 20"}) + @DisplayName("무승부인 경우를 올바르게 판단한다.") + void tieTest(int playerScore, int dealerScore) { + // when + MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); + // then + assertThat(result).isEqualTo(MatchResult.TIE); + } +} diff --git a/src/test/java/blackjack/game/MatchResultsTest.java b/src/test/java/blackjack/game/MatchResultsTest.java new file mode 100644 index 0000000000..5b3c999b09 --- /dev/null +++ b/src/test/java/blackjack/game/MatchResultsTest.java @@ -0,0 +1,52 @@ +package blackjack.game; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertAll; + +import blackjack.player.Score; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class MatchResultsTest { + + @Test + @DisplayName("이름으로 결과를 올바르게 가져온다.") + void getResultByNameTest() { + MatchResults matchResults = new MatchResults(); + matchResults.addResult("aru", new Score(20), new Score(21)); + assertThat(matchResults.getResultByName("aru")).isEqualTo(MatchResult.DEALER_WIN); + } + + @Test + @DisplayName("이름이 존재하지 않는 경우 예외를 발생시킨다.") + void nameNotFoundTest() { + // given + MatchResults matchResults = new MatchResults(); + // when, then + assertThatThrownBy(() -> matchResults.getResultByName("pobi")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 존재하지 않는 이름입니다."); + } + + @Test + @DisplayName("원하는 결과의 개수를 구한다.") + void getDesiredResultCountTest() { + // given + MatchResults matchResults = new MatchResults(); + matchResults.addResult("aru", new Score(10), new Score(20)); + matchResults.addResult("pobi", new Score(10), new Score(20)); + matchResults.addResult("atto", new Score(10), new Score(10)); + matchResults.addResult("jazz", new Score(20), new Score(10)); + // when + int playerWinCount = matchResults.getResultCount(MatchResult.PLAYER_WIN); + int tieCount = matchResults.getResultCount(MatchResult.TIE); + int dealerWinCount = matchResults.getResultCount(MatchResult.DEALER_WIN); + // then + assertAll( + () -> assertThat(playerWinCount).isEqualTo(1), + () -> assertThat(tieCount).isEqualTo(1), + () -> assertThat(dealerWinCount).isEqualTo(2) + ); + } +} diff --git a/src/test/java/blackjack/player/DealerTest.java b/src/test/java/blackjack/player/DealerTest.java new file mode 100644 index 0000000000..d9897d57b5 --- /dev/null +++ b/src/test/java/blackjack/player/DealerTest.java @@ -0,0 +1,73 @@ +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import blackjack.card.Card; +import blackjack.card.Rank; +import blackjack.card.Shape; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class DealerTest { + + @Test + @DisplayName("딜러는 16점 이하이면 추가 드로우가 가능하다.") + void ableToDrawTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.SIX) + ); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); + // when + boolean isDrawable = dealer.hasDrawableScore(); + // then + assertThat(isDrawable).isTrue(); + } + + @Test + @DisplayName("딜러는 16점 초과이면 추가 드로우가 불가능하다.") + void unableToDrawTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.SEVEN) + ); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); + // when + boolean isDrawable = dealer.hasDrawableScore(); + // then + assertThat(isDrawable).isFalse(); + } + + @Test + @DisplayName("딜러의 첫 번째 카드를 가져온다.") + void getFirstCardTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.SEVEN) + ); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); + // when, then + assertThat(dealer.getFirstCard()).isEqualTo(new Card(Shape.HEART, Rank.JACK)); + } + + @Test + @DisplayName("딜러가 카드를 가지고 있지 않을 때 가져가는 것을 시도하면 예외를 발생시킨다.") + void getFirstCardOnEmptyHandTest() { + // given + List cards = List.of(); + Hand hand = new Hand(cards); + Dealer dealer = new Dealer(hand); + // when, then + assertThatThrownBy(dealer::getFirstCard) + .isInstanceOf(IllegalStateException.class) + .hasMessage("[ERROR] 딜러가 카드를 가지고 있지 않습니다."); + } +} diff --git a/src/test/java/blackjack/player/HandTest.java b/src/test/java/blackjack/player/HandTest.java new file mode 100644 index 0000000000..7e0b01b150 --- /dev/null +++ b/src/test/java/blackjack/player/HandTest.java @@ -0,0 +1,53 @@ +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.card.Card; +import blackjack.card.Rank; +import blackjack.card.Shape; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class HandTest { + + @Test + @DisplayName("플레이어의 점수를 계산한다.") + void calculateScoreTest() { + // given + List cards = List.of( + new Card(Shape.SPADE, Rank.KING), + new Card(Shape.HEART, Rank.EIGHT) + ); + Hand hand = new Hand(cards); + // when, then + assertThat(hand.calculateScore()).isEqualTo(new Score(18)); + } + + @Test + @DisplayName("플레이어의 점수를 계산할 때, Ace의 점수를 유리한 방향(11)으로 결정한다.") + void calculateAceAsElevenTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.TEN), + new Card(Shape.CLOVER, Rank.ACE) + ); + Hand hand = new Hand(cards); + // when, then + assertThat(hand.calculateScore()).isEqualTo(new Score(21)); + } + + @Test + @DisplayName("플레이어의 점수를 계산할 때, Ace의 점수를 유리한 방향(1)으로 결정한다.") + void calculateAceAsOneTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.TEN), + new Card(Shape.CLOVER, Rank.ACE), + new Card(Shape.DIAMOND, Rank.TEN) + ); + Hand hand = new Hand(cards); + // when, then + assertThat(hand.calculateScore()).isEqualTo(new Score(21)); + } +} diff --git a/src/test/java/blackjack/player/NameTest.java b/src/test/java/blackjack/player/NameTest.java new file mode 100644 index 0000000000..dc205b7b23 --- /dev/null +++ b/src/test/java/blackjack/player/NameTest.java @@ -0,0 +1,37 @@ +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +class NameTest { + + @ParameterizedTest + @ValueSource(strings = {"12", "12345"}) + @DisplayName("이름이 잘 생성된다.") + void validNameTest(String name) { + assertDoesNotThrow(() -> new Name(name)); + } + + @ParameterizedTest + @NullAndEmptySource + @DisplayName("이름이 공백으로 이루어진 경우 예외를 발생시킨다.") + void blankNameTest(String name) { + assertThatThrownBy(() -> new Name(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이름은 공백일 수 없습니다."); + } + + @ParameterizedTest + @ValueSource(strings = {"a", "abcdef"}) + @DisplayName("이름이 길이 제한을 어기는 경우 예외를 발생시킨다.") + void longNameTest(String name) { + assertThatThrownBy(() -> new Name(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이름은 2글자 이상 5글자 이하여야 합니다."); + } +} diff --git a/src/test/java/blackjack/player/PlayerTest.java b/src/test/java/blackjack/player/PlayerTest.java new file mode 100644 index 0000000000..140bca5001 --- /dev/null +++ b/src/test/java/blackjack/player/PlayerTest.java @@ -0,0 +1,46 @@ +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThat; + +import blackjack.card.Card; +import blackjack.card.Rank; +import blackjack.card.Shape; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PlayerTest { + + @Test + @DisplayName("플레이어는 21점 미만이면 추가 드로우가 가능하다.") + void ableToDrawTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.TEN) + ); + Hand hand = new Hand(cards); + Player player = new Player("aru", hand); + // when + boolean isDrawable = player.hasDrawableScore(); + // then + assertThat(isDrawable).isTrue(); + } + + @Test + @DisplayName("플렝이어는 21점 초과이면 추가 드로우가 불가능하다.") + void unableToDrawTest() { + // given + List cards = List.of( + new Card(Shape.HEART, Rank.JACK), + new Card(Shape.DIAMOND, Rank.TEN), + new Card(Shape.DIAMOND, Rank.TWO) + ); + Hand hand = new Hand(cards); + Player player = new Player("atto", hand); + // when + boolean isDrawable = player.hasDrawableScore(); + // then + assertThat(isDrawable).isFalse(); + } +} diff --git a/src/test/java/blackjack/player/PlayersTest.java b/src/test/java/blackjack/player/PlayersTest.java new file mode 100644 index 0000000000..92bf1268d2 --- /dev/null +++ b/src/test/java/blackjack/player/PlayersTest.java @@ -0,0 +1,51 @@ +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PlayersTest { + + @Test + @DisplayName("플레이어의 이름이 중복될 경우 예외를 발생시킨다") + void duplicateNameTest() { + // given + List names = List.of("aru", "atto", "aru"); + // when, then + assertThatThrownBy(() -> new Players(names)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이름은 중복될 수 없습니다."); + } + + @Test + @DisplayName("플레이어의 수가 제한을 초과하는 경우 예외를 발생시킨다.") + void exceedingPlayersSizeTest() { + // given + List playerNames = List.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"); + // when, then + assertThatThrownBy(() -> new Players(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 플레이어의 수는 1명 이상 10명 이하여야 합니다."); + } + + @Test + @DisplayName("플레이어가 없는 경우 예외를 발생시킨다.") + void emptyPlayersSizeTest() { + // given + List playerNames = List.of(); + // when, then + assertThatThrownBy(() -> new Players(playerNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 플레이어의 수는 1명 이상 10명 이하여야 합니다."); + } + + @Test + @DisplayName("플레이어로 null이 전달되는 경우 예외를 발생시킨다.") + void nullPlayerTest() { + assertThatThrownBy(() -> new Players(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 플레이어로 null이 전달되었습니다."); + } +} diff --git a/src/test/java/blackjack/player/ScoreTest.java b/src/test/java/blackjack/player/ScoreTest.java new file mode 100644 index 0000000000..c3141344aa --- /dev/null +++ b/src/test/java/blackjack/player/ScoreTest.java @@ -0,0 +1,76 @@ +package blackjack.player; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class ScoreTest { + + @Test + @DisplayName("점수를 더할 수 있다.") + void addScoreTest() { + Score score = new Score(2); + + assertThat(score.add(3)).isEqualTo(new Score(5)); + } + + @Test + @DisplayName("점수가 버스트인지 판단한다.") + void isBustTest() { + Score bustScore = new Score(22); + Score notBustScore = new Score(21); + + assertAll( + () -> assertThat(bustScore.isBust()).isTrue(), + () -> assertThat(notBustScore.isBust()).isFalse() + ); + } + + @Test + @DisplayName("점수가 버스트인지 판단한다.") + void isNotBustTest() { + Score bustScore = new Score(22); + Score notBustScore = new Score(21); + + assertAll( + () -> assertThat(bustScore.isNotBust()).isFalse(), + () -> assertThat(notBustScore.isNotBust()).isTrue() + ); + } + + @Test + @DisplayName("점수의 대소비교가 가능하다.") + void isLargerThanTest() { + Score score = new Score(15); + + assertAll( + () -> assertThat(score.isLargerThan(new Score(14))).isTrue(), + () -> assertThat(score.isLargerThan(new Score(16))).isFalse() + ); + } + + @Test + @DisplayName("점수의 대소비교가 가능하다.") + void isSmallerThanEqualTest() { + Score score = new Score(15); + + assertAll( + () -> assertThat(score.isSmallerThanOrEqualTo(new Score(14))).isFalse(), + () -> assertThat(score.isSmallerThanOrEqualTo(new Score(16))).isTrue() + ); + } + + @Test + @DisplayName("보정된 에이스 점수를 계산한다.") + void changeToLargeAceTest() { + Score canChangeScore = new Score(11); + Score cantChangeScore = new Score(12); + + assertAll( + () -> assertThat(canChangeScore.changeToLargeAceScore()).isEqualTo(new Score(21)), + () -> assertThat(cantChangeScore.changeToLargeAceScore()).isEqualTo(new Score(12)) + ); + } +} From c5476b05638d4d0d730b22289dafadec4f588c90 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Fri, 15 Mar 2024 16:42:20 +0900 Subject: [PATCH 70/85] =?UTF-8?q?feat(Money):=20=EB=B0=B0=ED=8C=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/game/Money.java | 21 +++++++++++++++++++++ src/test/java/blackjack/game/MoneyTest.java | 19 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/main/java/blackjack/game/Money.java create mode 100644 src/test/java/blackjack/game/MoneyTest.java diff --git a/src/main/java/blackjack/game/Money.java b/src/main/java/blackjack/game/Money.java new file mode 100644 index 0000000000..2a75d96dde --- /dev/null +++ b/src/main/java/blackjack/game/Money.java @@ -0,0 +1,21 @@ +package blackjack.game; + +public class Money { + + private final int money; + + Money(int money) { + validateNatural(money); + this.money = money; + } + + private void validateNatural(int input) { + if (input <= 0) { + throw new IllegalArgumentException("[ERROR] 금액은 양수여야 합니다."); + } + } + + public int getMoney() { + return money; + } +} diff --git a/src/test/java/blackjack/game/MoneyTest.java b/src/test/java/blackjack/game/MoneyTest.java new file mode 100644 index 0000000000..1215d7f936 --- /dev/null +++ b/src/test/java/blackjack/game/MoneyTest.java @@ -0,0 +1,19 @@ +package blackjack.game; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class MoneyTest { + + @ParameterizedTest + @ValueSource(ints = {0, -1000}) + @DisplayName("금액이 양수가 아니면 예외를 발생시킨다.") + void validateNaturalTest(int money) { + assertThatThrownBy(() -> new Money(money)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 금액은 양수여야 합니다."); + } +} From c2ada09da0bb4b8a6306b9cc816bbd8b3d9c0248 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Fri, 15 Mar 2024 16:46:46 +0900 Subject: [PATCH 71/85] =?UTF-8?q?feat(Hand):=20=EB=B8=94=EB=9E=99=EC=9E=AD?= =?UTF-8?q?=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Hand.java | 6 ++++ src/main/java/blackjack/player/Score.java | 4 +++ src/test/java/blackjack/player/HandTest.java | 30 ++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/main/java/blackjack/player/Hand.java b/src/main/java/blackjack/player/Hand.java index ac3acbdaed..ef4c748ff6 100644 --- a/src/main/java/blackjack/player/Hand.java +++ b/src/main/java/blackjack/player/Hand.java @@ -7,6 +7,8 @@ public class Hand { + private static final int BLACKJACK_COUNT = 2; + private final List cards; Hand(List cards) { @@ -40,6 +42,10 @@ public void addCard(Card card) { cards.add(card); } + public boolean isBlackJack() { + return calculateScore().isBlackJack() && getCards().size() == BLACKJACK_COUNT; + } + public List getCards() { return Collections.unmodifiableList(cards); } diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java index 3ee3d2dfc4..19b991767b 100644 --- a/src/main/java/blackjack/player/Score.java +++ b/src/main/java/blackjack/player/Score.java @@ -45,6 +45,10 @@ public Score changeToLargeAceScore() { return largeAceScore; } + public boolean isBlackJack() { + return score == BLACKJACK; + } + public int getScore() { return score; } diff --git a/src/test/java/blackjack/player/HandTest.java b/src/test/java/blackjack/player/HandTest.java index 7e0b01b150..9b4dbdda92 100644 --- a/src/test/java/blackjack/player/HandTest.java +++ b/src/test/java/blackjack/player/HandTest.java @@ -1,6 +1,7 @@ package blackjack.player; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; import blackjack.card.Card; import blackjack.card.Rank; @@ -50,4 +51,33 @@ void calculateAceAsOneTest() { // when, then assertThat(hand.calculateScore()).isEqualTo(new Score(21)); } + + @Test + @DisplayName("블랙잭 여부를 확인한다.") + void isBlackJackTest() { + List cardsBlackJack = List.of( + new Card(Shape.CLOVER, Rank.ACE), + new Card(Shape.DIAMOND, Rank.TEN) + ); + Hand handBlackJack = new Hand(cardsBlackJack); + + List cards21 = List.of( + new Card(Shape.CLOVER, Rank.JACK), + new Card(Shape.DIAMOND, Rank.TEN), + new Card(Shape.HEART, Rank.ACE) + ); + Hand hand21 = new Hand(cards21); + + List cards20 = List.of( + new Card(Shape.CLOVER, Rank.JACK), + new Card(Shape.DIAMOND, Rank.TEN) + ); + Hand hand20 = new Hand(cards20); + + assertAll( + () -> assertThat(handBlackJack.isBlackJack()).isTrue(), + () -> assertThat(hand21.isBlackJack()).isFalse(), + () -> assertThat(hand20.isBlackJack()).isFalse() + ); + } } From d595119ccbc7418b119438023ca770b47ea87e2d Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Fri, 15 Mar 2024 16:51:22 +0900 Subject: [PATCH 72/85] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=82=AC=ED=95=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7f90631694..9d6c7f7cc3 100644 --- a/README.md +++ b/README.md @@ -31,17 +31,29 @@ - [x] 플레이어들의 이름은 중복될 수 없다. - [x] 플레이어들의 인원수는 1명 이상 10명 이하이다. +### 베팅 결과 +- [ ] 플레이어별 배팅 금액을 저장한다. + +### 배팅 금액 +- [x] 배팅 금액은 자연수이다. + ### 딜러 - [x] 플레이어의 기능을 상속한다. - [x] 17점 이상이 될 때까지 카드를 계속 뽑는다. ### 게임 결과 -- [x] 게임 결과를 아래의 순서대로 올바르게 판단한다. - 1. 플레이어의 점수가 21점을 초과하면 딜러가 승리한다. - 2. 플레이어의 점수가 21점을 초과하지 않으면서 딜러의 점수가 21점을 초과하면 플레이어가 승리한다. - 3. 딜러와 플레이어의 점수를 비교해 승패를 결정한다. - 4. 점수가 같으면 무승부이다. -- [x] 각 플레이어별 게임 결과를 저장한다. +- [ ] 게임 결과를 아래의 순서대로 올바르게 판단한다. + 1. 플레이어는 배팅 금액의 1.5배만큼 돈을 번다. + - [ ] 플레이어가 블랙잭이고 딜러가 블랙잭이 아닌 경우 + 2. 플레이어는 배팅 금액만큼 돈을 번다. + - [ ] 플레이어가 버스트가 아니고 딜러가 버스트인 경우 + - [ ] 플레이어와 딜러가 버스트가 아니고 플레이어의 점수가 더 큰 경우 + 3. 플레이어는 배팅 금액을 잃는다. + - [ ] 플레이어가 버스트인 경우 + - [ ] 플레이어와 딜러가 버스트가 아니고 딜러의 점수가 더 큰 경우 + 4. 플레이어는 배팅 금액을 다시 돌려받는다. + - [ ] 플레이어와 딜러가 버스트가 아니고 동점인 경우 +- [ ] 각 플레이어별 게임 결과를 저장한다. --- From feec13da727618ebce16925f575f6c073bd904b6 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Fri, 15 Mar 2024 18:09:22 +0900 Subject: [PATCH 73/85] =?UTF-8?q?feat(MatchResult):=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EC=9D=98=20=EC=88=98=EC=9D=B5=20=EB=B9=84?= =?UTF-8?q?=EC=9C=A8=20=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/game/MatchResult.java | 50 ++++++-- .../java/blackjack/game/MatchResultTest.java | 108 ++++++++++++++---- 2 files changed, 124 insertions(+), 34 deletions(-) diff --git a/src/main/java/blackjack/game/MatchResult.java b/src/main/java/blackjack/game/MatchResult.java index e5dd19c827..885eaed4ca 100644 --- a/src/main/java/blackjack/game/MatchResult.java +++ b/src/main/java/blackjack/game/MatchResult.java @@ -1,34 +1,62 @@ package blackjack.game; +import blackjack.player.Hand; import blackjack.player.Score; public enum MatchResult { - DEALER_WIN, - PLAYER_WIN, - TIE; + DEALER_WIN(-1), + PLAYER_WIN(1), + PLAYER_BLACKJACK(1.5), + TIE(0); - public static MatchResult chooseWinner(Score playerScore, Score dealerScore) { - if (isPlayerWinningCondition(playerScore, dealerScore)) { - return PLAYER_WIN; + private final double rateOfPrize; + + MatchResult(double rateOfPrize) { + this.rateOfPrize = rateOfPrize; + } + + public static double calculateRateOfPrize(Hand playerHand, Hand dealerHand) { + if (isPlayerBlackJackCondition(playerHand, dealerHand)) { + return PLAYER_BLACKJACK.rateOfPrize; } - if (isDealerWinningCondition(playerScore, dealerScore)) { - return DEALER_WIN; + if (isPlayerWinningCondition(playerHand, dealerHand)) { + return PLAYER_WIN.rateOfPrize; } - return TIE; + if (isDealerWinningCondition(playerHand, dealerHand)) { + return DEALER_WIN.rateOfPrize; + } + return TIE.rateOfPrize; + } + + private static boolean isPlayerBlackJackCondition(Hand playerHand, Hand dealerHand) { + return playerHand.isBlackJack() && !dealerHand.isBlackJack(); } - private static boolean isPlayerWinningCondition(Score playerScore, Score dealerScore) { + private static boolean isPlayerWinningCondition(Hand playerHand, Hand dealerHand) { + Score playerScore = playerHand.calculateScore(); + Score dealerScore = dealerHand.calculateScore(); + if (playerScore.isBust()) { return false; } return dealerScore.isBust() || playerScore.isLargerThan(dealerScore); } - private static boolean isDealerWinningCondition(Score playerScore, Score dealerScore) { + private static boolean isDealerWinningCondition(Hand playerHand, Hand dealerHand) { + Score playerScore = playerHand.calculateScore(); + Score dealerScore = dealerHand.calculateScore(); + if (playerScore.isBust()) { return true; } + if (dealerHand.isBlackJack() && !playerHand.isBlackJack()) { + return true; + } return dealerScore.isNotBust() && dealerScore.isLargerThan(playerScore); } + + double getRateOfPrize() { + return rateOfPrize; + } } diff --git a/src/test/java/blackjack/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java index b5236a1a4c..171edff6ca 100644 --- a/src/test/java/blackjack/game/MatchResultTest.java +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -2,40 +2,102 @@ import static org.assertj.core.api.Assertions.assertThat; -import blackjack.player.Score; +import blackjack.card.Card; +import blackjack.card.Rank; +import blackjack.card.Shape; +import blackjack.player.Hand; +import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class MatchResultTest { + static Hand handBlackJack = new Hand(List.of( + new Card(Shape.CLOVER, Rank.ACE), + new Card(Shape.DIAMOND, Rank.TEN) + )); + static Hand hand22 = new Hand(List.of( + new Card(Shape.HEART, Rank.TEN), + new Card(Shape.CLOVER, Rank.TEN), + new Card(Shape.DIAMOND, Rank.TWO) + )); + static Hand hand21 = new Hand(List.of( + new Card(Shape.CLOVER, Rank.JACK), + new Card(Shape.DIAMOND, Rank.TEN), + new Card(Shape.HEART, Rank.ACE) + )); + static Hand hand20 = new Hand(List.of( + new Card(Shape.CLOVER, Rank.JACK), + new Card(Shape.DIAMOND, Rank.TEN) + )); + + @ParameterizedTest + @MethodSource("playerWinCases") + @DisplayName("플레이어가 배팅 금액만큼 돈을 버는 경우를 올바르게 판단한다.") + void playerWinTest(Hand playerHand, Hand dealerHand) { + double result = MatchResult.calculateRateOfPrize(playerHand, dealerHand); + + assertThat(result).isEqualTo(MatchResult.PLAYER_WIN.getRateOfPrize()); + } + + static Stream playerWinCases() { + return Stream.of( + Arguments.of(hand20, hand22), + Arguments.of(hand21, hand20) + ); + } + @ParameterizedTest - @CsvSource(value = {"20, 22", "20, 19", "21, 20"}) - @DisplayName("플레이어가 이기는 경우를 올바르게 판단한다.") - void playerWinningTest(int playerScore, int dealerScore) { - // when - MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); - // then - assertThat(result).isEqualTo(MatchResult.PLAYER_WIN); + @MethodSource("playerBlackJackCases") + @DisplayName("플레이어가 배팅 금액의 1.5배만큼 돈을 버는 경우를 올바르게 판단한다.") + void playerBlackJackTest(Hand playerHand, Hand dealerHand) { + double result = MatchResult.calculateRateOfPrize(playerHand, dealerHand); + + assertThat(result).isEqualTo(MatchResult.PLAYER_BLACKJACK.getRateOfPrize()); + } + + static Stream playerBlackJackCases() { + return Stream.of( + Arguments.of(handBlackJack, hand22), + Arguments.of(handBlackJack, hand21), + Arguments.of(handBlackJack, hand20) + ); } @ParameterizedTest - @CsvSource(value = {"22, 20", "22, 22", "20, 21", "14, 18"}) - @DisplayName("딜러가 이기는 경우를 올바르게 판단한다.") - void dealerWinningTest(int playerScore, int dealerScore) { - // when - MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); - // then - assertThat(result).isEqualTo(MatchResult.DEALER_WIN); + @MethodSource("dealerWinCases") + @DisplayName("플레이어가 배팅 금액을 잃는 경우를 올바르게 판단한다.") + void dealerWinTest(Hand playerHand, Hand dealerHand) { + double result = MatchResult.calculateRateOfPrize(playerHand, dealerHand); + + assertThat(result).isEqualTo(MatchResult.DEALER_WIN.getRateOfPrize()); + } + + static Stream dealerWinCases() { + return Stream.of( + Arguments.of(hand21, handBlackJack), + Arguments.of(hand22, hand20), + Arguments.of(hand20, hand21) + ); } @ParameterizedTest - @CsvSource(value = {"21, 21", "20, 20"}) - @DisplayName("무승부인 경우를 올바르게 판단한다.") - void tieTest(int playerScore, int dealerScore) { - // when - MatchResult result = MatchResult.chooseWinner(new Score(playerScore), new Score(dealerScore)); - // then - assertThat(result).isEqualTo(MatchResult.TIE); + @MethodSource("tieCases") + @DisplayName("플레이어가 배팅 금액을 돌려받는 경우를 올바르게 판단한다.") + void tieTest(Hand playerHand, Hand dealerHand) { + double result = MatchResult.calculateRateOfPrize(playerHand, dealerHand); + + assertThat(result).isEqualTo(MatchResult.TIE.getRateOfPrize()); + } + + static Stream tieCases() { + return Stream.of( + Arguments.of(handBlackJack, handBlackJack), + Arguments.of(hand21, hand21), + Arguments.of(hand20, hand20) + ); } } From 6a713c22a005760f8c47d8aecb33bf419bf2d5c5 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 15:12:18 +0900 Subject: [PATCH 74/85] =?UTF-8?q?refactor(Players):=20Set=EC=9D=84=20HashS?= =?UTF-8?q?et=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Players.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/blackjack/player/Players.java b/src/main/java/blackjack/player/Players.java index ed18881912..6c31cd41cf 100644 --- a/src/main/java/blackjack/player/Players.java +++ b/src/main/java/blackjack/player/Players.java @@ -1,8 +1,8 @@ package blackjack.player; import blackjack.card.Deck; +import java.util.HashSet; import java.util.List; -import java.util.Set; public class Players { @@ -39,7 +39,7 @@ private void validateSize(List playerNames) { } private void validateUniqueNames(List playerNames) { - if (Set.copyOf(playerNames).size() != playerNames.size()) { + if (new HashSet<>(playerNames).size() != playerNames.size()) { throw new IllegalArgumentException("[ERROR] 이름은 중복될 수 없습니다."); } } From fb2703277e3bdf9dd917c4b07fb999f58c0c947f Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 15:57:02 +0900 Subject: [PATCH 75/85] =?UTF-8?q?feat(MatchResults):=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=EB=B3=84=20=EC=88=98=EC=9D=B5=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 플레이어의 수익 확인 - 딜러의 수익 확인 --- .../java/blackjack/game/MatchResults.java | 35 ++++++----- src/main/java/blackjack/player/Hand.java | 2 +- src/main/java/blackjack/player/Player.java | 8 ++- .../java/blackjack/game/MatchResultsTest.java | 62 ++++++++++--------- 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/main/java/blackjack/game/MatchResults.java b/src/main/java/blackjack/game/MatchResults.java index 6446f6656e..c894aaaab8 100644 --- a/src/main/java/blackjack/game/MatchResults.java +++ b/src/main/java/blackjack/game/MatchResults.java @@ -1,33 +1,38 @@ package blackjack.game; -import blackjack.player.Score; +import blackjack.player.Hand; +import blackjack.player.Player; import java.util.HashMap; import java.util.Map; public class MatchResults { - private final Map results; + private final Hand dealerHand; + private final Map results; - public MatchResults() { + public MatchResults(Hand dealerHand) { + this.dealerHand = dealerHand; this.results = new HashMap<>(); } - public void addResult(String playerName, Score playerScore, Score dealerScore) { - MatchResult result = MatchResult.chooseWinner(playerScore, dealerScore); - results.put(playerName, result); + public void addResult(Player player, Money money) { + double rateOfPrize = MatchResult.calculateRateOfPrize(player.getHand(), dealerHand); + int prizeMoney = (int) (money.getMoney() * rateOfPrize); + results.put(player, prizeMoney); } - public MatchResult getResultByName(String playerName) { - if (!results.containsKey(playerName)) { - throw new IllegalArgumentException("[ERROR] 존재하지 않는 이름입니다."); + public int getResultOf(Player player) { + if (!results.containsKey(player)) { + throw new IllegalArgumentException("[ERROR] 존재하지 않는 플레이어입니다."); } - return results.get(playerName); + return results.get(player); } - public int getResultCount(MatchResult result) { - return (int) results.values() - .stream() - .filter(matchResult -> matchResult == result) - .count(); + public int getDealerResult() { + int dealerResult = 0; + for (Map.Entry result : results.entrySet()) { + dealerResult -= result.getValue(); + } + return dealerResult; } } diff --git a/src/main/java/blackjack/player/Hand.java b/src/main/java/blackjack/player/Hand.java index ef4c748ff6..f9ab63282f 100644 --- a/src/main/java/blackjack/player/Hand.java +++ b/src/main/java/blackjack/player/Hand.java @@ -11,7 +11,7 @@ public class Hand { private final List cards; - Hand(List cards) { + public Hand(List cards) { this.cards = cards; } diff --git a/src/main/java/blackjack/player/Player.java b/src/main/java/blackjack/player/Player.java index e61fde1b2d..9bc68a1d91 100644 --- a/src/main/java/blackjack/player/Player.java +++ b/src/main/java/blackjack/player/Player.java @@ -9,12 +9,12 @@ public class Player { private final Name name; private final Hand hand; - Player(String name, Hand hand) { + public Player(String name, Hand hand) { this.name = new Name(name); this.hand = hand; } - Player(String name) { + public Player(String name) { this(name, new Hand()); } @@ -42,4 +42,8 @@ public Score getScore() { public List getCards() { return hand.getCards(); } + + public Hand getHand() { + return hand; + } } diff --git a/src/test/java/blackjack/game/MatchResultsTest.java b/src/test/java/blackjack/game/MatchResultsTest.java index 5b3c999b09..27b028e45f 100644 --- a/src/test/java/blackjack/game/MatchResultsTest.java +++ b/src/test/java/blackjack/game/MatchResultsTest.java @@ -2,51 +2,53 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; -import blackjack.player.Score; +import blackjack.card.Card; +import blackjack.card.Rank; +import blackjack.card.Shape; +import blackjack.player.Hand; +import blackjack.player.Player; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class MatchResultsTest { + Hand dealerHand = new Hand(List.of( + new Card(Shape.DIAMOND, Rank.TEN), + new Card(Shape.HEART, Rank.TEN + ))); + Hand playerHand = new Hand(List.of( + new Card(Shape.CLOVER, Rank.TEN), + new Card(Shape.DIAMOND, Rank.FIVE + ))); + Player player = new Player("atto", playerHand); + MatchResults matchResults = new MatchResults(dealerHand); + Money money = new Money(10000); + + @BeforeEach + void beforeEach() { + matchResults.addResult(player, money); + } + @Test - @DisplayName("이름으로 결과를 올바르게 가져온다.") + @DisplayName("플레이어로 배팅 결과를 올바르게 가져온다.") void getResultByNameTest() { - MatchResults matchResults = new MatchResults(); - matchResults.addResult("aru", new Score(20), new Score(21)); - assertThat(matchResults.getResultByName("aru")).isEqualTo(MatchResult.DEALER_WIN); + assertThat(matchResults.getResultOf(player)).isEqualTo(-10000); } @Test - @DisplayName("이름이 존재하지 않는 경우 예외를 발생시킨다.") + @DisplayName("플레이어가 존재하지 않는 경우 예외를 발생시킨다.") void nameNotFoundTest() { - // given - MatchResults matchResults = new MatchResults(); - // when, then - assertThatThrownBy(() -> matchResults.getResultByName("pobi")) + assertThatThrownBy(() -> matchResults.getResultOf(new Player("pobi"))) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("[ERROR] 존재하지 않는 이름입니다."); + .hasMessage("[ERROR] 존재하지 않는 플레이어입니다."); } @Test - @DisplayName("원하는 결과의 개수를 구한다.") - void getDesiredResultCountTest() { - // given - MatchResults matchResults = new MatchResults(); - matchResults.addResult("aru", new Score(10), new Score(20)); - matchResults.addResult("pobi", new Score(10), new Score(20)); - matchResults.addResult("atto", new Score(10), new Score(10)); - matchResults.addResult("jazz", new Score(20), new Score(10)); - // when - int playerWinCount = matchResults.getResultCount(MatchResult.PLAYER_WIN); - int tieCount = matchResults.getResultCount(MatchResult.TIE); - int dealerWinCount = matchResults.getResultCount(MatchResult.DEALER_WIN); - // then - assertAll( - () -> assertThat(playerWinCount).isEqualTo(1), - () -> assertThat(tieCount).isEqualTo(1), - () -> assertThat(dealerWinCount).isEqualTo(2) - ); + @DisplayName("딜러의 수익을 구한다.") + void getDealerResultTest() { + assertThat(matchResults.getDealerResult()).isEqualTo(10000); } } From 2ec2baab52228aceac3d1ce3991b6560e9255425 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:01:09 +0900 Subject: [PATCH 76/85] =?UTF-8?q?feat(View):=20=EB=B0=B0=ED=8C=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1,=20=EC=B5=9C=EC=A2=85=20=EC=88=98=EC=9D=B5?= =?UTF-8?q?=20=EC=9E=85=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/InputView.java | 14 ++++++++++++++ src/main/java/blackjack/view/OutputView.java | 17 +++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index ea46be171b..4a57211bc7 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -16,6 +16,20 @@ public List readNames() { return Arrays.stream(names).toList(); } + public int readBattingAmount() { + String input = scanner.nextLine(); + validateInteger(input); + return Integer.parseInt(input); + } + + private void validateInteger(String input) { + try { + Integer.parseInt(input); + } catch (IllegalArgumentException e) { + System.out.println("[ERROR] 정수가 아닙니다."); + } + } + public String readCommand() { return scanner.nextLine(); } diff --git a/src/main/java/blackjack/view/OutputView.java b/src/main/java/blackjack/view/OutputView.java index 62f42f5d44..50bdc0ccda 100644 --- a/src/main/java/blackjack/view/OutputView.java +++ b/src/main/java/blackjack/view/OutputView.java @@ -1,11 +1,9 @@ package blackjack.view; import blackjack.card.Card; -import blackjack.game.MatchResult; import blackjack.player.Score; import blackjack.view.display.CardRankDisplay; import blackjack.view.display.CardShapeDisplay; -import blackjack.view.display.PlayerResultDisplay; import java.util.List; public class OutputView { @@ -17,6 +15,10 @@ public void printNamesRequest() { System.out.println("게임에 참여할 사람의 이름을 입력하세요.(쉼표 기준으로 분리)"); } + public void printBettingRequestMessage(String name) { + System.out.println(name + "의 배팅 금액은?"); + } + public void printInitializeBlackJack(List names) { System.out.println("딜러와 " + String.join(NAME_SEPARATOR, names) + "에게 2장을 나누었습니다."); } @@ -46,16 +48,15 @@ public void printPlayerCardsWithScore(String name, List cards, Score score } public void printResultStart() { - System.out.println("## 최종 승패"); + System.out.println("## 최종 수익"); } - public void printDealerResult(int winCount, int tieCount, int loseCount) { - System.out.println("딜러: " + winCount + "승 " + tieCount + "무 " + loseCount + "패"); + public void printDealerResult(int dealerResult) { + System.out.println("딜러: " + dealerResult + "원"); } - public void printPlayerResult(String name, MatchResult result) { - String resultDisplay = PlayerResultDisplay.getDisplayByResult(result).getDisplay(); - System.out.println(name + ": " + resultDisplay); + public void printPlayerResult(String name, int result) { + System.out.println(name + ": " + result + "원"); } public void printNewLine() { From 13c85a2e8aef170d777290292a62abf5c1ee8c52 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:15:16 +0900 Subject: [PATCH 77/85] =?UTF-8?q?feat(PlayerBettingMoney):=20=ED=94=8C?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=96=B4=EB=B3=84=20=EB=B0=B0=ED=8C=85=20?= =?UTF-8?q?=EA=B8=88=EC=95=A1=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blackjack/game/PlayerBettingMoney.java | 28 +++++++++++ .../game/PlayerBettingMoneyTest.java | 48 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/main/java/blackjack/game/PlayerBettingMoney.java create mode 100644 src/test/java/blackjack/game/PlayerBettingMoneyTest.java diff --git a/src/main/java/blackjack/game/PlayerBettingMoney.java b/src/main/java/blackjack/game/PlayerBettingMoney.java new file mode 100644 index 0000000000..5648d6ad45 --- /dev/null +++ b/src/main/java/blackjack/game/PlayerBettingMoney.java @@ -0,0 +1,28 @@ +package blackjack.game; + +import blackjack.player.Player; +import java.util.HashMap; +import java.util.Map; + +public class PlayerBettingMoney { + + private final Map bettingMoney; + + public PlayerBettingMoney() { + this.bettingMoney = new HashMap<>(); + } + + public void addBetting(Player player, Money money) { + if (bettingMoney.containsKey(player)) { + throw new IllegalArgumentException("[ERROR] 이미 존재하는 플레이어입니다."); + } + bettingMoney.put(player, money); + } + + public Money getBettingAmountOf(Player player) { + if (!bettingMoney.containsKey(player)) { + throw new IllegalArgumentException("[ERROR] 존재하지 않는 플레이어입니다."); + } + return bettingMoney.get(player); + } +} diff --git a/src/test/java/blackjack/game/PlayerBettingMoneyTest.java b/src/test/java/blackjack/game/PlayerBettingMoneyTest.java new file mode 100644 index 0000000000..4f6a781ad3 --- /dev/null +++ b/src/test/java/blackjack/game/PlayerBettingMoneyTest.java @@ -0,0 +1,48 @@ +package blackjack.game; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import blackjack.player.Player; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PlayerBettingMoneyTest { + private PlayerBettingMoney playerBettingMoney; + private Player player; + private Money money; + + @BeforeEach + void beforeEach() { + playerBettingMoney = new PlayerBettingMoney(); + player = new Player("atto"); + money = new Money(10000); + + playerBettingMoney.addBetting(player, money); + } + + @Test + @DisplayName("플레이어별 배팅 금액을 저장한다.") + void addBettingTest() { + assertThat(playerBettingMoney.getBettingAmountOf(player)).isEqualTo(money); + } + + @Test + @DisplayName("존재하지 않는 플레이어의 배팅 결과를 가져오려 할 경우 예외를 발생시킨다.") + void notExistPlayerTest() { + Player notExistPlayer = new Player("pobi"); + + assertThatThrownBy(() -> playerBettingMoney.getBettingAmountOf(notExistPlayer)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 존재하지 않는 플레이어입니다."); + } + + @Test + @DisplayName("이미 존재하는 플레이어의 배팅 결과를 저장하려 할 경우 예외를 발생시킨다.") + void alreadyExistPlayerTest() { + assertThatThrownBy(() -> playerBettingMoney.addBetting(player, money)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이미 존재하는 플레이어입니다."); + } +} From f0573719ba04bf3688ad3a45a3b95d60571777bf Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:17:42 +0900 Subject: [PATCH 78/85] =?UTF-8?q?refactor(BlackJackGame):=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EB=90=9C=20=EA=B2=8C=EC=9E=84=20=ED=9D=90=EB=A6=84=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/blackjack/game/BlackJackGame.java | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/main/java/blackjack/game/BlackJackGame.java b/src/main/java/blackjack/game/BlackJackGame.java index 473bc42d0d..2522a90930 100644 --- a/src/main/java/blackjack/game/BlackJackGame.java +++ b/src/main/java/blackjack/game/BlackJackGame.java @@ -21,14 +21,14 @@ public BlackJackGame(InputView inputView, OutputView outputView) { public void play() { Deck deck = Deck.createShuffledFullDeck(); Dealer dealer = new Dealer(); - Players players = createPlayers(); + PlayerBettingMoney playerBettingMoney = decideBettingMoney(players); initializeGame(deck, dealer, players); proceedPlayersTurn(deck, players); proceedDealerTurn(deck, dealer); showCardsWithScore(dealer, players); - showMatchResult(dealer, players); + showMatchResult(dealer, players, playerBettingMoney); } private Players createPlayers() { @@ -39,6 +39,17 @@ private Players createPlayers() { return players; } + private PlayerBettingMoney decideBettingMoney(Players players) { + PlayerBettingMoney playerBettingMoney = new PlayerBettingMoney(); + for (Player player : players.getPlayers()) { + outputView.printBettingRequestMessage(player.getName()); + Money money = new Money(inputView.readBattingAmount()); + playerBettingMoney.addBetting(player, money); + outputView.printNewLine(); + } + return playerBettingMoney; + } + private void initializeGame(Deck deck, Dealer dealer, Players players) { players.doInitialDraw(deck); dealer.doInitialDraw(deck); @@ -97,34 +108,29 @@ private void showCardsWithScore(Dealer dealer, Players players) { outputView.printNewLine(); } - private void showMatchResult(Dealer dealer, Players players) { - MatchResults matchResults = calculateMatchResults(dealer, players); + private void showMatchResult(Dealer dealer, Players players, PlayerBettingMoney bettingResults) { + MatchResults matchResults = calculateMatchResults(dealer, players, bettingResults); outputView.printResultStart(); showDealerResult(matchResults); showPlayersResult(players, matchResults); } - private MatchResults calculateMatchResults(Dealer dealer, Players players) { - MatchResults matchResults = new MatchResults(); + private MatchResults calculateMatchResults(Dealer dealer, Players players, PlayerBettingMoney bettingResults) { + MatchResults matchResults = new MatchResults(dealer.getHand()); for (Player player : players.getPlayers()) { - matchResults.addResult(player.getName(), player.getScore(), dealer.getScore()); + matchResults.addResult(player, bettingResults.getBettingAmountOf(player)); } return matchResults; } private void showDealerResult(MatchResults matchResults) { - outputView.printDealerResult( - matchResults.getResultCount(MatchResult.DEALER_WIN), - matchResults.getResultCount(MatchResult.TIE), - matchResults.getResultCount(MatchResult.PLAYER_WIN) - ); + outputView.printDealerResult(matchResults.getDealerResult()); } private void showPlayersResult(Players players, MatchResults matchResults) { for (Player player : players.getPlayers()) { - String playerName = player.getName(); - MatchResult result = matchResults.getResultByName(playerName); - outputView.printPlayerResult(playerName, result); + int playerResult = matchResults.getResultOf(player); + outputView.printPlayerResult(player.getName(), playerResult); } } } From e02326f40279b9d77a6ce9341db2aafed0b5a8bd Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:24:38 +0900 Subject: [PATCH 79/85] =?UTF-8?q?refactor(Test):=20=EC=A0=91=EA=B7=BC?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=EC=9E=90=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/game/MatchResultTest.java | 8 ++++---- src/test/java/blackjack/game/MatchResultsTest.java | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/blackjack/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java index 171edff6ca..106631532a 100644 --- a/src/test/java/blackjack/game/MatchResultTest.java +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -15,21 +15,21 @@ class MatchResultTest { - static Hand handBlackJack = new Hand(List.of( + private static final Hand handBlackJack = new Hand(List.of( new Card(Shape.CLOVER, Rank.ACE), new Card(Shape.DIAMOND, Rank.TEN) )); - static Hand hand22 = new Hand(List.of( + private static final Hand hand22 = new Hand(List.of( new Card(Shape.HEART, Rank.TEN), new Card(Shape.CLOVER, Rank.TEN), new Card(Shape.DIAMOND, Rank.TWO) )); - static Hand hand21 = new Hand(List.of( + private static final Hand hand21 = new Hand(List.of( new Card(Shape.CLOVER, Rank.JACK), new Card(Shape.DIAMOND, Rank.TEN), new Card(Shape.HEART, Rank.ACE) )); - static Hand hand20 = new Hand(List.of( + private static final Hand hand20 = new Hand(List.of( new Card(Shape.CLOVER, Rank.JACK), new Card(Shape.DIAMOND, Rank.TEN) )); diff --git a/src/test/java/blackjack/game/MatchResultsTest.java b/src/test/java/blackjack/game/MatchResultsTest.java index 27b028e45f..4833c47181 100644 --- a/src/test/java/blackjack/game/MatchResultsTest.java +++ b/src/test/java/blackjack/game/MatchResultsTest.java @@ -15,17 +15,17 @@ class MatchResultsTest { - Hand dealerHand = new Hand(List.of( + private final Hand dealerHand = new Hand(List.of( new Card(Shape.DIAMOND, Rank.TEN), new Card(Shape.HEART, Rank.TEN ))); - Hand playerHand = new Hand(List.of( + private final Hand playerHand = new Hand(List.of( new Card(Shape.CLOVER, Rank.TEN), new Card(Shape.DIAMOND, Rank.FIVE ))); - Player player = new Player("atto", playerHand); - MatchResults matchResults = new MatchResults(dealerHand); - Money money = new Money(10000); + private final Player player = new Player("atto", playerHand); + private final MatchResults matchResults = new MatchResults(dealerHand); + private final Money money = new Money(10000); @BeforeEach void beforeEach() { From 706741cfb6917f865038a41477afc666d6767e61 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:24:55 +0900 Subject: [PATCH 80/85] =?UTF-8?q?style(Test):=20=EA=B0=9C=ED=96=89=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 --- src/test/java/blackjack/game/PlayerBettingMoneyTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/blackjack/game/PlayerBettingMoneyTest.java b/src/test/java/blackjack/game/PlayerBettingMoneyTest.java index 4f6a781ad3..75628faa1d 100644 --- a/src/test/java/blackjack/game/PlayerBettingMoneyTest.java +++ b/src/test/java/blackjack/game/PlayerBettingMoneyTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; class PlayerBettingMoneyTest { + private PlayerBettingMoney playerBettingMoney; private Player player; private Money money; From fd097e384b823eca4fb479b56d4516cac717d000 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:28:20 +0900 Subject: [PATCH 81/85] =?UTF-8?q?refactor(InputView):=20=EB=8B=A8=EC=88=9C?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=98=88=EC=99=B8=20=EC=B6=9C=EB=A0=A5=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/view/InputView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/view/InputView.java b/src/main/java/blackjack/view/InputView.java index 4a57211bc7..a13eeedf1c 100644 --- a/src/main/java/blackjack/view/InputView.java +++ b/src/main/java/blackjack/view/InputView.java @@ -26,7 +26,7 @@ private void validateInteger(String input) { try { Integer.parseInt(input); } catch (IllegalArgumentException e) { - System.out.println("[ERROR] 정수가 아닙니다."); + throw new IllegalArgumentException("[ERROR] 정수가 아닙니다."); } } From e9f554d8338b17bd298347ca1273711bca3277b7 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:29:10 +0900 Subject: [PATCH 82/85] =?UTF-8?q?refactor(Score):=20final=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Score.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/player/Score.java b/src/main/java/blackjack/player/Score.java index 19b991767b..ad58843a41 100644 --- a/src/main/java/blackjack/player/Score.java +++ b/src/main/java/blackjack/player/Score.java @@ -7,7 +7,7 @@ public class Score { private static final int BLACKJACK = 21; private static final int ADDITIONAL_ACE = 10; - private int score; + private final int score; public Score(int score) { this.score = score; From 8aaf97bb4dc7e711c768a2ceaeeab35d06d39ea4 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:35:08 +0900 Subject: [PATCH 83/85] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=82=AC=ED=95=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9d6c7f7cc3..ccdaf59ccd 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ - [x] 플레이어들의 인원수는 1명 이상 10명 이하이다. ### 베팅 결과 -- [ ] 플레이어별 배팅 금액을 저장한다. +- [x] 플레이어별 배팅 금액을 저장한다. ### 배팅 금액 - [x] 배팅 금액은 자연수이다. @@ -42,18 +42,19 @@ - [x] 17점 이상이 될 때까지 카드를 계속 뽑는다. ### 게임 결과 -- [ ] 게임 결과를 아래의 순서대로 올바르게 판단한다. +- [x] 게임 결과를 아래의 순서대로 올바르게 판단한다. 1. 플레이어는 배팅 금액의 1.5배만큼 돈을 번다. - - [ ] 플레이어가 블랙잭이고 딜러가 블랙잭이 아닌 경우 + - [x] 플레이어가 블랙잭이고 딜러가 블랙잭이 아닌 경우 2. 플레이어는 배팅 금액만큼 돈을 번다. - - [ ] 플레이어가 버스트가 아니고 딜러가 버스트인 경우 - - [ ] 플레이어와 딜러가 버스트가 아니고 플레이어의 점수가 더 큰 경우 + - [x] 플레이어가 버스트가 아니고 딜러가 버스트인 경우 + - [x] 플레이어와 딜러가 버스트가 아니고 플레이어의 점수가 더 큰 경우 3. 플레이어는 배팅 금액을 잃는다. - - [ ] 플레이어가 버스트인 경우 - - [ ] 플레이어와 딜러가 버스트가 아니고 딜러의 점수가 더 큰 경우 + - [x] 플레이어가 버스트인 경우 + - [x] 플레이어와 딜러가 버스트가 아니고 딜러의 점수가 더 큰 경우 + - [x] 플레이어가 블랙잭이 아니고 딜러가 블랙잭인 경우 4. 플레이어는 배팅 금액을 다시 돌려받는다. - - [ ] 플레이어와 딜러가 버스트가 아니고 동점인 경우 -- [ ] 각 플레이어별 게임 결과를 저장한다. + - [x] 플레이어와 딜러가 버스트가 아니고 동점인 경우 +- [x] 각 플레이어별 게임 결과를 저장한다. --- @@ -65,4 +66,4 @@ - [x] 플레이어가 카드를 새로 뽑을 때마다 카드 현황을 공개한다. - [x] 각 플레이어는 딜러와만 승패를 겨룬다. - [x] 딜러는 모든 플레이어와 승패를 겨룬다. -- [x] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 승패를 확인한다. +- [x] 게임을 완료한 후 딜러를 포함한 모든 플레이어의 수익을 확인한다. From dd795c3333d56f2f6e17f66bfd2b8518893564d7 Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:35:26 +0900 Subject: [PATCH 84/85] =?UTF-8?q?refactor(Test):=20=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/blackjack/game/MatchResultTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/blackjack/game/MatchResultTest.java b/src/test/java/blackjack/game/MatchResultTest.java index 106631532a..fffbd0d200 100644 --- a/src/test/java/blackjack/game/MatchResultTest.java +++ b/src/test/java/blackjack/game/MatchResultTest.java @@ -78,9 +78,10 @@ void dealerWinTest(Hand playerHand, Hand dealerHand) { static Stream dealerWinCases() { return Stream.of( - Arguments.of(hand21, handBlackJack), Arguments.of(hand22, hand20), - Arguments.of(hand20, hand21) + Arguments.of(hand22, hand22), + Arguments.of(hand20, hand21), + Arguments.of(hand21, handBlackJack) ); } From 22b97bb27bf2d8ad191ac450d8cd04a6faa5953f Mon Sep 17 00:00:00 2001 From: hyxrxn Date: Sat, 16 Mar 2024 16:58:30 +0900 Subject: [PATCH 85/85] =?UTF-8?q?refactor(Dealer):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20super=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/blackjack/player/Dealer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/blackjack/player/Dealer.java b/src/main/java/blackjack/player/Dealer.java index 76c67ec1de..d713c71656 100644 --- a/src/main/java/blackjack/player/Dealer.java +++ b/src/main/java/blackjack/player/Dealer.java @@ -16,7 +16,7 @@ public Dealer() { } public Card getFirstCard() { - List cards = super.getCards(); + List cards = getCards(); if (cards.isEmpty()) { throw new IllegalStateException("[ERROR] 딜러가 카드를 가지고 있지 않습니다."); }