From 90a90f86211a2f07375f545af48458c2dd084870 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 13:01:07 +0900 Subject: [PATCH 01/19] =?UTF-8?q?docs=20:=20=EA=B8=B0=EB=8A=A5=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 491aece1..ddae3d20 100644 --- a/README.md +++ b/README.md @@ -1 +1,34 @@ -# java-racingcar-precourse \ No newline at end of file +# java-racingcar-precourse + +# 기능 목록 +## 자동차 게임 +- 주어진 횟수 동안 n 대의 자동차는 전진 또는 멈출 수 있다. + - 0에서 9 사이에서 무작위 값을 구한다. + - 값이 4 이상이면 자동차를 전진 시킨다. +- 우승자를 구한다. + - 우승자는 한 명 이상일 수 있다. + - 우승자는 위치의 숫자가 가장 높은 자동차이다. + +## 자동차 +- 자동차는 이름을 가진다. +- 자동차는 위치를 가진다. +- 자동차의 위치를 전진 시키면 위치를 1 증가 시킨다. + +## 이름 +- 자동차 이름은 5자 이하만 가능하다. + - 자동차 이름이 5자 초과면 IllegalStateException 를 발생시킨다. + +## 위치 +- 위치를 1 증가 시킨다. +- 위치 값보다 함수로 전달받은 위치 값이 작으면 false 를 반환한다. + +# 입출력 요구사항 +## 입력 요구사항 +- 주어진 문자열을 쉼표를 기준으로 구분한다. +- 숫자를 입력 받는다. +- 잘못된 값을 입력할 경우 IllegalArgumentException 을 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다 시 받는다. + +## 출력 요구사항 +- 문자열을 출력한다. +- 문자열이 여러 개일 경우 쉼표를 이용하여 구분한다. + From be3792f0f1474fb6821551fed16b1804af7817f1 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 13:17:59 +0900 Subject: [PATCH 02/19] =?UTF-8?q?feat=20:=20=EC=9D=B4=EB=A6=84=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=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/racingcar/domain/Name.java | 33 ++++++++++++++++++++ src/test/java/racingcar/domain/NameTest.java | 23 ++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/main/java/racingcar/domain/Name.java create mode 100644 src/test/java/racingcar/domain/NameTest.java diff --git a/src/main/java/racingcar/domain/Name.java b/src/main/java/racingcar/domain/Name.java new file mode 100644 index 00000000..cdb924bd --- /dev/null +++ b/src/main/java/racingcar/domain/Name.java @@ -0,0 +1,33 @@ +package racingcar.domain; + +import java.util.Objects; + +public class Name { + private static final int NAME_LENGTH_LIMIT = 5; + + private final String name; + + public Name(final String name) { + if (name.length() > NAME_LENGTH_LIMIT) { + throw new IllegalArgumentException("이름은 5자 이하만 가능합니다."); + } + this.name = name; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Name name1 = (Name) o; + return Objects.equals(name, name1.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} diff --git a/src/test/java/racingcar/domain/NameTest.java b/src/test/java/racingcar/domain/NameTest.java new file mode 100644 index 00000000..6e1173f9 --- /dev/null +++ b/src/test/java/racingcar/domain/NameTest.java @@ -0,0 +1,23 @@ +package racingcar.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName("이름 테스트") +public class NameTest { + @ParameterizedTest + @ValueSource(strings = {"woni", "pobi", "jun", "jason"}) + void 이름_생성(final String value) { + Name name = new Name(value); + + Assertions.assertThat(name).isEqualTo(new Name(value)); + } + + @ParameterizedTest + @ValueSource(strings = {"eleven", "abcdefg"}) + void 이름이_5자_초과면_에러를_반환한다(final String value) { + Assertions.assertThatIllegalArgumentException().isThrownBy(() -> new Name(value)); + } +} From 4a2be6fc2c8a0865b9ee28f62f2e02829366d1ce Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 13:18:21 +0900 Subject: [PATCH 03/19] =?UTF-8?q?feat=20:=20=EC=9C=84=EC=B9=98=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=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/racingcar/domain/Position.java | 36 ++++++++++++++++++ .../java/racingcar/domain/PositionTest.java | 38 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/main/java/racingcar/domain/Position.java create mode 100644 src/test/java/racingcar/domain/PositionTest.java diff --git a/src/main/java/racingcar/domain/Position.java b/src/main/java/racingcar/domain/Position.java new file mode 100644 index 00000000..b2695a55 --- /dev/null +++ b/src/main/java/racingcar/domain/Position.java @@ -0,0 +1,36 @@ +package racingcar.domain; + +import java.util.Objects; + +public class Position { + private final int value; + + public Position(final int value) { + this.value = value; + } + + public Position forward() { + return new Position(this.value + 1); + } + + public boolean isUpper(final Position position) { + return this.value > position.value; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Position position = (Position) o; + return value == position.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/racingcar/domain/PositionTest.java b/src/test/java/racingcar/domain/PositionTest.java new file mode 100644 index 00000000..505dfe92 --- /dev/null +++ b/src/test/java/racingcar/domain/PositionTest.java @@ -0,0 +1,38 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName("위치 테스트") +public class PositionTest { + @ParameterizedTest + @ValueSource(ints = {0, 1, 3, 100}) + void 위치_생성(final int value) { + Position position = new Position(value); + + assertThat(position).isEqualTo(new Position(value)); + } + + @Test + void 위치를_1_증가_시켜_반환한다() { + Position position = new Position(0); + + assertThat(position.forward()).isEqualTo(new Position(1)); + } + + @Test + void 위치_값보다_전달_받은_위치_값이_작으면_flase를_반환한다() { + Position position = new Position(10); + + assertAll( + () -> assertThat(position.isUpper(new Position(11))).isFalse(), + () -> assertThat(position.isUpper(new Position(9))).isTrue(), + () -> assertThat(position.isUpper(new Position(-100))).isTrue() + ); + } +} From 05008612b2020f15400f80fa758d97767f282453 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 13:26:51 +0900 Subject: [PATCH 04/19] =?UTF-8?q?feat=20:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=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/racingcar/domain/Car.java | 34 +++++++++++++++++++++ src/test/java/racingcar/domain/CarTest.java | 33 ++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/main/java/racingcar/domain/Car.java create mode 100644 src/test/java/racingcar/domain/CarTest.java diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java new file mode 100644 index 00000000..09a3f7fd --- /dev/null +++ b/src/main/java/racingcar/domain/Car.java @@ -0,0 +1,34 @@ +package racingcar.domain; + +import java.util.Objects; + +public class Car { + private final Name name; + private final Position position; + + public Car(final Name name, final Position position) { + this.name = name; + this.position = position; + } + + public Car forward() { + return new Car(name, position.forward()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Car car = (Car) o; + return Objects.equals(name, car.name) && Objects.equals(position, car.position); + } + + @Override + public int hashCode() { + return Objects.hash(name, position); + } +} diff --git a/src/test/java/racingcar/domain/CarTest.java b/src/test/java/racingcar/domain/CarTest.java new file mode 100644 index 00000000..e15d5d95 --- /dev/null +++ b/src/test/java/racingcar/domain/CarTest.java @@ -0,0 +1,33 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("자동차 테스트") +public class CarTest { + @Test + void 자동차_생성() { + Name name = new Name("pobi"); + Position position = new Position(0); + + Car car = new Car(name, position); + + assertThat(car).isEqualTo(new Car(new Name("pobi"), new Position(0))); + } + + @Test + void 자동차_위치를_전진시킨다() { + Name name = new Name("pobi"); + Position position = new Position(0); + + Car car = new Car(name, position); + + assertAll( + () -> assertThat(car.forward()).isEqualTo(new Car(new Name("pobi"), new Position(1))), + () -> assertThat(car.forward()).isNotEqualTo(new Car(new Name("pobi"), new Position(0))) + ); + } +} From bf1077f04d928f27b5d1c2d8f604c9804f34f43d Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 14:11:31 +0900 Subject: [PATCH 05/19] =?UTF-8?q?docs=20:=20=EA=B8=B0=EB=8A=A5=EB=AA=A9?= =?UTF-8?q?=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 --- README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ddae3d20..a75bd31c 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,46 @@ # java-racingcar-precourse # 기능 목록 + ## 자동차 게임 - 주어진 횟수 동안 n 대의 자동차는 전진 또는 멈출 수 있다. - - 0에서 9 사이에서 무작위 값을 구한다. - - 값이 4 이상이면 자동차를 전진 시킨다. + +## 전진 룰 +- 0에서 9 사이에서 무작위 값을 구한다. +- 값이 4 이상이면 자동차를 전진 시킨다. + +## 자동차 목록 + - 우승자를 구한다. - - 우승자는 한 명 이상일 수 있다. - - 우승자는 위치의 숫자가 가장 높은 자동차이다. + - 우승자는 한 명 이상일 수 있다. + - 우승자는 위치의 숫자가 가장 높은 자동차이다. ## 자동차 + - 자동차는 이름을 가진다. - 자동차는 위치를 가진다. - 자동차의 위치를 전진 시키면 위치를 1 증가 시킨다. ## 이름 + - 자동차 이름은 5자 이하만 가능하다. - - 자동차 이름이 5자 초과면 IllegalStateException 를 발생시킨다. + - 자동차 이름이 5자 초과면 IllegalStateException 를 발생시킨다. ## 위치 + - 위치를 1 증가 시킨다. - 위치 값보다 함수로 전달받은 위치 값이 작으면 false 를 반환한다. # 입출력 요구사항 + ## 입력 요구사항 + - 주어진 문자열을 쉼표를 기준으로 구분한다. - 숫자를 입력 받는다. - 잘못된 값을 입력할 경우 IllegalArgumentException 을 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다 시 받는다. ## 출력 요구사항 + - 문자열을 출력한다. - 문자열이 여러 개일 경우 쉼표를 이용하여 구분한다. From 3fcd60112d6a8c45fb285f42ccc2ee8fc2478106 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 14:14:39 +0900 Subject: [PATCH 06/19] =?UTF-8?q?feat=20:=20=EC=A0=84=EC=A7=84=20=EB=A3=B0?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/domain/ForwardRule.java | 6 +++++ .../java/racingcar/domain/ForwardRules.java | 10 +++++++ .../racingcar/domain/ForwardRuleTest.java | 26 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/main/java/racingcar/domain/ForwardRule.java create mode 100644 src/main/java/racingcar/domain/ForwardRules.java create mode 100644 src/test/java/racingcar/domain/ForwardRuleTest.java diff --git a/src/main/java/racingcar/domain/ForwardRule.java b/src/main/java/racingcar/domain/ForwardRule.java new file mode 100644 index 00000000..14d35fc2 --- /dev/null +++ b/src/main/java/racingcar/domain/ForwardRule.java @@ -0,0 +1,6 @@ +package racingcar.domain; + +@FunctionalInterface +public interface ForwardRule { + boolean isForward(final int number); +} diff --git a/src/main/java/racingcar/domain/ForwardRules.java b/src/main/java/racingcar/domain/ForwardRules.java new file mode 100644 index 00000000..35d51311 --- /dev/null +++ b/src/main/java/racingcar/domain/ForwardRules.java @@ -0,0 +1,10 @@ +package racingcar.domain; + +public enum ForwardRules implements ForwardRule { + MORE_THAN_FOUR { + @Override + public boolean isForward(final int number) { + return number >= 4; + } + } +} diff --git a/src/test/java/racingcar/domain/ForwardRuleTest.java b/src/test/java/racingcar/domain/ForwardRuleTest.java new file mode 100644 index 00000000..add5f5df --- /dev/null +++ b/src/test/java/racingcar/domain/ForwardRuleTest.java @@ -0,0 +1,26 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName("전진 룰 테스트") +public class ForwardRuleTest { + @ParameterizedTest + @ValueSource(ints = {4, 5, 10, 100, 999}) + void 숫자가_4_이상이면_전진한다(final int number) { + ForwardRule forwardRule = ForwardRules.MORE_THAN_FOUR; + + assertThat(forwardRule.isForward(number)).isTrue(); + } + + @ParameterizedTest + @ValueSource(ints = {3, 2, 1, 0, -4, -10, -999}) + void 숫자가_4_이상이면_전진하지_않는다(final int number) { + ForwardRule forwardRule = ForwardRules.MORE_THAN_FOUR; + + assertThat(forwardRule.isForward(number)).isFalse(); + } +} From cdd394ae8d9bd06087400d468cb98a8b69f5ffcc Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 14:43:42 +0900 Subject: [PATCH 07/19] =?UTF-8?q?docs=20:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=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 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index a75bd31c..abdcb5a5 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ - 우승자는 한 명 이상일 수 있다. - 우승자는 위치의 숫자가 가장 높은 자동차이다. +- 포지션이 같은 자동차 목록을 반환한다. + +- 포지션이 가장 높은 자동차의 포지션을 반환한다. + ## 자동차 - 자동차는 이름을 가진다. From 22e58be00d04ceee31b9f820367e898fc91315ae Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 14:44:11 +0900 Subject: [PATCH 08/19] =?UTF-8?q?feat=20:=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=EC=9D=98=20=EC=9C=84=EC=B9=98=EB=A5=BC=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/Car.java | 4 ++++ src/test/java/racingcar/domain/CarTest.java | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index 09a3f7fd..54cbb85b 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -15,6 +15,10 @@ public Car forward() { return new Car(name, position.forward()); } + public Position position() { + return this.position; + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/test/java/racingcar/domain/CarTest.java b/src/test/java/racingcar/domain/CarTest.java index e15d5d95..75deb542 100644 --- a/src/test/java/racingcar/domain/CarTest.java +++ b/src/test/java/racingcar/domain/CarTest.java @@ -22,7 +22,6 @@ public class CarTest { void 자동차_위치를_전진시킨다() { Name name = new Name("pobi"); Position position = new Position(0); - Car car = new Car(name, position); assertAll( @@ -30,4 +29,13 @@ public class CarTest { () -> assertThat(car.forward()).isNotEqualTo(new Car(new Name("pobi"), new Position(0))) ); } + + @Test + void 자동차_위치를_반환한다() { + Name name = new Name("pobi"); + Position position = new Position(0); + Car car = new Car(name, position); + + assertThat(car.position()).isEqualTo(new Position(0)); + } } From 301240489ebe9b65107f748510bde90e728b9756 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 14:45:24 +0900 Subject: [PATCH 09/19] =?UTF-8?q?feat=20:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=ED=8F=AC=EC=A7=80=EC=85=98=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/Cars.java | 50 ++++++++++++++++++++ src/test/java/racingcar/domain/CarsTest.java | 46 ++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/main/java/racingcar/domain/Cars.java create mode 100644 src/test/java/racingcar/domain/CarsTest.java diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java new file mode 100644 index 00000000..62410ada --- /dev/null +++ b/src/main/java/racingcar/domain/Cars.java @@ -0,0 +1,50 @@ +package racingcar.domain; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public class Cars { + private final List cars; + + public Cars(final Car... cars) { + this.cars = Arrays.stream(cars).toList(); + } + + public Position highestPosition() { + Position highestPosition = cars.get(0).position(); + + for (Car car : cars) { + if (car.position().isUpper(highestPosition)) { + highestPosition = car.position(); + } + } + + return highestPosition; + } + + public Cars equalPosition(final Position position) { + Car[] cars = this.cars.stream() + .filter(car -> car.position().equals(position)) + .toArray(Car[]::new); + + return new Cars(cars); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final Cars cars1 = (Cars) o; + return Objects.equals(cars, cars1.cars); + } + + @Override + public int hashCode() { + return Objects.hash(cars); + } +} diff --git a/src/test/java/racingcar/domain/CarsTest.java b/src/test/java/racingcar/domain/CarsTest.java new file mode 100644 index 00000000..5d4aeee6 --- /dev/null +++ b/src/test/java/racingcar/domain/CarsTest.java @@ -0,0 +1,46 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("자동차 목록 테스트") +class CarsTest { + @Test + void 자동차_목록_생성() { + Car car1 = createCar("pobi", 0); + Car car2 = createCar("woni", 0); + Car car3 = createCar("jun", 0); + + Cars cars = new Cars(car1, car2, car3); + + assertThat(cars).isEqualTo(new Cars(car1, car2, car3)); + } + + @Test + void 포지션이_가장_높은_자동차의_포지션을_반환한다() { + Car car1 = createCar("pobi", 0); + Car car2 = createCar("woni", 11); + Car car3 = createCar("jun", 9); + Cars cars = new Cars(car1, car2, car3); + + assertThat(cars.highestPosition()).isEqualTo(new Position(11)); + } + + @Test + void 포지션이_같은_자동차_목록을_반환한다() { + Car car1 = createCar("pobi", 0); + Car car2 = createCar("woni", 11); + Car car3 = createCar("jun", 11); + Cars cars = new Cars(car1, car2, car3); + + assertThat(cars.equalPosition(new Position(11))).isEqualTo(new Cars(car2, car3)); + } + + private Car createCar(final String name, final int position) { + Name carName = new Name(name); + Position carPosition = new Position(position); + return new Car(carName, carPosition); + } +} From f5f370cba3c808c6f539765d692a8fc99bcdad55 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 14:46:03 +0900 Subject: [PATCH 10/19] =?UTF-8?q?feat=20:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=8A=B9=EC=9E=90=20=EB=A3=B0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/domain/WinnerRule.java | 5 ++++ .../java/racingcar/domain/WinnerRules.java | 12 ++++++++ .../java/racingcar/domain/WinnerRuleTest.java | 29 +++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 src/main/java/racingcar/domain/WinnerRule.java create mode 100644 src/main/java/racingcar/domain/WinnerRules.java create mode 100644 src/test/java/racingcar/domain/WinnerRuleTest.java diff --git a/src/main/java/racingcar/domain/WinnerRule.java b/src/main/java/racingcar/domain/WinnerRule.java new file mode 100644 index 00000000..2989a753 --- /dev/null +++ b/src/main/java/racingcar/domain/WinnerRule.java @@ -0,0 +1,5 @@ +package racingcar.domain; + +public interface WinnerRule { + Cars winner(final Cars cars); +} diff --git a/src/main/java/racingcar/domain/WinnerRules.java b/src/main/java/racingcar/domain/WinnerRules.java new file mode 100644 index 00000000..9ab74022 --- /dev/null +++ b/src/main/java/racingcar/domain/WinnerRules.java @@ -0,0 +1,12 @@ +package racingcar.domain; + +public enum WinnerRules implements WinnerRule { + HIGHEST_POSITION { + @Override + public Cars winner(final Cars cars) { + Position highestPosition = cars.highestPosition(); + cars.equalPosition(highestPosition); + return null; + } + } +} diff --git a/src/test/java/racingcar/domain/WinnerRuleTest.java b/src/test/java/racingcar/domain/WinnerRuleTest.java new file mode 100644 index 00000000..6044fc6e --- /dev/null +++ b/src/test/java/racingcar/domain/WinnerRuleTest.java @@ -0,0 +1,29 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("승자 룰 테스트") +class WinnerRuleTest { + @Test + void 위치가_가장_높은_자동차_목록을_반환한다() { + Car car1 = createCar("pobi", 9); + Car car2 = createCar("woni", 0); + Car car3 = createCar("jun", 9); + Car car4 = createCar("jason", 0); + Cars cars = new Cars(car1, car2, car3, car4); + WinnerRule winnerRule = WinnerRules.HIGHEST_POSITION; + + Cars winner = winnerRule.winner(cars); + + assertThat(winner).isEqualTo(new Cars(car1, car3)); + } + + private Car createCar(final String name, final int position) { + Name carName = new Name(name); + Position carPosition = new Position(position); + return new Car(carName, carPosition); + } +} From 5acf09642ae7eae76375ba03451a6816ce317897 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 15:03:12 +0900 Subject: [PATCH 11/19] =?UTF-8?q?docs=20:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=A9?= =?UTF-8?q?=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 --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index abdcb5a5..1ed9c435 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,17 @@ # 기능 목록 ## 자동차 게임 + - 주어진 횟수 동안 n 대의 자동차는 전진 또는 멈출 수 있다. ## 전진 룰 -- 0에서 9 사이에서 무작위 값을 구한다. + - 값이 4 이상이면 자동차를 전진 시킨다. +## 숫자 뽑기 룰 + +- 0에서 9 사이에서 무작위 값을 구한다. + ## 자동차 목록 - 우승자를 구한다. From 23496209662010b5a9ff45657a9046c2f4465fe3 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 15:03:29 +0900 Subject: [PATCH 12/19] =?UTF-8?q?feat=20:=20=EC=88=AB=EC=9E=90=20=EB=BD=91?= =?UTF-8?q?=EA=B8=B0=20=EB=A3=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/domain/PickNumberRule.java | 5 ++++ .../racingcar/domain/PickNumberRules.java | 14 +++++++++++ .../racingcar/domain/PickNumberRuleTest.java | 24 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 src/main/java/racingcar/domain/PickNumberRule.java create mode 100644 src/main/java/racingcar/domain/PickNumberRules.java create mode 100644 src/test/java/racingcar/domain/PickNumberRuleTest.java diff --git a/src/main/java/racingcar/domain/PickNumberRule.java b/src/main/java/racingcar/domain/PickNumberRule.java new file mode 100644 index 00000000..ba29ce1d --- /dev/null +++ b/src/main/java/racingcar/domain/PickNumberRule.java @@ -0,0 +1,5 @@ +package racingcar.domain; + +public interface PickNumberRule { + int pick(); +} diff --git a/src/main/java/racingcar/domain/PickNumberRules.java b/src/main/java/racingcar/domain/PickNumberRules.java new file mode 100644 index 00000000..c5027889 --- /dev/null +++ b/src/main/java/racingcar/domain/PickNumberRules.java @@ -0,0 +1,14 @@ +package racingcar.domain; + +import java.security.SecureRandom; + +public enum PickNumberRules implements PickNumberRule { + RANDOM { + SecureRandom random = new SecureRandom(); + + @Override + public int pick() { + return random.nextInt(10); + } + } +} diff --git a/src/test/java/racingcar/domain/PickNumberRuleTest.java b/src/test/java/racingcar/domain/PickNumberRuleTest.java new file mode 100644 index 00000000..a7389873 --- /dev/null +++ b/src/test/java/racingcar/domain/PickNumberRuleTest.java @@ -0,0 +1,24 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; + +@DisplayName("숫자 뽑기 룰 테스트") +public class PickNumberRuleTest { + @RepeatedTest(100) + @Test + void 숫자_0부터_9까지의_숫자를_뽑는다() { + PickNumberRule pickNumberRule = PickNumberRules.RANDOM; + + int value = pickNumberRule.pick(); + + assertAll( + () -> assertThat(value >= 0).isTrue(), + () -> assertThat(value <= 9).isTrue() + ); + } +} From ed3ea5cb472a46252f2d540ab9d669eacc40cf69 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 15:12:54 +0900 Subject: [PATCH 13/19] =?UTF-8?q?feat=20:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A0=84=EC=A7=84=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=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/racingcar/domain/Cars.java | 12 +++++++++++ src/test/java/racingcar/domain/CarsTest.java | 22 ++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index 62410ada..8a2e9db9 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -31,6 +31,18 @@ public Cars equalPosition(final Position position) { return new Cars(cars); } + public Cars forward(final ForwardRule forwardRule, final PickNumberRule pickNumberRule) { + Car[] forwardCars = this.cars.stream() + .map(car -> { + if (forwardRule.isForward(pickNumberRule.pick())) { + return car.forward(); + } + return car; + }).toArray(Car[]::new); + + return new Cars(forwardCars); + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/test/java/racingcar/domain/CarsTest.java b/src/test/java/racingcar/domain/CarsTest.java index 5d4aeee6..2890e588 100644 --- a/src/test/java/racingcar/domain/CarsTest.java +++ b/src/test/java/racingcar/domain/CarsTest.java @@ -38,6 +38,28 @@ class CarsTest { assertThat(cars.equalPosition(new Position(11))).isEqualTo(new Cars(car2, car3)); } + @Test + void 자동차_목록을_전진시킨다() { + Car car1 = createCar("pobi", 0); + Car car2 = createCar("woni", 0); + Car car3 = createCar("jun", 0); + Cars cars = new Cars(car1, car2, car3); + + Cars forwardCars = cars.forward(ForwardRules.MORE_THAN_FOUR, () -> 4); + + assertThat(forwardCars).isEqualTo(new Cars(car1.forward(), car2.forward(), car3.forward())); + } + + @Test + void 뽑은_숫자가_전진룰에_만족하지_않으면_자동차는_전진하지_않는다() { + Car car1 = createCar("pobi", 0); + Cars cars = new Cars(car1); + + Cars forwardCars = cars.forward(ForwardRules.MORE_THAN_FOUR, () -> 3); + + assertThat(forwardCars).isEqualTo(new Cars(new Car(new Name("pobi"), new Position(0)))); + } + private Car createCar(final String name, final int position) { Name carName = new Name(name); Position carPosition = new Position(position); From 9a48d40ac9065669bc08edbbe928529d2170b733 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 15:40:03 +0900 Subject: [PATCH 14/19] =?UTF-8?q?fix=20:=20=EC=8A=B9=EC=9E=90=20=EB=A3=B0?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/WinnerRules.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/racingcar/domain/WinnerRules.java b/src/main/java/racingcar/domain/WinnerRules.java index 9ab74022..b9c163bf 100644 --- a/src/main/java/racingcar/domain/WinnerRules.java +++ b/src/main/java/racingcar/domain/WinnerRules.java @@ -5,8 +5,7 @@ public enum WinnerRules implements WinnerRule { @Override public Cars winner(final Cars cars) { Position highestPosition = cars.highestPosition(); - cars.equalPosition(highestPosition); - return null; + return cars.equalPosition(highestPosition); } } } From 084799ae9e0a7cb75009922ac008cc6f5e3230bc Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 19:59:19 +0900 Subject: [PATCH 15/19] =?UTF-8?q?feat=20:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=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/racingcar/domain/Activity.java | 16 ++++++ src/main/java/racingcar/domain/Cars.java | 4 ++ src/main/java/racingcar/domain/RacingCar.java | 45 +++++++++++++++++ .../java/racingcar/domain/RacingCarTest.java | 50 +++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 src/main/java/racingcar/domain/Activity.java create mode 100644 src/main/java/racingcar/domain/RacingCar.java create mode 100644 src/test/java/racingcar/domain/RacingCarTest.java diff --git a/src/main/java/racingcar/domain/Activity.java b/src/main/java/racingcar/domain/Activity.java new file mode 100644 index 00000000..fa708eef --- /dev/null +++ b/src/main/java/racingcar/domain/Activity.java @@ -0,0 +1,16 @@ +package racingcar.domain; + +import java.util.Collections; +import java.util.List; + +public class Activity { + private final List cars; + + public Activity(final List cars) { + this.cars = cars; + } + + public List value() { + return Collections.unmodifiableList(this.cars); + } +} diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index 8a2e9db9..2cd93967 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -43,6 +43,10 @@ public Cars forward(final ForwardRule forwardRule, final PickNumberRule pickNumb return new Cars(forwardCars); } + public Activity activity() { + return new Activity(this.cars); + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/main/java/racingcar/domain/RacingCar.java b/src/main/java/racingcar/domain/RacingCar.java new file mode 100644 index 00000000..da3a7b9c --- /dev/null +++ b/src/main/java/racingcar/domain/RacingCar.java @@ -0,0 +1,45 @@ +package racingcar.domain; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.IntStream; + +public class RacingCar { + private static final Position RACING_CAR_DEFAULT_POSITION = new Position(0); + + private Cars cars; + private final List activities; + private final PickNumberRule pickNumberRule; + private final ForwardRule forwardRule; + private final WinnerRule winnerRule; + + public RacingCar( + final PickNumberRule pickNumberRule, + final ForwardRule forwardRule, + final WinnerRule winnerRule, + final Name... names + ) { + Car[] carArray = Arrays.stream(names) + .map(name -> new Car(name, RACING_CAR_DEFAULT_POSITION)) + .toArray(Car[]::new); + + this.cars = new Cars(carArray); + this.activities = new ArrayList<>(); + this.pickNumberRule = pickNumberRule; + this.forwardRule = forwardRule; + this.winnerRule = winnerRule; + } + + public void play(final int number) { + IntStream.range(0, number) + .forEach(i -> { + this.cars = this.cars.forward(this.forwardRule, pickNumberRule); + this.activities.add(this.cars.activity()); + }); + } + + public Cars winner() { + return winnerRule.winner(this.cars); + } +} diff --git a/src/test/java/racingcar/domain/RacingCarTest.java b/src/test/java/racingcar/domain/RacingCarTest.java new file mode 100644 index 00000000..2029f3c6 --- /dev/null +++ b/src/test/java/racingcar/domain/RacingCarTest.java @@ -0,0 +1,50 @@ +package racingcar.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static racingcar.domain.ForwardRules.MORE_THAN_FOUR; +import static racingcar.domain.PickNumberRules.RANDOM; +import static racingcar.domain.WinnerRules.HIGHEST_POSITION; + +import java.lang.reflect.Field; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("자동차 게임 테스트") +public class RacingCarTest { + @Test + void 자동차_게임_생성() { + Name name1 = new Name("pobi"); + Name name2 = new Name("woni"); + Name name3 = new Name("jun"); + + assertDoesNotThrow(() -> new RacingCar(RANDOM, MORE_THAN_FOUR, HIGHEST_POSITION, name1, name2, name3)); + } + + @Test + void 주어진_N회_동안_자동차를_룰에따라_전진시킨다() throws NoSuchFieldException, IllegalAccessException { + Name name1 = new Name("pobi"); + Name name2 = new Name("woni"); + RacingCar racingCar = new RacingCar(() -> 4, MORE_THAN_FOUR, HIGHEST_POSITION, name1, name2); + + racingCar.play(3); + + Field field = racingCar.getClass().getDeclaredField("cars"); + field.setAccessible(true); + Cars cars = (Cars) field.get(racingCar); + assertThat(cars).isEqualTo(new Cars(new Car(name1, new Position(3)), new Car(name2, new Position(3)))); + } + + @Test + void 승자를_반환한다() { + Name name1 = new Name("pobi"); + Name name2 = new Name("woni"); + RacingCar racingCar = new RacingCar(() -> 4, MORE_THAN_FOUR, HIGHEST_POSITION, name1, name2); + racingCar.play(1); + Position position1 = new Position(1); + Car car1 = new Car(new Name("pobi"), position1); + Car car2 = new Car(new Name("woni"), position1); + + assertThat(racingCar.winner()).isEqualTo(new Cars(car1, car2)); + } +} From 859e6834c6f5c3c48d19af75f4e0f93b3280b5f7 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 21:22:59 +0900 Subject: [PATCH 16/19] =?UTF-8?q?feat=20:=20getter=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/racingcar/domain/Car.java | 4 ++++ src/main/java/racingcar/domain/Cars.java | 4 ++++ src/main/java/racingcar/domain/Name.java | 4 ++++ src/main/java/racingcar/domain/Position.java | 4 ++++ src/main/java/racingcar/domain/RacingCar.java | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index 54cbb85b..ab2d72d9 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -19,6 +19,10 @@ public Position position() { return this.position; } + public Name name() { + return this.name; + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index 2cd93967..ea75a0ce 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -47,6 +47,10 @@ public Activity activity() { return new Activity(this.cars); } + public List value() { + return this.cars; + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/main/java/racingcar/domain/Name.java b/src/main/java/racingcar/domain/Name.java index cdb924bd..3141ec6f 100644 --- a/src/main/java/racingcar/domain/Name.java +++ b/src/main/java/racingcar/domain/Name.java @@ -14,6 +14,10 @@ public Name(final String name) { this.name = name; } + public String value() { + return this.name; + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/main/java/racingcar/domain/Position.java b/src/main/java/racingcar/domain/Position.java index b2695a55..5f81ec84 100644 --- a/src/main/java/racingcar/domain/Position.java +++ b/src/main/java/racingcar/domain/Position.java @@ -17,6 +17,10 @@ public boolean isUpper(final Position position) { return this.value > position.value; } + public int value() { + return this.value; + } + @Override public boolean equals(final Object o) { if (this == o) { diff --git a/src/main/java/racingcar/domain/RacingCar.java b/src/main/java/racingcar/domain/RacingCar.java index da3a7b9c..a474a5aa 100644 --- a/src/main/java/racingcar/domain/RacingCar.java +++ b/src/main/java/racingcar/domain/RacingCar.java @@ -42,4 +42,8 @@ public void play(final int number) { public Cars winner() { return winnerRule.winner(this.cars); } + + public List activities() { + return this.activities; + } } From 49a6dc698b86866a349cfc47f2c2232ebf493b7f Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 21:23:41 +0900 Subject: [PATCH 17/19] =?UTF-8?q?feat=20:=20=EB=A0=88=EC=9D=B4=EC=8B=B1=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EC=95=A0=ED=94=8C=EB=A6=AC=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/RacingCarService.java | 51 +++++++++++++++++++ .../application/port/ActivityResponse.java | 18 +++++++ .../application/port/CarResponse.java | 21 ++++++++ .../port/RacingCarResultResponse.java | 23 +++++++++ .../port/in/RacingCarPlayUseCase.java | 7 +++ 5 files changed, 120 insertions(+) create mode 100644 src/main/java/racingcar/application/RacingCarService.java create mode 100644 src/main/java/racingcar/application/port/ActivityResponse.java create mode 100644 src/main/java/racingcar/application/port/CarResponse.java create mode 100644 src/main/java/racingcar/application/port/RacingCarResultResponse.java create mode 100644 src/main/java/racingcar/application/port/in/RacingCarPlayUseCase.java diff --git a/src/main/java/racingcar/application/RacingCarService.java b/src/main/java/racingcar/application/RacingCarService.java new file mode 100644 index 00000000..a604bfa6 --- /dev/null +++ b/src/main/java/racingcar/application/RacingCarService.java @@ -0,0 +1,51 @@ +package racingcar.application; + +import java.util.Arrays; +import java.util.List; +import racingcar.application.port.RacingCarResultResponse; +import racingcar.application.port.in.RacingCarPlayUseCase; +import racingcar.domain.Activity; +import racingcar.domain.Car; +import racingcar.domain.ForwardRule; +import racingcar.domain.Name; +import racingcar.domain.PickNumberRule; +import racingcar.domain.RacingCar; +import racingcar.domain.WinnerRule; + +public class RacingCarService implements RacingCarPlayUseCase { + private final PickNumberRule pickNumberRule; + private final ForwardRule forwardRule; + private final WinnerRule winnerRule; + + public RacingCarService( + final PickNumberRule pickNumberRule, + final ForwardRule forwardRule, + final WinnerRule winnerRule + ) { + this.pickNumberRule = pickNumberRule; + this.forwardRule = forwardRule; + this.winnerRule = winnerRule; + } + + @Override + public RacingCarResultResponse play(final int number, final String... names) { + RacingCar racingCar = createDefaultRacingCar(names); + racingCar.play(number); + return createRacingCarResultResponse(racingCar); + } + + private RacingCar createDefaultRacingCar(final String[] names) { + return new RacingCar( + this.pickNumberRule, + this.forwardRule, + this.winnerRule, + Arrays.stream(names).map(Name::new).toArray(Name[]::new) + ); + } + + private RacingCarResultResponse createRacingCarResultResponse(final RacingCar racingCar) { + List activities = racingCar.activities(); + List winners = racingCar.winner().value(); + return new RacingCarResultResponse(activities, winners); + } +} diff --git a/src/main/java/racingcar/application/port/ActivityResponse.java b/src/main/java/racingcar/application/port/ActivityResponse.java new file mode 100644 index 00000000..8a61a75f --- /dev/null +++ b/src/main/java/racingcar/application/port/ActivityResponse.java @@ -0,0 +1,18 @@ +package racingcar.application.port; + +import java.util.List; +import racingcar.domain.Activity; + +public class ActivityResponse { + private final List carResponses; + + public ActivityResponse(final Activity activity) { + this.carResponses = activity.value().stream() + .map(CarResponse::new) + .toList(); + } + + public List carResponses() { + return carResponses; + } +} diff --git a/src/main/java/racingcar/application/port/CarResponse.java b/src/main/java/racingcar/application/port/CarResponse.java new file mode 100644 index 00000000..03355d95 --- /dev/null +++ b/src/main/java/racingcar/application/port/CarResponse.java @@ -0,0 +1,21 @@ +package racingcar.application.port; + +import racingcar.domain.Car; + +public class CarResponse { + private final String name; + private final int position; + + public CarResponse(final Car car) { + this.name = car.name().value(); + this.position = car.position().value(); + } + + public String name() { + return this.name; + } + + public int position() { + return this.position; + } +} diff --git a/src/main/java/racingcar/application/port/RacingCarResultResponse.java b/src/main/java/racingcar/application/port/RacingCarResultResponse.java new file mode 100644 index 00000000..06dba983 --- /dev/null +++ b/src/main/java/racingcar/application/port/RacingCarResultResponse.java @@ -0,0 +1,23 @@ +package racingcar.application.port; + +import java.util.List; +import racingcar.domain.Activity; +import racingcar.domain.Car; + +public class RacingCarResultResponse { + private final List activities; + private final List winners; + + public RacingCarResultResponse(final List activities, final List winners) { + this.activities = activities.stream().map(ActivityResponse::new).toList(); + this.winners = winners.stream().map(CarResponse::new).toList(); + } + + public List activities() { + return this.activities; + } + + public List winners() { + return this.winners; + } +} diff --git a/src/main/java/racingcar/application/port/in/RacingCarPlayUseCase.java b/src/main/java/racingcar/application/port/in/RacingCarPlayUseCase.java new file mode 100644 index 00000000..05301e57 --- /dev/null +++ b/src/main/java/racingcar/application/port/in/RacingCarPlayUseCase.java @@ -0,0 +1,7 @@ +package racingcar.application.port.in; + +import racingcar.application.port.RacingCarResultResponse; + +public interface RacingCarPlayUseCase { + RacingCarResultResponse play(final int number, final String... names); +} From b78d0c1d14a7930e4d885050199d2bb3fff929f9 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 21:24:41 +0900 Subject: [PATCH 18/19] =?UTF-8?q?feat=20:=20console=20=EC=BB=A8=ED=8B=80?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../racingcar/adapter/ConsoleController.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/main/java/racingcar/adapter/ConsoleController.java diff --git a/src/main/java/racingcar/adapter/ConsoleController.java b/src/main/java/racingcar/adapter/ConsoleController.java new file mode 100644 index 00000000..9490627d --- /dev/null +++ b/src/main/java/racingcar/adapter/ConsoleController.java @@ -0,0 +1,77 @@ +package racingcar.adapter; + +import java.util.List; +import java.util.Scanner; +import java.util.stream.Collectors; +import racingcar.application.port.ActivityResponse; +import racingcar.application.port.CarResponse; +import racingcar.application.port.RacingCarResultResponse; +import racingcar.application.port.in.RacingCarPlayUseCase; + +public class ConsoleController { + private static final String NAME_SEPARATOR = ","; + private static final String WINNER_DELIMITER = ", "; + private static final String CAR_RESPONSE_DELIMITER = " : "; + private static final String POSITION_TEXT = "-"; + private static final String NEW_LINE = "\n"; + + private static final Scanner scanner = new Scanner(System.in); + + private final RacingCarPlayUseCase racingCarPlayUseCase; + + public ConsoleController(final RacingCarPlayUseCase racingCarPlayUseCase) { + this.racingCarPlayUseCase = racingCarPlayUseCase; + } + + public void play() { + String[] names = inputNames(); + int number = inputNumber(); + RacingCarResultResponse racingCarResultResponse = this.racingCarPlayUseCase.play(number, names); + print(racingCarResultResponse); + } + + private void print(final RacingCarResultResponse racingCarResultResponse) { + System.out.println("실행결과"); + printCarActivities(racingCarResultResponse); + printWinner(racingCarResultResponse.winners()); + } + + private void printCarActivities(final RacingCarResultResponse racingCarResultResponse) { + racingCarResultResponse.activities().stream() + .map(ActivityResponse::carResponses) + .map(this::printCarResponse) + .forEach(System.out::println); + } + + private void printWinner(final List winners) { + String winnerText = winners.stream().map(CarResponse::name).collect(Collectors.joining(WINNER_DELIMITER)); + System.out.println("최종 우승자 : " + winnerText); + } + + private String printCarResponse(List carResponses) { + return carResponses.stream() + .map(carResponse -> String + .join(CAR_RESPONSE_DELIMITER, carResponse.name(), positionText(carResponse.position()))) + .collect(Collectors.joining(NEW_LINE)) + NEW_LINE; + } + + private String positionText(final int position) { + return POSITION_TEXT.repeat(position); + } + + private String[] inputNames() { + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + String text = scanner.nextLine(); + return text.split(NAME_SEPARATOR); + } + + private int inputNumber() { + try { + System.out.println("시도할 회수는 몇회인가요?"); + return Integer.parseInt(scanner.nextLine()); + } catch (NumberFormatException exception) { + System.out.println("[ERROR] 숫자만 입력 가능합니다."); + return inputNumber(); + } + } +} From 1ceee7b4bf48ed1c8f580ee0b308362051a7ef81 Mon Sep 17 00:00:00 2001 From: Yunsik-Choi Date: Sun, 9 Jun 2024 21:24:56 +0900 Subject: [PATCH 19/19] =?UTF-8?q?feat=20:=20=EB=A0=88=EC=9D=B4=EC=8B=B1=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=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/racingcar/RacingCarMain.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/racingcar/RacingCarMain.java diff --git a/src/main/java/racingcar/RacingCarMain.java b/src/main/java/racingcar/RacingCarMain.java new file mode 100644 index 00000000..dd9b2348 --- /dev/null +++ b/src/main/java/racingcar/RacingCarMain.java @@ -0,0 +1,22 @@ +package racingcar; + +import racingcar.adapter.ConsoleController; +import racingcar.application.RacingCarService; +import racingcar.application.port.in.RacingCarPlayUseCase; +import racingcar.domain.ForwardRules; +import racingcar.domain.PickNumberRules; +import racingcar.domain.WinnerRules; + +public class RacingCarMain { + public static void main(String[] args) { + RacingCarPlayUseCase racingCarPlayUseCase = new RacingCarService( + PickNumberRules.RANDOM, + ForwardRules.MORE_THAN_FOUR, + WinnerRules.HIGHEST_POSITION + ); + + ConsoleController consoleController = new ConsoleController(racingCarPlayUseCase); + + consoleController.play(); + } +}