From cfb670705ec7578f5f73ed2b3dbd0f657ad0c20d Mon Sep 17 00:00:00 2001 From: GY102912 Date: Mon, 30 Sep 2024 13:33:54 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20racing=20car=20-=20=EB=9E=9C?= =?UTF-8?q?=EB=8D=A4=EC=9C=BC=EB=A1=9C=20=EB=A0=88=EC=9D=B4=EC=8B=B1?= =?UTF-8?q?=EC=B9=B4=EB=A5=BC=20=EC=A0=84=EC=A7=84=20=ED=98=B9=EC=9D=80=20?= =?UTF-8?q?=EC=A0=95=EC=A7=80=20=EC=8B=9C=ED=82=A4=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84=20-=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=8B=B1=EC=B9=B4=EC=9D=98=20=EC=9D=B4=EB=A6=84=EC=9D=84=20?= =?UTF-8?q?=EB=B0=9B=EB=8A=94=20=EC=83=9D=EC=84=B1=EC=A0=80=EC=99=80=20get?= =?UTF-8?q?ter,=20setter=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 --- .gitignore | 0 build.gradle | 0 gradle/wrapper/gradle-wrapper.jar | Bin gradle/wrapper/gradle-wrapper.properties | 0 gradlew.bat | 0 settings.gradle | 0 src/main/java/.gitkeep | 0 src/main/java/cholog/RacingCar.java | 33 +++++++++++++++++++++++ src/test/java/.gitkeep | 0 9 files changed, 33 insertions(+) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 build.gradle mode change 100644 => 100755 gradle/wrapper/gradle-wrapper.jar mode change 100644 => 100755 gradle/wrapper/gradle-wrapper.properties mode change 100644 => 100755 gradlew.bat mode change 100644 => 100755 settings.gradle mode change 100644 => 100755 src/main/java/.gitkeep create mode 100644 src/main/java/cholog/RacingCar.java mode change 100644 => 100755 src/test/java/.gitkeep diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/build.gradle b/build.gradle old mode 100644 new mode 100755 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar old mode 100644 new mode 100755 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties old mode 100644 new mode 100755 diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 diff --git a/settings.gradle b/settings.gradle old mode 100644 new mode 100755 diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep old mode 100644 new mode 100755 diff --git a/src/main/java/cholog/RacingCar.java b/src/main/java/cholog/RacingCar.java new file mode 100644 index 00000000..3e616baf --- /dev/null +++ b/src/main/java/cholog/RacingCar.java @@ -0,0 +1,33 @@ +public class RacingCar { + private String name; + + public RacingCar(String name) { + this.name = name; + } + + public void moveByRandom(){ + int random = (int) (Math.random() * 10); + if (random >= 4){ + go(); + } + if (random < 4){ + stop(); + } + } + + public void go(){ + System.out.println(name + " goes forward"); + } + + public void stop(){ + System.out.println(name + " stops"); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep old mode 100644 new mode 100755 From 271b3144b266b51ee1e095277ce23ef160a15c61 Mon Sep 17 00:00:00 2001 From: GY102912 Date: Mon, 30 Sep 2024 14:13:51 +0900 Subject: [PATCH 2/6] =?UTF-8?q?test:=20racing=20car=20-=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=8B=B1=EC=B9=B4=20=EC=A0=84=EC=A7=84=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=95=EC=A7=80=20=ED=99=95=EC=9D=B8=20-=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=8B=B1=EC=B9=B4=20=EC=9C=A0=ED=9A=A8=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EC=9D=B4=EB=A6=84=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=B0=9C=EC=83=9D=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/cholog/RacingCar.java | 22 ++++----- src/test/java/cholog/TestRacingCar.java | 60 +++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 src/test/java/cholog/TestRacingCar.java diff --git a/src/main/java/cholog/RacingCar.java b/src/main/java/cholog/RacingCar.java index 3e616baf..83725b57 100644 --- a/src/main/java/cholog/RacingCar.java +++ b/src/main/java/cholog/RacingCar.java @@ -2,25 +2,22 @@ public class RacingCar { private String name; public RacingCar(String name) { - this.name = name; + setName(name); } - public void moveByRandom(){ - int random = (int) (Math.random() * 10); + public String moveByRandom(int random){ if (random >= 4){ - go(); - } - if (random < 4){ - stop(); + return go(); } + return stop(); } - public void go(){ - System.out.println(name + " goes forward"); + private String go(){ + return name + " goes forward"; } - public void stop(){ - System.out.println(name + " stops"); + private String stop(){ + return name + " stops"; } public String getName() { @@ -28,6 +25,9 @@ public String getName() { } public void setName(String name) { + if (name == null || name.trim().isEmpty()) { + throw new IllegalArgumentException("Racing car name cannot be empty"); + } this.name = name; } } diff --git a/src/test/java/cholog/TestRacingCar.java b/src/test/java/cholog/TestRacingCar.java new file mode 100644 index 00000000..aeb069e0 --- /dev/null +++ b/src/test/java/cholog/TestRacingCar.java @@ -0,0 +1,60 @@ +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.assertj.core.api.Assertions.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +public class TestRacingCar { + + @Nested + public class moveByRandom{ + private RacingCar racingCar; + + @BeforeEach + void setUp() { + racingCar = new RacingCar("myRacingCar"); + } + + @Test + @DisplayName("레이싱카 전진 확인") + public void testGo(){ + //given + int random = 9; + + //when + String actual = racingCar.moveByRandom(random); + String expected = racingCar.getName() + " goes forward"; + + //then + assertThat(actual).isEqualTo(expected); + } + @Test + @DisplayName("레이싱카 정지 확인") + public void testStop(){ + //given + int random = 0; + + //when + String actual = racingCar.moveByRandom(random); + String expected = racingCar.getName() + " stops"; + + //then + assertThat(actual).isEqualTo(expected); + } + @Test + @DisplayName("레이싱카의 이름이 유효하지 않을 시 에러 발생") + public void testValidName(){ + //given + + //when + + //then + assertThatThrownBy(() -> { + racingCar.setName(null); + }).isInstanceOf(IllegalArgumentException.class); + } + } +} From 39f7cd3961cbd644dff5c40613a0a4accb0fea69 Mon Sep 17 00:00:00 2001 From: GY102912 Date: Mon, 30 Sep 2024 14:21:54 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20moveByRandom=20go=20=EB=98=90?= =?UTF-8?q?=EB=8A=94=20stop=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8F=84=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/cholog/RacingCar.java | 12 ++---------- src/test/java/cholog/TestRacingCar.java | 7 +++---- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/java/cholog/RacingCar.java b/src/main/java/cholog/RacingCar.java index 83725b57..71074ede 100644 --- a/src/main/java/cholog/RacingCar.java +++ b/src/main/java/cholog/RacingCar.java @@ -7,17 +7,9 @@ public RacingCar(String name) { public String moveByRandom(int random){ if (random >= 4){ - return go(); + return "go"; } - return stop(); - } - - private String go(){ - return name + " goes forward"; - } - - private String stop(){ - return name + " stops"; + return "stop"; } public String getName() { diff --git a/src/test/java/cholog/TestRacingCar.java b/src/test/java/cholog/TestRacingCar.java index aeb069e0..f780db91 100644 --- a/src/test/java/cholog/TestRacingCar.java +++ b/src/test/java/cholog/TestRacingCar.java @@ -1,7 +1,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -26,7 +25,7 @@ public void testGo(){ //when String actual = racingCar.moveByRandom(random); - String expected = racingCar.getName() + " goes forward"; + String expected = "go"; //then assertThat(actual).isEqualTo(expected); @@ -39,7 +38,7 @@ public void testStop(){ //when String actual = racingCar.moveByRandom(random); - String expected = racingCar.getName() + " stops"; + String expected = "stop"; //then assertThat(actual).isEqualTo(expected); @@ -49,7 +48,7 @@ public void testStop(){ public void testValidName(){ //given - //when + //when racingCar.getName() + " stops" //then assertThatThrownBy(() -> { From a06f16a666526cacb861b48618a631b1ba4d2094 Mon Sep 17 00:00:00 2001 From: GY102912 Date: Tue, 1 Oct 2024 15:15:16 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20racing=20contest=20-=20=EC=A3=BC?= =?UTF-8?q?=EC=96=B4=EC=A7=84=20=ED=9A=9F=EC=88=98=20round=EB=A7=8C?= =?UTF-8?q?=ED=81=BC=20=EA=B0=81=20=EB=A0=88=EC=9D=B4=EC=8B=B1=EC=B9=B4?= =?UTF-8?q?=EB=A5=BC=20=EB=AC=B4=EC=9E=91=EC=9C=84=EB=A1=9C=20=EC=9B=80?= =?UTF-8?q?=EC=A7=81=EC=97=AC=20=EC=B4=9D=20=EC=9D=B4=EB=8F=99=EA=B1=B0?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EA=B5=AC=ED=95=98=EB=8A=94=20start=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EA=B5=AC=ED=98=84=20-=20?= =?UTF-8?q?=EC=A3=BC=EC=96=B4=EC=A7=84=20=EB=A0=88=EC=9D=B4=EC=8B=B1=20?= =?UTF-8?q?=EA=B2=BD=EA=B8=B0=20=ED=9B=84=20=EC=B4=9D=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20=EA=B1=B0=EB=A6=AC=EB=A5=BC=20=EB=B0=94=ED=83=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=8A=B9=EC=9E=90=EB=A5=BC=20=EA=B0=80=EB=A6=AC?= =?UTF-8?q?=EB=8A=94=20ranking=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=20=EA=B0=81=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/cholog/RacingCar.java | 6 +- src/main/java/cholog/RacingContest.java | 41 +++++++++ src/test/java/cholog/TestRacingCar.java | 92 ++++++++++----------- src/test/java/cholog/TestRacingContest.java | 54 ++++++++++++ 4 files changed, 143 insertions(+), 50 deletions(-) create mode 100644 src/main/java/cholog/RacingContest.java create mode 100644 src/test/java/cholog/TestRacingContest.java diff --git a/src/main/java/cholog/RacingCar.java b/src/main/java/cholog/RacingCar.java index 71074ede..8020676f 100644 --- a/src/main/java/cholog/RacingCar.java +++ b/src/main/java/cholog/RacingCar.java @@ -5,11 +5,11 @@ public RacingCar(String name) { setName(name); } - public String moveByRandom(int random){ + public int moveByRandom(int random){ if (random >= 4){ - return "go"; + return 1; //go } - return "stop"; + return 0; //stop } public String getName() { diff --git a/src/main/java/cholog/RacingContest.java b/src/main/java/cholog/RacingContest.java new file mode 100644 index 00000000..a03c0c84 --- /dev/null +++ b/src/main/java/cholog/RacingContest.java @@ -0,0 +1,41 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Random; +import lombok.Getter; + +@Getter +public class RacingContest { + private static final Random random = new Random(); //테스트를 위해 랜덤 숫자를 구하는 기능은 외부에 있어야 할까? + private final RacingCar[] RACING_CARS; + private final int rounds; + + public RacingContest(RacingCar[] racingCars, int racingRounds) { + RACING_CARS = racingCars; + rounds = racingRounds; + } + + public int[] start(){ + int[] distances = new int[RACING_CARS.length]; + + for (int r = 0; r < rounds; r++) { + for (int c = 0; c < RACING_CARS.length; c++) { + distances[c] += RACING_CARS[c].moveByRandom(random.nextInt(10)); + } + } + + return distances; + } + + public ArrayList ranking(int[] distances){ + int maxDist = Arrays.stream(distances).max().getAsInt(); // winner decision + ArrayList winners = new ArrayList<>(); + + for (int i = 0; i < distances.length; i++) { + if (distances[i] == maxDist) { + winners.add(RACING_CARS[i].getName()); + } + } + + return winners; + } +} diff --git a/src/test/java/cholog/TestRacingCar.java b/src/test/java/cholog/TestRacingCar.java index f780db91..bc6bdd47 100644 --- a/src/test/java/cholog/TestRacingCar.java +++ b/src/test/java/cholog/TestRacingCar.java @@ -8,52 +8,50 @@ public class TestRacingCar { - @Nested - public class moveByRandom{ - private RacingCar racingCar; - - @BeforeEach - void setUp() { - racingCar = new RacingCar("myRacingCar"); - } - - @Test - @DisplayName("레이싱카 전진 확인") - public void testGo(){ - //given - int random = 9; - - //when - String actual = racingCar.moveByRandom(random); - String expected = "go"; - - //then - assertThat(actual).isEqualTo(expected); - } - @Test - @DisplayName("레이싱카 정지 확인") - public void testStop(){ - //given - int random = 0; - - //when - String actual = racingCar.moveByRandom(random); - String expected = "stop"; - - //then - assertThat(actual).isEqualTo(expected); - } - @Test - @DisplayName("레이싱카의 이름이 유효하지 않을 시 에러 발생") - public void testValidName(){ - //given - - //when racingCar.getName() + " stops" - - //then - assertThatThrownBy(() -> { - racingCar.setName(null); - }).isInstanceOf(IllegalArgumentException.class); - } + private RacingCar racingCar; + + @BeforeEach + void setUp() { + racingCar = new RacingCar("myRacingCar"); + } + + @Test + @DisplayName("레이싱카 전진 확인") + public void testGo(){ + //given + int random = 9; + + //when + int actual = racingCar.moveByRandom(random); + int expected = 1; + + //then + assertThat(actual).isEqualTo(expected); + } + @Test + @DisplayName("레이싱카 정지 확인") + public void testStop(){ + //given + int random = 0; + + //when + int actual = racingCar.moveByRandom(random); + int expected = 0; + + //then + assertThat(actual).isEqualTo(expected); + } + + @Test + @DisplayName("레이싱카의 이름이 유효하지 않을 시 에러 발생") + public void testValidName(){ + //given + + //when racingCar.getName() + " stops" + + //then + assertThatThrownBy(() -> { + racingCar.setName(null); + }).isInstanceOf(IllegalArgumentException.class); } } diff --git a/src/test/java/cholog/TestRacingContest.java b/src/test/java/cholog/TestRacingContest.java new file mode 100644 index 00000000..a298c236 --- /dev/null +++ b/src/test/java/cholog/TestRacingContest.java @@ -0,0 +1,54 @@ +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class TestRacingContest { + private static int round; + private static RacingContest contest; + private static final String[] names = new String[]{"neo", "brie", "brown"}; + + @BeforeAll + public static void setUp() { + RacingCar[] participants = new RacingCar[]{ + new RacingCar(names[0]), + new RacingCar(names[1]), + new RacingCar(names[2]) + }; + round = 10; + contest = new RacingContest(participants, round); + } + + @Test + @DisplayName("경기 결과 모든 차의 주행거리가 0 이상이고 주어진 횟수 round 이하인지 확인") + public void testStart() { + //given + int round = contest.getRounds(); + + //when + int[] distances = contest.start(); + int maxDist = Arrays.stream(distances).max().getAsInt(); + int minDist = Arrays.stream(distances).min().getAsInt(); + + //then + assertThat(maxDist).isBetween(0, round + 1); + assertThat(minDist).isBetween(0, round + 1); + } + @Test + @DisplayName("경기 결과를 바탕으로 우승자를 가려낼 수 있는지 확인") + public void testRanking() { + //given + int[] distances = new int[]{0, round, round}; + String[] winners = new String[]{names[1], names[2]}; + + //when + ArrayList actual = contest.ranking(distances); + ArrayList expected = new ArrayList<>(Arrays.asList(winners)); + + //then + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + } +} From 6c116c2e7bc33ef351615343d93ea7b8b3cc94ab Mon Sep 17 00:00:00 2001 From: GY102912 Date: Tue, 1 Oct 2024 15:25:01 +0900 Subject: [PATCH 5/6] =?UTF-8?q?style:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=A3=BC=EC=84=9D=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/cholog/RacingContest.java | 2 +- src/test/java/cholog/TestRacingCar.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/cholog/RacingContest.java b/src/main/java/cholog/RacingContest.java index a03c0c84..6b582207 100644 --- a/src/main/java/cholog/RacingContest.java +++ b/src/main/java/cholog/RacingContest.java @@ -5,7 +5,7 @@ @Getter public class RacingContest { - private static final Random random = new Random(); //테스트를 위해 랜덤 숫자를 구하는 기능은 외부에 있어야 할까? + private static final Random random = new Random(); private final RacingCar[] RACING_CARS; private final int rounds; diff --git a/src/test/java/cholog/TestRacingCar.java b/src/test/java/cholog/TestRacingCar.java index bc6bdd47..a27c6a39 100644 --- a/src/test/java/cholog/TestRacingCar.java +++ b/src/test/java/cholog/TestRacingCar.java @@ -47,7 +47,7 @@ public void testStop(){ public void testValidName(){ //given - //when racingCar.getName() + " stops" + //when //then assertThatThrownBy(() -> { From f6fc53479bd1c8c733b8b0466d405d6effa42400 Mon Sep 17 00:00:00 2001 From: GY102912 Date: Mon, 14 Oct 2024 01:33:25 +0900 Subject: [PATCH 6/6] feat: racing contest with input/output view --- src/main/java/cholog/Main.java | 15 +++++++ src/main/java/cholog/RacingContest.java | 41 ----------------- .../java/cholog/{ => domain}/RacingCar.java | 11 ++--- .../java/cholog/domain/RacingContest.java | 43 ++++++++++++++++++ src/main/java/cholog/view/InputView.java | 31 +++++++++++++ src/main/java/cholog/view/ResultView.java | 44 +++++++++++++++++++ src/test/java/cholog/TestRacingCar.java | 5 ++- src/test/java/cholog/TestRacingContest.java | 33 +++++++------- 8 files changed, 158 insertions(+), 65 deletions(-) create mode 100644 src/main/java/cholog/Main.java delete mode 100644 src/main/java/cholog/RacingContest.java rename src/main/java/cholog/{ => domain}/RacingCar.java (81%) create mode 100644 src/main/java/cholog/domain/RacingContest.java create mode 100644 src/main/java/cholog/view/InputView.java create mode 100644 src/main/java/cholog/view/ResultView.java diff --git a/src/main/java/cholog/Main.java b/src/main/java/cholog/Main.java new file mode 100644 index 00000000..6e0aa723 --- /dev/null +++ b/src/main/java/cholog/Main.java @@ -0,0 +1,15 @@ +import domain.RacingContest; +import view.InputView; +import view.ResultView; + + +public class Main { + + public static void main(String[] args) throws Exception { + final var playerNames = InputView.getPlayerNames(); + final var rounds = InputView.getRounds(); + final var racingContest = new RacingContest(playerNames, rounds); + + ResultView.printContest(racingContest); + } +} diff --git a/src/main/java/cholog/RacingContest.java b/src/main/java/cholog/RacingContest.java deleted file mode 100644 index 6b582207..00000000 --- a/src/main/java/cholog/RacingContest.java +++ /dev/null @@ -1,41 +0,0 @@ -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Random; -import lombok.Getter; - -@Getter -public class RacingContest { - private static final Random random = new Random(); - private final RacingCar[] RACING_CARS; - private final int rounds; - - public RacingContest(RacingCar[] racingCars, int racingRounds) { - RACING_CARS = racingCars; - rounds = racingRounds; - } - - public int[] start(){ - int[] distances = new int[RACING_CARS.length]; - - for (int r = 0; r < rounds; r++) { - for (int c = 0; c < RACING_CARS.length; c++) { - distances[c] += RACING_CARS[c].moveByRandom(random.nextInt(10)); - } - } - - return distances; - } - - public ArrayList ranking(int[] distances){ - int maxDist = Arrays.stream(distances).max().getAsInt(); // winner decision - ArrayList winners = new ArrayList<>(); - - for (int i = 0; i < distances.length; i++) { - if (distances[i] == maxDist) { - winners.add(RACING_CARS[i].getName()); - } - } - - return winners; - } -} diff --git a/src/main/java/cholog/RacingCar.java b/src/main/java/cholog/domain/RacingCar.java similarity index 81% rename from src/main/java/cholog/RacingCar.java rename to src/main/java/cholog/domain/RacingCar.java index 8020676f..71436e8a 100644 --- a/src/main/java/cholog/RacingCar.java +++ b/src/main/java/cholog/domain/RacingCar.java @@ -1,3 +1,8 @@ +package domain; + +import lombok.Getter; + +@Getter public class RacingCar { private String name; @@ -12,11 +17,7 @@ public int moveByRandom(int random){ return 0; //stop } - public String getName() { - return name; - } - - public void setName(String name) { + private void setName(String name) { if (name == null || name.trim().isEmpty()) { throw new IllegalArgumentException("Racing car name cannot be empty"); } diff --git a/src/main/java/cholog/domain/RacingContest.java b/src/main/java/cholog/domain/RacingContest.java new file mode 100644 index 00000000..8fc165a0 --- /dev/null +++ b/src/main/java/cholog/domain/RacingContest.java @@ -0,0 +1,43 @@ +package domain; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import lombok.Getter; + +@Getter +public class RacingContest { + private static final Random random = new Random(); + private final List racingCars; + private final Map distances; + private final int rounds; + + public RacingContest(List playerNames, int rounds) { + this.racingCars = playerNames.stream().map(RacingCar::new).toList(); + this.distances = new HashMap<>(); + for (RacingCar car : racingCars){ + distances.putIfAbsent(car.getName(), 0); + } + this.rounds = rounds; + } + + public void goRound(){ + for (RacingCar car : racingCars) { + String name = car.getName(); + int move = car.moveByRandom(random.nextInt(10)); + distances.compute(name, (k, v) -> v + move); + } + } + + public List getWinners() { + List winners = new ArrayList<>(); + int max = distances.values().stream().max(Integer::compareTo).get(); + distances.entrySet().stream() + .filter(e -> e.getValue() >= max) + .forEach(e -> winners.add(e.getKey())); + + return winners; + } +} diff --git a/src/main/java/cholog/view/InputView.java b/src/main/java/cholog/view/InputView.java new file mode 100644 index 00000000..ffae42d5 --- /dev/null +++ b/src/main/java/cholog/view/InputView.java @@ -0,0 +1,31 @@ +package view; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + private static final Scanner sc = new Scanner(System.in); + + public static List getPlayerNames() throws Exception { + System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); + var playerNames = Arrays.asList(sc.nextLine().split(",")); + if (playerNames.isEmpty()) { + throw new Exception("자동차 이름이 입력되지 않았습니다."); + } + if (playerNames.size() < 2) { + throw new Exception("2개 이상의 자동차 이름이 입력되지 않았습니다."); + } + return playerNames; + } + + public static int getRounds() throws Exception { + System.out.println("시도할 회수는 몇회인가요?"); + var rounds = Integer.parseInt(sc.nextLine()); + if (rounds <= 0) { + throw new IOException(); + } + return rounds; + } +} diff --git a/src/main/java/cholog/view/ResultView.java b/src/main/java/cholog/view/ResultView.java new file mode 100644 index 00000000..bbafb76d --- /dev/null +++ b/src/main/java/cholog/view/ResultView.java @@ -0,0 +1,44 @@ +package view; + +import domain.RacingContest; +import java.util.List; +import java.util.Map; + +public class ResultView { + + private static void printRound(Map distances) { + if (distances.isEmpty()) { + throw new IllegalArgumentException(); + } + StringBuilder sb = new StringBuilder(); + + for (Map.Entry player : distances.entrySet()) { + sb.append(player.getKey()).append(" : "); + sb.append("-".repeat(player.getValue())).append("\n"); + } + + System.out.println(sb); + } + + public static void printWinners(List winners) { + if (winners.isEmpty()) { + throw new IllegalArgumentException(); + } + System.out.print(String.join(", ", winners)); + System.out.println("가 최종 우승했습니다."); + } + + public static void printContest(RacingContest contest) { + if (contest == null) { + throw new IllegalArgumentException(); + } + int rounds = contest.getRounds(); + + System.out.println("\n실행 결과"); + for (int r = 0; r < rounds; r++){ + contest.goRound(); + printRound(contest.getDistances()); + } + printWinners(contest.getWinners()); + } +} diff --git a/src/test/java/cholog/TestRacingCar.java b/src/test/java/cholog/TestRacingCar.java index a27c6a39..97207bd8 100644 --- a/src/test/java/cholog/TestRacingCar.java +++ b/src/test/java/cholog/TestRacingCar.java @@ -1,9 +1,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import domain.RacingCar; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; public class TestRacingCar { @@ -46,12 +46,13 @@ public void testStop(){ @DisplayName("레이싱카의 이름이 유효하지 않을 시 에러 발생") public void testValidName(){ //given + String name = null; //when //then assertThatThrownBy(() -> { - racingCar.setName(null); + new RacingCar(name); }).isInstanceOf(IllegalArgumentException.class); } } diff --git a/src/test/java/cholog/TestRacingContest.java b/src/test/java/cholog/TestRacingContest.java index a298c236..11a92ae6 100644 --- a/src/test/java/cholog/TestRacingContest.java +++ b/src/test/java/cholog/TestRacingContest.java @@ -1,25 +1,23 @@ import static org.assertj.core.api.Assertions.assertThat; +import domain.RacingCar; +import domain.RacingContest; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class TestRacingContest { - private static int round; + private static RacingContest contest; - private static final String[] names = new String[]{"neo", "brie", "brown"}; @BeforeAll public static void setUp() { - RacingCar[] participants = new RacingCar[]{ - new RacingCar(names[0]), - new RacingCar(names[1]), - new RacingCar(names[2]) - }; - round = 10; - contest = new RacingContest(participants, round); + int rounds = 5; + List playerNames = Arrays.asList("neo", "brie", "brown"); + contest = new RacingContest(playerNames, rounds); } @Test @@ -27,11 +25,11 @@ public static void setUp() { public void testStart() { //given int round = contest.getRounds(); + var distances = contest.getDistances(); //when - int[] distances = contest.start(); - int maxDist = Arrays.stream(distances).max().getAsInt(); - int minDist = Arrays.stream(distances).min().getAsInt(); + int maxDist = distances.values().stream().max(Integer::compareTo).get(); + int minDist = distances.values().stream().min(Integer::compareTo).get(); //then assertThat(maxDist).isBetween(0, round + 1); @@ -41,14 +39,15 @@ public void testStart() { @DisplayName("경기 결과를 바탕으로 우승자를 가려낼 수 있는지 확인") public void testRanking() { //given - int[] distances = new int[]{0, round, round}; - String[] winners = new String[]{names[1], names[2]}; + contest.goRound(); + var distances = contest.getDistances(); + var winners = contest.getWinners(); //when - ArrayList actual = contest.ranking(distances); - ArrayList expected = new ArrayList<>(Arrays.asList(winners)); + var actual = distances.get(winners.get(0)); + var expected = distances.values().stream().max(Integer::compareTo).get(); //then - assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + assertThat(actual).isEqualTo(expected); } }