From 4bce6c40cc8cd548c0ce290999c90bebcadc308b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 15:26:34 +0900 Subject: [PATCH 01/22] =?UTF-8?q?docs(README):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=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 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..610cb5997d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,15 @@ +## 기능 목록 +- [ ] 자동차 이름 입력 받기 + - [ ] 쉼표로 구분 됐는지 입력값 검증 + - [ ] 잘못된 입력의 경우 에러 문구 출력 + - [ ] 이름의 길이가 5자 이하인지 검증 + - [ ] 5자 초과의 경우 에러 문구 출력 + - [ ] 중복되는 이름이 있는지 검증 + - [ ] 중복시 에러 문구 출력 +- [ ] 시도 회수 입력 받기 +- [ ] 자동차 이동 + - [ ] 차수별 이동 + - [ ] 차수별 현황 출력 +- [ ] 최종 우승자 선정 + - [ ] 최종 우승자 안내 문구 출력 + - [ ] 공동 우승자의 경우 ", " 로 구분하여 출력 From 06115e805df965b13dcec8251c4a44e5c2c74671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:09:35 +0900 Subject: [PATCH 02/22] =?UTF-8?q?feat(CarController):=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 4 ++++ src/main/java/racingcar/Application.java | 4 +++- .../java/racingcar/controller/CarController.java | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/controller/CarController.java diff --git a/docs/README.md b/docs/README.md index 610cb5997d..72a6859251 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,3 +13,7 @@ - [ ] 최종 우승자 선정 - [ ] 최종 우승자 안내 문구 출력 - [ ] 공동 우승자의 경우 ", " 로 구분하여 출력 + +## 구현 클래스 목록 +- CarController + - play() diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index b9ed0456a3..e65cdf9d99 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,9 @@ package racingcar; +import racingcar.controller.CarController; + public class Application { public static void main(String[] args) { - // TODO 구현 진행 + new CarController().play(); } } diff --git a/src/main/java/racingcar/controller/CarController.java b/src/main/java/racingcar/controller/CarController.java new file mode 100644 index 0000000000..22ba4f1cbe --- /dev/null +++ b/src/main/java/racingcar/controller/CarController.java @@ -0,0 +1,16 @@ +package racingcar.controller; + +import racingcar.io.InputManager; +import racingcar.io.OutputView; +import racingcar.service.CarService; + +public class CarController { + + private final InputManager inputManager = new InputManager(); + private final OutputView outputView = new OutputView(); + private final CarService carService = new CarService(); + + public void play() { + inputManager.readCars(); + } +} From 61fc03e3077b2ebda4d8eb13acb887b820334c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:10:18 +0900 Subject: [PATCH 03/22] =?UTF-8?q?feat(InputValidator):=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=B0=A8=20=EC=9E=85=EB=A0=A5=EA=B0=92=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/io/InputValidator.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/racingcar/io/InputValidator.java diff --git a/src/main/java/racingcar/io/InputValidator.java b/src/main/java/racingcar/io/InputValidator.java new file mode 100644 index 0000000000..cde7ea8622 --- /dev/null +++ b/src/main/java/racingcar/io/InputValidator.java @@ -0,0 +1,13 @@ +package racingcar.io; + +import racingcar.constant.ErrorMessage; + +public class InputValidator { + private static final String CAR_DELIMITER = ","; + + public void validateCars(final String input) { + if (input.startsWith(CAR_DELIMITER) || input.endsWith(CAR_DELIMITER)) { + throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_INPUT.getMessage()); + } + } +} From 776bd52b977418f96e59afb2b0047191ee325412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:10:40 +0900 Subject: [PATCH 04/22] =?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?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/io/InputView.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/racingcar/io/InputView.java diff --git a/src/main/java/racingcar/io/InputView.java b/src/main/java/racingcar/io/InputView.java new file mode 100644 index 0000000000..8162667ef9 --- /dev/null +++ b/src/main/java/racingcar/io/InputView.java @@ -0,0 +1,17 @@ +package racingcar.io; + +import camp.nextstep.edu.missionutils.Console; + +import java.util.List; + +public class InputView { + + private final InputValidator inputValidator = new InputValidator(); + + + public String readCars() { + final String input = Console.readLine(); + inputValidator.validateCars(input); + return input; + } +} From 2b98a8b05d32907cc9151beb0b25acbc43ae288d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:11:47 +0900 Subject: [PATCH 05/22] =?UTF-8?q?feat(InputManager):=20=EC=9E=98=EB=AA=BB?= =?UTF-8?q?=EB=90=9C=20=EC=9E=85=EB=A0=A5=EC=8B=9C=20=EC=9E=AC=EC=8B=9C?= =?UTF-8?q?=EB=8F=84=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 9 ++++++ src/main/java/racingcar/io/InputManager.java | 32 ++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/main/java/racingcar/io/InputManager.java diff --git a/docs/README.md b/docs/README.md index 72a6859251..74470fd0ad 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,3 +17,12 @@ ## 구현 클래스 목록 - CarController - play() + +- InputView + - readCars() + +- InputManager + - readCars() + +- InputValidator + - validateCars() diff --git a/src/main/java/racingcar/io/InputManager.java b/src/main/java/racingcar/io/InputManager.java new file mode 100644 index 0000000000..5286012263 --- /dev/null +++ b/src/main/java/racingcar/io/InputManager.java @@ -0,0 +1,32 @@ +package racingcar.io; + +import racingcar.domain.Car; +import racingcar.domain.Cars; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class InputManager { + + private static final String CAR_DELIMITER = ","; + private final InputView inputView = new InputView(); + + public Cars readCars() { + return read(() -> { + final List cars = Arrays.stream(inputView.readCars().split(CAR_DELIMITER)).map(Car::new).collect(Collectors.toList()); + return new Cars(cars); + }); + } + + private T read(final Supplier supplier) { + while (true) { + try { + return supplier.get(); + } catch (final IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } +} From e032b0f77495950674b1582d17ff3192dc4e51c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:12:15 +0900 Subject: [PATCH 06/22] =?UTF-8?q?feat(ErrorMessage):=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=97=B4=EA=B1=B0=ED=98=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 3 +++ .../java/racingcar/constant/ErrorMessage.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/main/java/racingcar/constant/ErrorMessage.java diff --git a/docs/README.md b/docs/README.md index 74470fd0ad..69e6d42bd3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,3 +26,6 @@ - InputValidator - validateCars() + +## 열거형 목록 +- ErrorMessage \ No newline at end of file diff --git a/src/main/java/racingcar/constant/ErrorMessage.java b/src/main/java/racingcar/constant/ErrorMessage.java new file mode 100644 index 0000000000..9ab732822c --- /dev/null +++ b/src/main/java/racingcar/constant/ErrorMessage.java @@ -0,0 +1,17 @@ +package racingcar.constant; + +public enum ErrorMessage { + INVALID_CAR_INPUT("자동차 이름을 입력할 시 쉼표로 구분해야 합니다."), + INVALID_CARS_NUM("자동차 이름에 중복이 있습니다."); + + private static final String ERROR_PREFIX = "[ERROR] "; + private final String message; + + ErrorMessage(final String message) { + this.message = message; + } + + public String getMessage() { + return ERROR_PREFIX + this.message; + } +} From abc07917443c962bf36d3ba9fdcded8952a7ecd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:15:19 +0900 Subject: [PATCH 07/22] =?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=EA=B8=B8=EC=9D=B4=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 14 ++++++++----- src/main/java/racingcar/Car.java | 12 ----------- .../java/racingcar/constant/ErrorMessage.java | 3 ++- src/main/java/racingcar/domain/Car.java | 20 +++++++++++++++++++ 4 files changed, 31 insertions(+), 18 deletions(-) delete mode 100644 src/main/java/racingcar/Car.java create mode 100644 src/main/java/racingcar/domain/Car.java diff --git a/docs/README.md b/docs/README.md index 69e6d42bd3..37a3a6abd2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,9 @@ ## 기능 목록 -- [ ] 자동차 이름 입력 받기 - - [ ] 쉼표로 구분 됐는지 입력값 검증 - - [ ] 잘못된 입력의 경우 에러 문구 출력 - - [ ] 이름의 길이가 5자 이하인지 검증 - - [ ] 5자 초과의 경우 에러 문구 출력 +- [x] 자동차 이름 입력 받기 + - [x] 쉼표로 구분 됐는지 입력값 검증 + - [x] 잘못된 입력의 경우 에러 문구 출력 + - [x] 이름의 길이가 5자 이하인지 검증 + - [x] 5자 초과의 경우 에러 문구 출력 - [ ] 중복되는 이름이 있는지 검증 - [ ] 중복시 에러 문구 출력 - [ ] 시도 회수 입력 받기 @@ -27,5 +27,9 @@ - InputValidator - validateCars() +- Car + +- Cars + ## 열거형 목록 - ErrorMessage \ No newline at end of file diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java deleted file mode 100644 index ab3df94921..0000000000 --- a/src/main/java/racingcar/Car.java +++ /dev/null @@ -1,12 +0,0 @@ -package racingcar; - -public class Car { - private final String name; - private int position = 0; - - public Car(String name) { - this.name = name; - } - - // 추가 기능 구현 -} diff --git a/src/main/java/racingcar/constant/ErrorMessage.java b/src/main/java/racingcar/constant/ErrorMessage.java index 9ab732822c..747f9b7189 100644 --- a/src/main/java/racingcar/constant/ErrorMessage.java +++ b/src/main/java/racingcar/constant/ErrorMessage.java @@ -2,7 +2,8 @@ public enum ErrorMessage { INVALID_CAR_INPUT("자동차 이름을 입력할 시 쉼표로 구분해야 합니다."), - INVALID_CARS_NUM("자동차 이름에 중복이 있습니다."); + INVALID_CARS_NUM("자동차 이름에 중복이 있습니다."), + INVALID_CAR_NAME_LENGTH("자동차 이름의 길이가 잘못됐습니다."); private static final String ERROR_PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java new file mode 100644 index 0000000000..9025499198 --- /dev/null +++ b/src/main/java/racingcar/domain/Car.java @@ -0,0 +1,20 @@ +package racingcar.domain; + +import racingcar.constant.ErrorMessage; + +public class Car { + private static final Integer MAX_SIZE = 5; + private final String name; + private int position = 0; + + public Car(final String name) { + validateName(name); + this.name = name; + } + + private void validateName(final String name) { + if (name.length() > 5) { + throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_NAME_LENGTH.getMessage()); + } + } +} From 8f49343f2391b8da3d679aafe7cdc9a0e94deec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:16:08 +0900 Subject: [PATCH 08/22] =?UTF-8?q?feat(Cars):=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=20=EC=A4=91=EB=B3=B5=20=EC=9D=B4=EB=A6=84=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/domain/Car.java | 17 ++++++++++++++++- src/main/java/racingcar/domain/Cars.java | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/domain/Cars.java diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index 9025499198..d03553679d 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -2,6 +2,8 @@ import racingcar.constant.ErrorMessage; +import java.util.Objects; + public class Car { private static final Integer MAX_SIZE = 5; private final String name; @@ -13,8 +15,21 @@ public Car(final String name) { } private void validateName(final String name) { - if (name.length() > 5) { + if (name.length() > MAX_SIZE) { throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_NAME_LENGTH.getMessage()); } } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Car car = (Car) o; + return position == car.position && Objects.equals(name, car.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, position); + } } diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java new file mode 100644 index 0000000000..0fae133a14 --- /dev/null +++ b/src/main/java/racingcar/domain/Cars.java @@ -0,0 +1,21 @@ +package racingcar.domain; + +import racingcar.constant.ErrorMessage; + +import java.util.HashSet; +import java.util.List; + +public class Cars { + private final List cars; + + public Cars(final List cars) { + validateUnique(cars); + this.cars = cars; + } + + private void validateUnique(final List cars) { + if (new HashSet<>(cars).size() != cars.size()) { + throw new IllegalArgumentException(ErrorMessage.INVALID_CARS_NUM.getMessage()); + } + } +} From 3c5b96ff458ba11e844b2aeb8e00e9ea08e3acbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:20:11 +0900 Subject: [PATCH 09/22] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 13 ++++++++----- .../java/racingcar/constant/GameMessage.java | 16 ++++++++++++++++ .../java/racingcar/controller/CarController.java | 5 ++++- src/main/java/racingcar/io/OutputView.java | 9 +++++++++ 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 src/main/java/racingcar/constant/GameMessage.java create mode 100644 src/main/java/racingcar/io/OutputView.java diff --git a/docs/README.md b/docs/README.md index 37a3a6abd2..81b587e532 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,11 +1,13 @@ ## 기능 목록 +- [x] 자동차 이름 요청 메시지 출력 - [x] 자동차 이름 입력 받기 - [x] 쉼표로 구분 됐는지 입력값 검증 - - [x] 잘못된 입력의 경우 에러 문구 출력 + - [x] 잘못된 입력의 경우 에러 문구 출력 및 재시도 - [x] 이름의 길이가 5자 이하인지 검증 - - [x] 5자 초과의 경우 에러 문구 출력 - - [ ] 중복되는 이름이 있는지 검증 - - [ ] 중복시 에러 문구 출력 + - [x] 5자 초과의 경우 에러 문구 출력 및 재시도 + - [x] 중복되는 이름이 있는지 검증 + - [x] 중복시 에러 문구 출력 및 재시도 +- [ ] 시도 회수 요청 메시지 출력 - [ ] 시도 회수 입력 받기 - [ ] 자동차 이동 - [ ] 차수별 이동 @@ -32,4 +34,5 @@ - Cars ## 열거형 목록 -- ErrorMessage \ No newline at end of file +- ErrorMessage +- GameMessage \ No newline at end of file diff --git a/src/main/java/racingcar/constant/GameMessage.java b/src/main/java/racingcar/constant/GameMessage.java new file mode 100644 index 0000000000..3afb308185 --- /dev/null +++ b/src/main/java/racingcar/constant/GameMessage.java @@ -0,0 +1,16 @@ +package racingcar.constant; + +public enum GameMessage { + CAR_INPUT_REQUEST("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), + TRY_COUNT_REQUEST("시도할 회수는 몇회인가요?"); + + private final String message; + + GameMessage(final String message) { + this.message = message; + } + + public String getMessage() { + return this.message; + } +} diff --git a/src/main/java/racingcar/controller/CarController.java b/src/main/java/racingcar/controller/CarController.java index 22ba4f1cbe..cafed6f56c 100644 --- a/src/main/java/racingcar/controller/CarController.java +++ b/src/main/java/racingcar/controller/CarController.java @@ -1,5 +1,6 @@ package racingcar.controller; +import racingcar.domain.Cars; import racingcar.io.InputManager; import racingcar.io.OutputView; import racingcar.service.CarService; @@ -11,6 +12,8 @@ public class CarController { private final CarService carService = new CarService(); public void play() { - inputManager.readCars(); + outputView.printCarRequest(); + final Cars cars = inputManager.readCars(); + } } diff --git a/src/main/java/racingcar/io/OutputView.java b/src/main/java/racingcar/io/OutputView.java new file mode 100644 index 0000000000..5c7c65cec1 --- /dev/null +++ b/src/main/java/racingcar/io/OutputView.java @@ -0,0 +1,9 @@ +package racingcar.io; + +import racingcar.constant.GameMessage; + +public class OutputView { + public void printCarRequest() { + System.out.println(GameMessage.CAR_INPUT_REQUEST.getMessage()); + } +} From d13c52e418f43b77a5b68ef4a8b48564701e5674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:22:51 +0900 Subject: [PATCH 10/22] =?UTF-8?q?feat(CarRepository):=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EC=86=8C=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 11 ++++++++++- .../java/racingcar/repository/CarRepository.java | 12 ++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/repository/CarRepository.java diff --git a/docs/README.md b/docs/README.md index 81b587e532..9ed1f1bdd8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,6 +33,15 @@ - Cars +- OutputView + - printCarRequest() + +- CarService + - saveCars() + +- CarRepository + - saveCars() + ## 열거형 목록 - ErrorMessage -- GameMessage \ No newline at end of file +- GameMessage diff --git a/src/main/java/racingcar/repository/CarRepository.java b/src/main/java/racingcar/repository/CarRepository.java new file mode 100644 index 0000000000..18e39e6693 --- /dev/null +++ b/src/main/java/racingcar/repository/CarRepository.java @@ -0,0 +1,12 @@ +package racingcar.repository; + +import racingcar.domain.Cars; + +public class CarRepository { + + private Cars cars; + + public void saveCars(final Cars cars) { + this.cars = cars; + } +} From f8e024864cc000aab16f0040f94abd6cb42a2547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:23:21 +0900 Subject: [PATCH 11/22] =?UTF-8?q?feat(CarService):=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/service/CarService.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/racingcar/service/CarService.java diff --git a/src/main/java/racingcar/service/CarService.java b/src/main/java/racingcar/service/CarService.java new file mode 100644 index 0000000000..24b785b8c4 --- /dev/null +++ b/src/main/java/racingcar/service/CarService.java @@ -0,0 +1,12 @@ +package racingcar.service; + +import racingcar.domain.Cars; +import racingcar.repository.CarRepository; + +public class CarService { + private final CarRepository carRepository = new CarRepository(); + + public void saveCars(final Cars cars) { + carRepository.saveCars(cars); + } +} From eec4568dacde4ed260f027c3db42005d816cdbed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:25:24 +0900 Subject: [PATCH 12/22] =?UTF-8?q?feat:=20=EC=8B=9C=EB=8F=84=20=ED=9A=8C?= =?UTF-8?q?=EC=88=98=20=EC=9A=94=EC=B2=AD=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 3 ++- src/main/java/racingcar/controller/CarController.java | 11 ++++++++++- src/main/java/racingcar/io/OutputView.java | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 9ed1f1bdd8..eb8439b1a0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ - [x] 5자 초과의 경우 에러 문구 출력 및 재시도 - [x] 중복되는 이름이 있는지 검증 - [x] 중복시 에러 문구 출력 및 재시도 -- [ ] 시도 회수 요청 메시지 출력 +- [x] 시도 회수 요청 메시지 출력 - [ ] 시도 회수 입력 받기 - [ ] 자동차 이동 - [ ] 차수별 이동 @@ -35,6 +35,7 @@ - OutputView - printCarRequest() + - printTryCountRequest() - CarService - saveCars() diff --git a/src/main/java/racingcar/controller/CarController.java b/src/main/java/racingcar/controller/CarController.java index cafed6f56c..639a7b1de8 100644 --- a/src/main/java/racingcar/controller/CarController.java +++ b/src/main/java/racingcar/controller/CarController.java @@ -12,8 +12,17 @@ public class CarController { private final CarService carService = new CarService(); public void play() { + createCars(); + createTryCount(); + } + + private void createTryCount() { + outputView.printTryCountRequest(); + } + + private void createCars() { outputView.printCarRequest(); final Cars cars = inputManager.readCars(); - + carService.saveCars(cars); } } diff --git a/src/main/java/racingcar/io/OutputView.java b/src/main/java/racingcar/io/OutputView.java index 5c7c65cec1..6b6a5657b4 100644 --- a/src/main/java/racingcar/io/OutputView.java +++ b/src/main/java/racingcar/io/OutputView.java @@ -6,4 +6,8 @@ public class OutputView { public void printCarRequest() { System.out.println(GameMessage.CAR_INPUT_REQUEST.getMessage()); } + + public void printTryCountRequest() { + System.out.println(GameMessage.TRY_COUNT_REQUEST.getMessage()); + } } From 11359318f3e87e27f26ece0ade5ab481d268ba89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:32:10 +0900 Subject: [PATCH 13/22] =?UTF-8?q?feat(TryCount):=20=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 8 +++++++- src/main/java/racingcar/domain/TryCount.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/domain/TryCount.java diff --git a/docs/README.md b/docs/README.md index eb8439b1a0..89203878f9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,7 +8,8 @@ - [x] 중복되는 이름이 있는지 검증 - [x] 중복시 에러 문구 출력 및 재시도 - [x] 시도 회수 요청 메시지 출력 -- [ ] 시도 회수 입력 받기 +- [x] 시도 회수 입력 받기 + - [x] 입력값 숫자인지 검증 - [ ] 자동차 이동 - [ ] 차수별 이동 - [ ] 차수별 현황 출력 @@ -22,12 +23,15 @@ - InputView - readCars() + - readTryCount() - InputManager - readCars() + - readTryCount() - InputValidator - validateCars() + - validateTryCount() - Car @@ -43,6 +47,8 @@ - CarRepository - saveCars() +- TryCount + ## 열거형 목록 - ErrorMessage - GameMessage diff --git a/src/main/java/racingcar/domain/TryCount.java b/src/main/java/racingcar/domain/TryCount.java new file mode 100644 index 0000000000..f87d97a3ae --- /dev/null +++ b/src/main/java/racingcar/domain/TryCount.java @@ -0,0 +1,10 @@ +package racingcar.domain; + +public class TryCount { + + private final Integer tryCount; + + public TryCount(final Integer tryCount) { + this.tryCount = tryCount; + } +} From d7c8af0c248984786d8454729664a766163db8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:32:49 +0900 Subject: [PATCH 14/22] =?UTF-8?q?feat(InputValidator):=20=EC=8B=9C?= =?UTF-8?q?=EB=8F=84=20=ED=9A=9F=EC=88=98=20=EC=9E=85=EB=A0=A5=EA=B0=92=20?= =?UTF-8?q?=EC=88=AB=EC=9E=90=EC=9D=B8=EC=A7=80=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/io/InputValidator.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/racingcar/io/InputValidator.java b/src/main/java/racingcar/io/InputValidator.java index cde7ea8622..0ba3c10683 100644 --- a/src/main/java/racingcar/io/InputValidator.java +++ b/src/main/java/racingcar/io/InputValidator.java @@ -3,11 +3,20 @@ import racingcar.constant.ErrorMessage; public class InputValidator { + private static final String CAR_DELIMITER = ","; + private static final Character MIN_NUMBER = '0'; + private static final Character MAX_NUMBER = '9'; public void validateCars(final String input) { if (input.startsWith(CAR_DELIMITER) || input.endsWith(CAR_DELIMITER)) { throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_INPUT.getMessage()); } } + + public void validateTryCount(final String input) { + if (input.chars().anyMatch(c -> MIN_NUMBER < c || c < MAX_NUMBER)) { + throw new IllegalArgumentException(ErrorMessage.INVALID_TRY_COUNT_INPUT.getMessage()); + } + } } From aad9b4d5b52ffb7c0f34ba4c774da4b13f5141e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:33:18 +0900 Subject: [PATCH 15/22] =?UTF-8?q?feat(InputView):=20=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EC=9E=85=EB=A0=A5=20=EB=B0=8F=20=EC=9E=AC?= =?UTF-8?q?=EC=8B=9C=EB=8F=84=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/constant/ErrorMessage.java | 3 ++- src/main/java/racingcar/io/InputManager.java | 5 +++++ src/main/java/racingcar/io/InputView.java | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/constant/ErrorMessage.java b/src/main/java/racingcar/constant/ErrorMessage.java index 747f9b7189..f6852e042f 100644 --- a/src/main/java/racingcar/constant/ErrorMessage.java +++ b/src/main/java/racingcar/constant/ErrorMessage.java @@ -3,7 +3,8 @@ public enum ErrorMessage { INVALID_CAR_INPUT("자동차 이름을 입력할 시 쉼표로 구분해야 합니다."), INVALID_CARS_NUM("자동차 이름에 중복이 있습니다."), - INVALID_CAR_NAME_LENGTH("자동차 이름의 길이가 잘못됐습니다."); + INVALID_CAR_NAME_LENGTH("자동차 이름의 길이가 잘못됐습니다."), + INVALID_TRY_COUNT_INPUT("시도 회수의 입력값은 숫자만 가능합니다."); private static final String ERROR_PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/racingcar/io/InputManager.java b/src/main/java/racingcar/io/InputManager.java index 5286012263..a5e90edac5 100644 --- a/src/main/java/racingcar/io/InputManager.java +++ b/src/main/java/racingcar/io/InputManager.java @@ -2,6 +2,7 @@ import racingcar.domain.Car; import racingcar.domain.Cars; +import racingcar.domain.TryCount; import java.util.Arrays; import java.util.List; @@ -20,6 +21,10 @@ public Cars readCars() { }); } + public TryCount readTryCount() { + return read(() -> new TryCount(Integer.parseInt(inputView.readTryCount()))); + } + private T read(final Supplier supplier) { while (true) { try { diff --git a/src/main/java/racingcar/io/InputView.java b/src/main/java/racingcar/io/InputView.java index 8162667ef9..2cd99e6b05 100644 --- a/src/main/java/racingcar/io/InputView.java +++ b/src/main/java/racingcar/io/InputView.java @@ -14,4 +14,10 @@ public String readCars() { inputValidator.validateCars(input); return input; } + + public String readTryCount() { + final String input = Console.readLine(); + inputValidator.validateTryCount(input); + return input; + } } From 0341e584a376eb968c01b71d35b0eadb71cf1bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:34:46 +0900 Subject: [PATCH 16/22] =?UTF-8?q?feat:=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EC=A0=80=EC=9E=A5=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 2 ++ src/main/java/racingcar/controller/CarController.java | 3 +++ src/main/java/racingcar/repository/CarRepository.java | 6 ++++++ src/main/java/racingcar/service/CarService.java | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/docs/README.md b/docs/README.md index 89203878f9..0dacd335bb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -43,9 +43,11 @@ - CarService - saveCars() + - saveTryCount() - CarRepository - saveCars() + - saveTryCount() - TryCount diff --git a/src/main/java/racingcar/controller/CarController.java b/src/main/java/racingcar/controller/CarController.java index 639a7b1de8..c8453f77dd 100644 --- a/src/main/java/racingcar/controller/CarController.java +++ b/src/main/java/racingcar/controller/CarController.java @@ -1,6 +1,7 @@ package racingcar.controller; import racingcar.domain.Cars; +import racingcar.domain.TryCount; import racingcar.io.InputManager; import racingcar.io.OutputView; import racingcar.service.CarService; @@ -18,6 +19,8 @@ public void play() { private void createTryCount() { outputView.printTryCountRequest(); + final TryCount tryCount = inputManager.readTryCount(); + carService.saveTryCount(tryCount); } private void createCars() { diff --git a/src/main/java/racingcar/repository/CarRepository.java b/src/main/java/racingcar/repository/CarRepository.java index 18e39e6693..c9d451ef1e 100644 --- a/src/main/java/racingcar/repository/CarRepository.java +++ b/src/main/java/racingcar/repository/CarRepository.java @@ -1,12 +1,18 @@ package racingcar.repository; import racingcar.domain.Cars; +import racingcar.domain.TryCount; public class CarRepository { private Cars cars; + private TryCount tryCount; public void saveCars(final Cars cars) { this.cars = cars; } + + public void saveTryCount(final TryCount tryCount) { + this.tryCount = tryCount; + } } diff --git a/src/main/java/racingcar/service/CarService.java b/src/main/java/racingcar/service/CarService.java index 24b785b8c4..f043788171 100644 --- a/src/main/java/racingcar/service/CarService.java +++ b/src/main/java/racingcar/service/CarService.java @@ -1,6 +1,7 @@ package racingcar.service; import racingcar.domain.Cars; +import racingcar.domain.TryCount; import racingcar.repository.CarRepository; public class CarService { @@ -9,4 +10,8 @@ public class CarService { public void saveCars(final Cars cars) { carRepository.saveCars(cars); } + + public void saveTryCount(final TryCount tryCount) { + carRepository.saveTryCount(tryCount); + } } From fdbc536314ed7d06709f286fec21e01fc9308eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 16:40:35 +0900 Subject: [PATCH 17/22] =?UTF-8?q?feat:=20=EB=9E=9C=EB=8D=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EC=97=AC=EB=B6=80=20=EC=83=9D=EC=84=B1=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 1 + src/main/java/racingcar/constant/MoveStatus.java | 14 ++++++++++++++ .../java/racingcar/utils/RandomMoveGenerator.java | 15 +++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 src/main/java/racingcar/constant/MoveStatus.java create mode 100644 src/main/java/racingcar/utils/RandomMoveGenerator.java diff --git a/docs/README.md b/docs/README.md index 0dacd335bb..967ade01a1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -54,3 +54,4 @@ ## 열거형 목록 - ErrorMessage - GameMessage +- MoveStatus diff --git a/src/main/java/racingcar/constant/MoveStatus.java b/src/main/java/racingcar/constant/MoveStatus.java new file mode 100644 index 0000000000..d3f1f15eff --- /dev/null +++ b/src/main/java/racingcar/constant/MoveStatus.java @@ -0,0 +1,14 @@ +package racingcar.constant; + +public enum MoveStatus { + MOVE, STOP; + + private static final Integer moveDivider = 4; + + public static MoveStatus getMoveStatus(final int randomNumber) { + if (moveDivider <= randomNumber) { + return MOVE; + } + return STOP; + } +} diff --git a/src/main/java/racingcar/utils/RandomMoveGenerator.java b/src/main/java/racingcar/utils/RandomMoveGenerator.java new file mode 100644 index 0000000000..606826c9d7 --- /dev/null +++ b/src/main/java/racingcar/utils/RandomMoveGenerator.java @@ -0,0 +1,15 @@ +package racingcar.utils; + +import camp.nextstep.edu.missionutils.Randoms; +import racingcar.constant.MoveStatus; + +public class RandomMoveGenerator { + + private static final int MIN_RANGE = 0; + private static final int MAX_RANGE = 9; + + public MoveStatus generate() { + final int randomNumber = Randoms.pickNumberInRange(MIN_RANGE, MAX_RANGE); + return MoveStatus.getMoveStatus(randomNumber); + } +} From 9c68ef2efab6c4d4fa63d9c09bbe0964d82bd697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 17:12:09 +0900 Subject: [PATCH 18/22] =?UTF-8?q?fix:=20=EB=9E=9C=EB=8D=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EC=97=AC=EB=B6=80=20=EC=83=9D=EC=84=B1=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=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 | 5 +++- .../java/racingcar/constant/MoveStatus.java | 4 +++ .../java/racingcar/domain/MoveStatuses.java | 26 +++++++++++++++++++ .../racingcar/utils/RandomMoveGenerator.java | 13 +++++++++- 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/main/java/racingcar/domain/MoveStatuses.java diff --git a/docs/README.md b/docs/README.md index 967ade01a1..1e12b4da7a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,7 +11,7 @@ - [x] 시도 회수 입력 받기 - [x] 입력값 숫자인지 검증 - [ ] 자동차 이동 - - [ ] 차수별 이동 + - [x] 차수별 이동 - [ ] 차수별 현황 출력 - [ ] 최종 우승자 선정 - [ ] 최종 우승자 안내 문구 출력 @@ -51,6 +51,9 @@ - TryCount +- RandomMoveGenerator + - generate + ## 열거형 목록 - ErrorMessage - GameMessage diff --git a/src/main/java/racingcar/constant/MoveStatus.java b/src/main/java/racingcar/constant/MoveStatus.java index d3f1f15eff..add5db0df6 100644 --- a/src/main/java/racingcar/constant/MoveStatus.java +++ b/src/main/java/racingcar/constant/MoveStatus.java @@ -11,4 +11,8 @@ public static MoveStatus getMoveStatus(final int randomNumber) { } return STOP; } + + public boolean isMove() { + return this == MOVE; + } } diff --git a/src/main/java/racingcar/domain/MoveStatuses.java b/src/main/java/racingcar/domain/MoveStatuses.java new file mode 100644 index 0000000000..ed033751f7 --- /dev/null +++ b/src/main/java/racingcar/domain/MoveStatuses.java @@ -0,0 +1,26 @@ +package racingcar.domain; + +import racingcar.constant.ErrorMessage; +import racingcar.constant.MoveStatus; + +import java.util.List; + +public class MoveStatuses { + private static final int REMOVE_INDEX = 0; + private final List moveStatuses; + + public MoveStatuses(final List moveStatuses) { + this.moveStatuses = moveStatuses; + } + + public MoveStatus getNext() { + validateHasNext(); + return moveStatuses.remove(REMOVE_INDEX); + } + + private void validateHasNext() { + if (moveStatuses.isEmpty()) { + throw new IllegalStateException(ErrorMessage.HAS_NO_MOVE_STATUS.getMessage()); + } + } +} diff --git a/src/main/java/racingcar/utils/RandomMoveGenerator.java b/src/main/java/racingcar/utils/RandomMoveGenerator.java index 606826c9d7..eae5c026ac 100644 --- a/src/main/java/racingcar/utils/RandomMoveGenerator.java +++ b/src/main/java/racingcar/utils/RandomMoveGenerator.java @@ -2,13 +2,24 @@ import camp.nextstep.edu.missionutils.Randoms; import racingcar.constant.MoveStatus; +import racingcar.domain.MoveStatuses; + +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class RandomMoveGenerator { + private static final int START_INDEX = 0; private static final int MIN_RANGE = 0; private static final int MAX_RANGE = 9; - public MoveStatus generate() { + public MoveStatuses generate(final Integer numberOfCars) { + return new MoveStatuses(IntStream.range(START_INDEX, numberOfCars) + .mapToObj(i -> generate()) + .collect(Collectors.toList())); + } + + private MoveStatus generate() { final int randomNumber = Randoms.pickNumberInRange(MIN_RANGE, MAX_RANGE); return MoveStatus.getMoveStatus(randomNumber); } From a6a91ad4a073d435460874229a5d8b9469a0dca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 17:13:47 +0900 Subject: [PATCH 19/22] =?UTF-8?q?feat:=20=EC=9D=B4=EB=8F=99=20=EA=B8=B0?= =?UTF-8?q?=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/domain/Car.java | 7 ++++++ src/main/java/racingcar/domain/Cars.java | 24 ++++++++++++++++++- .../java/racingcar/domain/MoveStatuses.java | 3 ++- src/main/java/racingcar/domain/TryCount.java | 6 ++++- .../racingcar/repository/CarRepository.java | 8 +++++++ .../java/racingcar/service/CarService.java | 23 ++++++++++++++++++ 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index d03553679d..c4fd2a39c8 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -1,6 +1,7 @@ package racingcar.domain; import racingcar.constant.ErrorMessage; +import racingcar.constant.MoveStatus; import java.util.Objects; @@ -32,4 +33,10 @@ public boolean equals(final Object o) { public int hashCode() { return Objects.hash(name, position); } + + public void move(final MoveStatus moveStatus) { + if (moveStatus.isMove()) { + this.position++; + } + } } diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index 0fae133a14..45f17eaad7 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -1,7 +1,9 @@ package racingcar.domain; import racingcar.constant.ErrorMessage; +import racingcar.constant.MoveStatus; +import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -10,7 +12,7 @@ public class Cars { public Cars(final List cars) { validateUnique(cars); - this.cars = cars; + this.cars = Collections.unmodifiableList(cars); } private void validateUnique(final List cars) { @@ -18,4 +20,24 @@ private void validateUnique(final List cars) { throw new IllegalArgumentException(ErrorMessage.INVALID_CARS_NUM.getMessage()); } } + + public Integer getNumberOfCars() { + return cars.size(); + } + + public void moveAll(final MoveStatuses moveStatuses) { + cars.forEach(car -> move(car, moveStatuses.getNext())); + } + + private void move(final Car car, final MoveStatus moveStatus) { + car.move(moveStatus); + } + + public String findWinners() { + return null; + } + + public String getCurrentDirection() { + return null; + } } diff --git a/src/main/java/racingcar/domain/MoveStatuses.java b/src/main/java/racingcar/domain/MoveStatuses.java index ed033751f7..8862e6274f 100644 --- a/src/main/java/racingcar/domain/MoveStatuses.java +++ b/src/main/java/racingcar/domain/MoveStatuses.java @@ -3,6 +3,7 @@ import racingcar.constant.ErrorMessage; import racingcar.constant.MoveStatus; +import java.util.Collections; import java.util.List; public class MoveStatuses { @@ -10,7 +11,7 @@ public class MoveStatuses { private final List moveStatuses; public MoveStatuses(final List moveStatuses) { - this.moveStatuses = moveStatuses; + this.moveStatuses = Collections.unmodifiableList(moveStatuses); } public MoveStatus getNext() { diff --git a/src/main/java/racingcar/domain/TryCount.java b/src/main/java/racingcar/domain/TryCount.java index f87d97a3ae..a64fdf0fb1 100644 --- a/src/main/java/racingcar/domain/TryCount.java +++ b/src/main/java/racingcar/domain/TryCount.java @@ -2,9 +2,13 @@ public class TryCount { - private final Integer tryCount; + private Integer tryCount; public TryCount(final Integer tryCount) { this.tryCount = tryCount; } + + public boolean hasNext() { + return this.tryCount-- > 0; + } } diff --git a/src/main/java/racingcar/repository/CarRepository.java b/src/main/java/racingcar/repository/CarRepository.java index c9d451ef1e..6497a37d5d 100644 --- a/src/main/java/racingcar/repository/CarRepository.java +++ b/src/main/java/racingcar/repository/CarRepository.java @@ -15,4 +15,12 @@ public void saveCars(final Cars cars) { public void saveTryCount(final TryCount tryCount) { this.tryCount = tryCount; } + + public TryCount findTryCount() { + return this.tryCount; + } + + public Cars findCars() { + return this.cars; + } } diff --git a/src/main/java/racingcar/service/CarService.java b/src/main/java/racingcar/service/CarService.java index f043788171..c803a08ae9 100644 --- a/src/main/java/racingcar/service/CarService.java +++ b/src/main/java/racingcar/service/CarService.java @@ -1,11 +1,15 @@ package racingcar.service; import racingcar.domain.Cars; +import racingcar.domain.MoveStatuses; import racingcar.domain.TryCount; import racingcar.repository.CarRepository; +import racingcar.utils.RandomMoveGenerator; public class CarService { + private final CarRepository carRepository = new CarRepository(); + private final RandomMoveGenerator randomMoveGenerator = new RandomMoveGenerator(); public void saveCars(final Cars cars) { carRepository.saveCars(cars); @@ -14,4 +18,23 @@ public void saveCars(final Cars cars) { public void saveTryCount(final TryCount tryCount) { carRepository.saveTryCount(tryCount); } + + public TryCount findTryCount() { + return carRepository.findTryCount(); + } + + public String move() { + final Cars cars = carRepository.findCars(); + final MoveStatuses moveStatuses = randomMoveCars(cars.getNumberOfCars()); + cars.moveAll(moveStatuses); + return cars.getCurrentDirection(); + } + + private MoveStatuses randomMoveCars(final Integer numberOfCars) { + return randomMoveGenerator.generate(numberOfCars); + } + + public String findWinnerCars() { + return carRepository.findCars().findWinners(); + } } From cf70b0049bd6504e5a91a063a92ffb2183498941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 17:14:08 +0900 Subject: [PATCH 20/22] =?UTF-8?q?feat:=20=EB=A7=A4=20=EC=B0=A8=EC=8B=9C=20?= =?UTF-8?q?=EC=B6=9C=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 --- .../java/racingcar/constant/ErrorMessage.java | 3 ++- .../java/racingcar/constant/GameMessage.java | 4 +++- .../racingcar/controller/CarController.java | 17 +++++++++++++++++ src/main/java/racingcar/io/OutputView.java | 13 +++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/constant/ErrorMessage.java b/src/main/java/racingcar/constant/ErrorMessage.java index f6852e042f..95aa48a519 100644 --- a/src/main/java/racingcar/constant/ErrorMessage.java +++ b/src/main/java/racingcar/constant/ErrorMessage.java @@ -4,7 +4,8 @@ public enum ErrorMessage { INVALID_CAR_INPUT("자동차 이름을 입력할 시 쉼표로 구분해야 합니다."), INVALID_CARS_NUM("자동차 이름에 중복이 있습니다."), INVALID_CAR_NAME_LENGTH("자동차 이름의 길이가 잘못됐습니다."), - INVALID_TRY_COUNT_INPUT("시도 회수의 입력값은 숫자만 가능합니다."); + INVALID_TRY_COUNT_INPUT("시도 회수의 입력값은 숫자만 가능합니다."), + HAS_NO_MOVE_STATUS("다음 MoveStatus가 존재하지 않습니다."); private static final String ERROR_PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/racingcar/constant/GameMessage.java b/src/main/java/racingcar/constant/GameMessage.java index 3afb308185..5295ab0787 100644 --- a/src/main/java/racingcar/constant/GameMessage.java +++ b/src/main/java/racingcar/constant/GameMessage.java @@ -2,7 +2,9 @@ public enum GameMessage { CAR_INPUT_REQUEST("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), - TRY_COUNT_REQUEST("시도할 회수는 몇회인가요?"); + TRY_COUNT_REQUEST("시도할 회수는 몇회인가요?"), + MOVE_RESULT("실행 결과"), + WINNER_CARS("최종 우승자 : %s"); private final String message; diff --git a/src/main/java/racingcar/controller/CarController.java b/src/main/java/racingcar/controller/CarController.java index c8453f77dd..b5d2c1e9dc 100644 --- a/src/main/java/racingcar/controller/CarController.java +++ b/src/main/java/racingcar/controller/CarController.java @@ -2,6 +2,7 @@ import racingcar.domain.Cars; import racingcar.domain.TryCount; +import racingcar.domain.WinnerCars; import racingcar.io.InputManager; import racingcar.io.OutputView; import racingcar.service.CarService; @@ -15,6 +16,22 @@ public class CarController { public void play() { createCars(); createTryCount(); + moveCars(); + findWinnerCars(); + } + + private void moveCars() { + final TryCount tryCount = carService.findTryCount(); + + while(tryCount.hasNext()) { + final String currentDirection = carService.move(); + outputView.printCurrentDirection(currentDirection); + } + } + + private void findWinnerCars() { + final String winnerCars = carService.findWinnerCars(); + outputView.printWinnerCars(winnerCars); } private void createTryCount() { diff --git a/src/main/java/racingcar/io/OutputView.java b/src/main/java/racingcar/io/OutputView.java index 6b6a5657b4..afa49fb198 100644 --- a/src/main/java/racingcar/io/OutputView.java +++ b/src/main/java/racingcar/io/OutputView.java @@ -1,6 +1,7 @@ package racingcar.io; import racingcar.constant.GameMessage; +import racingcar.domain.Cars; public class OutputView { public void printCarRequest() { @@ -10,4 +11,16 @@ public void printCarRequest() { public void printTryCountRequest() { System.out.println(GameMessage.TRY_COUNT_REQUEST.getMessage()); } + + public void printMoveResult() { + System.out.println(GameMessage.MOVE_RESULT.getMessage()); + } + + public void printCurrentDirection(final String currentDirection) { + System.out.println(currentDirection); + } + + public void printWinnerCars(final String winnerCars) { + System.out.println(String.format(GameMessage.WINNER_CARS.getMessage(), winnerCars)); + } } From 12c11836919e81b38b65755abef04eeb3e07b66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 17:33:38 +0900 Subject: [PATCH 21/22] =?UTF-8?q?feat:=20=EA=B8=B0=EB=8A=A5=20=ED=9D=90?= =?UTF-8?q?=EB=A6=84=20=EC=97=B0=EA=B2=B0=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 28 +++++++++++++++---- .../java/racingcar/constant/GameMessage.java | 1 - .../racingcar/controller/CarController.java | 1 - src/main/java/racingcar/domain/Car.java | 24 ++++++++++++++++ src/main/java/racingcar/domain/Cars.java | 22 +++++++++++++-- .../java/racingcar/domain/MoveStatuses.java | 3 +- .../java/racingcar/io/InputValidator.java | 2 +- src/main/java/racingcar/io/OutputView.java | 4 --- 8 files changed, 70 insertions(+), 15 deletions(-) diff --git a/docs/README.md b/docs/README.md index 1e12b4da7a..390973318d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,12 +10,12 @@ - [x] 시도 회수 요청 메시지 출력 - [x] 시도 회수 입력 받기 - [x] 입력값 숫자인지 검증 -- [ ] 자동차 이동 +- [x] 자동차 이동 - [x] 차수별 이동 - - [ ] 차수별 현황 출력 -- [ ] 최종 우승자 선정 - - [ ] 최종 우승자 안내 문구 출력 - - [ ] 공동 우승자의 경우 ", " 로 구분하여 출력 + - [x] 차수별 현황 출력 +- [x] 최종 우승자 선정 + - [x] 최종 우승자 안내 문구 출력 + - [x] 공동 우승자의 경우 ", " 로 구분하여 출력 ## 구현 클래스 목록 - CarController @@ -34,22 +34,40 @@ - validateTryCount() - Car + - move() + - getPosition() + - getName() + - hasMaxPosition() + - getCurrentStatus() - Cars + - getNumberOfCars() + - moveAll() + - findWinners() + - getMaxPosition() + - getCurrentDirection() - OutputView - printCarRequest() - printTryCountRequest() + - printCurrentDirection() + - printWinnerCars() - CarService - saveCars() - saveTryCount() + - findTryCount() + - move() + - findWinnerCars() - CarRepository - saveCars() - saveTryCount() + - findCars() + - findTryCount() - TryCount + - hasNext() - RandomMoveGenerator - generate diff --git a/src/main/java/racingcar/constant/GameMessage.java b/src/main/java/racingcar/constant/GameMessage.java index 5295ab0787..bb827c92aa 100644 --- a/src/main/java/racingcar/constant/GameMessage.java +++ b/src/main/java/racingcar/constant/GameMessage.java @@ -3,7 +3,6 @@ public enum GameMessage { CAR_INPUT_REQUEST("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), TRY_COUNT_REQUEST("시도할 회수는 몇회인가요?"), - MOVE_RESULT("실행 결과"), WINNER_CARS("최종 우승자 : %s"); private final String message; diff --git a/src/main/java/racingcar/controller/CarController.java b/src/main/java/racingcar/controller/CarController.java index b5d2c1e9dc..fdf7e5d494 100644 --- a/src/main/java/racingcar/controller/CarController.java +++ b/src/main/java/racingcar/controller/CarController.java @@ -2,7 +2,6 @@ import racingcar.domain.Cars; import racingcar.domain.TryCount; -import racingcar.domain.WinnerCars; import racingcar.io.InputManager; import racingcar.io.OutputView; import racingcar.service.CarService; diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java index c4fd2a39c8..8cd17d0422 100644 --- a/src/main/java/racingcar/domain/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -4,9 +4,15 @@ import racingcar.constant.MoveStatus; import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class Car { + private static final Integer MAX_SIZE = 5; + private static final Integer START_INDEX = 0; + private static final String DIRECTION_TAG = "-"; + private static final String NAME_DELIMITER = " : "; private final String name; private int position = 0; @@ -39,4 +45,22 @@ public void move(final MoveStatus moveStatus) { this.position++; } } + + public Integer getPosition() { + return this.position; + } + + public String getName() { + return this.name; + } + + public boolean hasMaxPosition(final int maxPosition) { + return this.position == maxPosition; + } + + public String getCurrentStatus() { + return this.name + NAME_DELIMITER + IntStream.range(START_INDEX, position) + .mapToObj(i -> DIRECTION_TAG) + .collect(Collectors.joining()); + } } diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index 45f17eaad7..d24752ca69 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -6,8 +6,13 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.stream.Collectors; public class Cars { + + private static final Integer MIN_POSITION = 0; + private static final String WINNER_DELIMITER = ", "; + private static final String NEW_LINE_DELIMITER = "\n"; private final List cars; public Cars(final List cars) { @@ -34,10 +39,23 @@ private void move(final Car car, final MoveStatus moveStatus) { } public String findWinners() { - return null; + final int maxPosition = getMaxPosition(); + return cars.stream() + .filter(car -> car.hasMaxPosition(maxPosition)) + .map(Car::getName) + .collect(Collectors.joining(WINNER_DELIMITER)); + } + + public int getMaxPosition() { + return cars.stream() + .mapToInt(Car::getPosition) + .max() + .orElse(MIN_POSITION); } public String getCurrentDirection() { - return null; + return cars.stream() + .map(Car::getCurrentStatus) + .collect(Collectors.joining(NEW_LINE_DELIMITER)) + NEW_LINE_DELIMITER; } } diff --git a/src/main/java/racingcar/domain/MoveStatuses.java b/src/main/java/racingcar/domain/MoveStatuses.java index 8862e6274f..992ba31c76 100644 --- a/src/main/java/racingcar/domain/MoveStatuses.java +++ b/src/main/java/racingcar/domain/MoveStatuses.java @@ -3,6 +3,7 @@ import racingcar.constant.ErrorMessage; import racingcar.constant.MoveStatus; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -11,7 +12,7 @@ public class MoveStatuses { private final List moveStatuses; public MoveStatuses(final List moveStatuses) { - this.moveStatuses = Collections.unmodifiableList(moveStatuses); + this.moveStatuses = new ArrayList<>(moveStatuses); } public MoveStatus getNext() { diff --git a/src/main/java/racingcar/io/InputValidator.java b/src/main/java/racingcar/io/InputValidator.java index 0ba3c10683..f7067c2f7b 100644 --- a/src/main/java/racingcar/io/InputValidator.java +++ b/src/main/java/racingcar/io/InputValidator.java @@ -15,7 +15,7 @@ public void validateCars(final String input) { } public void validateTryCount(final String input) { - if (input.chars().anyMatch(c -> MIN_NUMBER < c || c < MAX_NUMBER)) { + if (input.chars().anyMatch(c -> MIN_NUMBER > c || c > MAX_NUMBER)) { throw new IllegalArgumentException(ErrorMessage.INVALID_TRY_COUNT_INPUT.getMessage()); } } diff --git a/src/main/java/racingcar/io/OutputView.java b/src/main/java/racingcar/io/OutputView.java index afa49fb198..6c5b1240e9 100644 --- a/src/main/java/racingcar/io/OutputView.java +++ b/src/main/java/racingcar/io/OutputView.java @@ -12,10 +12,6 @@ public void printTryCountRequest() { System.out.println(GameMessage.TRY_COUNT_REQUEST.getMessage()); } - public void printMoveResult() { - System.out.println(GameMessage.MOVE_RESULT.getMessage()); - } - public void printCurrentDirection(final String currentDirection) { System.out.println(currentDirection); } From 53548bf9c7e7571e52e6a9c7d5fded820f5bb7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=8A=B9=EC=A7=84?= Date: Mon, 18 Sep 2023 17:53:58 +0900 Subject: [PATCH 22/22] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=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 | 1 - .../java/racingcar/constant/ErrorMessage.java | 3 +- src/main/java/racingcar/domain/Cars.java | 9 +++- .../java/racingcar/domain/MoveStatuses.java | 5 ++- src/test/java/racingcar/domain/CarTest.java | 34 ++++++++++++++ src/test/java/racingcar/domain/CarsTest.java | 44 +++++++++++++++++++ .../racingcar/domain/MoveStatusesTest.java | 25 +++++++++++ .../java/racingcar/io/InputValidatorTest.java | 34 ++++++++++++++ 8 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 src/test/java/racingcar/domain/CarTest.java create mode 100644 src/test/java/racingcar/domain/CarsTest.java create mode 100644 src/test/java/racingcar/domain/MoveStatusesTest.java create mode 100644 src/test/java/racingcar/io/InputValidatorTest.java diff --git a/docs/README.md b/docs/README.md index 390973318d..1afd7749b3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -44,7 +44,6 @@ - getNumberOfCars() - moveAll() - findWinners() - - getMaxPosition() - getCurrentDirection() - OutputView diff --git a/src/main/java/racingcar/constant/ErrorMessage.java b/src/main/java/racingcar/constant/ErrorMessage.java index 95aa48a519..da32e69bc3 100644 --- a/src/main/java/racingcar/constant/ErrorMessage.java +++ b/src/main/java/racingcar/constant/ErrorMessage.java @@ -5,7 +5,8 @@ public enum ErrorMessage { INVALID_CARS_NUM("자동차 이름에 중복이 있습니다."), INVALID_CAR_NAME_LENGTH("자동차 이름의 길이가 잘못됐습니다."), INVALID_TRY_COUNT_INPUT("시도 회수의 입력값은 숫자만 가능합니다."), - HAS_NO_MOVE_STATUS("다음 MoveStatus가 존재하지 않습니다."); + HAS_NO_MOVE_STATUS("다음 MoveStatus가 존재하지 않습니다."), + INVALID_MOVE_STATUS_SIZE("MoveStatus의 개수가 잘못되었습니다."); private static final String ERROR_PREFIX = "[ERROR] "; private final String message; diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java index d24752ca69..836b4403ca 100644 --- a/src/main/java/racingcar/domain/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -31,9 +31,16 @@ public Integer getNumberOfCars() { } public void moveAll(final MoveStatuses moveStatuses) { + validateMoveStatusSize(moveStatuses); cars.forEach(car -> move(car, moveStatuses.getNext())); } + private void validateMoveStatusSize(final MoveStatuses moveStatuses) { + if (cars.size() != moveStatuses.getSize()) { + throw new IllegalArgumentException(ErrorMessage.INVALID_MOVE_STATUS_SIZE.getMessage()); + } + } + private void move(final Car car, final MoveStatus moveStatus) { car.move(moveStatus); } @@ -46,7 +53,7 @@ public String findWinners() { .collect(Collectors.joining(WINNER_DELIMITER)); } - public int getMaxPosition() { + private int getMaxPosition() { return cars.stream() .mapToInt(Car::getPosition) .max() diff --git a/src/main/java/racingcar/domain/MoveStatuses.java b/src/main/java/racingcar/domain/MoveStatuses.java index 992ba31c76..f5f513fd91 100644 --- a/src/main/java/racingcar/domain/MoveStatuses.java +++ b/src/main/java/racingcar/domain/MoveStatuses.java @@ -4,7 +4,6 @@ import racingcar.constant.MoveStatus; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class MoveStatuses { @@ -20,6 +19,10 @@ public MoveStatus getNext() { return moveStatuses.remove(REMOVE_INDEX); } + public int getSize() { + return this.moveStatuses.size(); + } + private void validateHasNext() { if (moveStatuses.isEmpty()) { throw new IllegalStateException(ErrorMessage.HAS_NO_MOVE_STATUS.getMessage()); diff --git a/src/test/java/racingcar/domain/CarTest.java b/src/test/java/racingcar/domain/CarTest.java new file mode 100644 index 0000000000..6bb8765e2d --- /dev/null +++ b/src/test/java/racingcar/domain/CarTest.java @@ -0,0 +1,34 @@ +package racingcar.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import racingcar.constant.MoveStatus; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("Car 도메인에서") +class CarTest { + + @Test + @DisplayName("이름의 길이가 5를 초과하는 경우 예외를 던진다.") + void create() { + Assertions.assertThatThrownBy(() -> new Car("asdfasdf")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("MoveStatus의 상태에 따라 움직인다.") + void move() { + //given + final Car car = new Car("aaa"); + final Integer olderPosition = car.getPosition(); + + //when + car.move(MoveStatus.STOP); + car.move(MoveStatus.MOVE); + + //then + Assertions.assertThat(car.getPosition()).isNotEqualTo(olderPosition); + } +} diff --git a/src/test/java/racingcar/domain/CarsTest.java b/src/test/java/racingcar/domain/CarsTest.java new file mode 100644 index 0000000000..8458c6e399 --- /dev/null +++ b/src/test/java/racingcar/domain/CarsTest.java @@ -0,0 +1,44 @@ +package racingcar.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import racingcar.constant.MoveStatus; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("Car를 가지는 일급 컬렉션에서") +class CarsTest { + + @Test + @DisplayName("생성시 같은 name의 car가 존재하면 예외를 던진다.") + void create() { + Assertions.assertThatThrownBy(() -> new Cars(Arrays.asList(new Car("a"), new Car("a")))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("Car와 MoveStatus의 개수가 상이할 시 예외를 던진다.") + void moveAll() { + final Cars cars = new Cars(Arrays.asList(new Car("a"), new Car("b"))); + Assertions.assertThatThrownBy(() -> cars.moveAll(new MoveStatuses(Arrays.asList(MoveStatus.MOVE, MoveStatus.STOP, MoveStatus.MOVE)))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("우승차 조회가 수행되는가") + void findWinners() { + //given + final String winner = "a"; + final Cars cars = new Cars(Arrays.asList(new Car(winner), new Car("b"))); + cars.moveAll(new MoveStatuses(Arrays.asList(MoveStatus.MOVE, MoveStatus.STOP))); + + //when + final String winnerString = cars.findWinners(); + + //then + Assertions.assertThat(winnerString).isEqualTo(winner); + } +} diff --git a/src/test/java/racingcar/domain/MoveStatusesTest.java b/src/test/java/racingcar/domain/MoveStatusesTest.java new file mode 100644 index 0000000000..a49ecf9ceb --- /dev/null +++ b/src/test/java/racingcar/domain/MoveStatusesTest.java @@ -0,0 +1,25 @@ +package racingcar.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import racingcar.constant.MoveStatus; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("MoveStatus 리스트 를 가지는 일급컬렉션에서") +class MoveStatusesTest { + + @Test + @DisplayName("남은 MoveStatus가 없을 때 예외를 던진다.") + void getNext() { + final MoveStatuses moveStatuses = new MoveStatuses(Arrays.asList()); + + Assertions.assertThatThrownBy(moveStatuses::getNext) + .isInstanceOf(IllegalStateException.class); + } +} diff --git a/src/test/java/racingcar/io/InputValidatorTest.java b/src/test/java/racingcar/io/InputValidatorTest.java new file mode 100644 index 0000000000..1be0fac96a --- /dev/null +++ b/src/test/java/racingcar/io/InputValidatorTest.java @@ -0,0 +1,34 @@ +package racingcar.io; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +@DisplayName("입력값 검증에서") +class InputValidatorTest { + + private final InputValidator inputValidator = new InputValidator(); + + @Test + @DisplayName("쉼표로 시작하는 입력값에 대해 예외를 던진다.") + void validateCarsWithStartsWithComma() { + Assertions.assertThatThrownBy(() -> inputValidator.validateCars(",pobi")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("쉼표로 끝나는 입력값에 대해 예외를 던진다.") + void validateCarsWithEndsWithComma() { + Assertions.assertThatThrownBy(() -> inputValidator.validateCars("pobi,abc,")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("숫자가 아닌 값에 대해 예외를 던진다.") + void validateTryCount() { + Assertions.assertThatThrownBy(() -> inputValidator.validateTryCount("a")) + .isInstanceOf(IllegalArgumentException.class); + } +}