From 3732b706ca3e98fb7808701f20a827cd8450e280 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 13:26:04 +0900 Subject: [PATCH 01/42] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..0e3e48f56 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,25 @@ +# 구현 기능 목록 + +## 자동차 +- [ ] 전진하거나 멈출 수 있다. + - [ ] 연료가 4 이상일 경우 전진한다. + - [ ] **[예외처리]** 연료가 0 미만 9 초과의 값이 들어오면 예외처리한다. +- [ ] **[예외처리]** 자동차의 이름은 5자 이하여야 한다. + + +## 자동차 경주 게임 +- [ ] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. +- [ ] 각 자동차에 이름을 부여할 수 있다. +- [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) + + +## 입력 +- [ ] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름을 입력받는다. +- [ ] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +- [ ] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. + + +## 출력 +- [ ] 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- [ ] 최종 우승자를 출력한다. + - [ ] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. From 64f0da6fc5031dec522e737d4aaff97db4150571 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 13:42:01 +0900 Subject: [PATCH 02/42] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 0e3e48f56..078c7b0ed 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,10 @@ # 구현 기능 목록 ## 자동차 +- [ ] **[예외처리]** 자동차의 이름이 5자 초과일 경우 예외처리한다. - [ ] 전진하거나 멈출 수 있다. - [ ] 연료가 4 이상일 경우 전진한다. - [ ] **[예외처리]** 연료가 0 미만 9 초과의 값이 들어오면 예외처리한다. -- [ ] **[예외처리]** 자동차의 이름은 5자 이하여야 한다. ## 자동차 경주 게임 From c74ffb98ae9b413292f5963766a5e50d08232f23 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 13:48:44 +0900 Subject: [PATCH 03/42] =?UTF-8?q?test(Car):=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=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/test/java/racingcar/CarTest.java | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/racingcar/CarTest.java diff --git a/src/test/java/racingcar/CarTest.java b/src/test/java/racingcar/CarTest.java new file mode 100644 index 000000000..f7a26bed0 --- /dev/null +++ b/src/test/java/racingcar/CarTest.java @@ -0,0 +1,26 @@ +package racingcar; + + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class CarTest { + + @Test + @DisplayName("자동차의 이름은 5자 이하여야 한다.") + void 자동차_이름_유효성_성공_테스트() { + Car fives = new Car("fives"); + assertThat(fives).isNotNull(); + } + + @Test + @DisplayName("자동차의 이름은 5자 초과이면 예외처리한다.") + void 자동차_이름_유효성_실패_테스트() { + //given + assertThatThrownBy(() -> new Car("sixCar")) + .isInstanceOf(IllegalArgumentException.class); + } +} From d3b17d40a8c9459b5e49b2a450d2e2268f00ebe5 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 13:50:34 +0900 Subject: [PATCH 04/42] =?UTF-8?q?feat(Car):=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/Car.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 078c7b0ed..741e7f195 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ # 구현 기능 목록 ## 자동차 -- [ ] **[예외처리]** 자동차의 이름이 5자 초과일 경우 예외처리한다. +- [x] **[예외처리]** 자동차의 이름이 5자 초과일 경우 예외처리한다. - [ ] 전진하거나 멈출 수 있다. - [ ] 연료가 4 이상일 경우 전진한다. - [ ] **[예외처리]** 연료가 0 미만 9 초과의 값이 들어오면 예외처리한다. diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java index ab3df9492..9e8e885b6 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/Car.java @@ -1,12 +1,23 @@ package racingcar; public class Car { + + public static final int MIN_FUEL = 4; + public static final int MAX_FUEL = 9; + public static final int MAX_NAME_LENGTH = 5; + private final String name; private int position = 0; public Car(String name) { + validateName(name); this.name = name; } // 추가 기능 구현 + private void validateName(String name) { + if (name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("자동차의 이름은 5자 이하여야 합니다."); + } + } } From 540274070aad379a46d9a981c34c714991a7e115 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 13:51:31 +0900 Subject: [PATCH 05/42] =?UTF-8?q?test(Car):=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=20=EC=A0=84=EC=A7=84=20=EA=B8=B0=EB=8A=A5=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/test/java/racingcar/CarTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/racingcar/CarTest.java b/src/test/java/racingcar/CarTest.java index f7a26bed0..fe9e957de 100644 --- a/src/test/java/racingcar/CarTest.java +++ b/src/test/java/racingcar/CarTest.java @@ -23,4 +23,17 @@ class CarTest { assertThatThrownBy(() -> new Car("sixCar")) .isInstanceOf(IllegalArgumentException.class); } + + @Test + @DisplayName("들어온 값이 4이상이면 전진한다.") + void 자동차_전진_테스트() { + //given + Car pobi = new Car("pobi"); + //when + int prePosition = pobi.getCurrentPosition(); + pobi.moveOrStop(4); + //then + int currentPostion = pobi.getCurrentPosition(); + assertThat(prePosition + 1).isEqualTo(currentPostion); + } } From 5c37b2f83d103704c6051f42e98dc19bc7c3767c Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 13:52:59 +0900 Subject: [PATCH 06/42] =?UTF-8?q?feat(Car):=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=20=EC=97=B0=EB=A3=8C=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=A0=84?= =?UTF-8?q?=EC=A7=84=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 --- docs/README.md | 6 +++--- src/main/java/racingcar/Car.java | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 741e7f195..a2f140f96 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,9 +2,9 @@ ## 자동차 - [x] **[예외처리]** 자동차의 이름이 5자 초과일 경우 예외처리한다. -- [ ] 전진하거나 멈출 수 있다. - - [ ] 연료가 4 이상일 경우 전진한다. - - [ ] **[예외처리]** 연료가 0 미만 9 초과의 값이 들어오면 예외처리한다. +- [x] 전진하거나 멈출 수 있다. + - [x] 연료가 4 이상일 경우 전진한다. + - [x] **[예외처리]** 연료가 0 미만 9 초과의 값이 들어오면 예외처리한다. ## 자동차 경주 게임 diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java index 9e8e885b6..3599db92f 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/Car.java @@ -20,4 +20,26 @@ private void validateName(String name) { throw new IllegalArgumentException("자동차의 이름은 5자 이하여야 합니다."); } } + + + public void moveOrStop(int fuel) { + validateFuel(fuel); + if (fuel >= MIN_FUEL) { + move(); + } + } + + private void validateFuel(int fuel) { + if (fuel < 0 || fuel > MAX_FUEL) { + throw new IllegalArgumentException("연료는 0 이상 9 이하의 값이어야 합니다."); + } + } + + private void move() { + position++; + } + + public int getCurrentPosition() { + return position; + } } From a50d563c6d6c62592b0ce266ae17c5b37b20a652 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:05:56 +0900 Subject: [PATCH 07/42] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=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 자동차 이름을 부여하는 부분은 자동차쪽으로 수정 --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index a2f140f96..cfecf8e76 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,8 @@ # 구현 기능 목록 ## 자동차 -- [x] **[예외처리]** 자동차의 이름이 5자 초과일 경우 예외처리한다. +- [x] 각 자동차에 이름을 부여할 수 있다. + - [x] **[예외처리]** 자동차의 이름이 5자 초과일 경우 예외처리한다. - [x] 전진하거나 멈출 수 있다. - [x] 연료가 4 이상일 경우 전진한다. - [x] **[예외처리]** 연료가 0 미만 9 초과의 값이 들어오면 예외처리한다. @@ -9,7 +10,6 @@ ## 자동차 경주 게임 - [ ] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. -- [ ] 각 자동차에 이름을 부여할 수 있다. - [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) From a38d016eff56780361091dc24451c218f46edcf3 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:18:41 +0900 Subject: [PATCH 08/42] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index cfecf8e76..3e053def5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,13 +9,18 @@ ## 자동차 경주 게임 -- [ ] 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. +- [ ] 자동차 경주를 개최한다. + - [ ] 경주에 참여할 자동차들을 등록한다. + - [ ] 이동 횟수를 등록한다. + - [ ] **[예외처리]** 이동횟수가 0보다 작으면 예외처리한다. +- [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. - [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) ## 입력 - [ ] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름을 입력받는다. - [ ] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. + - [ ] **[예외처리]** 이동 횟수는 숫자여야 한다. - [ ] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. From 06d72a5b6eaaad7ab45a6819cf379c16c8775fb6 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:19:57 +0900 Subject: [PATCH 09/42] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index 3e053def5..05c4d205d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,10 +9,10 @@ ## 자동차 경주 게임 -- [ ] 자동차 경주를 개최한다. - - [ ] 경주에 참여할 자동차들을 등록한다. - - [ ] 이동 횟수를 등록한다. - - [ ] **[예외처리]** 이동횟수가 0보다 작으면 예외처리한다. +- [ ] 경주에 참여할 자동차들을 등록한다. + - [ ] **[예외처리]** 참여할 자동차는 최소 1대여야한다. +- [ ] 이동 횟수를 등록한다. + - [ ] **[예외처리]** 이동횟수가 0보다 작으면 예외처리한다. - [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. - [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) From 61b8dafbbd98ab8432378e55ad537d9f7a92d9b9 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:36:39 +0900 Subject: [PATCH 10/42] =?UTF-8?q?test(CarGame):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EB=93=B1=EB=A1=9D=20=EC=84=B1=EA=B3=B5,=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=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/test/java/racingcar/CarGameTest.java | 44 ++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/java/racingcar/CarGameTest.java diff --git a/src/test/java/racingcar/CarGameTest.java b/src/test/java/racingcar/CarGameTest.java new file mode 100644 index 000000000..d7512efb2 --- /dev/null +++ b/src/test/java/racingcar/CarGameTest.java @@ -0,0 +1,44 @@ +package racingcar; + + +import static org.assertj.core.api.Assertions.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class CarGameTest { + + @Test + @DisplayName("자동차 경주 자동차 등록 성공 테스트") + void 자동차_등록_성공_테스트() { + //given + CarGame carGame = new CarGame(); + //when + List cars = Arrays.asList("pobi", "woni", "jun"); + carGame.registerCar(cars); + //then + List carNames = carGame.getCars() + .stream() + .map(Car::getName) + .collect(Collectors.toList()); + + assertThat(carNames) + .contains("pobi", "woni", "jun"); + } + + @Test + @DisplayName("자동차 경주 자동차 등록 실패 테스트") + void 자동차_등록_실패_테스트() { + //given + CarGame carGame = new CarGame(); + //when + List cars = new ArrayList<>(); + //then + assertThatThrownBy(() -> carGame.registerCar(cars)) + .isInstanceOf(IllegalArgumentException.class); + } +} From 16af14f281a1075cdb789222590699508a7150eb Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:37:27 +0900 Subject: [PATCH 11/42] =?UTF-8?q?feat(Car):=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=88=98?= =?UTF-8?q?=20=EC=9E=88=EA=B2=8C=20getter=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Car.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java index 3599db92f..084112a5b 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/Car.java @@ -42,4 +42,8 @@ private void move() { public int getCurrentPosition() { return position; } + + public String getName() { + return name; + } } From 970064cf274d054b3ea1ab367f57ab2c55cf275f Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:38:01 +0900 Subject: [PATCH 12/42] =?UTF-8?q?feat(CarGame):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EB=93=B1=EB=A1=9D=ED=95=98=EB=8A=94=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 --- docs/README.md | 4 ++-- src/main/java/racingcar/CarGame.java | 30 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 src/main/java/racingcar/CarGame.java diff --git a/docs/README.md b/docs/README.md index 05c4d205d..3adbb8ecb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,8 +9,8 @@ ## 자동차 경주 게임 -- [ ] 경주에 참여할 자동차들을 등록한다. - - [ ] **[예외처리]** 참여할 자동차는 최소 1대여야한다. +- [x] 경주에 참여할 자동차들을 등록한다. + - [x] **[예외처리]** 참여할 자동차는 최소 1대여야한다. - [ ] 이동 횟수를 등록한다. - [ ] **[예외처리]** 이동횟수가 0보다 작으면 예외처리한다. - [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. diff --git a/src/main/java/racingcar/CarGame.java b/src/main/java/racingcar/CarGame.java new file mode 100644 index 000000000..fd98a53ab --- /dev/null +++ b/src/main/java/racingcar/CarGame.java @@ -0,0 +1,30 @@ +package racingcar; + +import java.util.ArrayList; +import java.util.List; + +public class CarGame { + + private List cars; + + public CarGame() { + cars = new ArrayList<>(); + } + + public void registerCar(List cars) { + validateCars(cars); + for (String carName : cars) { + this.cars.add(new Car(carName)); + } + } + + private void validateCars(List cars) { + if (cars.isEmpty()) { + throw new IllegalArgumentException("등록할 자동차는 최소 1대여야 합니다."); + } + } + + public List getCars() { + return cars; + } +} From b9be6d027b37aa7e8620a52b90fefaa4196107ae Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:40:44 +0900 Subject: [PATCH 13/42] =?UTF-8?q?refactor(CarGameTest):=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20init=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/racingcar/CarGameTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/test/java/racingcar/CarGameTest.java b/src/test/java/racingcar/CarGameTest.java index d7512efb2..782de9795 100644 --- a/src/test/java/racingcar/CarGameTest.java +++ b/src/test/java/racingcar/CarGameTest.java @@ -7,16 +7,21 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class CarGameTest { + private CarGame carGame; + + @BeforeEach + void init() { + carGame = new CarGame(); + } @Test @DisplayName("자동차 경주 자동차 등록 성공 테스트") void 자동차_등록_성공_테스트() { - //given - CarGame carGame = new CarGame(); //when List cars = Arrays.asList("pobi", "woni", "jun"); carGame.registerCar(cars); @@ -33,8 +38,6 @@ class CarGameTest { @Test @DisplayName("자동차 경주 자동차 등록 실패 테스트") void 자동차_등록_실패_테스트() { - //given - CarGame carGame = new CarGame(); //when List cars = new ArrayList<>(); //then From d35210de80e7b3d4edd997fee487c266b430a0af Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:42:58 +0900 Subject: [PATCH 14/42] =?UTF-8?q?docs:=20=EC=9D=B4=EB=8F=99=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0보다 작으면 -> 0 이하면 --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 3adbb8ecb..e81a79019 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,7 +12,7 @@ - [x] 경주에 참여할 자동차들을 등록한다. - [x] **[예외처리]** 참여할 자동차는 최소 1대여야한다. - [ ] 이동 횟수를 등록한다. - - [ ] **[예외처리]** 이동횟수가 0보다 작으면 예외처리한다. + - [ ] **[예외처리]** 이동횟수가 0 이하면 예외처리한다. - [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. - [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) From a0fd5c5e69d005d9a5ec61bba21d98fe23e9a12e Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:46:22 +0900 Subject: [PATCH 15/42] =?UTF-8?q?test(CarGame):=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EB=93=B1=EB=A1=9D=EC=8B=9C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EB=A1=9C=EC=A7=81=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/racingcar/CarGameTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/racingcar/CarGameTest.java b/src/test/java/racingcar/CarGameTest.java index 782de9795..efa5d676c 100644 --- a/src/test/java/racingcar/CarGameTest.java +++ b/src/test/java/racingcar/CarGameTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.ArrayList; import java.util.Arrays; @@ -44,4 +45,13 @@ void init() { assertThatThrownBy(() -> carGame.registerCar(cars)) .isInstanceOf(IllegalArgumentException.class); } + + @Test + @DisplayName("이동횟수 등록 실패 테스트") + void CarGameTest() { + int moveCounts = 0; + + assertThatThrownBy(() -> carGame.registerMoveCounts(moveCounts)) + .isInstanceOf(IllegalArgumentException.class); + } } From 389d30f9e535eeb20b7860f316b5cbd381430e94 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 14:47:14 +0900 Subject: [PATCH 16/42] =?UTF-8?q?feat(CarGame):=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EB=93=B1=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- src/main/java/racingcar/CarGame.java | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index e81a79019..d79822dbc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,8 +11,8 @@ ## 자동차 경주 게임 - [x] 경주에 참여할 자동차들을 등록한다. - [x] **[예외처리]** 참여할 자동차는 최소 1대여야한다. -- [ ] 이동 횟수를 등록한다. - - [ ] **[예외처리]** 이동횟수가 0 이하면 예외처리한다. +- [x] 이동 횟수를 등록한다. + - [x] **[예외처리]** 이동횟수가 0 이하면 예외처리한다. - [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. - [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) diff --git a/src/main/java/racingcar/CarGame.java b/src/main/java/racingcar/CarGame.java index fd98a53ab..e6d356dad 100644 --- a/src/main/java/racingcar/CarGame.java +++ b/src/main/java/racingcar/CarGame.java @@ -6,6 +6,7 @@ public class CarGame { private List cars; + private int moveCounts; public CarGame() { cars = new ArrayList<>(); @@ -27,4 +28,15 @@ private void validateCars(List cars) { public List getCars() { return cars; } + + public void registerMoveCounts(int moveCounts) { + validateMoveCounts(moveCounts); + this.moveCounts = moveCounts; + } + + private void validateMoveCounts(int moveCounts) { + if (moveCounts <= 0) { + throw new IllegalArgumentException("이동횟수는 최소 1회 이상이어야 합니다."); + } + } } From 15427cd2bafd5fa56d6a465da711ff249b8bf080 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:00:29 +0900 Subject: [PATCH 17/42] =?UTF-8?q?refactor(Car):=20=EC=83=81=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MIN_FUEL -> MIN_MOVE_FUEL 최소 연료 = MIN_FUEL --- src/main/java/racingcar/Car.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java index 084112a5b..d574ef167 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/Car.java @@ -2,8 +2,10 @@ public class Car { - public static final int MIN_FUEL = 4; + public static final int MIN_FUEL = 0; public static final int MAX_FUEL = 9; + public static final int MIN_MOVE_FUEL = 4; + public static final int MAX_NAME_LENGTH = 5; private final String name; @@ -24,13 +26,13 @@ private void validateName(String name) { public void moveOrStop(int fuel) { validateFuel(fuel); - if (fuel >= MIN_FUEL) { + if (fuel >= MIN_MOVE_FUEL) { move(); } } private void validateFuel(int fuel) { - if (fuel < 0 || fuel > MAX_FUEL) { + if (fuel < MIN_FUEL || fuel > MAX_FUEL) { throw new IllegalArgumentException("연료는 0 이상 9 이하의 값이어야 합니다."); } } From 475188d327870687690cfe68ce35c64e66f1250f Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:16:34 +0900 Subject: [PATCH 18/42] =?UTF-8?q?refactor(CarGameTest):=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CarGameTest -> 이동횟수_등록_실패_테스트 --- src/test/java/racingcar/CarGameTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/racingcar/CarGameTest.java b/src/test/java/racingcar/CarGameTest.java index efa5d676c..1efb8d811 100644 --- a/src/test/java/racingcar/CarGameTest.java +++ b/src/test/java/racingcar/CarGameTest.java @@ -48,7 +48,7 @@ void init() { @Test @DisplayName("이동횟수 등록 실패 테스트") - void CarGameTest() { + void 이동횟수_등록_실패_테스트() { int moveCounts = 0; assertThatThrownBy(() -> carGame.registerMoveCounts(moveCounts)) From 7f14435e3a13dc3d123009bf7fd32ba842c0881e Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:17:17 +0900 Subject: [PATCH 19/42] =?UTF-8?q?docs:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EA=B2=BD=EC=A3=BC=20=EA=B2=8C=EC=9E=84=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index d79822dbc..ad4ebc271 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,7 +13,8 @@ - [x] **[예외처리]** 참여할 자동차는 최소 1대여야한다. - [x] 이동 횟수를 등록한다. - [x] **[예외처리]** 이동횟수가 0 이하면 예외처리한다. -- [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. +- [ ] 자동차 경주를 시작한다. + - [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. - [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) From 780dc00911e0d0ec9d87b0a91bab7072e41a91c5 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:31:14 +0900 Subject: [PATCH 20/42] =?UTF-8?q?test(CarGame):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EA=B2=BD=EC=A3=BC=20=EC=9A=B0=EC=8A=B9=EC=9E=90=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=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/test/java/racingcar/CarGameTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/racingcar/CarGameTest.java b/src/test/java/racingcar/CarGameTest.java index 1efb8d811..b493b30f6 100644 --- a/src/test/java/racingcar/CarGameTest.java +++ b/src/test/java/racingcar/CarGameTest.java @@ -54,4 +54,18 @@ void init() { assertThatThrownBy(() -> carGame.registerMoveCounts(moveCounts)) .isInstanceOf(IllegalArgumentException.class); } + + @Test + @DisplayName("자동차 경주 우승자 테스트") + void 경주_우승자_테스트() { + //given + List cars = Arrays.asList("pobi", "woni", "jun"); + carGame.registerCar(cars); + carGame.registerMoveCounts(5); + //when + carGame.startRacing(); + //then + List winners = carGame.announceWinners(); + assertThat(winners).isSubsetOf(cars); + } } From 2eb43953c52f49f89c5d56fb962cefec28f9cf6b Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:31:55 +0900 Subject: [PATCH 21/42] =?UTF-8?q?feat(CarGame):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EA=B2=BD=EC=A3=BC=20=EC=8B=9C=EC=9E=91=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 --- docs/README.md | 4 ++-- src/main/java/racingcar/CarGame.java | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index ad4ebc271..e5b78a478 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,8 +13,8 @@ - [x] **[예외처리]** 참여할 자동차는 최소 1대여야한다. - [x] 이동 횟수를 등록한다. - [x] **[예외처리]** 이동횟수가 0 이하면 예외처리한다. -- [ ] 자동차 경주를 시작한다. - - [ ] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. +- [x] 자동차 경주를 시작한다. + - [x] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. - [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) diff --git a/src/main/java/racingcar/CarGame.java b/src/main/java/racingcar/CarGame.java index e6d356dad..6d503a60d 100644 --- a/src/main/java/racingcar/CarGame.java +++ b/src/main/java/racingcar/CarGame.java @@ -1,7 +1,9 @@ package racingcar; +import camp.nextstep.edu.missionutils.Randoms; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class CarGame { @@ -39,4 +41,16 @@ private void validateMoveCounts(int moveCounts) { throw new IllegalArgumentException("이동횟수는 최소 1회 이상이어야 합니다."); } } + + public void startRacing() { + for (int i = 0; i < moveCounts; i++) { + for (Car car : cars) { + car.moveOrStop(getRandomFuel()); + } + } + } + + private int getRandomFuel() { + return Randoms.pickNumberInRange(Car.MIN_FUEL, Car.MAX_FUEL); + } } From 6854d1072a168c427900dce9bc24cc50bd4b72ac Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:33:48 +0900 Subject: [PATCH 22/42] =?UTF-8?q?feat(CarGame):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EA=B2=BD=EC=A3=BC=20=EC=9A=B0=EC=8A=B9=EC=9E=90=20?= =?UTF-8?q?=EC=95=8C=EB=A0=A4=EC=A3=BC=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/CarGame.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e5b78a478..50eaefc4d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,7 +15,7 @@ - [x] **[예외처리]** 이동횟수가 0 이하면 예외처리한다. - [x] 자동차 경주를 시작한다. - [x] 각 이동횟수마다 각 자동차에게 랜덤한 연료를 주입한다. -- [ ] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) +- [x] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다.(여러명의 우승자가 나올 수 있다.) ## 입력 diff --git a/src/main/java/racingcar/CarGame.java b/src/main/java/racingcar/CarGame.java index 6d503a60d..0f66342fb 100644 --- a/src/main/java/racingcar/CarGame.java +++ b/src/main/java/racingcar/CarGame.java @@ -53,4 +53,12 @@ public void startRacing() { private int getRandomFuel() { return Randoms.pickNumberInRange(Car.MIN_FUEL, Car.MAX_FUEL); } + + public List announceWinners() { + return cars.stream() + .filter(car -> car.getCurrentPosition() == cars.stream().map(Car::getCurrentPosition) + .max(Integer::compareTo).orElse(0)) + .map(Car::getName) + .collect(Collectors.toList()); + } } From 391b8026bf8f144e7a0a0fd9bbc10f7b4703db2c Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:41:25 +0900 Subject: [PATCH 23/42] =?UTF-8?q?feat(InputView):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=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 --- docs/README.md | 2 +- src/main/java/racingcar/InputView.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/InputView.java diff --git a/docs/README.md b/docs/README.md index 50eaefc4d..7c2dbfd9f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -19,7 +19,7 @@ ## 입력 -- [ ] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름을 입력받는다. +- [x] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름을 입력받는다. - [ ] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. - [ ] **[예외처리]** 이동 횟수는 숫자여야 한다. - [ ] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. diff --git a/src/main/java/racingcar/InputView.java b/src/main/java/racingcar/InputView.java new file mode 100644 index 000000000..50b18b4d7 --- /dev/null +++ b/src/main/java/racingcar/InputView.java @@ -0,0 +1,17 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Console; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class InputView { + + public static final String CAR_REGEX = ","; + + public List inputCars() { + String input = Console.readLine(); + String[] inputCars = input.split(CAR_REGEX); + return Arrays.stream(inputCars).collect(Collectors.toList()); + } +} From a36a3f5cc1bed015cc068ef1921c88b6d42ea967 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 15:45:08 +0900 Subject: [PATCH 24/42] =?UTF-8?q?feat(InputView):=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++-- src/main/java/racingcar/InputView.java | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 7c2dbfd9f..5f6355e28 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,8 +20,8 @@ ## 입력 - [x] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름을 입력받는다. -- [ ] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. - - [ ] **[예외처리]** 이동 횟수는 숫자여야 한다. +- [x] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. + - [x] **[예외처리]** 이동 횟수는 숫자여야 한다. - [ ] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. diff --git a/src/main/java/racingcar/InputView.java b/src/main/java/racingcar/InputView.java index 50b18b4d7..fb278284f 100644 --- a/src/main/java/racingcar/InputView.java +++ b/src/main/java/racingcar/InputView.java @@ -3,15 +3,29 @@ import camp.nextstep.edu.missionutils.Console; import java.util.Arrays; import java.util.List; +import java.util.regex.Pattern; import java.util.stream.Collectors; public class InputView { public static final String CAR_REGEX = ","; + private static final String ONLY_NUMBER_REGEX = "^[0-9]+$"; public List inputCars() { String input = Console.readLine(); String[] inputCars = input.split(CAR_REGEX); return Arrays.stream(inputCars).collect(Collectors.toList()); } + + public int inputMoveCounts() { + String input = Console.readLine(); + validateNumber(input); + return Integer.parseInt(input); + } + + private void validateNumber(String input) { + if (!Pattern.matches(ONLY_NUMBER_REGEX, input)) { + throw new IllegalArgumentException("숫자만 입력이 가능합니다."); + } + } } From 7548e0fc8e3def5699d4e15ab32a8d8eda5eab90 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 16:14:36 +0900 Subject: [PATCH 25/42] =?UTF-8?q?feat(OutputView):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=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 --- docs/README.md | 2 +- src/main/java/racingcar/OutputView.java | 33 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/OutputView.java diff --git a/docs/README.md b/docs/README.md index 5f6355e28..fd0f8ea84 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,6 +26,6 @@ ## 출력 -- [ ] 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- [x] 자동차 이름과 자동차의 현재 위치를 출력한다. - [ ] 최종 우승자를 출력한다. - [ ] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. diff --git a/src/main/java/racingcar/OutputView.java b/src/main/java/racingcar/OutputView.java new file mode 100644 index 000000000..6da1f8cfb --- /dev/null +++ b/src/main/java/racingcar/OutputView.java @@ -0,0 +1,33 @@ +package racingcar; + +import java.util.List; + +public class OutputView { + + public static final String CAR_FORMAT = "%s : %s"; + public static final String MOVE_UNIT = "-"; + + public void printCars(List cars) { + for (Car car : cars) { + printCar(car); + } + printNewLine(); + } + + private void printNewLine() { + System.out.println(); + } + + private void printCar(Car car) { + System.out.printf(CAR_FORMAT, car.getName(), getMove(car.getCurrentPosition())); + printNewLine(); + } + + private String getMove(int currentPosition) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < currentPosition; i++) { + stringBuilder.append(MOVE_UNIT); + } + return stringBuilder.toString(); + } +} From 40e9197955935f3515d3b0a80e402447c65c8a93 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 16:19:19 +0900 Subject: [PATCH 26/42] =?UTF-8?q?feat(OutputView):=20=EC=9A=B0=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=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 --- docs/README.md | 4 ++-- src/main/java/racingcar/OutputView.java | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index fd0f8ea84..7e197cd08 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,5 +27,5 @@ ## 출력 - [x] 자동차 이름과 자동차의 현재 위치를 출력한다. -- [ ] 최종 우승자를 출력한다. - - [ ] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. +- [x] 최종 우승자를 출력한다. + - [x] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. diff --git a/src/main/java/racingcar/OutputView.java b/src/main/java/racingcar/OutputView.java index 6da1f8cfb..52101a4b8 100644 --- a/src/main/java/racingcar/OutputView.java +++ b/src/main/java/racingcar/OutputView.java @@ -1,11 +1,13 @@ package racingcar; import java.util.List; +import java.util.stream.Collectors; public class OutputView { public static final String CAR_FORMAT = "%s : %s"; public static final String MOVE_UNIT = "-"; + public static final String DELIMITER = ", "; public void printCars(List cars) { for (Car car : cars) { @@ -30,4 +32,10 @@ private String getMove(int currentPosition) { } return stringBuilder.toString(); } + + public void printWinners(List winners) { + String winnersName = winners.stream() + .collect(Collectors.joining(DELIMITER)); + System.out.printf("최종 우승자 : %s", winnersName); + } } From 0d8b21e75b7948e8c7ddc246108aa830570f727a Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 16:29:37 +0900 Subject: [PATCH 27/42] =?UTF-8?q?feat(InputView):=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=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/racingcar/InputView.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/racingcar/InputView.java b/src/main/java/racingcar/InputView.java index fb278284f..36a9df1d2 100644 --- a/src/main/java/racingcar/InputView.java +++ b/src/main/java/racingcar/InputView.java @@ -11,13 +11,18 @@ public class InputView { public static final String CAR_REGEX = ","; private static final String ONLY_NUMBER_REGEX = "^[0-9]+$"; + public static final String INPUT_CAR_MESSAGE = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"; + public static final String INPUT_MOVE_COUNTS_MESSAGE = "시도할 회수는 몇회인가요?"; + public List inputCars() { + System.out.println(INPUT_CAR_MESSAGE); String input = Console.readLine(); String[] inputCars = input.split(CAR_REGEX); return Arrays.stream(inputCars).collect(Collectors.toList()); } public int inputMoveCounts() { + System.out.println(INPUT_MOVE_COUNTS_MESSAGE); String input = Console.readLine(); validateNumber(input); return Integer.parseInt(input); From 8eb4a8104dff9b78e1a6b40e8507cb64fd0f5099 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 16:38:59 +0900 Subject: [PATCH 28/42] =?UTF-8?q?refactor(CarGame):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EA=B2=BD=EC=A3=BC=20=EC=8B=9C=EC=9E=91=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 레이스를 이동횟수 만큼 실행 -> 레이스를 1회만 실행하고 이동횟수를 차감하도록 --- src/main/java/racingcar/CarGame.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/racingcar/CarGame.java b/src/main/java/racingcar/CarGame.java index 0f66342fb..032f456a8 100644 --- a/src/main/java/racingcar/CarGame.java +++ b/src/main/java/racingcar/CarGame.java @@ -43,11 +43,17 @@ private void validateMoveCounts(int moveCounts) { } public void startRacing() { - for (int i = 0; i < moveCounts; i++) { - for (Car car : cars) { - car.moveOrStop(getRandomFuel()); - } + if (checkIsOver()) { + throw new IllegalStateException("경기가 종료되었습니다."); } + for (Car car : cars) { + car.moveOrStop(getRandomFuel()); + } + moveCounts--; + } + + public boolean checkIsOver() { + return moveCounts <= 0; } private int getRandomFuel() { From 9cb01d1dd954b50e620d2575e481dc1bf7198d8b Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 16:46:00 +0900 Subject: [PATCH 29/42] =?UTF-8?q?feat(OutputView):=20=EA=B2=BD=EA=B8=B0=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/OutputView.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/OutputView.java b/src/main/java/racingcar/OutputView.java index 52101a4b8..6040cc715 100644 --- a/src/main/java/racingcar/OutputView.java +++ b/src/main/java/racingcar/OutputView.java @@ -8,6 +8,7 @@ public class OutputView { public static final String CAR_FORMAT = "%s : %s"; public static final String MOVE_UNIT = "-"; public static final String DELIMITER = ", "; + public static final String RACE_START_MESSAGE = "실행 결과"; public void printCars(List cars) { for (Car car : cars) { @@ -20,6 +21,11 @@ private void printNewLine() { System.out.println(); } + public void printRaceStart() { + printNewLine(); + System.out.println(RACE_START_MESSAGE); + } + private void printCar(Car car) { System.out.printf(CAR_FORMAT, car.getName(), getMove(car.getCurrentPosition())); printNewLine(); @@ -34,8 +40,7 @@ private String getMove(int currentPosition) { } public void printWinners(List winners) { - String winnersName = winners.stream() - .collect(Collectors.joining(DELIMITER)); + String winnersName = String.join(DELIMITER, winners); System.out.printf("최종 우승자 : %s", winnersName); } } From b7c46fabb3de00b6941add9b577da82e9b7b87e2 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 16:58:23 +0900 Subject: [PATCH 30/42] =?UTF-8?q?feat(InputView):=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=B0=A8=20=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 1 + src/main/java/racingcar/InputView.java | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/docs/README.md b/docs/README.md index 7e197cd08..6b96b0605 100644 --- a/docs/README.md +++ b/docs/README.md @@ -20,6 +20,7 @@ ## 입력 - [x] 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름을 입력받는다. + - [x] **[예외처리]** 쉼표를 기준으로 나눴을 때 자동차 이름이 0보다 작거나 5보다 크면 예외처리한다. - [x] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. - [x] **[예외처리]** 이동 횟수는 숫자여야 한다. - [ ] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. diff --git a/src/main/java/racingcar/InputView.java b/src/main/java/racingcar/InputView.java index 36a9df1d2..54dc06eed 100644 --- a/src/main/java/racingcar/InputView.java +++ b/src/main/java/racingcar/InputView.java @@ -17,10 +17,24 @@ public class InputView { public List inputCars() { System.out.println(INPUT_CAR_MESSAGE); String input = Console.readLine(); + validateInputCars(input); String[] inputCars = input.split(CAR_REGEX); return Arrays.stream(inputCars).collect(Collectors.toList()); } + private void validateInputCars(String input) { + if (input.endsWith(CAR_REGEX)) { + throw new IllegalArgumentException("자동차의 이름은 1~5자여야 합니다."); + } + + String[] inputCars = input.split(CAR_REGEX); + for (String inputCar : inputCars) { + if (inputCar.length() > Car.MAX_NAME_LENGTH) { + throw new IllegalArgumentException("자동차의 이름은 1~5자여야 합니다."); + } + } + } + public int inputMoveCounts() { System.out.println(INPUT_MOVE_COUNTS_MESSAGE); String input = Console.readLine(); From 9ae3034fecdacc7ccccde0cb9efdc4bb8f8351fc Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 16:59:26 +0900 Subject: [PATCH 31/42] =?UTF-8?q?feat(MainController):=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=B0=A8=20=EA=B2=BD=EC=A3=BC=20=EC=88=9C=EC=84=9C?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EA=B3=BC=20=EC=9E=85/=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=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/MainController.java | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/main/java/racingcar/MainController.java diff --git a/src/main/java/racingcar/MainController.java b/src/main/java/racingcar/MainController.java new file mode 100644 index 000000000..5bb483ad8 --- /dev/null +++ b/src/main/java/racingcar/MainController.java @@ -0,0 +1,45 @@ +package racingcar; + +import java.util.List; + +public class MainController { + + private final CarGame carGame; + private final InputView inputView; + private final OutputView outputView; + + public MainController() { + carGame = new CarGame(); + inputView = new InputView(); + outputView = new OutputView(); + } + + public void run() { + registerCars(); + registerMoveCounts(); + startRace(); + endRace(); + } + + private void registerCars() { + List inputCars = inputView.inputCars(); + carGame.registerCar(inputCars); + } + + private void registerMoveCounts() { + int moveCounts = inputView.inputMoveCounts(); + carGame.registerMoveCounts(moveCounts); + } + + private void startRace() { + outputView.printRaceStart(); + while (!carGame.checkIsOver()) { + carGame.startRacing(); + outputView.printCars(carGame.getCars()); + } + } + + private void endRace() { + outputView.printWinners(carGame.announceWinners()); + } +} From 694ec26b58a66ae13033a51674070f36af277c0e Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:01:53 +0900 Subject: [PATCH 32/42] =?UTF-8?q?feat(OutputView):=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=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/OutputView.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/racingcar/OutputView.java b/src/main/java/racingcar/OutputView.java index 6040cc715..ca4dd2732 100644 --- a/src/main/java/racingcar/OutputView.java +++ b/src/main/java/racingcar/OutputView.java @@ -9,6 +9,7 @@ public class OutputView { public static final String MOVE_UNIT = "-"; public static final String DELIMITER = ", "; public static final String RACE_START_MESSAGE = "실행 결과"; + public static final String ERROR_SUFFIX = "[ERROR]"; public void printCars(List cars) { for (Car car : cars) { @@ -43,4 +44,8 @@ public void printWinners(List winners) { String winnersName = String.join(DELIMITER, winners); System.out.printf("최종 우승자 : %s", winnersName); } + + public void printError(String errorMessage) { + System.out.printf("%s %s\n", ERROR_SUFFIX, errorMessage); + } } From 82bdc23d6f84af3bcd142d97075b6093ce17450c Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:12:59 +0900 Subject: [PATCH 33/42] =?UTF-8?q?feat(MainController):=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=EA=B0=80=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20=EC=9E=85=EB=A0=A5=ED=95=A0=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EA=B7=B8=20=EB=B6=80=EB=B6=84=EB=B6=80=ED=84=B0=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 +- src/main/java/racingcar/MainController.java | 24 +++++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index 6b96b0605..566c056d1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,7 +23,7 @@ - [x] **[예외처리]** 쉼표를 기준으로 나눴을 때 자동차 이름이 0보다 작거나 5보다 크면 예외처리한다. - [x] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. - [x] **[예외처리]** 이동 횟수는 숫자여야 한다. -- [ ] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. +- [x] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. ## 출력 diff --git a/src/main/java/racingcar/MainController.java b/src/main/java/racingcar/MainController.java index 5bb483ad8..a387f4f46 100644 --- a/src/main/java/racingcar/MainController.java +++ b/src/main/java/racingcar/MainController.java @@ -22,13 +22,29 @@ public void run() { } private void registerCars() { - List inputCars = inputView.inputCars(); - carGame.registerCar(inputCars); + while (true) { + try { + List inputCars = inputView.inputCars(); + carGame.registerCar(inputCars); + } catch (IllegalArgumentException e) { + outputView.printError(e.getMessage()); + continue; + } + break; + } } private void registerMoveCounts() { - int moveCounts = inputView.inputMoveCounts(); - carGame.registerMoveCounts(moveCounts); + while (true) { + try { + int moveCounts = inputView.inputMoveCounts(); + carGame.registerMoveCounts(moveCounts); + } catch (IllegalArgumentException e) { + outputView.printError(e.getMessage()); + continue; + } + break; + } } private void startRace() { From 03a3227c576c10e78dc2ca118d22f30522607928 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:13:22 +0900 Subject: [PATCH 34/42] =?UTF-8?q?feat(Application):=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EB=9E=A8=20=EC=8B=9C=EC=9E=91=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=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/Application.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index b9ed0456a..242c04ce6 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -3,5 +3,7 @@ public class Application { public static void main(String[] args) { // TODO 구현 진행 + MainController mainController = new MainController(); + mainController.run(); } } From 4696e372593e442eb9e533b16dfc757062adbf41 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:26:44 +0900 Subject: [PATCH 35/42] =?UTF-8?q?refactor(All):=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Car.java | 4 ++-- src/main/java/racingcar/CarGame.java | 8 ++++---- src/main/java/racingcar/InputView.java | 13 +++++-------- src/main/java/racingcar/Message.java | 17 +++++++++++++++++ src/main/java/racingcar/OutputView.java | 10 +++++----- 5 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 src/main/java/racingcar/Message.java diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java index d574ef167..f715ae262 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/Car.java @@ -19,7 +19,7 @@ public Car(String name) { // 추가 기능 구현 private void validateName(String name) { if (name.length() > MAX_NAME_LENGTH) { - throw new IllegalArgumentException("자동차의 이름은 5자 이하여야 합니다."); + throw new IllegalArgumentException(Message.CAR_NAME_VALIDATION); } } @@ -33,7 +33,7 @@ public void moveOrStop(int fuel) { private void validateFuel(int fuel) { if (fuel < MIN_FUEL || fuel > MAX_FUEL) { - throw new IllegalArgumentException("연료는 0 이상 9 이하의 값이어야 합니다."); + throw new IllegalArgumentException(Message.CAR_FUEL_VALIDATION); } } diff --git a/src/main/java/racingcar/CarGame.java b/src/main/java/racingcar/CarGame.java index 032f456a8..896547c5e 100644 --- a/src/main/java/racingcar/CarGame.java +++ b/src/main/java/racingcar/CarGame.java @@ -7,7 +7,7 @@ public class CarGame { - private List cars; + private final List cars; private int moveCounts; public CarGame() { @@ -23,7 +23,7 @@ public void registerCar(List cars) { private void validateCars(List cars) { if (cars.isEmpty()) { - throw new IllegalArgumentException("등록할 자동차는 최소 1대여야 합니다."); + throw new IllegalArgumentException(Message.NUMBER_OF_CARS_VALIDATION); } } @@ -38,13 +38,13 @@ public void registerMoveCounts(int moveCounts) { private void validateMoveCounts(int moveCounts) { if (moveCounts <= 0) { - throw new IllegalArgumentException("이동횟수는 최소 1회 이상이어야 합니다."); + throw new IllegalArgumentException(Message.MOVE_COUNTS_VALIDATION); } } public void startRacing() { if (checkIsOver()) { - throw new IllegalStateException("경기가 종료되었습니다."); + throw new IllegalStateException(Message.GAME_OVER); } for (Car car : cars) { car.moveOrStop(getRandomFuel()); diff --git a/src/main/java/racingcar/InputView.java b/src/main/java/racingcar/InputView.java index 54dc06eed..2e7787800 100644 --- a/src/main/java/racingcar/InputView.java +++ b/src/main/java/racingcar/InputView.java @@ -11,11 +11,8 @@ public class InputView { public static final String CAR_REGEX = ","; private static final String ONLY_NUMBER_REGEX = "^[0-9]+$"; - public static final String INPUT_CAR_MESSAGE = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"; - public static final String INPUT_MOVE_COUNTS_MESSAGE = "시도할 회수는 몇회인가요?"; - public List inputCars() { - System.out.println(INPUT_CAR_MESSAGE); + System.out.println(Message.INPUT_CAR_MESSAGE); String input = Console.readLine(); validateInputCars(input); String[] inputCars = input.split(CAR_REGEX); @@ -24,19 +21,19 @@ public List inputCars() { private void validateInputCars(String input) { if (input.endsWith(CAR_REGEX)) { - throw new IllegalArgumentException("자동차의 이름은 1~5자여야 합니다."); + throw new IllegalArgumentException(Message.CAR_NAME_VALIDATION); } String[] inputCars = input.split(CAR_REGEX); for (String inputCar : inputCars) { if (inputCar.length() > Car.MAX_NAME_LENGTH) { - throw new IllegalArgumentException("자동차의 이름은 1~5자여야 합니다."); + throw new IllegalArgumentException(Message.CAR_NAME_VALIDATION); } } } public int inputMoveCounts() { - System.out.println(INPUT_MOVE_COUNTS_MESSAGE); + System.out.println(Message.INPUT_MOVE_COUNTS_MESSAGE); String input = Console.readLine(); validateNumber(input); return Integer.parseInt(input); @@ -44,7 +41,7 @@ public int inputMoveCounts() { private void validateNumber(String input) { if (!Pattern.matches(ONLY_NUMBER_REGEX, input)) { - throw new IllegalArgumentException("숫자만 입력이 가능합니다."); + throw new IllegalArgumentException(Message.INPUT_NUMBER_ERROR); } } } diff --git a/src/main/java/racingcar/Message.java b/src/main/java/racingcar/Message.java new file mode 100644 index 000000000..ffd78d551 --- /dev/null +++ b/src/main/java/racingcar/Message.java @@ -0,0 +1,17 @@ +package racingcar; + +public class Message { + + public static final String CAR_NAME_VALIDATION = "자동차의 이름은 1~5자여야 합니다."; + public static final String CAR_FUEL_VALIDATION = "연료는 0 이상 9 이하의 값이어야 합니다."; + public static final String NUMBER_OF_CARS_VALIDATION = "등록할 자동차는 최소 1대여야 합니다."; + public static final String MOVE_COUNTS_VALIDATION = "이동횟수는 최소 1회 이상이어야 합니다."; + public static final String GAME_OVER = "경기가 종료되었습니다."; + + public static final String INPUT_CAR_MESSAGE = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"; + public static final String INPUT_MOVE_COUNTS_MESSAGE = "시도할 회수는 몇회인가요?"; + public static final String INPUT_NUMBER_ERROR = "숫자만 입력이 가능합니다."; + + public static final String OUTPUT_RACE_RESULT = "실행 결과"; + +} diff --git a/src/main/java/racingcar/OutputView.java b/src/main/java/racingcar/OutputView.java index ca4dd2732..bbb26c88b 100644 --- a/src/main/java/racingcar/OutputView.java +++ b/src/main/java/racingcar/OutputView.java @@ -1,15 +1,15 @@ package racingcar; import java.util.List; -import java.util.stream.Collectors; public class OutputView { public static final String CAR_FORMAT = "%s : %s"; public static final String MOVE_UNIT = "-"; public static final String DELIMITER = ", "; - public static final String RACE_START_MESSAGE = "실행 결과"; public static final String ERROR_SUFFIX = "[ERROR]"; + public static final String WINNER_FORMAT = "최종 우승자 : %s"; + public static final String ERROR_FORMAT = "%s %s\n"; public void printCars(List cars) { for (Car car : cars) { @@ -24,7 +24,7 @@ private void printNewLine() { public void printRaceStart() { printNewLine(); - System.out.println(RACE_START_MESSAGE); + System.out.println(Message.OUTPUT_RACE_RESULT); } private void printCar(Car car) { @@ -42,10 +42,10 @@ private String getMove(int currentPosition) { public void printWinners(List winners) { String winnersName = String.join(DELIMITER, winners); - System.out.printf("최종 우승자 : %s", winnersName); + System.out.printf(WINNER_FORMAT, winnersName); } public void printError(String errorMessage) { - System.out.printf("%s %s\n", ERROR_SUFFIX, errorMessage); + System.out.printf(ERROR_FORMAT, ERROR_SUFFIX, errorMessage); } } From a61b1a575fe695fc2801466a8855d5dcc9894d8b Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:28:38 +0900 Subject: [PATCH 36/42] =?UTF-8?q?perf(OutputView):=20=EA=B0=9C=ED=96=89=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EA=B0=9C=ED=96=89=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Message.java | 2 +- src/main/java/racingcar/OutputView.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/racingcar/Message.java b/src/main/java/racingcar/Message.java index ffd78d551..59008b9e6 100644 --- a/src/main/java/racingcar/Message.java +++ b/src/main/java/racingcar/Message.java @@ -12,6 +12,6 @@ public class Message { public static final String INPUT_MOVE_COUNTS_MESSAGE = "시도할 회수는 몇회인가요?"; public static final String INPUT_NUMBER_ERROR = "숫자만 입력이 가능합니다."; - public static final String OUTPUT_RACE_RESULT = "실행 결과"; + public static final String OUTPUT_RACE_RESULT = "\n실행 결과"; } diff --git a/src/main/java/racingcar/OutputView.java b/src/main/java/racingcar/OutputView.java index bbb26c88b..8543152d0 100644 --- a/src/main/java/racingcar/OutputView.java +++ b/src/main/java/racingcar/OutputView.java @@ -4,7 +4,7 @@ public class OutputView { - public static final String CAR_FORMAT = "%s : %s"; + public static final String CAR_FORMAT = "%s : %s\n"; public static final String MOVE_UNIT = "-"; public static final String DELIMITER = ", "; public static final String ERROR_SUFFIX = "[ERROR]"; @@ -23,13 +23,11 @@ private void printNewLine() { } public void printRaceStart() { - printNewLine(); System.out.println(Message.OUTPUT_RACE_RESULT); } private void printCar(Car car) { System.out.printf(CAR_FORMAT, car.getName(), getMove(car.getCurrentPosition())); - printNewLine(); } private String getMove(int currentPosition) { From dfd971455ab4f96a1ae096447ecbf19d90abdd1c Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:29:43 +0900 Subject: [PATCH 37/42] =?UTF-8?q?refactor(InputView,=20OutputView):=20view?= =?UTF-8?q?=20=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/MainController.java | 2 ++ src/main/java/racingcar/{ => view}/InputView.java | 4 +++- src/main/java/racingcar/{ => view}/OutputView.java | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) rename src/main/java/racingcar/{ => view}/InputView.java (95%) rename src/main/java/racingcar/{ => view}/OutputView.java (95%) diff --git a/src/main/java/racingcar/MainController.java b/src/main/java/racingcar/MainController.java index a387f4f46..4dbbe479a 100644 --- a/src/main/java/racingcar/MainController.java +++ b/src/main/java/racingcar/MainController.java @@ -1,6 +1,8 @@ package racingcar; import java.util.List; +import racingcar.view.InputView; +import racingcar.view.OutputView; public class MainController { diff --git a/src/main/java/racingcar/InputView.java b/src/main/java/racingcar/view/InputView.java similarity index 95% rename from src/main/java/racingcar/InputView.java rename to src/main/java/racingcar/view/InputView.java index 2e7787800..ae0cbbfb2 100644 --- a/src/main/java/racingcar/InputView.java +++ b/src/main/java/racingcar/view/InputView.java @@ -1,10 +1,12 @@ -package racingcar; +package racingcar.view; import camp.nextstep.edu.missionutils.Console; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; import java.util.stream.Collectors; +import racingcar.Car; +import racingcar.Message; public class InputView { diff --git a/src/main/java/racingcar/OutputView.java b/src/main/java/racingcar/view/OutputView.java similarity index 95% rename from src/main/java/racingcar/OutputView.java rename to src/main/java/racingcar/view/OutputView.java index 8543152d0..5d76a7da8 100644 --- a/src/main/java/racingcar/OutputView.java +++ b/src/main/java/racingcar/view/OutputView.java @@ -1,6 +1,8 @@ -package racingcar; +package racingcar.view; import java.util.List; +import racingcar.Car; +import racingcar.Message; public class OutputView { From b8fb51bc26d75d05dc87382230ccf943a3df3a2d Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:39:36 +0900 Subject: [PATCH 38/42] =?UTF-8?q?docs:=20=EA=B5=AC=ED=98=84=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=EC=97=90=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EC=88=9C=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 566c056d1..ba8eda45a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ -# 구현 기능 목록 +# 🚗 구현 기능 목록 ## 자동차 - [x] 각 자동차에 이름을 부여할 수 있다. @@ -23,10 +23,17 @@ - [x] **[예외처리]** 쉼표를 기준으로 나눴을 때 자동차 이름이 0보다 작거나 5보다 크면 예외처리한다. - [x] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. - [x] **[예외처리]** 이동 횟수는 숫자여야 한다. -- [x] **[예외처리]** 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. +- [x] 사용자가 잘못된 값을 입력할 경우 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. ## 출력 - [x] 자동차 이름과 자동차의 현재 위치를 출력한다. - [x] 최종 우승자를 출력한다. - [x] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. + +--- +## 동작 순서 +1. 경주에 등록할 자동차를 입력받는다. +2. 경주 시도 횟수를 입력받는다. +3. 시도 횟수 만큼 자동차가 전진하거나 멈춘다. +4. 경주가 종료되고 우승자를 알려준다. From a0eda973463647d378d6efc948eeb961d772f1e0 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:49:37 +0900 Subject: [PATCH 39/42] =?UTF-8?q?feat(MainController):=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EB=B0=9C=EC=83=9D=EC=8B=9C=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/MainController.java | 30 +++++++++------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/java/racingcar/MainController.java b/src/main/java/racingcar/MainController.java index 4dbbe479a..6b389a065 100644 --- a/src/main/java/racingcar/MainController.java +++ b/src/main/java/racingcar/MainController.java @@ -24,28 +24,22 @@ public void run() { } private void registerCars() { - while (true) { - try { - List inputCars = inputView.inputCars(); - carGame.registerCar(inputCars); - } catch (IllegalArgumentException e) { - outputView.printError(e.getMessage()); - continue; - } - break; + try { + List inputCars = inputView.inputCars(); + carGame.registerCar(inputCars); + } catch (IllegalArgumentException e) { + outputView.printError(e.getMessage()); + registerCars(); } } private void registerMoveCounts() { - while (true) { - try { - int moveCounts = inputView.inputMoveCounts(); - carGame.registerMoveCounts(moveCounts); - } catch (IllegalArgumentException e) { - outputView.printError(e.getMessage()); - continue; - } - break; + try { + int moveCounts = inputView.inputMoveCounts(); + carGame.registerMoveCounts(moveCounts); + } catch (IllegalArgumentException e) { + outputView.printError(e.getMessage()); + registerMoveCounts(); } } From 5e3d7d3d0c066d4aed244c0530483077dc3fec00 Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 17:57:43 +0900 Subject: [PATCH 40/42] =?UTF-8?q?refactor(CarTest):=20=EA=B3=84=EC=B8=B5?= =?UTF-8?q?=ED=98=95=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/racingcar/CarTest.java | 72 +++++++++++++++++++--------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/src/test/java/racingcar/CarTest.java b/src/test/java/racingcar/CarTest.java index fe9e957de..8e666d8ae 100644 --- a/src/test/java/racingcar/CarTest.java +++ b/src/test/java/racingcar/CarTest.java @@ -5,35 +5,61 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +@DisplayName("Car 클래스") class CarTest { - @Test - @DisplayName("자동차의 이름은 5자 이하여야 한다.") - void 자동차_이름_유효성_성공_테스트() { - Car fives = new Car("fives"); - assertThat(fives).isNotNull(); - } + @Nested + @DisplayName("자동차 이름 유효성 검사") + class Describe_Car_Init { + + @Test + @DisplayName("이름이 5자 이하면 초기화 성공") + void 성공_테스트() { + Car fives = new Car("fives"); + assertThat(fives).isNotNull(); + } - @Test - @DisplayName("자동차의 이름은 5자 초과이면 예외처리한다.") - void 자동차_이름_유효성_실패_테스트() { - //given - assertThatThrownBy(() -> new Car("sixCar")) - .isInstanceOf(IllegalArgumentException.class); + @Test + @DisplayName("이름이 5자 초과이면 예외처리한다.") + void 실패_테스트() { + //given + assertThatThrownBy(() -> new Car("sixCar")) + .isInstanceOf(IllegalArgumentException.class); + } } - @Test - @DisplayName("들어온 값이 4이상이면 전진한다.") - void 자동차_전진_테스트() { - //given - Car pobi = new Car("pobi"); - //when - int prePosition = pobi.getCurrentPosition(); - pobi.moveOrStop(4); - //then - int currentPostion = pobi.getCurrentPosition(); - assertThat(prePosition + 1).isEqualTo(currentPostion); + @Nested + @DisplayName("전진 테스트") + class Describe_MoveOrStop { + + @Test + @DisplayName("들어온 값이 4 이상이면 전진한다.") + void 자동차_전진_테스트() { + //given + Car pobi = new Car("pobi"); + //when + int prePosition = pobi.getCurrentPosition(); + pobi.moveOrStop(4); + //then + int currentPostion = pobi.getCurrentPosition(); + assertThat(prePosition + 1).isEqualTo(currentPostion); + } + + @Test + @DisplayName("들어온 값이 4 미만이면 정지한다.") + void 자동차_정지_테스트() { + //given + Car pobi = new Car("pobi"); + //when + int prePosition = pobi.getCurrentPosition(); + pobi.moveOrStop(3); + //then + int currentPostion = pobi.getCurrentPosition(); + assertThat(prePosition).isEqualTo(currentPostion); + } } + } From bc56861bcfae4738615d01caf4650b3d724a34ed Mon Sep 17 00:00:00 2001 From: This2sho Date: Thu, 1 Dec 2022 18:00:24 +0900 Subject: [PATCH 41/42] =?UTF-8?q?refactor(CarGameTest):=20=EA=B3=84?= =?UTF-8?q?=EC=B8=B5=ED=98=95=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/racingcar/CarGameTest.java | 51 ++++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/test/java/racingcar/CarGameTest.java b/src/test/java/racingcar/CarGameTest.java index b493b30f6..f9ceeb48c 100644 --- a/src/test/java/racingcar/CarGameTest.java +++ b/src/test/java/racingcar/CarGameTest.java @@ -10,8 +10,10 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +@DisplayName("CarGame 클래스") class CarGameTest { private CarGame carGame; @@ -20,30 +22,35 @@ void init() { carGame = new CarGame(); } - @Test - @DisplayName("자동차 경주 자동차 등록 성공 테스트") - void 자동차_등록_성공_테스트() { - //when - List cars = Arrays.asList("pobi", "woni", "jun"); - carGame.registerCar(cars); - //then - List carNames = carGame.getCars() - .stream() - .map(Car::getName) - .collect(Collectors.toList()); + @Nested + @DisplayName("자동차 등록") + class Describe_Register { - assertThat(carNames) - .contains("pobi", "woni", "jun"); - } + @Test + @DisplayName("성공 테스트") + void 자동차_등록_성공_테스트() { + //when + List cars = Arrays.asList("pobi", "woni", "jun"); + carGame.registerCar(cars); + //then + List carNames = carGame.getCars() + .stream() + .map(Car::getName) + .collect(Collectors.toList()); - @Test - @DisplayName("자동차 경주 자동차 등록 실패 테스트") - void 자동차_등록_실패_테스트() { - //when - List cars = new ArrayList<>(); - //then - assertThatThrownBy(() -> carGame.registerCar(cars)) - .isInstanceOf(IllegalArgumentException.class); + assertThat(carNames) + .contains("pobi", "woni", "jun"); + } + + @Test + @DisplayName("실패시 에러발생") + void 자동차_등록_실패_테스트() { + //when + List cars = new ArrayList<>(); + //then + assertThatThrownBy(() -> carGame.registerCar(cars)) + .isInstanceOf(IllegalArgumentException.class); + } } @Test From 2cff2fa4e3d4a9a62bf1ba7c0812f6637671a230 Mon Sep 17 00:00:00 2001 From: This2sho Date: Tue, 6 Dec 2022 19:50:38 +0900 Subject: [PATCH 42/42] =?UTF-8?q?refactor(MainController):=20=EB=B0=98?= =?UTF-8?q?=EB=B3=B5=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=20try-catch=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/MainController.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/racingcar/MainController.java b/src/main/java/racingcar/MainController.java index 6b389a065..182d680e0 100644 --- a/src/main/java/racingcar/MainController.java +++ b/src/main/java/racingcar/MainController.java @@ -1,6 +1,7 @@ package racingcar; import java.util.List; +import java.util.function.Supplier; import racingcar.view.InputView; import racingcar.view.OutputView; @@ -24,23 +25,22 @@ public void run() { } private void registerCars() { + List inputCars = repeat(inputView::inputCars); + carGame.registerCar(inputCars); + } + + private T repeat(Supplier inputReader) { try { - List inputCars = inputView.inputCars(); - carGame.registerCar(inputCars); + return inputReader.get(); } catch (IllegalArgumentException e) { outputView.printError(e.getMessage()); - registerCars(); + return repeat(inputReader); } } private void registerMoveCounts() { - try { - int moveCounts = inputView.inputMoveCounts(); - carGame.registerMoveCounts(moveCounts); - } catch (IllegalArgumentException e) { - outputView.printError(e.getMessage()); - registerMoveCounts(); - } + int moveCounts = repeat(inputView::inputMoveCounts); + carGame.registerMoveCounts(moveCounts); } private void startRace() {