From ca9e7afff2802ba29b08eb5c417cfd59077ac91f Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 14:21:29 +0900 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/domain/GameNumber.java | 39 +++++++++++++++++++ .../java/baseball/domain/GameNumberTest.java | 22 +++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/main/java/baseball/domain/GameNumber.java create mode 100644 src/test/java/baseball/domain/GameNumberTest.java diff --git a/src/main/java/baseball/domain/GameNumber.java b/src/main/java/baseball/domain/GameNumber.java new file mode 100644 index 0000000000..b67379aaba --- /dev/null +++ b/src/main/java/baseball/domain/GameNumber.java @@ -0,0 +1,39 @@ +package baseball.domain; + +import java.util.Objects; + +public class GameNumber { + + private static final int MIN_VALUE = 1; + private static final int MAX_VALUE = 9; + + private final int value; + + public GameNumber(int value) { + validateRange(value); + this.value = value; + } + + private void validateRange(int value) { + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new IllegalArgumentException(String.format("[ERROR] 야구게임 숫자는 %d일 수 없습니다", value)); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GameNumber that = (GameNumber) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/baseball/domain/GameNumberTest.java b/src/test/java/baseball/domain/GameNumberTest.java new file mode 100644 index 0000000000..de186d1d9e --- /dev/null +++ b/src/test/java/baseball/domain/GameNumberTest.java @@ -0,0 +1,22 @@ +package baseball.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class GameNumberTest { + + @ParameterizedTest + @ValueSource(ints = {0, 10}) + void 게임_숫자가_1이상_9이하의_자연수가_아니면_예외를_던진다(int number) { + Assertions.assertThatThrownBy(() -> new GameNumber(number)) + .isInstanceOf(IllegalArgumentException.class); + } + + @ParameterizedTest + @ValueSource(ints = {1, 2, 3, 4, 5, 6, 7, 8, 9}) + void 게임_숫자는_1이상_9이하의_자연수여야한다(int number) { + Assertions.assertThatCode(() -> new GameNumber(number)) + .doesNotThrowAnyException(); + } +} From bdd44d305842a99c9b064dc7de624db56029b85b Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 15:26:07 +0900 Subject: [PATCH 02/18] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=88=98?= =?UTF-8?q?=EB=93=A4=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../baseball/domain/GameNumberCreator.java | 7 ++++++ .../java/baseball/domain/GameNumbers.java | 24 +++++++++++++++++++ .../java/baseball/domain/GameNumbersTest.java | 20 ++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 src/main/java/baseball/domain/GameNumberCreator.java create mode 100644 src/main/java/baseball/domain/GameNumbers.java create mode 100644 src/test/java/baseball/domain/GameNumbersTest.java diff --git a/src/main/java/baseball/domain/GameNumberCreator.java b/src/main/java/baseball/domain/GameNumberCreator.java new file mode 100644 index 0000000000..644b351438 --- /dev/null +++ b/src/main/java/baseball/domain/GameNumberCreator.java @@ -0,0 +1,7 @@ +package baseball.domain; + +import java.util.List; + +public interface GameNumberCreator { + List create(); +} diff --git a/src/main/java/baseball/domain/GameNumbers.java b/src/main/java/baseball/domain/GameNumbers.java new file mode 100644 index 0000000000..e9033a89b0 --- /dev/null +++ b/src/main/java/baseball/domain/GameNumbers.java @@ -0,0 +1,24 @@ +package baseball.domain; + +import java.util.List; + +public class GameNumbers { + + private static final int MAX_LENGTH = 3; + private final List numbers; + + public static GameNumbers from(GameNumberCreator numberCreator) { + return new GameNumbers(numberCreator.create()); + } + + private GameNumbers(List numbers) { + validateLength(numbers); + this.numbers = numbers; + } + + private void validateLength(List numbers) { + if (numbers.size() > MAX_LENGTH) { + throw new IllegalArgumentException(String.format("[ERROR] 게임 숫자는 %d 자리를 초과할 수 없습니다.", MAX_LENGTH)); + } + } +} diff --git a/src/test/java/baseball/domain/GameNumbersTest.java b/src/test/java/baseball/domain/GameNumbersTest.java new file mode 100644 index 0000000000..f31a7b78c6 --- /dev/null +++ b/src/test/java/baseball/domain/GameNumbersTest.java @@ -0,0 +1,20 @@ +package baseball.domain; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class GameNumbersTest { + + @Test + void 게임_넘버가_3자리를_초과하면_예외를_던진다() { + // given + GameNumberCreator creator = () -> + List.of(new GameNumber(1), new GameNumber(2), new GameNumber(3), new GameNumber(4)); + + assertThatThrownBy(() -> GameNumbers.from(creator)) + .isInstanceOf(IllegalArgumentException.class); + } + +} From e4e71af760052d63b6fc86a8eca5d4f39a296069 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 15:52:05 +0900 Subject: [PATCH 03/18] =?UTF-8?q?feat:=20=EC=9E=85=EB=A0=A5=EA=B0=92?= =?UTF-8?q?=EC=9D=84=20=EA=B2=8C=EC=9E=84=20=EC=88=98=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/StringToGameNumberCreator.java | 30 +++++++++++++++++++ .../domain/StringToGameNumberCreatorTest.java | 19 ++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/main/java/baseball/domain/StringToGameNumberCreator.java create mode 100644 src/test/java/baseball/domain/StringToGameNumberCreatorTest.java diff --git a/src/main/java/baseball/domain/StringToGameNumberCreator.java b/src/main/java/baseball/domain/StringToGameNumberCreator.java new file mode 100644 index 0000000000..53368c30e9 --- /dev/null +++ b/src/main/java/baseball/domain/StringToGameNumberCreator.java @@ -0,0 +1,30 @@ +package baseball.domain; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class StringToGameNumberCreator implements GameNumberCreator { + + private final String values; + + public StringToGameNumberCreator(String values) { + this.values = values; + } + + @Override + public List create() { + return Arrays.stream(values.split("")) + .map(this::parseInt) + .map(GameNumber::new) + .collect(Collectors.toList()); + } + + private Integer parseInt(String value) { + try { + return Integer.parseInt(values); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(String.format("[ERROR] 입력값 %s는 숫자가 아닙니다.", value)); + } + } +} diff --git a/src/test/java/baseball/domain/StringToGameNumberCreatorTest.java b/src/test/java/baseball/domain/StringToGameNumberCreatorTest.java new file mode 100644 index 0000000000..0fb8c649ee --- /dev/null +++ b/src/test/java/baseball/domain/StringToGameNumberCreatorTest.java @@ -0,0 +1,19 @@ +package baseball.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class StringToGameNumberCreatorTest { + + @ParameterizedTest + @ValueSource(strings = {"12 ", "-12", "ㅁ12", "1a3", "87?"}) + void 입력값에_숫자가_아닌_값이_존재하면_GameNumber생성_시_예외를_던진다(String values) { + // given + final StringToGameNumberCreator creator = new StringToGameNumberCreator(values); + + // when & then + Assertions.assertThatThrownBy(creator::create) + .isInstanceOf(IllegalArgumentException.class); + } +} From 3d209adc8477d149cb18035ca7d72b54a34b207a Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 15:56:39 +0900 Subject: [PATCH 04/18] =?UTF-8?q?feat:=20Integer=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=88=98=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/IntegerToGameNumberCreator.java | 19 +++++++++++++++++++ .../IntegerToGameNumberCreatorTest.java | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/main/java/baseball/domain/IntegerToGameNumberCreator.java create mode 100644 src/test/java/baseball/domain/IntegerToGameNumberCreatorTest.java diff --git a/src/main/java/baseball/domain/IntegerToGameNumberCreator.java b/src/main/java/baseball/domain/IntegerToGameNumberCreator.java new file mode 100644 index 0000000000..022c67ff9e --- /dev/null +++ b/src/main/java/baseball/domain/IntegerToGameNumberCreator.java @@ -0,0 +1,19 @@ +package baseball.domain; + +import java.util.List; +import java.util.stream.Collectors; + +public class IntegerToGameNumberCreator implements GameNumberCreator { + private final List values; + + public IntegerToGameNumberCreator(List values) { + this.values = values; + } + + @Override + public List create() { + return values.stream() + .map(GameNumber::new) + .collect(Collectors.toList()); + } +} diff --git a/src/test/java/baseball/domain/IntegerToGameNumberCreatorTest.java b/src/test/java/baseball/domain/IntegerToGameNumberCreatorTest.java new file mode 100644 index 0000000000..5515b4ee51 --- /dev/null +++ b/src/test/java/baseball/domain/IntegerToGameNumberCreatorTest.java @@ -0,0 +1,19 @@ +package baseball.domain; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class IntegerToGameNumberCreatorTest { + + @Test + void 숫자들을_통해_게임_숫자를_만들_수_있다() { + // given + final List values = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9); + final IntegerToGameNumberCreator creator = new IntegerToGameNumberCreator(values); + + // when & then + Assertions.assertThatCode(creator::create) + .doesNotThrowAnyException(); + } +} From de776a1329adc54168f4f43833733b06cc2b824c Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 16:00:30 +0900 Subject: [PATCH 05/18] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/domain/GameNumbers.java | 9 +++++---- .../{ => gamenumbercreator}/GameNumberCreator.java | 3 ++- .../IntegerToGameNumberCreator.java | 3 ++- .../StringToGameNumberCreator.java | 3 ++- src/test/java/baseball/ApplicationTest.java | 6 +++--- src/test/java/baseball/domain/GameNumbersTest.java | 1 + .../IntegerToGameNumberCreatorTest.java | 2 +- .../StringToGameNumberCreatorTest.java | 2 +- src/test/java/study/StringTest.java | 5 +++-- 9 files changed, 20 insertions(+), 14 deletions(-) rename src/main/java/baseball/domain/{ => gamenumbercreator}/GameNumberCreator.java (54%) rename src/main/java/baseball/domain/{ => gamenumbercreator}/IntegerToGameNumberCreator.java (85%) rename src/main/java/baseball/domain/{ => gamenumbercreator}/StringToGameNumberCreator.java (91%) rename src/test/java/baseball/domain/{ => gamenumbercreator}/IntegerToGameNumberCreatorTest.java (92%) rename src/test/java/baseball/domain/{ => gamenumbercreator}/StringToGameNumberCreatorTest.java (93%) diff --git a/src/main/java/baseball/domain/GameNumbers.java b/src/main/java/baseball/domain/GameNumbers.java index e9033a89b0..4cb2564341 100644 --- a/src/main/java/baseball/domain/GameNumbers.java +++ b/src/main/java/baseball/domain/GameNumbers.java @@ -1,5 +1,6 @@ package baseball.domain; +import baseball.domain.gamenumbercreator.GameNumberCreator; import java.util.List; public class GameNumbers { @@ -7,15 +8,15 @@ public class GameNumbers { private static final int MAX_LENGTH = 3; private final List numbers; - public static GameNumbers from(GameNumberCreator numberCreator) { - return new GameNumbers(numberCreator.create()); - } - private GameNumbers(List numbers) { validateLength(numbers); this.numbers = numbers; } + public static GameNumbers from(GameNumberCreator numberCreator) { + return new GameNumbers(numberCreator.create()); + } + private void validateLength(List numbers) { if (numbers.size() > MAX_LENGTH) { throw new IllegalArgumentException(String.format("[ERROR] 게임 숫자는 %d 자리를 초과할 수 없습니다.", MAX_LENGTH)); diff --git a/src/main/java/baseball/domain/GameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/GameNumberCreator.java similarity index 54% rename from src/main/java/baseball/domain/GameNumberCreator.java rename to src/main/java/baseball/domain/gamenumbercreator/GameNumberCreator.java index 644b351438..1550423b5e 100644 --- a/src/main/java/baseball/domain/GameNumberCreator.java +++ b/src/main/java/baseball/domain/gamenumbercreator/GameNumberCreator.java @@ -1,5 +1,6 @@ -package baseball.domain; +package baseball.domain.gamenumbercreator; +import baseball.domain.GameNumber; import java.util.List; public interface GameNumberCreator { diff --git a/src/main/java/baseball/domain/IntegerToGameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreator.java similarity index 85% rename from src/main/java/baseball/domain/IntegerToGameNumberCreator.java rename to src/main/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreator.java index 022c67ff9e..0a66975188 100644 --- a/src/main/java/baseball/domain/IntegerToGameNumberCreator.java +++ b/src/main/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreator.java @@ -1,5 +1,6 @@ -package baseball.domain; +package baseball.domain.gamenumbercreator; +import baseball.domain.GameNumber; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/baseball/domain/StringToGameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java similarity index 91% rename from src/main/java/baseball/domain/StringToGameNumberCreator.java rename to src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java index 53368c30e9..db8e830fe5 100644 --- a/src/main/java/baseball/domain/StringToGameNumberCreator.java +++ b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java @@ -1,5 +1,6 @@ -package baseball.domain; +package baseball.domain.gamenumbercreator; +import baseball.domain.GameNumber; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; diff --git a/src/test/java/baseball/ApplicationTest.java b/src/test/java/baseball/ApplicationTest.java index 3fa29fa67b..fcd4cde406 100644 --- a/src/test/java/baseball/ApplicationTest.java +++ b/src/test/java/baseball/ApplicationTest.java @@ -1,13 +1,13 @@ package baseball; -import camp.nextstep.edu.missionutils.test.NsTest; -import org.junit.jupiter.api.Test; - import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomNumberInRangeTest; import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import camp.nextstep.edu.missionutils.test.NsTest; +import org.junit.jupiter.api.Test; + class ApplicationTest extends NsTest { @Test void 게임종료_후_재시작() { diff --git a/src/test/java/baseball/domain/GameNumbersTest.java b/src/test/java/baseball/domain/GameNumbersTest.java index f31a7b78c6..afe63af3ed 100644 --- a/src/test/java/baseball/domain/GameNumbersTest.java +++ b/src/test/java/baseball/domain/GameNumbersTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; +import baseball.domain.gamenumbercreator.GameNumberCreator; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/baseball/domain/IntegerToGameNumberCreatorTest.java b/src/test/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreatorTest.java similarity index 92% rename from src/test/java/baseball/domain/IntegerToGameNumberCreatorTest.java rename to src/test/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreatorTest.java index 5515b4ee51..66e6234d0f 100644 --- a/src/test/java/baseball/domain/IntegerToGameNumberCreatorTest.java +++ b/src/test/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreatorTest.java @@ -1,4 +1,4 @@ -package baseball.domain; +package baseball.domain.gamenumbercreator; import java.util.List; import org.assertj.core.api.Assertions; diff --git a/src/test/java/baseball/domain/StringToGameNumberCreatorTest.java b/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java similarity index 93% rename from src/test/java/baseball/domain/StringToGameNumberCreatorTest.java rename to src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java index 0fb8c649ee..47ab098221 100644 --- a/src/test/java/baseball/domain/StringToGameNumberCreatorTest.java +++ b/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java @@ -1,4 +1,4 @@ -package baseball.domain; +package baseball.domain.gamenumbercreator; import org.assertj.core.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/study/StringTest.java b/src/test/java/study/StringTest.java index 462ab1c4a4..b8d0ba50a8 100644 --- a/src/test/java/study/StringTest.java +++ b/src/test/java/study/StringTest.java @@ -1,8 +1,9 @@ package study; -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.assertj.core.api.Assertions.*; +import org.junit.jupiter.api.Test; public class StringTest { From b0b21a581c19bf0aa97f82e5add7526f9d312f14 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 16:55:21 +0900 Subject: [PATCH 06/18] =?UTF-8?q?test:=20GameNumbersTest=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/baseball/domain/GameNumbers.java | 4 +++- .../java/baseball/domain/GameNumbersTest.java | 21 +++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/baseball/domain/GameNumbers.java b/src/main/java/baseball/domain/GameNumbers.java index 4cb2564341..e5acb30e31 100644 --- a/src/main/java/baseball/domain/GameNumbers.java +++ b/src/main/java/baseball/domain/GameNumbers.java @@ -2,6 +2,8 @@ import baseball.domain.gamenumbercreator.GameNumberCreator; import java.util.List; +import java.util.Objects; +import java.util.stream.IntStream; public class GameNumbers { @@ -18,7 +20,7 @@ public static GameNumbers from(GameNumberCreator numberCreator) { } private void validateLength(List numbers) { - if (numbers.size() > MAX_LENGTH) { + if (numbers.size() != MAX_LENGTH) { throw new IllegalArgumentException(String.format("[ERROR] 게임 숫자는 %d 자리를 초과할 수 없습니다.", MAX_LENGTH)); } } diff --git a/src/test/java/baseball/domain/GameNumbersTest.java b/src/test/java/baseball/domain/GameNumbersTest.java index afe63af3ed..948765f74b 100644 --- a/src/test/java/baseball/domain/GameNumbersTest.java +++ b/src/test/java/baseball/domain/GameNumbersTest.java @@ -4,18 +4,27 @@ import baseball.domain.gamenumbercreator.GameNumberCreator; import java.util.List; -import org.junit.jupiter.api.Test; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class GameNumbersTest { - @Test - void 게임_넘버가_3자리를_초과하면_예외를_던진다() { + public static Stream invalidGameNumbers() { + return Stream.of( + Arguments.of(List.of(new GameNumber(1), new GameNumber(2), new GameNumber(3), new GameNumber(4))), + Arguments.of(List.of(new GameNumber(1), new GameNumber(2))) + ); + } + + @ParameterizedTest + @MethodSource("invalidGameNumbers") + void 게임_넘버가_3자리가_아니면_예외를_던진다(List gameNumbers) { // given - GameNumberCreator creator = () -> - List.of(new GameNumber(1), new GameNumber(2), new GameNumber(3), new GameNumber(4)); + GameNumberCreator creator = () -> gameNumbers; assertThatThrownBy(() -> GameNumbers.from(creator)) .isInstanceOf(IllegalArgumentException.class); } - } From 79a476085636615df727d4025a16c8ec7ac48c4d Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 16:59:59 +0900 Subject: [PATCH 07/18] =?UTF-8?q?feat:=20GameResult=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/domain/GameResult.java | 32 +++++++++++++++++++ .../java/baseball/domain/GameResultTest.java | 23 +++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/main/java/baseball/domain/GameResult.java create mode 100644 src/test/java/baseball/domain/GameResultTest.java diff --git a/src/main/java/baseball/domain/GameResult.java b/src/main/java/baseball/domain/GameResult.java new file mode 100644 index 0000000000..e7ed600216 --- /dev/null +++ b/src/main/java/baseball/domain/GameResult.java @@ -0,0 +1,32 @@ +package baseball.domain; + +import java.util.Arrays; + +public enum GameResult { + ZERO(0, 0), + ZERO_STRIKE_ONE_BALL(0, 1), + ZERO_STRIKE_TWO_BALL(0, 2), + ZERO_STRIKE_THREE_BALL(0, 3), + ONE_STRIKE_ZERO_BALL(1, 0), + ONE_STRIKE_ONE_BALL(1, 1), + ONE_STRIKE_TWO_BALL(1, 2), + TWO_STRIKE_ZERO_BALL(2, 0), + TWO_STRIKE_ONE_BALL(2, 1), + THREE_STRIKE(3, 0); + + private final int strike; + private final int ball; + + GameResult(int strike, int ball) { + this.strike = strike; + this.ball = ball; + } + + public static GameResult find(int strike, int ball) { + return Arrays.stream(GameResult.values()) + .filter(gameResult -> gameResult.strike == strike && gameResult.ball == ball) + .findAny() + .orElseThrow(() -> new IllegalArgumentException( + String.format("[ERROR] %d 스트라이크 %d 볼에 해달하는 결과는 존재하지 않습니다.", strike, ball))); + } +} diff --git a/src/test/java/baseball/domain/GameResultTest.java b/src/test/java/baseball/domain/GameResultTest.java new file mode 100644 index 0000000000..a1ad2b28c8 --- /dev/null +++ b/src/test/java/baseball/domain/GameResultTest.java @@ -0,0 +1,23 @@ +package baseball.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class GameResultTest { + + @ParameterizedTest + @CsvSource(value = {"0, -1", "-1, 1"}) + void 올바르지않은_strike나_ball값으로_결과를_찾으면_예외를_던진다(int strike, int ball) { + Assertions.assertThatThrownBy(() -> GameResult.find(strike, ball)) + .isInstanceOf(IllegalArgumentException.class); + } + + @ParameterizedTest + @CsvSource(value = {"0, 0", "0, 1", "0, 2", "0, 3", "1, 0", "1, 1", "1, 2", "2, 0", "2, 1", "3, 0"}) + void 올바른_strike_ball값으로_결과를_찾을_수_있다(int strike, int ball) { + Assertions.assertThatCode(() -> GameResult.find(strike, ball)) + .doesNotThrowAnyException(); + } + +} From 7a4efb6cb16fd00a21c81712a90eceec14cce2a2 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 17:06:19 +0900 Subject: [PATCH 08/18] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EA=B3=84=EC=82=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/baseball/domain/GameNumbers.java | 29 ++++++++++++++++ .../java/baseball/domain/GameNumbersTest.java | 33 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/main/java/baseball/domain/GameNumbers.java b/src/main/java/baseball/domain/GameNumbers.java index e5acb30e31..b31aead0f2 100644 --- a/src/main/java/baseball/domain/GameNumbers.java +++ b/src/main/java/baseball/domain/GameNumbers.java @@ -24,4 +24,33 @@ private void validateLength(List numbers) { throw new IllegalArgumentException(String.format("[ERROR] 게임 숫자는 %d 자리를 초과할 수 없습니다.", MAX_LENGTH)); } } + + public GameResult calculateResult(GameNumbers other) { + int strike = (int) IntStream.range(0, other.numbers.size()) + .filter(i -> other.numbers.get(i).equals(this.numbers.get(i))) + .count(); + + int ball = (int) other.numbers.stream() + .filter(this.numbers::contains) + .count() - strike; + + return GameResult.find(strike, ball); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + GameNumbers that = (GameNumbers) o; + return Objects.equals(numbers, that.numbers); + } + + @Override + public int hashCode() { + return Objects.hash(numbers); + } } diff --git a/src/test/java/baseball/domain/GameNumbersTest.java b/src/test/java/baseball/domain/GameNumbersTest.java index 948765f74b..bddd511638 100644 --- a/src/test/java/baseball/domain/GameNumbersTest.java +++ b/src/test/java/baseball/domain/GameNumbersTest.java @@ -1,5 +1,6 @@ package baseball.domain; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import baseball.domain.gamenumbercreator.GameNumberCreator; @@ -18,6 +19,26 @@ public static Stream invalidGameNumbers() { ); } + public static Stream numbers() { + final List computerNumbers = List.of(new GameNumber(1), new GameNumber(2), new GameNumber(3)); + + return Stream.of( + Arguments.of( + computerNumbers, + List.of(new GameNumber(1), new GameNumber(2), new GameNumber(3)), + GameResult.THREE_STRIKE), + Arguments.of( + computerNumbers, + List.of(new GameNumber(2), new GameNumber(1), new GameNumber(3)), + GameResult.ONE_STRIKE_TWO_BALL), + Arguments.of( + computerNumbers, + List.of(new GameNumber(7), new GameNumber(8), new GameNumber(9)), + GameResult.ZERO) + ); + + } + @ParameterizedTest @MethodSource("invalidGameNumbers") void 게임_넘버가_3자리가_아니면_예외를_던진다(List gameNumbers) { @@ -27,4 +48,16 @@ public static Stream invalidGameNumbers() { assertThatThrownBy(() -> GameNumbers.from(creator)) .isInstanceOf(IllegalArgumentException.class); } + + @ParameterizedTest + @MethodSource("numbers") + void 게임_넘버들로_게임_결과를_생성할_수_있다(List com, List player, GameResult result) { + // given + final GameNumbers computerNumber = GameNumbers.from(() -> com); + final GameNumbers playerNumber = GameNumbers.from(() -> player); + + // when & then + assertThat(computerNumber.calculateResult(playerNumber)) + .isEqualTo(result); + } } From 8a59a937c664cf9985a5dc15100552cb25166523 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 17:17:40 +0900 Subject: [PATCH 09/18] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=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 --- src/main/java/baseball/domain/GameNumbers.java | 8 ++++++++ src/test/java/baseball/domain/GameNumbersTest.java | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/baseball/domain/GameNumbers.java b/src/main/java/baseball/domain/GameNumbers.java index b31aead0f2..2dfa1b2f69 100644 --- a/src/main/java/baseball/domain/GameNumbers.java +++ b/src/main/java/baseball/domain/GameNumbers.java @@ -1,6 +1,7 @@ package baseball.domain; import baseball.domain.gamenumbercreator.GameNumberCreator; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.stream.IntStream; @@ -12,6 +13,7 @@ public class GameNumbers { private GameNumbers(List numbers) { validateLength(numbers); + validateDuplicate(numbers); this.numbers = numbers; } @@ -25,6 +27,12 @@ private void validateLength(List numbers) { } } + private void validateDuplicate(List numbers) { + if (numbers.size() != new HashSet<>(numbers).size()) { + throw new IllegalArgumentException("[ERROR] 게임 숫자는 중복된 값을 가질 수 없습니다."); + } + } + public GameResult calculateResult(GameNumbers other) { int strike = (int) IntStream.range(0, other.numbers.size()) .filter(i -> other.numbers.get(i).equals(this.numbers.get(i))) diff --git a/src/test/java/baseball/domain/GameNumbersTest.java b/src/test/java/baseball/domain/GameNumbersTest.java index bddd511638..856061b23e 100644 --- a/src/test/java/baseball/domain/GameNumbersTest.java +++ b/src/test/java/baseball/domain/GameNumbersTest.java @@ -6,6 +6,7 @@ import baseball.domain.gamenumbercreator.GameNumberCreator; import java.util.List; import java.util.stream.Stream; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -49,6 +50,17 @@ public static Stream numbers() { .isInstanceOf(IllegalArgumentException.class); } + @Test + void 중복된_게임_넘버가_존재하면_예외를_던진다() { + // given + final List gameNumbers = List.of(new GameNumber(2), new GameNumber(2), new GameNumber(3)); + GameNumberCreator creator = () -> gameNumbers; + + // when & then + assertThatThrownBy(() -> GameNumbers.from(creator)) + .isInstanceOf(IllegalArgumentException.class); + } + @ParameterizedTest @MethodSource("numbers") void 게임_넘버들로_게임_결과를_생성할_수_있다(List com, List player, GameResult result) { From 201effb89e32f10866189788348c87aac2b225f2 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Fri, 24 Mar 2023 20:48:17 +0900 Subject: [PATCH 10/18] =?UTF-8?q?feat:=20Application=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/Application.java | 53 ++++++++++++++++++- src/main/java/baseball/domain/GameNumber.java | 6 +++ .../java/baseball/domain/GameNumbers.java | 4 +- src/main/java/baseball/domain/GameResult.java | 8 +++ .../gamenumbercreator/GameNumberCreator.java | 2 +- .../IntegerToGameNumberCreator.java | 20 ------- .../RandomIntegerToGameNumberCreator.java | 17 ++++++ .../StringToGameNumberCreator.java | 8 ++- .../java/baseball/service/GameService.java | 21 ++++++++ .../java/baseball/domain/GameNumberTest.java | 1 + .../java/baseball/domain/GameNumbersTest.java | 8 +-- ...RandomIntegerToGameNumberCreatorTest.java} | 8 ++- .../StringToGameNumberCreatorTest.java | 13 ++++- 13 files changed, 133 insertions(+), 36 deletions(-) delete mode 100644 src/main/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreator.java create mode 100644 src/main/java/baseball/domain/gamenumbercreator/RandomIntegerToGameNumberCreator.java create mode 100644 src/main/java/baseball/service/GameService.java rename src/test/java/baseball/domain/gamenumbercreator/{IntegerToGameNumberCreatorTest.java => RandomIntegerToGameNumberCreatorTest.java} (51%) diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index dd95a34214..d893b4d34d 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -1,7 +1,58 @@ package baseball; +import baseball.domain.GameResult; +import baseball.service.GameService; +import camp.nextstep.edu.missionutils.Console; + public class Application { + public static void main(String[] args) { - // TODO: 프로그램 구현 + while (true) { + playGame(); + + System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); + if (Console.readLine().equals("2")) { + System.out.println("게임 종료"); + break; + } + } + } + + private static void playGame() { + GameService gameService = new GameService(); + + System.out.println("숫자 야구 게임을 시작합니다."); + while (true) { + System.out.print("숫자를 입력해주세요 : "); + String playerInput = Console.readLine(); + GameResult result = gameService.findResult(playerInput); + String answer = getResultComment(result); + System.out.println(answer); + if (result.equals(GameResult.THREE_STRIKE)) { + break; + } + } + } + + private static String getResultComment(GameResult result) { + final int strike = result.getStrike(); + final int ball = result.getBall(); + + if (strike == 0 && ball == 0) { + return "낫싱"; + } + + StringBuilder answer = new StringBuilder(); + if (ball != 0) { + answer.append(ball); + answer.append("볼 "); + } + + if (strike != 0) { + answer.append(result.getStrike()); + answer.append("스트라이크"); + } + + return answer.toString(); } } diff --git a/src/main/java/baseball/domain/GameNumber.java b/src/main/java/baseball/domain/GameNumber.java index b67379aaba..0eca55de80 100644 --- a/src/main/java/baseball/domain/GameNumber.java +++ b/src/main/java/baseball/domain/GameNumber.java @@ -1,5 +1,6 @@ package baseball.domain; +import camp.nextstep.edu.missionutils.Randoms; import java.util.Objects; public class GameNumber { @@ -20,6 +21,11 @@ private void validateRange(int value) { } } + public static GameNumber createRandomNumber() { + final int number = Randoms.pickNumberInRange(MIN_VALUE, MAX_VALUE); + return new GameNumber(number); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/src/main/java/baseball/domain/GameNumbers.java b/src/main/java/baseball/domain/GameNumbers.java index 2dfa1b2f69..e30d5363d3 100644 --- a/src/main/java/baseball/domain/GameNumbers.java +++ b/src/main/java/baseball/domain/GameNumbers.java @@ -18,12 +18,12 @@ private GameNumbers(List numbers) { } public static GameNumbers from(GameNumberCreator numberCreator) { - return new GameNumbers(numberCreator.create()); + return new GameNumbers(numberCreator.create(MAX_LENGTH)); } private void validateLength(List numbers) { if (numbers.size() != MAX_LENGTH) { - throw new IllegalArgumentException(String.format("[ERROR] 게임 숫자는 %d 자리를 초과할 수 없습니다.", MAX_LENGTH)); + throw new IllegalArgumentException(String.format("[ERROR] 게임 숫자는 %d 자리여야합니다.", MAX_LENGTH)); } } diff --git a/src/main/java/baseball/domain/GameResult.java b/src/main/java/baseball/domain/GameResult.java index e7ed600216..73f5d0c67c 100644 --- a/src/main/java/baseball/domain/GameResult.java +++ b/src/main/java/baseball/domain/GameResult.java @@ -29,4 +29,12 @@ public static GameResult find(int strike, int ball) { .orElseThrow(() -> new IllegalArgumentException( String.format("[ERROR] %d 스트라이크 %d 볼에 해달하는 결과는 존재하지 않습니다.", strike, ball))); } + + public int getStrike() { + return strike; + } + + public int getBall() { + return ball; + } } diff --git a/src/main/java/baseball/domain/gamenumbercreator/GameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/GameNumberCreator.java index 1550423b5e..6364405361 100644 --- a/src/main/java/baseball/domain/gamenumbercreator/GameNumberCreator.java +++ b/src/main/java/baseball/domain/gamenumbercreator/GameNumberCreator.java @@ -4,5 +4,5 @@ import java.util.List; public interface GameNumberCreator { - List create(); + List create(int maxLength); } diff --git a/src/main/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreator.java deleted file mode 100644 index 0a66975188..0000000000 --- a/src/main/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreator.java +++ /dev/null @@ -1,20 +0,0 @@ -package baseball.domain.gamenumbercreator; - -import baseball.domain.GameNumber; -import java.util.List; -import java.util.stream.Collectors; - -public class IntegerToGameNumberCreator implements GameNumberCreator { - private final List values; - - public IntegerToGameNumberCreator(List values) { - this.values = values; - } - - @Override - public List create() { - return values.stream() - .map(GameNumber::new) - .collect(Collectors.toList()); - } -} diff --git a/src/main/java/baseball/domain/gamenumbercreator/RandomIntegerToGameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/RandomIntegerToGameNumberCreator.java new file mode 100644 index 0000000000..8c771ca8ea --- /dev/null +++ b/src/main/java/baseball/domain/gamenumbercreator/RandomIntegerToGameNumberCreator.java @@ -0,0 +1,17 @@ +package baseball.domain.gamenumbercreator; + +import baseball.domain.GameNumber; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class RandomIntegerToGameNumberCreator implements GameNumberCreator { + + @Override + public List create(int maxLength) { + return Stream.generate(GameNumber::createRandomNumber) + .distinct() + .limit(maxLength) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java index db8e830fe5..9b760c70e2 100644 --- a/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java +++ b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java @@ -14,7 +14,11 @@ public StringToGameNumberCreator(String values) { } @Override - public List create() { + public List create(int maxLength) { + if (values.length() != maxLength) { + throw new IllegalArgumentException(String.format("[ERROR] %s는 %d 자리수가 아닙니다.", values, maxLength)); + } + return Arrays.stream(values.split("")) .map(this::parseInt) .map(GameNumber::new) @@ -23,7 +27,7 @@ public List create() { private Integer parseInt(String value) { try { - return Integer.parseInt(values); + return Integer.parseInt(value); } catch (NumberFormatException e) { throw new IllegalArgumentException(String.format("[ERROR] 입력값 %s는 숫자가 아닙니다.", value)); } diff --git a/src/main/java/baseball/service/GameService.java b/src/main/java/baseball/service/GameService.java new file mode 100644 index 0000000000..41d0b81314 --- /dev/null +++ b/src/main/java/baseball/service/GameService.java @@ -0,0 +1,21 @@ +package baseball.service; + +import baseball.domain.GameNumbers; +import baseball.domain.GameResult; +import baseball.domain.gamenumbercreator.RandomIntegerToGameNumberCreator; +import baseball.domain.gamenumbercreator.StringToGameNumberCreator; + +public class GameService { + + private final GameNumbers answerNumbers; + + public GameService() { + this.answerNumbers = GameNumbers.from(new RandomIntegerToGameNumberCreator()); + } + + public GameResult findResult(String playerRequest) { + final StringToGameNumberCreator creator = new StringToGameNumberCreator(playerRequest); + final GameNumbers playerNumbers = GameNumbers.from(creator); + return answerNumbers.calculateResult(playerNumbers); + } +} diff --git a/src/test/java/baseball/domain/GameNumberTest.java b/src/test/java/baseball/domain/GameNumberTest.java index de186d1d9e..1f2b02b7e5 100644 --- a/src/test/java/baseball/domain/GameNumberTest.java +++ b/src/test/java/baseball/domain/GameNumberTest.java @@ -1,6 +1,7 @@ package baseball.domain; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; diff --git a/src/test/java/baseball/domain/GameNumbersTest.java b/src/test/java/baseball/domain/GameNumbersTest.java index 856061b23e..93f24fe490 100644 --- a/src/test/java/baseball/domain/GameNumbersTest.java +++ b/src/test/java/baseball/domain/GameNumbersTest.java @@ -44,7 +44,7 @@ public static Stream numbers() { @MethodSource("invalidGameNumbers") void 게임_넘버가_3자리가_아니면_예외를_던진다(List gameNumbers) { // given - GameNumberCreator creator = () -> gameNumbers; + GameNumberCreator creator = maxLength -> gameNumbers; assertThatThrownBy(() -> GameNumbers.from(creator)) .isInstanceOf(IllegalArgumentException.class); @@ -54,7 +54,7 @@ public static Stream numbers() { void 중복된_게임_넘버가_존재하면_예외를_던진다() { // given final List gameNumbers = List.of(new GameNumber(2), new GameNumber(2), new GameNumber(3)); - GameNumberCreator creator = () -> gameNumbers; + GameNumberCreator creator = maxLength -> gameNumbers; // when & then assertThatThrownBy(() -> GameNumbers.from(creator)) @@ -65,8 +65,8 @@ public static Stream numbers() { @MethodSource("numbers") void 게임_넘버들로_게임_결과를_생성할_수_있다(List com, List player, GameResult result) { // given - final GameNumbers computerNumber = GameNumbers.from(() -> com); - final GameNumbers playerNumber = GameNumbers.from(() -> player); + final GameNumbers computerNumber = GameNumbers.from(maxLength -> com); + final GameNumbers playerNumber = GameNumbers.from(maxLength -> player); // when & then assertThat(computerNumber.calculateResult(playerNumber)) diff --git a/src/test/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreatorTest.java b/src/test/java/baseball/domain/gamenumbercreator/RandomIntegerToGameNumberCreatorTest.java similarity index 51% rename from src/test/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreatorTest.java rename to src/test/java/baseball/domain/gamenumbercreator/RandomIntegerToGameNumberCreatorTest.java index 66e6234d0f..f9a99b9369 100644 --- a/src/test/java/baseball/domain/gamenumbercreator/IntegerToGameNumberCreatorTest.java +++ b/src/test/java/baseball/domain/gamenumbercreator/RandomIntegerToGameNumberCreatorTest.java @@ -1,19 +1,17 @@ package baseball.domain.gamenumbercreator; -import java.util.List; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; -class IntegerToGameNumberCreatorTest { +class RandomIntegerToGameNumberCreatorTest { @Test void 숫자들을_통해_게임_숫자를_만들_수_있다() { // given - final List values = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9); - final IntegerToGameNumberCreator creator = new IntegerToGameNumberCreator(values); + final RandomIntegerToGameNumberCreator creator = new RandomIntegerToGameNumberCreator(); // when & then - Assertions.assertThatCode(creator::create) + Assertions.assertThatCode(() -> creator.create(3)) .doesNotThrowAnyException(); } } diff --git a/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java b/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java index 47ab098221..10262063b4 100644 --- a/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java +++ b/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java @@ -1,6 +1,7 @@ package baseball.domain.gamenumbercreator; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -13,7 +14,17 @@ class StringToGameNumberCreatorTest { final StringToGameNumberCreator creator = new StringToGameNumberCreator(values); // when & then - Assertions.assertThatThrownBy(creator::create) + Assertions.assertThatThrownBy(() -> creator.create(3)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 정상적인_수로_게임_넘버를_만들_수_있다() { + // given + final StringToGameNumberCreator creator = new StringToGameNumberCreator("123"); + + // when & then + Assertions.assertThatThrownBy(() -> creator.create(3)) .isInstanceOf(IllegalArgumentException.class); } } From a0590277d9ca9fdffc9eb8b958d003f294e13ddd Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Sun, 26 Mar 2023 02:07:16 +0900 Subject: [PATCH 11/18] =?UTF-8?q?refactor:=20=EC=9D=BC=EA=B8=89=20?= =?UTF-8?q?=EC=BB=AC=EB=A0=89=EC=85=98=EC=9D=98=20=EC=B0=B8=EC=A1=B0?= =?UTF-8?q?=EB=A5=BC=20=EB=81=8A=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/domain/GameNumbers.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/baseball/domain/GameNumbers.java b/src/main/java/baseball/domain/GameNumbers.java index e30d5363d3..de59817bc8 100644 --- a/src/main/java/baseball/domain/GameNumbers.java +++ b/src/main/java/baseball/domain/GameNumbers.java @@ -1,6 +1,7 @@ package baseball.domain; import baseball.domain.gamenumbercreator.GameNumberCreator; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -14,7 +15,7 @@ public class GameNumbers { private GameNumbers(List numbers) { validateLength(numbers); validateDuplicate(numbers); - this.numbers = numbers; + this.numbers = new ArrayList<>(numbers); } public static GameNumbers from(GameNumberCreator numberCreator) { From b719d6c66848f5e2cca68c7cdd9a9458d48a1f92 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Sun, 26 Mar 2023 02:08:15 +0900 Subject: [PATCH 12/18] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gamenumbercreator/StringToGameNumberCreator.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java index 9b760c70e2..da827d4923 100644 --- a/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java +++ b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java @@ -15,9 +15,7 @@ public StringToGameNumberCreator(String values) { @Override public List create(int maxLength) { - if (values.length() != maxLength) { - throw new IllegalArgumentException(String.format("[ERROR] %s는 %d 자리수가 아닙니다.", values, maxLength)); - } + validteLength(maxLength); return Arrays.stream(values.split("")) .map(this::parseInt) @@ -25,6 +23,12 @@ public List create(int maxLength) { .collect(Collectors.toList()); } + private void validteLength(int maxLength) { + if (values.length() != maxLength) { + throw new IllegalArgumentException(String.format("[ERROR] %s는 %d 자리수가 아닙니다.", values, maxLength)); + } + } + private Integer parseInt(String value) { try { return Integer.parseInt(value); From 31a091426e06aa86debf11df76c53e67c4e28cdc Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Sun, 26 Mar 2023 02:10:32 +0900 Subject: [PATCH 13/18] =?UTF-8?q?refactor:=20strike=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=20=EC=A7=81=EC=A0=91=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/Application.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index d893b4d34d..702ed7e536 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -49,7 +49,7 @@ private static String getResultComment(GameResult result) { } if (strike != 0) { - answer.append(result.getStrike()); + answer.append(strike); answer.append("스트라이크"); } From 5573e23c3476c429af24c8b855211ec4b29325d1 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Sun, 26 Mar 2023 02:14:44 +0900 Subject: [PATCH 14/18] =?UTF-8?q?refactor:=20=EA=B3=84=EC=86=8D=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EB=90=A0=20=ED=95=84=EC=9A=94=EA=B0=80=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EA=B0=9D=EC=B2=B4=EB=A5=BC=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EB=B3=80=EC=88=98=EB=A1=9C=20=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/service/GameService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/baseball/service/GameService.java b/src/main/java/baseball/service/GameService.java index 41d0b81314..c3379a31af 100644 --- a/src/main/java/baseball/service/GameService.java +++ b/src/main/java/baseball/service/GameService.java @@ -2,15 +2,17 @@ import baseball.domain.GameNumbers; import baseball.domain.GameResult; +import baseball.domain.gamenumbercreator.GameNumberCreator; import baseball.domain.gamenumbercreator.RandomIntegerToGameNumberCreator; import baseball.domain.gamenumbercreator.StringToGameNumberCreator; public class GameService { + private static final GameNumberCreator NUMBER_CREATOR = new RandomIntegerToGameNumberCreator(); private final GameNumbers answerNumbers; public GameService() { - this.answerNumbers = GameNumbers.from(new RandomIntegerToGameNumberCreator()); + this.answerNumbers = GameNumbers.from(NUMBER_CREATOR); } public GameResult findResult(String playerRequest) { From 33a288f9b1a50c5c8adc47795cfbc809496dd979 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Sun, 26 Mar 2023 02:30:09 +0900 Subject: [PATCH 15/18] =?UTF-8?q?refactor:=20=EC=9E=AC=EC=8B=9C=EC=9E=91?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=EA=B0=92=EC=9D=B4=201,2=EA=B0=80=20?= =?UTF-8?q?=EC=95=84=EB=8B=88=EB=A9=B4=20=EC=98=88=EC=99=B8=EA=B0=80=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=98=EB=8F=84=EB=A1=9D=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/baseball/Application.java | 6 ++++- src/main/java/baseball/RestartMessage.java | 28 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/main/java/baseball/RestartMessage.java diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index 702ed7e536..9218b2be94 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -11,7 +11,9 @@ public static void main(String[] args) { playGame(); System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."); - if (Console.readLine().equals("2")) { + + final RestartMessage restartMessage = new RestartMessage(Console.readLine()); + if (restartMessage.isEnd()) { System.out.println("게임 종료"); break; } @@ -25,7 +27,9 @@ private static void playGame() { while (true) { System.out.print("숫자를 입력해주세요 : "); String playerInput = Console.readLine(); + GameResult result = gameService.findResult(playerInput); + String answer = getResultComment(result); System.out.println(answer); if (result.equals(GameResult.THREE_STRIKE)) { diff --git a/src/main/java/baseball/RestartMessage.java b/src/main/java/baseball/RestartMessage.java new file mode 100644 index 0000000000..467b2135cd --- /dev/null +++ b/src/main/java/baseball/RestartMessage.java @@ -0,0 +1,28 @@ +package baseball; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RestartMessage { + + private static final String RESTART_MESSAGE = "1"; + private static final String END_MESSAGE = "2"; + private static final Pattern PATTERN = Pattern.compile(String.format("[%s%s]", RESTART_MESSAGE, END_MESSAGE)); + private final String value; + + public RestartMessage(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + final Matcher matcher = PATTERN.matcher(value); + if (!matcher.matches()) { + throw new IllegalArgumentException(String.format("[ERROR] 재시작 입력 값은 %s 일 수 없습니다.", value)); + } + } + + public boolean isEnd() { + return this.value.equals(END_MESSAGE); + } +} From 0cf7b4c47916218fb116ac97e1a917f157818976 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Mon, 27 Mar 2023 12:31:15 +0900 Subject: [PATCH 16/18] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EB=81=9D=20=EC=97=AC=EB=B6=80=EB=A5=BC=20GameResult=20?= =?UTF-8?q?=EB=82=B4=EB=B6=80=EB=A1=9C=20=EC=88=A8=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/Application.java | 2 +- src/main/java/baseball/domain/GameResult.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index 9218b2be94..09093183fb 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -32,7 +32,7 @@ private static void playGame() { String answer = getResultComment(result); System.out.println(answer); - if (result.equals(GameResult.THREE_STRIKE)) { + if (result.isEnd()) { break; } } diff --git a/src/main/java/baseball/domain/GameResult.java b/src/main/java/baseball/domain/GameResult.java index 73f5d0c67c..5f671fb94a 100644 --- a/src/main/java/baseball/domain/GameResult.java +++ b/src/main/java/baseball/domain/GameResult.java @@ -30,6 +30,10 @@ public static GameResult find(int strike, int ball) { String.format("[ERROR] %d 스트라이크 %d 볼에 해달하는 결과는 존재하지 않습니다.", strike, ball))); } + public boolean isEnd() { + return this == THREE_STRIKE; + } + public int getStrike() { return strike; } From 06b7e3c7d3df2a0d105bb356fef91f6147b318fc Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Mon, 27 Mar 2023 12:33:52 +0900 Subject: [PATCH 17/18] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20GameResult=20=EB=82=B4=EB=B6=80=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/baseball/Application.java | 25 +------------------ src/main/java/baseball/domain/GameResult.java | 23 ++++++++++++----- .../StringToGameNumberCreatorTest.java | 4 +-- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/main/java/baseball/Application.java b/src/main/java/baseball/Application.java index 09093183fb..f20d5fa028 100644 --- a/src/main/java/baseball/Application.java +++ b/src/main/java/baseball/Application.java @@ -30,33 +30,10 @@ private static void playGame() { GameResult result = gameService.findResult(playerInput); - String answer = getResultComment(result); - System.out.println(answer); + System.out.println(result.getResultComment()); if (result.isEnd()) { break; } } } - - private static String getResultComment(GameResult result) { - final int strike = result.getStrike(); - final int ball = result.getBall(); - - if (strike == 0 && ball == 0) { - return "낫싱"; - } - - StringBuilder answer = new StringBuilder(); - if (ball != 0) { - answer.append(ball); - answer.append("볼 "); - } - - if (strike != 0) { - answer.append(strike); - answer.append("스트라이크"); - } - - return answer.toString(); - } } diff --git a/src/main/java/baseball/domain/GameResult.java b/src/main/java/baseball/domain/GameResult.java index 5f671fb94a..f716011de3 100644 --- a/src/main/java/baseball/domain/GameResult.java +++ b/src/main/java/baseball/domain/GameResult.java @@ -34,11 +34,22 @@ public boolean isEnd() { return this == THREE_STRIKE; } - public int getStrike() { - return strike; - } - - public int getBall() { - return ball; + public String getResultComment() { + if (strike == 0 && ball == 0) { + return "낫싱"; + } + + StringBuilder answer = new StringBuilder(); + if (ball != 0) { + answer.append(ball); + answer.append("볼 "); + } + + if (strike != 0) { + answer.append(strike); + answer.append("스트라이크"); + } + + return answer.toString(); } } diff --git a/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java b/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java index 10262063b4..b2855af55e 100644 --- a/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java +++ b/src/test/java/baseball/domain/gamenumbercreator/StringToGameNumberCreatorTest.java @@ -24,7 +24,7 @@ class StringToGameNumberCreatorTest { final StringToGameNumberCreator creator = new StringToGameNumberCreator("123"); // when & then - Assertions.assertThatThrownBy(() -> creator.create(3)) - .isInstanceOf(IllegalArgumentException.class); + Assertions.assertThatCode(() -> creator.create(3)) + .doesNotThrowAnyException(); } } From 2d7c265b74e973737070d91bf7e17dc3f4de9809 Mon Sep 17 00:00:00 2001 From: seong-wooo Date: Mon, 27 Mar 2023 12:51:25 +0900 Subject: [PATCH 18/18] =?UTF-8?q?refactor:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/gamenumbercreator/StringToGameNumberCreator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java index da827d4923..f50b22e69f 100644 --- a/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java +++ b/src/main/java/baseball/domain/gamenumbercreator/StringToGameNumberCreator.java @@ -15,7 +15,7 @@ public StringToGameNumberCreator(String values) { @Override public List create(int maxLength) { - validteLength(maxLength); + validateLength(maxLength); return Arrays.stream(values.split("")) .map(this::parseInt) @@ -23,7 +23,7 @@ public List create(int maxLength) { .collect(Collectors.toList()); } - private void validteLength(int maxLength) { + private void validateLength(int maxLength) { if (values.length() != maxLength) { throw new IllegalArgumentException(String.format("[ERROR] %s는 %d 자리수가 아닙니다.", values, maxLength)); }