From 2f7b20954cf9da089e410737f96d976c4951435e Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 22:13:52 +0900 Subject: [PATCH 01/15] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=AA=A9=EB=A1=9D=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 491aece1..923a6e79 100644 --- a/README.md +++ b/README.md @@ -1 +1,158 @@ -# java-racingcar-precourse \ No newline at end of file +# java-racingcar-precourse + + +# 자동차 경주 - 프리코스 + +## 프리코스 진행 방식 + +-------- + +## 진행 방식 + +- 미션은 **과제 진행 요구사항, 기능 요구사항, 프로그래밍 요구사항** 세 가지로 구성되어 있다. +- 세 개의 요구사항을 만족하기 위해 노력한다. 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다. +- 기능 요구 사항에 기재되지 않은 내용은 스스로 판단하여 구현한다. + +## 미션 제출 방법 +- 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다. + - GitHub을 활용한 제출 방법은 프리코스 진행 가이드 문서를 참고해 제출한다. + - 풀 리퀘스트 제목은 '[$이름] 프리코스 미션 제출합니다.'로 작성한다. +- GitHub에 미션을 제출한 후 구글 폼에 PR 링크를 포함하여 최종 제출한다. + +## 과제 진행 소감 +과제를 수행하면서 느낀 점, 배운 점, 많은 시간을 투자한 부분 등 자유롭게 작성한다. + +**예시** + +``` +이번 미션은 생각만큼 쉽지 않았습니다. +특히 기능을 분리해서 기능 단위로 커밋하는 것이 쉽지 않다는 것을 깨달았습니다. +기능 단위로 분리하고 커밋하기 위해 다양한 방법으로 연습하였습니다. +하지만 일단 기능을 분리해서 구현하고 나니 좀 더 명확하게 구현할 수 있다는 것을 느낄 수 있었습니다. +미션을 수행하면서 더욱 성장한 걸 느꼈어요. :) +``` + +## 과제 제출 전 체크 리스트 +- 터미널에서 `java -version` 을 실행하여 Java 버전이 17인지 확인한다. Eclipse 또는 IntelliJ IDEA와 같은 IDE에서 Java 17로 실행되는지 확인한다. +- 터미널에서 Mac 또는 Linux 사용자의 경우 `./gradlew clean test` 명령을 실행하고, Windows 사용자의 경우 `gradlew.bat clean test` 또 +는 `./gradlew.bat clean test` 명령을 실행할 때 모든 테스트가 아래와 같이 통과하는지 확인한다. + + `BUILD SUCCESSFUL in 0s` + +## 자동차 경주 + +---------- +## 과제 진행 요구 사항 +- 미션은 자동차 경주 저장소를 포크하고 클론하는 것으로 시작한다. +- 기능을 구현하기 전 에 구현할 기능 목록을 정리해 추가한다. README.md +- Git의 커밋 단위는 앞 단계에서 에 정리한 기능 목록 단위로 추가한다. README.md + - AngularJS Git Commit Message Conventions을 참고해 커밋 메시지를 작성한다. +- 자세한 과제 진행 방법은 프리코스 진행 가이드 문서를 참고한다. + +## 기능 요구사항 + +초간단 자동차 경주 게임을 구현한다. + +- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. +- 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. +- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +- 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다. +- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. +- 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. +- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. +- `Exception`이 아닌 `IllegalArgumentException`, `IllegalStateException` 등과 같은 명확한 유형을 처리한다. + +
+ +## 실행 결과 + +``` +경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분) +pobi,woni,jun +시도할 회수는 몇회인가요? +5 + +실행 결과 +pobi : - +woni : +jun : - + +pobi : -- +woni : - +jun : -- + +pobi : --- +woni : -- +jun : --- + +pobi : ---- +woni : --- +jun : ---- + +pobi : ----- +woni : ---- +jun : ----- + +최종 우승자 : pobi, jun +``` + +## 프로그래밍 요구 사항 1 + +- JDK 17 버전에서 실행 가능해야 한다. +- 프로그램을 실행하는 시작점은 `Application`의 `main()`이다. +- build.gradle 파일은 변경할 수 없으며, 제공된 라이브러리 이외의 외부 라이브러리는 사용하지 않는다. +- 프로그램 종료 시 를 호출하지 않는다. `System.exit()` +- 프로그래밍 요구 사항에서 달리 명시하지 않는 한 파일, 패키지 등의 이름을 바꾸거나 이동하지 않는다. + +## 프로그래밍 요구 사항 2 +- 자바 코드 컨벤션을 지키면서 프로그래밍한다. + - 기본적으로 Google Java Style Guide를 원칙으로 한다. + - 단, 들여쓰기는 '2 spaces'가 아닌 '4 spaces'로 한다. +- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다. + - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. + - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다. +- 3항 연산자를 쓰지 않는다. +- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라. +- JUnit 5와 AssertJ를 이용하여 정리한 기능 목록이 정상적으로 작동하는지 테스트 코드로 확인한다. + - 테스트 도구 사용법이 익숙하지 않다면 아래 문서를 참고하여 학습한 후 테스트를 구현한다. + - JUnit 5 User Guide + - AssertJ User Guide + - AssertJ Exception Assertions + - Guide to JUnit 5 Parameterized Tests + +## 프로그래밍 요구 사항 3 +- 함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다. + - 함수(또는 메서드)가 한 가지 일만 잘 하도록 구현한다. +- else 예약어를 쓰지 않는다. + - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. + - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. +- 도메인 로직에 단위 테스트를 구현해야 한다. 단, UI(System.out, System.in, Scanner) 로직은 제외한다. + - 핵심 로직을 구현하는 코드와 UI를 담당하는 로직을 분리해 구현한다. + - 힌트: MVC 패턴 기반으로 구현한 후, View와 Controller를 제외한 Model에 대한 단위 테스트 추가에 집중한다 + +## 기능 구현 목록 +1. 게임 초기화 + - [ ] 자동차 이름 입력 + - [ ] `예외 처리` : 빈 값 입력 + - [ ] `예외 처리` : 이름이 5자 초과 + - [ ] `예외 처리` : 구분자 예외 처리 + - [ ] 이동 횟수 입력 + - [ ] `예외 처리` : 빈 값 입력 + - [ ] `예외 처리` : 음수 입력 + - [ ] `예외 처리` : 숫자가 아닌 입력 + +2. 게임 진행 + - [ ] 입력된 횟수만큼 이동 + - [ ] 0 ~ 9 까지의 무작위 숫자 뽑기 + - [ ] 4 이상 일 시 전진 + - [ ] 3 이하인 경우 동작 하지 않음 + - [ ] 실행 된 결과 출력 + - [ ] 맨 처음 출력 시 `실행 결과`를 출력한다. + - [ ] `${이름}: ---` 와 같은 형식으로 출력한다. + - [ ] 이동 문자는 `-`로 한다. + - [ ] 이름이 입력 된 순서대로 실행 결과를 출력한다. +3. 게임 종료 + - [ ] 우승자 출력 + - [ ] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. + - [ ] `최종 우승자 : ${이름}` 형태로 출력한다. \ No newline at end of file From 1d0cfd5c3578cba6326254df60214210154b2773 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 22:18:31 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=20=ED=81=B4?= =?UTF-8?q?=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 --- src/main/java/main/java/racingcar/Application.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/main/java/racingcar/Application.java diff --git a/src/main/java/main/java/racingcar/Application.java b/src/main/java/main/java/racingcar/Application.java new file mode 100644 index 00000000..a81ff09c --- /dev/null +++ b/src/main/java/main/java/racingcar/Application.java @@ -0,0 +1,7 @@ +package main.java.racingcar; + +public class Application { + public static void main(String[] args) { + + } +} From a3e0ed5b1e6f54d927222b044317806e4350f382 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 22:21:03 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=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/main/java/racingcar/Application.java | 3 ++- src/main/java/main/java/racingcar/MainController.java | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 src/main/java/main/java/racingcar/MainController.java diff --git a/src/main/java/main/java/racingcar/Application.java b/src/main/java/main/java/racingcar/Application.java index a81ff09c..7164a229 100644 --- a/src/main/java/main/java/racingcar/Application.java +++ b/src/main/java/main/java/racingcar/Application.java @@ -2,6 +2,7 @@ public class Application { public static void main(String[] args) { - + MainController mainController = new MainController(); + mainController.run(); } } diff --git a/src/main/java/main/java/racingcar/MainController.java b/src/main/java/main/java/racingcar/MainController.java new file mode 100644 index 00000000..5b72cbce --- /dev/null +++ b/src/main/java/main/java/racingcar/MainController.java @@ -0,0 +1,8 @@ +package main.java.racingcar; + +public class MainController { + + public void run() { + + } +} From 33181980b134c84f8b1098f16f7c929b0d69bc38 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 22:39:56 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20(=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=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 - 자동차 이름 입력 추가 - 빈 값 입력 예외 처리 추가 (ErrorMessage) - 자동차 이름 입력 사용자 입력 값 추가 (ViewMessage) - 자동차 배열 객체 추가 (Cars) - 자동차 객체 추가 (Car) --- README.md | 4 ++-- .../main/java/racingcar/MainController.java | 11 ++++++++++ .../java/main/java/racingcar/domain/Car.java | 4 ++++ .../java/main/java/racingcar/domain/Cars.java | 14 ++++++++++++ .../java/racingcar/message/ErrorMessage.java | 9 ++++++++ .../java/racingcar/message/ViewMessage.java | 8 +++++++ .../main/java/racingcar/view/InputView.java | 22 +++++++++++++++++++ 7 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/main/java/main/java/racingcar/domain/Car.java create mode 100644 src/main/java/main/java/racingcar/domain/Cars.java create mode 100644 src/main/java/main/java/racingcar/message/ErrorMessage.java create mode 100644 src/main/java/main/java/racingcar/message/ViewMessage.java create mode 100644 src/main/java/main/java/racingcar/view/InputView.java diff --git a/README.md b/README.md index 923a6e79..bad5d0d7 100644 --- a/README.md +++ b/README.md @@ -133,8 +133,8 @@ jun : ----- ## 기능 구현 목록 1. 게임 초기화 - - [ ] 자동차 이름 입력 - - [ ] `예외 처리` : 빈 값 입력 + - [x] 자동차 이름 입력 + - [x] `예외 처리` : 빈 값 입력 - [ ] `예외 처리` : 이름이 5자 초과 - [ ] `예외 처리` : 구분자 예외 처리 - [ ] 이동 횟수 입력 diff --git a/src/main/java/main/java/racingcar/MainController.java b/src/main/java/main/java/racingcar/MainController.java index 5b72cbce..f9e4bc1e 100644 --- a/src/main/java/main/java/racingcar/MainController.java +++ b/src/main/java/main/java/racingcar/MainController.java @@ -1,8 +1,19 @@ package main.java.racingcar; +import main.java.racingcar.domain.Cars; +import main.java.racingcar.message.ViewMessage; +import main.java.racingcar.view.InputView; + public class MainController { public void run() { + Cars cars = this.initCars(); + } + private Cars initCars() { + String inputValue = InputView.inputString(ViewMessage.INPUT_CAR_NAME); + return Cars.createByString(inputValue); } + + } diff --git a/src/main/java/main/java/racingcar/domain/Car.java b/src/main/java/main/java/racingcar/domain/Car.java new file mode 100644 index 00000000..b36c0bed --- /dev/null +++ b/src/main/java/main/java/racingcar/domain/Car.java @@ -0,0 +1,4 @@ +package main.java.racingcar.domain; + +public class Car { +} diff --git a/src/main/java/main/java/racingcar/domain/Cars.java b/src/main/java/main/java/racingcar/domain/Cars.java new file mode 100644 index 00000000..cbcef219 --- /dev/null +++ b/src/main/java/main/java/racingcar/domain/Cars.java @@ -0,0 +1,14 @@ +package main.java.racingcar.domain; + +import java.util.ArrayList; +import java.util.List; + +public record Cars(List CarList) { + + public static final String CAR_NAME_DELIMITER = ","; + + public static Cars createByString(String carsString) { + // TODO: 사용자 입력 받아 Cars 변환 로직 구현 + return new Cars(new ArrayList<>()); + } +} diff --git a/src/main/java/main/java/racingcar/message/ErrorMessage.java b/src/main/java/main/java/racingcar/message/ErrorMessage.java new file mode 100644 index 00000000..27967ccd --- /dev/null +++ b/src/main/java/main/java/racingcar/message/ErrorMessage.java @@ -0,0 +1,9 @@ +package main.java.racingcar.message; + +public class ErrorMessage { + + private ErrorMessage() { + } + + public static String INPUT_BLANK = "[ERROR] 빈 값을 입력 했습니다."; +} diff --git a/src/main/java/main/java/racingcar/message/ViewMessage.java b/src/main/java/main/java/racingcar/message/ViewMessage.java new file mode 100644 index 00000000..e23c0a9d --- /dev/null +++ b/src/main/java/main/java/racingcar/message/ViewMessage.java @@ -0,0 +1,8 @@ +package main.java.racingcar.message; + +public class ViewMessage { + + private ViewMessage() { + } + public static String INPUT_CAR_NAME = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"; +} diff --git a/src/main/java/main/java/racingcar/view/InputView.java b/src/main/java/main/java/racingcar/view/InputView.java new file mode 100644 index 00000000..76563813 --- /dev/null +++ b/src/main/java/main/java/racingcar/view/InputView.java @@ -0,0 +1,22 @@ +package main.java.racingcar.view; + + +import main.java.racingcar.message.ErrorMessage; + +import java.util.Scanner; + +public class InputView { + private static final Scanner scanner = new Scanner(System.in); + public static String inputString(String message) { + System.out.println(message); + String inputValue = scanner.nextLine(); + validateBlank(inputValue); + return inputValue; + } + + public static void validateBlank(String input) { + if (input.isBlank()) { + throw new IllegalArgumentException(ErrorMessage.INPUT_BLANK); + } + } +} From fdd1dbfe98b40d49ad50afb7c8555cbccf54fecd Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 22:49:44 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20(=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=9E=85=EB=A0=A5)=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 자동차 이름 입력 문자열 자동차 객체로 변경하는 메서드 추가 (splitByDelimiter, createByString) - 자동차명 예외 추가 (ErrorMessage) - 자동차 이름 컬렉션 추가 (CarName) - 자동차 객체 추가 (Car) --- src/main/java/main/java/racingcar/Utils.java | 10 +++++++ .../java/main/java/racingcar/domain/Car.java | 6 ++++ .../main/java/racingcar/domain/CarName.java | 30 +++++++++++++++++++ .../java/main/java/racingcar/domain/Cars.java | 10 +++++-- .../java/racingcar/message/ErrorMessage.java | 1 + 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/main/java/main/java/racingcar/Utils.java create mode 100644 src/main/java/main/java/racingcar/domain/CarName.java diff --git a/src/main/java/main/java/racingcar/Utils.java b/src/main/java/main/java/racingcar/Utils.java new file mode 100644 index 00000000..5439ea46 --- /dev/null +++ b/src/main/java/main/java/racingcar/Utils.java @@ -0,0 +1,10 @@ +package main.java.racingcar; + +import java.util.Arrays; +import java.util.List; + +public class Utils { + public static List splitByDelimiter(String str, String delimiter) { + return Arrays.asList(str.split(delimiter)); + } +} diff --git a/src/main/java/main/java/racingcar/domain/Car.java b/src/main/java/main/java/racingcar/domain/Car.java index b36c0bed..d3b99330 100644 --- a/src/main/java/main/java/racingcar/domain/Car.java +++ b/src/main/java/main/java/racingcar/domain/Car.java @@ -1,4 +1,10 @@ package main.java.racingcar.domain; public class Car { + + private final CarName name; + public Car(CarName carName) { + this.name = carName; + // TODO: speed, position 구현 + } } diff --git a/src/main/java/main/java/racingcar/domain/CarName.java b/src/main/java/main/java/racingcar/domain/CarName.java new file mode 100644 index 00000000..f6204bfc --- /dev/null +++ b/src/main/java/main/java/racingcar/domain/CarName.java @@ -0,0 +1,30 @@ +package main.java.racingcar.domain; + +import main.java.racingcar.message.ErrorMessage; + +public class CarName { + + private static final int MAX_NAME_LENGTH = 5; + private final String name; + public CarName(String name) { + this.validateName(name); + this.name = name; + } + + private void validateName(String name) { + this.validateBlank(name); + this.validateNameLength(name); + } + + private void validateBlank(String name) { + if (name == null || name.isBlank()) { + throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_NAME); + } + } + + private void validateNameLength(String name) { + if (name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_NAME); + } + } +} diff --git a/src/main/java/main/java/racingcar/domain/Cars.java b/src/main/java/main/java/racingcar/domain/Cars.java index cbcef219..f00ec105 100644 --- a/src/main/java/main/java/racingcar/domain/Cars.java +++ b/src/main/java/main/java/racingcar/domain/Cars.java @@ -1,6 +1,6 @@ package main.java.racingcar.domain; -import java.util.ArrayList; +import main.java.racingcar.Utils; import java.util.List; public record Cars(List CarList) { @@ -8,7 +8,11 @@ public record Cars(List CarList) { public static final String CAR_NAME_DELIMITER = ","; public static Cars createByString(String carsString) { - // TODO: 사용자 입력 받아 Cars 변환 로직 구현 - return new Cars(new ArrayList<>()); + List carList = Utils.splitByDelimiter(carsString, CAR_NAME_DELIMITER) + .stream() + .map(CarName::new) + .map(Car::new) + .toList(); + return new Cars(carList); } } diff --git a/src/main/java/main/java/racingcar/message/ErrorMessage.java b/src/main/java/main/java/racingcar/message/ErrorMessage.java index 27967ccd..0112ab12 100644 --- a/src/main/java/main/java/racingcar/message/ErrorMessage.java +++ b/src/main/java/main/java/racingcar/message/ErrorMessage.java @@ -6,4 +6,5 @@ private ErrorMessage() { } public static String INPUT_BLANK = "[ERROR] 빈 값을 입력 했습니다."; + public static String INVALID_CAR_NAME = "[ERROR] 자동차 이름은 5자 이하여야 합니다.."; } From 6274166bebd71b9c430d2b67bb01cabf539eccf8 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 22:54:13 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20=EC=B6=94=EA=B0=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이름, 속력, 위치 추가 (Car) - 음수 입력 받았을 때 예외 추가 (ErrorMessage) - 위치 객체 추가 (Position) --- .../java/main/java/racingcar/domain/Car.java | 6 +++++- .../main/java/racingcar/domain/Position.java | 19 +++++++++++++++++++ .../java/racingcar/message/ErrorMessage.java | 4 +++- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/main/java/main/java/racingcar/domain/Position.java diff --git a/src/main/java/main/java/racingcar/domain/Car.java b/src/main/java/main/java/racingcar/domain/Car.java index d3b99330..c43a6685 100644 --- a/src/main/java/main/java/racingcar/domain/Car.java +++ b/src/main/java/main/java/racingcar/domain/Car.java @@ -2,9 +2,13 @@ public class Car { + public static final int START_POSITION = 0; private final CarName name; + private final int speed; + private final Position position; public Car(CarName carName) { this.name = carName; - // TODO: speed, position 구현 + this.speed = 1; + this.position = new Position(START_POSITION); } } diff --git a/src/main/java/main/java/racingcar/domain/Position.java b/src/main/java/main/java/racingcar/domain/Position.java new file mode 100644 index 00000000..6315b5a1 --- /dev/null +++ b/src/main/java/main/java/racingcar/domain/Position.java @@ -0,0 +1,19 @@ +package main.java.racingcar.domain; + +import main.java.racingcar.message.ErrorMessage; + +public class Position { + + private int amount; + + public Position(int amount){ + this.validate(amount); + this.amount = amount; + } + + public void validate(int amount) { + if (amount < 0) { + throw new IllegalArgumentException(ErrorMessage.INVALID_NEGATIVE); + } + } +} diff --git a/src/main/java/main/java/racingcar/message/ErrorMessage.java b/src/main/java/main/java/racingcar/message/ErrorMessage.java index 0112ab12..2037397f 100644 --- a/src/main/java/main/java/racingcar/message/ErrorMessage.java +++ b/src/main/java/main/java/racingcar/message/ErrorMessage.java @@ -6,5 +6,7 @@ private ErrorMessage() { } public static String INPUT_BLANK = "[ERROR] 빈 값을 입력 했습니다."; - public static String INVALID_CAR_NAME = "[ERROR] 자동차 이름은 5자 이하여야 합니다.."; + public static String INVALID_CAR_NAME = "[ERROR] 자동차 이름은 5자 이하여야 합니다."; + + public static String INVALID_NEGATIVE = "0보다 작은 값을 입력할 수 없습니다."; } From 82507c20b7ab95a0526232d0ff9b29cfb1700a16 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 23:04:53 +0900 Subject: [PATCH 07/15] =?UTF-8?q?feat:=20=EC=9D=B4=EB=8F=99=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=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 - 시도 횟수 객체 추가 (TrialCount) - 횟수 입력 ViewMessage 추가 - 숫자 입력 예외 추가 - InputView 검증 로직 추가 (숫자 검증) --- README.md | 10 +++++----- .../java/main/java/racingcar/MainController.java | 7 +++++++ .../main/java/racingcar/domain/TrialCount.java | 14 ++++++++++++++ .../java/racingcar/message/ErrorMessage.java | 1 + .../main/java/racingcar/message/ViewMessage.java | 1 + .../java/main/java/racingcar/view/InputView.java | 16 ++++++++++++++++ 6 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/main/java/main/java/racingcar/domain/TrialCount.java diff --git a/README.md b/README.md index bad5d0d7..75040c90 100644 --- a/README.md +++ b/README.md @@ -135,12 +135,12 @@ jun : ----- 1. 게임 초기화 - [x] 자동차 이름 입력 - [x] `예외 처리` : 빈 값 입력 - - [ ] `예외 처리` : 이름이 5자 초과 + - [x] `예외 처리` : 이름이 5자 초과 - [ ] `예외 처리` : 구분자 예외 처리 - - [ ] 이동 횟수 입력 - - [ ] `예외 처리` : 빈 값 입력 - - [ ] `예외 처리` : 음수 입력 - - [ ] `예외 처리` : 숫자가 아닌 입력 + - [x] 이동 횟수 입력 + - [x] `예외 처리` : 빈 값 입력 + - [x] `예외 처리` : 음수 입력 + - [x] `예외 처리` : 숫자가 아닌 입력 2. 게임 진행 - [ ] 입력된 횟수만큼 이동 diff --git a/src/main/java/main/java/racingcar/MainController.java b/src/main/java/main/java/racingcar/MainController.java index f9e4bc1e..f7cae408 100644 --- a/src/main/java/main/java/racingcar/MainController.java +++ b/src/main/java/main/java/racingcar/MainController.java @@ -1,6 +1,7 @@ package main.java.racingcar; import main.java.racingcar.domain.Cars; +import main.java.racingcar.domain.TrialCount; import main.java.racingcar.message.ViewMessage; import main.java.racingcar.view.InputView; @@ -8,6 +9,7 @@ public class MainController { public void run() { Cars cars = this.initCars(); + TrialCount trialCount = this.initTrialCount(); } private Cars initCars() { @@ -15,5 +17,10 @@ private Cars initCars() { return Cars.createByString(inputValue); } + private TrialCount initTrialCount() { + int count = InputView.inputInteger(ViewMessage.INPUT_TRIAL_COUNT); + return new TrialCount(count); + } + } diff --git a/src/main/java/main/java/racingcar/domain/TrialCount.java b/src/main/java/main/java/racingcar/domain/TrialCount.java new file mode 100644 index 00000000..29c1faa9 --- /dev/null +++ b/src/main/java/main/java/racingcar/domain/TrialCount.java @@ -0,0 +1,14 @@ +package main.java.racingcar.domain; + +import main.java.racingcar.message.ErrorMessage; + +public record TrialCount(int count) { + public TrialCount { + this.validate(count); + } + private void validate(int count) { + if (count < 0) { + throw new IllegalArgumentException(ErrorMessage.INVALID_NEGATIVE); + } + } +} diff --git a/src/main/java/main/java/racingcar/message/ErrorMessage.java b/src/main/java/main/java/racingcar/message/ErrorMessage.java index 2037397f..6b98372f 100644 --- a/src/main/java/main/java/racingcar/message/ErrorMessage.java +++ b/src/main/java/main/java/racingcar/message/ErrorMessage.java @@ -8,5 +8,6 @@ private ErrorMessage() { public static String INPUT_BLANK = "[ERROR] 빈 값을 입력 했습니다."; public static String INVALID_CAR_NAME = "[ERROR] 자동차 이름은 5자 이하여야 합니다."; + public static String INPUT_NOT_INTEGER = "[ERROR] 숫자를 입력해야 합니다"; public static String INVALID_NEGATIVE = "0보다 작은 값을 입력할 수 없습니다."; } diff --git a/src/main/java/main/java/racingcar/message/ViewMessage.java b/src/main/java/main/java/racingcar/message/ViewMessage.java index e23c0a9d..586fc369 100644 --- a/src/main/java/main/java/racingcar/message/ViewMessage.java +++ b/src/main/java/main/java/racingcar/message/ViewMessage.java @@ -5,4 +5,5 @@ public class ViewMessage { private ViewMessage() { } public static String INPUT_CAR_NAME = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"; + public static String INPUT_TRIAL_COUNT = "시도할 회수는 몇회인가요?"; } diff --git a/src/main/java/main/java/racingcar/view/InputView.java b/src/main/java/main/java/racingcar/view/InputView.java index 76563813..da5cd4f7 100644 --- a/src/main/java/main/java/racingcar/view/InputView.java +++ b/src/main/java/main/java/racingcar/view/InputView.java @@ -19,4 +19,20 @@ public static void validateBlank(String input) { throw new IllegalArgumentException(ErrorMessage.INPUT_BLANK); } } + + public static int inputInteger(String message) { + System.out.println(message); + String inputValue = scanner.nextLine(); + validateBlank(inputValue); + validateInteger(inputValue); + return Integer.parseInt(inputValue); + } + + public static void validateInteger(String input) { + try { + Integer.parseInt(input); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ErrorMessage.INPUT_NOT_INTEGER); + } + } } From ed240c0af38e5d39821d5e6e445834a763c0ce7c Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 23:20:57 +0900 Subject: [PATCH 08/15] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=A7=84?= =?UTF-8?q?=ED=96=89=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 - 게임 결과 출력 메시지 추가 - Random으로 4보다 큰 수 추출하는 메서드 추 - 숫자 입력 예외 추가 - position 더하는 로직 추가 - 자동차 이동 로직 추가 --- README.md | 8 ++++---- .../java/main/java/racingcar/MainController.java | 12 ++++++++++++ src/main/java/main/java/racingcar/Utils.java | 7 +++++++ src/main/java/main/java/racingcar/domain/Car.java | 6 ++++++ .../java/main/java/racingcar/domain/Cars.java | 7 ++++++- .../java/main/java/racingcar/domain/Position.java | 4 ++++ .../main/java/racingcar/domain/TrialCount.java | 4 ++++ .../main/java/racingcar/message/ViewMessage.java | 2 ++ .../java/main/java/racingcar/view/OutputView.java | 15 +++++++++++++++ 9 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/main/java/main/java/racingcar/view/OutputView.java diff --git a/README.md b/README.md index 75040c90..364ac418 100644 --- a/README.md +++ b/README.md @@ -143,10 +143,10 @@ jun : ----- - [x] `예외 처리` : 숫자가 아닌 입력 2. 게임 진행 - - [ ] 입력된 횟수만큼 이동 - - [ ] 0 ~ 9 까지의 무작위 숫자 뽑기 - - [ ] 4 이상 일 시 전진 - - [ ] 3 이하인 경우 동작 하지 않음 + - [x] 입력된 횟수만큼 이동 + - [x] 0 ~ 9 까지의 무작위 숫자 뽑기 + - [x] 4 이상 일 시 전진 + - [x] 3 이하인 경우 동작 하지 않음 - [ ] 실행 된 결과 출력 - [ ] 맨 처음 출력 시 `실행 결과`를 출력한다. - [ ] `${이름}: ---` 와 같은 형식으로 출력한다. diff --git a/src/main/java/main/java/racingcar/MainController.java b/src/main/java/main/java/racingcar/MainController.java index f7cae408..4d042bf0 100644 --- a/src/main/java/main/java/racingcar/MainController.java +++ b/src/main/java/main/java/racingcar/MainController.java @@ -4,12 +4,14 @@ import main.java.racingcar.domain.TrialCount; import main.java.racingcar.message.ViewMessage; import main.java.racingcar.view.InputView; +import main.java.racingcar.view.OutputView; public class MainController { public void run() { Cars cars = this.initCars(); TrialCount trialCount = this.initTrialCount(); + this.proceedGame(cars, trialCount); } private Cars initCars() { @@ -22,5 +24,15 @@ private TrialCount initTrialCount() { return new TrialCount(count); } + private void proceedGame(Cars cars, TrialCount trialCount) { + int moveCount = 0; + OutputView.printMessage(ViewMessage.GAME_RESULT); + while(trialCount.isMoreThan(moveCount)) { + cars.commandAllCarsToMove(); + OutputView.printMovingResult(cars); + moveCount++; + } + } + } diff --git a/src/main/java/main/java/racingcar/Utils.java b/src/main/java/main/java/racingcar/Utils.java index 5439ea46..8017ef76 100644 --- a/src/main/java/main/java/racingcar/Utils.java +++ b/src/main/java/main/java/racingcar/Utils.java @@ -2,9 +2,16 @@ import java.util.Arrays; import java.util.List; +import java.util.Random; public class Utils { public static List splitByDelimiter(String str, String delimiter) { return Arrays.asList(str.split(delimiter)); } + + public static boolean isFourOrMore() { + Random random = new Random(); + int randomNumber = random.nextInt(10); // 0에서 9 사이의 난수 생성 + return randomNumber >= 4; + } } diff --git a/src/main/java/main/java/racingcar/domain/Car.java b/src/main/java/main/java/racingcar/domain/Car.java index c43a6685..ac1f96c8 100644 --- a/src/main/java/main/java/racingcar/domain/Car.java +++ b/src/main/java/main/java/racingcar/domain/Car.java @@ -11,4 +11,10 @@ public Car(CarName carName) { this.speed = 1; this.position = new Position(START_POSITION); } + + public void moveForwardIfTrue(boolean isForward) { + if(isForward) { + this.position.increment(speed); + } + } } diff --git a/src/main/java/main/java/racingcar/domain/Cars.java b/src/main/java/main/java/racingcar/domain/Cars.java index f00ec105..2254356d 100644 --- a/src/main/java/main/java/racingcar/domain/Cars.java +++ b/src/main/java/main/java/racingcar/domain/Cars.java @@ -3,7 +3,7 @@ import main.java.racingcar.Utils; import java.util.List; -public record Cars(List CarList) { +public record Cars(List carList) { public static final String CAR_NAME_DELIMITER = ","; @@ -15,4 +15,9 @@ public static Cars createByString(String carsString) { .toList(); return new Cars(carList); } + + public void commandAllCarsToMove() { + carList.forEach(car -> + car.moveForwardIfTrue(Utils.isFourOrMore())); + } } diff --git a/src/main/java/main/java/racingcar/domain/Position.java b/src/main/java/main/java/racingcar/domain/Position.java index 6315b5a1..59f21347 100644 --- a/src/main/java/main/java/racingcar/domain/Position.java +++ b/src/main/java/main/java/racingcar/domain/Position.java @@ -16,4 +16,8 @@ public void validate(int amount) { throw new IllegalArgumentException(ErrorMessage.INVALID_NEGATIVE); } } + + public void increment(int speed) { + this.amount += speed; + } } diff --git a/src/main/java/main/java/racingcar/domain/TrialCount.java b/src/main/java/main/java/racingcar/domain/TrialCount.java index 29c1faa9..a72c200b 100644 --- a/src/main/java/main/java/racingcar/domain/TrialCount.java +++ b/src/main/java/main/java/racingcar/domain/TrialCount.java @@ -11,4 +11,8 @@ private void validate(int count) { throw new IllegalArgumentException(ErrorMessage.INVALID_NEGATIVE); } } + + public boolean isMoreThan(int count) { + return this.count > count; + } } diff --git a/src/main/java/main/java/racingcar/message/ViewMessage.java b/src/main/java/main/java/racingcar/message/ViewMessage.java index 586fc369..98d83b0c 100644 --- a/src/main/java/main/java/racingcar/message/ViewMessage.java +++ b/src/main/java/main/java/racingcar/message/ViewMessage.java @@ -6,4 +6,6 @@ private ViewMessage() { } public static String INPUT_CAR_NAME = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"; public static String INPUT_TRIAL_COUNT = "시도할 회수는 몇회인가요?"; + + public static String GAME_RESULT = "\n실행 결과"; } diff --git a/src/main/java/main/java/racingcar/view/OutputView.java b/src/main/java/main/java/racingcar/view/OutputView.java new file mode 100644 index 00000000..71e4c2a9 --- /dev/null +++ b/src/main/java/main/java/racingcar/view/OutputView.java @@ -0,0 +1,15 @@ +package main.java.racingcar.view; + +import main.java.racingcar.domain.Cars; + +public class OutputView { + + public static void printMessage(String message) { + System.out.println(message); + } + + public static void printMovingResult(Cars cars) { + System.out.println(cars); + System.out.println(); + } +} From d67bbecc1de735cf2c3ad86c6b6589a2f6b3a5d6 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 23:34:21 +0900 Subject: [PATCH 09/15] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=A2=85?= =?UTF-8?q?=EB=A3=8C=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 - 게임 종료 로직 추가 - 우승자 위치 출력 로직 추가 - 우승자 리스트 출력 추가 - 결과 출력 로직 추가 --- README.md | 16 +++++++------- .../main/java/racingcar/MainController.java | 9 +++++++- .../java/main/java/racingcar/domain/Car.java | 18 +++++++++++++++ .../main/java/racingcar/domain/CarName.java | 4 ++++ .../java/main/java/racingcar/domain/Cars.java | 22 +++++++++++++++++++ .../main/java/racingcar/domain/Position.java | 4 ++++ .../java/racingcar/message/ViewMessage.java | 5 ++++- .../main/java/racingcar/view/OutputView.java | 14 ++++++++++++ 8 files changed, 82 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 364ac418..4f04776e 100644 --- a/README.md +++ b/README.md @@ -147,12 +147,12 @@ jun : ----- - [x] 0 ~ 9 까지의 무작위 숫자 뽑기 - [x] 4 이상 일 시 전진 - [x] 3 이하인 경우 동작 하지 않음 - - [ ] 실행 된 결과 출력 - - [ ] 맨 처음 출력 시 `실행 결과`를 출력한다. - - [ ] `${이름}: ---` 와 같은 형식으로 출력한다. - - [ ] 이동 문자는 `-`로 한다. - - [ ] 이름이 입력 된 순서대로 실행 결과를 출력한다. + - [x] 실행 된 결과 출력 + - [x] 맨 처음 출력 시 `실행 결과`를 출력한다. + - [x] `${이름}: ---` 와 같은 형식으로 출력한다. + - [x] 이동 문자는 `-`로 한다. + - [x] 이름이 입력 된 순서대로 실행 결과를 출력한다. 3. 게임 종료 - - [ ] 우승자 출력 - - [ ] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. - - [ ] `최종 우승자 : ${이름}` 형태로 출력한다. \ No newline at end of file + - [x] 우승자 출력 + - [x] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. + - [x] `최종 우승자 : ${이름}` 형태로 출력한다. \ No newline at end of file diff --git a/src/main/java/main/java/racingcar/MainController.java b/src/main/java/main/java/racingcar/MainController.java index 4d042bf0..2f6dfbb8 100644 --- a/src/main/java/main/java/racingcar/MainController.java +++ b/src/main/java/main/java/racingcar/MainController.java @@ -1,17 +1,21 @@ package main.java.racingcar; +import main.java.racingcar.domain.Car; import main.java.racingcar.domain.Cars; import main.java.racingcar.domain.TrialCount; import main.java.racingcar.message.ViewMessage; import main.java.racingcar.view.InputView; import main.java.racingcar.view.OutputView; +import java.util.List; + public class MainController { public void run() { Cars cars = this.initCars(); TrialCount trialCount = this.initTrialCount(); this.proceedGame(cars, trialCount); + this.endGame(cars); } private Cars initCars() { @@ -34,5 +38,8 @@ private void proceedGame(Cars cars, TrialCount trialCount) { } } - + private void endGame(Cars cars) { + List winner = cars.getWinnerList(); + OutputView.printWinner(winner); + } } diff --git a/src/main/java/main/java/racingcar/domain/Car.java b/src/main/java/main/java/racingcar/domain/Car.java index ac1f96c8..1dff36ad 100644 --- a/src/main/java/main/java/racingcar/domain/Car.java +++ b/src/main/java/main/java/racingcar/domain/Car.java @@ -2,6 +2,7 @@ public class Car { + public static final String CAR_POSITION_SIGN = "-"; public static final int START_POSITION = 0; private final CarName name; private final int speed; @@ -17,4 +18,21 @@ public void moveForwardIfTrue(boolean isForward) { this.position.increment(speed); } } + + public boolean isSamePosition(int position) { + return this.position.getAmount() == position; + } + + public String getName() { + return this.name.getName(); + } + + public int getPosition() { + return this.position.getAmount(); + } + + @Override + public String toString() { + return this.name.getName() + " : " + this.CAR_POSITION_SIGN.repeat(this.position.getAmount()); + } } diff --git a/src/main/java/main/java/racingcar/domain/CarName.java b/src/main/java/main/java/racingcar/domain/CarName.java index f6204bfc..2d8943a5 100644 --- a/src/main/java/main/java/racingcar/domain/CarName.java +++ b/src/main/java/main/java/racingcar/domain/CarName.java @@ -27,4 +27,8 @@ private void validateNameLength(String name) { throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_NAME); } } + + public String getName() { + return name; + } } diff --git a/src/main/java/main/java/racingcar/domain/Cars.java b/src/main/java/main/java/racingcar/domain/Cars.java index 2254356d..f7bd4ec8 100644 --- a/src/main/java/main/java/racingcar/domain/Cars.java +++ b/src/main/java/main/java/racingcar/domain/Cars.java @@ -2,6 +2,7 @@ import main.java.racingcar.Utils; import java.util.List; +import java.util.stream.Collectors; public record Cars(List carList) { @@ -20,4 +21,25 @@ public void commandAllCarsToMove() { carList.forEach(car -> car.moveForwardIfTrue(Utils.isFourOrMore())); } + + public List getWinnerList() { + Integer winnerPosition = getWinnerPosition(); + return carList.stream() + .filter(car -> car.isSamePosition(winnerPosition)) + .collect(Collectors.toList()); + } + + private Integer getWinnerPosition() { + return carList.stream() + .map(Car::getPosition) + .max(Integer::compareTo) + .orElse(0); + } + + @Override + public String toString() { + return carList.stream() + .map(Car::toString) + .collect(Collectors.joining("\n")); + } } diff --git a/src/main/java/main/java/racingcar/domain/Position.java b/src/main/java/main/java/racingcar/domain/Position.java index 59f21347..eafc3665 100644 --- a/src/main/java/main/java/racingcar/domain/Position.java +++ b/src/main/java/main/java/racingcar/domain/Position.java @@ -20,4 +20,8 @@ public void validate(int amount) { public void increment(int speed) { this.amount += speed; } + + public int getAmount() { + return amount; + } } diff --git a/src/main/java/main/java/racingcar/message/ViewMessage.java b/src/main/java/main/java/racingcar/message/ViewMessage.java index 98d83b0c..71893ef8 100644 --- a/src/main/java/main/java/racingcar/message/ViewMessage.java +++ b/src/main/java/main/java/racingcar/message/ViewMessage.java @@ -6,6 +6,9 @@ private ViewMessage() { } public static String INPUT_CAR_NAME = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"; public static String INPUT_TRIAL_COUNT = "시도할 회수는 몇회인가요?"; - public static String GAME_RESULT = "\n실행 결과"; + public static String WINNER_RESULT_FORMAT = "최종 우승자 : %s"; + + public static String WINNER_RESULT_DELIMITER = ", "; + } diff --git a/src/main/java/main/java/racingcar/view/OutputView.java b/src/main/java/main/java/racingcar/view/OutputView.java index 71e4c2a9..a7181956 100644 --- a/src/main/java/main/java/racingcar/view/OutputView.java +++ b/src/main/java/main/java/racingcar/view/OutputView.java @@ -1,7 +1,14 @@ package main.java.racingcar.view; +import main.java.racingcar.domain.Car; import main.java.racingcar.domain.Cars; +import java.util.List; +import java.util.stream.Collectors; + +import static main.java.racingcar.message.ViewMessage.WINNER_RESULT_DELIMITER; +import static main.java.racingcar.message.ViewMessage.WINNER_RESULT_FORMAT; + public class OutputView { public static void printMessage(String message) { @@ -12,4 +19,11 @@ public static void printMovingResult(Cars cars) { System.out.println(cars); System.out.println(); } + + public static void printWinner(List winner) { + String winnerStr = winner.stream() + .map(Car::getName) + .collect(Collectors.joining(WINNER_RESULT_DELIMITER)); + System.out.printf(WINNER_RESULT_FORMAT, winnerStr); + } } From 04efeb14e1dd0bd3a9144665047d1d4efc571f37 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 23:40:54 +0900 Subject: [PATCH 10/15] =?UTF-8?q?test:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20=EC=83=9D=EC=84=B1=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 | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 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 00000000..fb43406c --- /dev/null +++ b/src/test/java/racingcar/CarTest.java @@ -0,0 +1,33 @@ +package racingcar; + +import main.java.racingcar.domain.Car; +import main.java.racingcar.domain.CarName; +import main.java.racingcar.message.ErrorMessage; +import org.assertj.core.api.Assertions; +import org.assertj.core.api.Assertions.*; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; + +class CarTest { + + @DisplayName("자동차 이름 생성 성공 테스트") + @ParameterizedTest + @ValueSource(strings = {"a", "jin", "a2", "abcd", "12345"}) + void CarNameSuccessTest(String name) { + Car car = new Car(new CarName(name)); + assertThat(car.getName()).isEqualTo(name); + } + + @DisplayName("자동차 이름 생성 실패 테스트") + @ParameterizedTest + @ValueSource(strings = {"", " ", "5자를넘는이름테스트", "123456"}) + void CarNameFailTest(String name) { + Assertions.assertThatThrownBy(() ->{ + new Car(new CarName(name)); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_CAR_NAME); + } +} From f7d753e7564b2b94f9288b43e06516e38789d9b5 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 23:47:34 +0900 Subject: [PATCH 11/15] =?UTF-8?q?test:=20=EA=B2=BD=EC=A3=BC=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=B0=A8=EB=93=A4=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=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/CarsTest.java | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/test/java/racingcar/CarsTest.java diff --git a/src/test/java/racingcar/CarsTest.java b/src/test/java/racingcar/CarsTest.java new file mode 100644 index 00000000..0a323fe6 --- /dev/null +++ b/src/test/java/racingcar/CarsTest.java @@ -0,0 +1,55 @@ +package racingcar; + +import main.java.racingcar.domain.Car; +import main.java.racingcar.domain.CarName; +import main.java.racingcar.domain.Cars; +import main.java.racingcar.message.ErrorMessage; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class CarsTest { + + @DisplayName("createByString 성공 테스트") + @Test + void createByStringSuccessTest() { + Cars cars = Cars.createByString("A,B,C,D"); + Cars answer = new Cars(List.of( + new Car(new CarName("A")), + new Car(new CarName("B")), + new Car(new CarName("C")), + new Car(new CarName("D")) + )); + assertThat(cars.toString()).isEqualTo(answer.toString()); + } + + @DisplayName("createByString 실패 테스트") + @Test + void createByStringFailTest() { + Assertions.assertThatThrownBy(() -> Cars.createByString("A B C D")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_CAR_NAME); + } + + @DisplayName("commandAllCarsToMove를 실행하면 최개 실행 횟수까지 전진한다.") + @Test + void commandAllCarsToMove() { + Car car1 = new Car(new CarName("car1")); + Car car2 = new Car(new CarName("car2")); + Car car3 = new Car(new CarName("car3")); + + Cars cars = new Cars(List.of(car1, car2, car3)); + + cars.commandAllCarsToMove(); + cars.commandAllCarsToMove(); + cars.commandAllCarsToMove(); + + assertThat(car1.getPosition()).isLessThanOrEqualTo(3); + assertThat(car1.getPosition()).isLessThanOrEqualTo(3); + assertThat(car1.getPosition()).isLessThanOrEqualTo(3); + } +} From 685765802b5cca2929c2aeffe133893d475b8aba Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 23:51:28 +0900 Subject: [PATCH 12/15] =?UTF-8?q?test:=20Utils=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=EC=9E=90=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/ConverterTest.java | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/java/racingcar/ConverterTest.java diff --git a/src/test/java/racingcar/ConverterTest.java b/src/test/java/racingcar/ConverterTest.java new file mode 100644 index 00000000..d6f515c8 --- /dev/null +++ b/src/test/java/racingcar/ConverterTest.java @@ -0,0 +1,29 @@ +package racingcar; + +import main.java.racingcar.Utils; +import org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.List; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +class ConverterTest { + @ParameterizedTest + @MethodSource("splitByDelimiterArguments") + void splitByDelimiterTest(String src, String delimiter, List expected) { + assertThat(Utils.splitByDelimiter(src, delimiter)).isEqualTo(expected); + } + + static Stream splitByDelimiterArguments() { + return Stream.of( + Arguments.of("a,b,c", ",", List.of("a", "b", "c")), + Arguments.of("a b c", " ", List.of("a", "b", "c")), + Arguments.of("a,b c", " ", List.of("a,b", "c")), + Arguments.of(",,,", ",", List.of()) + ); + } +} From cfb289e4af28c231e7fa33f9804ff25184db4eed Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Sun, 9 Jun 2024 23:55:16 +0900 Subject: [PATCH 13/15] =?UTF-8?q?test:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=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/MovingTest.java | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/test/java/racingcar/MovingTest.java diff --git a/src/test/java/racingcar/MovingTest.java b/src/test/java/racingcar/MovingTest.java new file mode 100644 index 00000000..fe6ad7a7 --- /dev/null +++ b/src/test/java/racingcar/MovingTest.java @@ -0,0 +1,36 @@ +package racingcar; + +import main.java.racingcar.domain.Car; +import main.java.racingcar.domain.CarName; +import org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MovingTest { + + @DisplayName("움직이지 않으면 위치는 0이다.") + @Test + void moveFailTest() { + Car car = new Car(new CarName("car")); + assertThat(car.isSamePosition(0)).isTrue(); + } + + @DisplayName("자동차가 1회 움직이면 위치는 1이다.") + @Test + void moveSuccessTest() { + Car car = new Car(new CarName("car")); + car.moveForwardIfTrue(true); + assertThat(car.isSamePosition(1)).isTrue(); + } + + @DisplayName("자동차와 위치가 다른 경우 isSamePosition은 false이다.") + @Test + void moveSamePositionFailTest() { + Car car = new Car(new CarName("car")); + car.moveForwardIfTrue(true); + car.moveForwardIfTrue(true); + assertThat(car.isSamePosition(1)).isFalse(); + } +} From c704c90380d9edba33d48cf912818e8801554fe6 Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Mon, 10 Jun 2024 00:01:12 +0900 Subject: [PATCH 14/15] =?UTF-8?q?test:=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=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/TrialCountTest.java | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/test/java/racingcar/TrialCountTest.java diff --git a/src/test/java/racingcar/TrialCountTest.java b/src/test/java/racingcar/TrialCountTest.java new file mode 100644 index 00000000..eaee0f72 --- /dev/null +++ b/src/test/java/racingcar/TrialCountTest.java @@ -0,0 +1,38 @@ +package racingcar; + +import main.java.racingcar.domain.TrialCount; +import main.java.racingcar.message.ErrorMessage; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class TrialCountTest { + + @DisplayName("TrialCount 0으로 생성시 IllegalArgumentException 예외를 발생시킨다.") + @ParameterizedTest + @ValueSource(ints = {0, 1, 2, 3, 4, 5, 9999999}) + void trialCountSuccess(int count) { + Assertions.assertThatNoException() + .isThrownBy(() -> new TrialCount(count)); + } + + @DisplayName("TrialCount 음수로 생성시 IllegalArgumentException 예외를 발생시킨다.") + @ParameterizedTest + @ValueSource(ints = {-1, -2, -3, -9999}) + void trialCountException(int count) { + Assertions.assertThatThrownBy(() -> new TrialCount(count)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_NEGATIVE); + } + + @DisplayName("isMoreThan.") + @Test + void moreThan() { + TrialCount trialCount = new TrialCount(10); + Assertions.assertThat(trialCount.isMoreThan(9)).isTrue(); + Assertions.assertThat(trialCount.isMoreThan(10)).isFalse(); + Assertions.assertThat(trialCount.isMoreThan(11)).isFalse(); + } +} From 95b8a5d13b5a30804180baef759ad6798e262dad Mon Sep 17 00:00:00 2001 From: LeeJin0527 Date: Mon, 10 Jun 2024 00:04:20 +0900 Subject: [PATCH 15/15] =?UTF-8?q?test:=20=EC=9A=B0=EC=8A=B9=EC=9E=90=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=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/WinnerTest.java | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/test/java/racingcar/WinnerTest.java diff --git a/src/test/java/racingcar/WinnerTest.java b/src/test/java/racingcar/WinnerTest.java new file mode 100644 index 00000000..3874d372 --- /dev/null +++ b/src/test/java/racingcar/WinnerTest.java @@ -0,0 +1,67 @@ +package racingcar; + +import main.java.racingcar.domain.Car; +import main.java.racingcar.domain.CarName; +import main.java.racingcar.domain.Cars; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class WinnerTest { + @DisplayName("우승자가 1명만 있는 경우 리스트에는 한 명만 있다.") + @Test + void getSingleWinnerTest() { + Car car1 = new Car(new CarName("car1")); + Car car2 = new Car(new CarName("car2")); + Car car3 = new Car(new CarName("car3")); + + Cars cars = new Cars(List.of(car1, car2, car3)); + + car1.moveForwardIfTrue(true); + car2.moveForwardIfTrue(false); + car3.moveForwardIfTrue(false); + + List winner = cars.getWinnerList(); + + assertThat(winner).containsExactly(car1); + } + + @DisplayName("우승자가 1명만 있는 경우 리스트에는 한 명만 있다.") + @Test + void getDoubleWinnerTest() { + Car car1 = new Car(new CarName("car1")); + Car car2 = new Car(new CarName("car2")); + Car car3 = new Car(new CarName("car3")); + + Cars cars = new Cars(List.of(car1, car2, car3)); + + car1.moveForwardIfTrue(true); + car2.moveForwardIfTrue(true); + car3.moveForwardIfTrue(false); + + List winner = cars.getWinnerList(); + + assertThat(winner).containsExactly(car1, car2); + } + + @DisplayName("우승자가 1명만 있는 경우 리스트에는 한 명만 있다.") + @Test + void getTripleWinnerTest() { + Car car1 = new Car(new CarName("car1")); + Car car2 = new Car(new CarName("car2")); + Car car3 = new Car(new CarName("car3")); + + Cars cars = new Cars(List.of(car1, car2, car3)); + + car1.moveForwardIfTrue(true); + car2.moveForwardIfTrue(true); + car3.moveForwardIfTrue(true); + + List winner = cars.getWinnerList(); + + assertThat(winner).containsExactly(car1, car2, car3); + } +}