From b5ccdf338c2ff3894b80ebaea3e6a248ac38885c Mon Sep 17 00:00:00 2001 From: SangWookie Date: Mon, 28 Oct 2024 17:59:35 +0900 Subject: [PATCH 01/11] docs: program features --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/README.md b/README.md index d0286c859f..882d666c02 100644 --- a/README.md +++ b/README.md @@ -1 +1,50 @@ # java-racingcar-precourse + +--- + +## 요구사항 분석 +* 입력 처리 클래스 구현 + * 쉼표를 기준으로 경주할 자동자 이름을 분리하여 입력 + * 시도할 횟수 입력 +* Car(자동차) 클래스 구현 + * 이름 + * 현재 위치 +* Race(경주) 클래스 구현 + * 게임 진행 메소드 +* 출력(Race 클래스에서 구현) + * 차수별 실행 결과 + * 단독 우승자 안내 문구 + * 공동 우승자 안내 문구 +* 잘못된 입력 처리 + * 입력 클래스에서 입력값을 확인한 후 예외 발생 + +### 출력예시: +``` +경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분) +pobi,woni,jun +시도할 횟수는 몇 회인가요? +5 + +실행 결과 +pobi : - +woni : +jun : - + +pobi : -- +woni : - +jun : -- + +pobi : --- +woni : -- +jun : --- + +pobi : ---- +woni : --- +jun : ---- + +pobi : ----- +woni : ---- +jun : ----- + +최종 우승자 : pobi, jun +``` \ No newline at end of file From 8f63a365295baf55cb50783140b1601d6838fc8b Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 00:07:24 +0900 Subject: [PATCH 02/11] docs(readme): add requirement for test code --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 882d666c02..252bee3bca 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ * 공동 우승자 안내 문구 * 잘못된 입력 처리 * 입력 클래스에서 입력값을 확인한 후 예외 발생 +* 각 항목별 테스트 코드 작성 ### 출력예시: ``` From bf70a1ec8de36aaf83d319715dffeeeb00f633bf Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 00:32:02 +0900 Subject: [PATCH 03/11] feat($input): input handler add with basic features --- src/main/java/racingcar/Application.java | 10 ++++++++- src/main/java/racingcar/InputHandler.java | 27 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/InputHandler.java diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e724..0cc82da789 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,15 @@ package racingcar; +import camp.nextstep.edu.missionutils.Console; + +import java.util.List; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + InputHandler inputHandler = new InputHandler(); + + inputHandler.inputNames(); + inputHandler.inputCount(); + } } diff --git a/src/main/java/racingcar/InputHandler.java b/src/main/java/racingcar/InputHandler.java new file mode 100644 index 0000000000..c404afc573 --- /dev/null +++ b/src/main/java/racingcar/InputHandler.java @@ -0,0 +1,27 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Console; + +import java.util.List; + +public class InputHandler { + String input; + List names; + Integer runCount; + + public void inputNames(){ + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + this.input = Console.readLine(); + this.names = InputHandler.commaSeparator(input); + } + + public void inputCount(){ + System.out.println("시도할 횟수는 몇 회인가요?"); + this.runCount = Integer.parseInt(Console.readLine()); + } + + public static List commaSeparator(String input){ + List names = List.of(input.split(",")); + return names; + } +} From a9540a84e1cee9be2147b56ee7336113bfb3ea27 Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 00:33:57 +0900 Subject: [PATCH 04/11] fix($input): fix input handler variables visibility --- src/main/java/racingcar/InputHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/racingcar/InputHandler.java b/src/main/java/racingcar/InputHandler.java index c404afc573..b624e111fb 100644 --- a/src/main/java/racingcar/InputHandler.java +++ b/src/main/java/racingcar/InputHandler.java @@ -5,9 +5,9 @@ import java.util.List; public class InputHandler { - String input; - List names; - Integer runCount; + private String input; + private List names; + private Integer runCount; public void inputNames(){ System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); From 87254d70dc1e9cd73aa62fbb64a74148bab9ec43 Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 00:41:17 +0900 Subject: [PATCH 05/11] fix($car): add Car class for basic operations --- src/main/java/racingcar/Car.java | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/java/racingcar/Car.java diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java new file mode 100644 index 0000000000..112271bc33 --- /dev/null +++ b/src/main/java/racingcar/Car.java @@ -0,0 +1,29 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Randoms; + +public class Car { + private String name; + private Integer location; + + public Car(String name) { + this.name = name; + this.location = 0; + } + + public void moveOnceRandom() { + int num = Randoms.pickNumberInRange(0, 9); + + if (num > 4) { + location++; + } + } + + public String getNameAndLocation() { + String returnStr = name + " : "; + for (int i = 0; i < location; i++) { + returnStr += "-"; + } + return returnStr; + } +} From bcc6b6d7bb363907bcc5795f6eec7a1a2dadb91b Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 01:35:32 +0900 Subject: [PATCH 06/11] chore: add necessary getters --- src/main/java/racingcar/Car.java | 10 +++++++++- src/main/java/racingcar/InputHandler.java | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java index 112271bc33..96513f8b2d 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/Car.java @@ -4,7 +4,7 @@ public class Car { private String name; - private Integer location; + private int location; public Car(String name) { this.name = name; @@ -19,6 +19,14 @@ public void moveOnceRandom() { } } + public int getLocation() { + return location; + } + + public String getName() { + return name; + } + public String getNameAndLocation() { String returnStr = name + " : "; for (int i = 0; i < location; i++) { diff --git a/src/main/java/racingcar/InputHandler.java b/src/main/java/racingcar/InputHandler.java index b624e111fb..cffeb4e619 100644 --- a/src/main/java/racingcar/InputHandler.java +++ b/src/main/java/racingcar/InputHandler.java @@ -7,7 +7,7 @@ public class InputHandler { private String input; private List names; - private Integer runCount; + private int runCount; public void inputNames(){ System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); @@ -24,4 +24,12 @@ public static List commaSeparator(String input){ List names = List.of(input.split(",")); return names; } + + public Integer getRunCount() { + return runCount; + } + + public List getNames() { + return names; + } } From dae019e61e95b91bddb9cfd4f2bf5cf13544aafb Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 01:36:44 +0900 Subject: [PATCH 07/11] feat($Race): add race running logics --- src/main/java/racingcar/Application.java | 11 +++++ src/main/java/racingcar/Race.java | 51 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/main/java/racingcar/Race.java diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index 0cc82da789..742d978548 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -2,6 +2,7 @@ import camp.nextstep.edu.missionutils.Console; +import java.util.ArrayList; import java.util.List; public class Application { @@ -11,5 +12,15 @@ public static void main(String[] args) { inputHandler.inputNames(); inputHandler.inputCount(); + List cars = new ArrayList<>(); + for(String name : inputHandler.getNames()){ + Car car = new Car(name); + cars.add(car); + } + + Race race = new Race(cars, inputHandler.getRunCount()); + + race.runRace(); + race.showWinners(); } } diff --git a/src/main/java/racingcar/Race.java b/src/main/java/racingcar/Race.java new file mode 100644 index 0000000000..4201837ea2 --- /dev/null +++ b/src/main/java/racingcar/Race.java @@ -0,0 +1,51 @@ +package racingcar; + +import org.junit.platform.commons.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public class Race { + private List cars; + private int count; + + public Race(List cars, int count) { + this.cars = cars; + this.count = count; + } + + public void runOneRound(){ + for(Car car : cars){ + car.moveOnceRandom(); + } + } + + public void printLocations(){ + for(Car car : cars){ + System.out.println(car.getNameAndLocation()); + } + } + + public void runRace(){ + System.out.println("실행 결과"); + for(int i = 0; i < count; i++){ + runOneRound(); + printLocations(); + System.out.println(); + } + } + + public void showWinners(){ + int max = cars.stream().map(Car::getLocation).max(Integer::compareTo).orElse(Integer.MIN_VALUE); + + List winners = new ArrayList<>(); + for(Car car : cars){ + if(car.getLocation() == max){ + winners.add(car.getName()); + } + } + + String winnersOutput = String.join(", ", winners); + System.out.println("최종 우승자 : " + winnersOutput); + } +} From 5f1ff777918d95fd3806a9a6724e306a65855987 Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 01:48:14 +0900 Subject: [PATCH 08/11] feat($Exception): add exception code for wrong inputs --- src/main/java/racingcar/InputHandler.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/racingcar/InputHandler.java b/src/main/java/racingcar/InputHandler.java index cffeb4e619..f1dd60e458 100644 --- a/src/main/java/racingcar/InputHandler.java +++ b/src/main/java/racingcar/InputHandler.java @@ -22,6 +22,14 @@ public void inputCount(){ public static List commaSeparator(String input){ List names = List.of(input.split(",")); + for(String name : names){ + if(name.trim().isEmpty()){ + throw new IllegalArgumentException("이름이 비었습니다."); + } + if(name.length() > 5){ + throw new IllegalArgumentException("이름은 5자 이하만 가능합니다."); + } + } return names; } From 218330240681d19b99922714f9fca3a781e50d83 Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 01:48:51 +0900 Subject: [PATCH 09/11] fix($Car): fix wrong move logic --- src/main/java/racingcar/Car.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java index 96513f8b2d..d96aee81e6 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/Car.java @@ -14,7 +14,7 @@ public Car(String name) { public void moveOnceRandom() { int num = Randoms.pickNumberInRange(0, 9); - if (num > 4) { + if (num >= 4) { location++; } } From 3f88f226c22aac80efba14fbdea456fb5dd2611b Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 02:20:03 +0900 Subject: [PATCH 10/11] test($Car): add test codes --- src/test/java/racingcar/CarTest.java | 42 +++++++++++++++++ src/test/java/racingcar/InputHandlerTest.java | 46 +++++++++++++++++++ src/test/java/racingcar/RaceTest.java | 38 +++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 src/test/java/racingcar/CarTest.java create mode 100644 src/test/java/racingcar/InputHandlerTest.java create mode 100644 src/test/java/racingcar/RaceTest.java diff --git a/src/test/java/racingcar/CarTest.java b/src/test/java/racingcar/CarTest.java new file mode 100644 index 0000000000..bad6714125 --- /dev/null +++ b/src/test/java/racingcar/CarTest.java @@ -0,0 +1,42 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Randoms; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomNumberInRangeTest; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class CarTest { + private Car car; + + @BeforeEach + void setUp() { + car = new Car("pobi"); + } + + @Test + void 자동차의_이름을_반환한다() { + assertThat(car.getName()).isEqualTo("pobi"); + } + + @Test + void 자동차의_초기_위치는_0이다() { + assertThat(car.getLocation()).isEqualTo(0); + } + + @Test + void 자동차는_랜덤숫자가_4이상일_경우_이동한다() { + assertRandomNumberInRangeTest( + () -> { + car.moveOnceRandom(); + assertThat(car.getLocation()).isEqualTo(1); + + car.moveOnceRandom(); + assertThat(car.getLocation()).isEqualTo(1); + }, + 4, 3 + ); + } +} \ No newline at end of file diff --git a/src/test/java/racingcar/InputHandlerTest.java b/src/test/java/racingcar/InputHandlerTest.java new file mode 100644 index 0000000000..ea59c40464 --- /dev/null +++ b/src/test/java/racingcar/InputHandlerTest.java @@ -0,0 +1,46 @@ +package racingcar; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class InputHandlerTest { + + private InputHandler inputHandler; + + @BeforeEach + void setUp() { + inputHandler = new InputHandler(); + } + + @Test + void 자동차_이름을_쉼표로_구분하여_입력할_수_있다() { + String input = "pobi,woni"; + List expectedNames = List.of("pobi", "woni"); + + List names = InputHandler.commaSeparator(input); + + assertThat(names).isEqualTo(expectedNames); + } + + @Test + void 자동차_이름은_빈_문자열일_수_없다() { + String input = "pobi,,woni"; + + assertThatThrownBy(() -> InputHandler.commaSeparator(input)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 자동차_이름은_5자_이하만_허용된다() { + String input = "pobi,woni,longname"; + + assertThatThrownBy(() -> InputHandler.commaSeparator(input)) + .isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file diff --git a/src/test/java/racingcar/RaceTest.java b/src/test/java/racingcar/RaceTest.java new file mode 100644 index 0000000000..57deb10dac --- /dev/null +++ b/src/test/java/racingcar/RaceTest.java @@ -0,0 +1,38 @@ +package racingcar; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Arrays; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class RaceTest { + private Race race; + private ByteArrayOutputStream outputStream; + + @BeforeEach + void setUp() { + Car car1 = new Car("pobi"); + Car car2 = new Car("woni"); + race = new Race(Arrays.asList(car1, car2), 5); + + outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + } + + @Test + void 경주가_정상적으로_진행되는지_테스트() { + race.runRace(); + race.showWinners(); + + String output = outputStream.toString(); + assertThat(output).contains("실행 결과"); // 경주 시작 메시지 확인 + assertThat(output).contains("pobi : ", "woni : "); // 자동차의 위치 정보가 출력되었는지 확인 + + assertThat(output).contains("최종 우승자 : "); // 최종 우승자 메시지 확인 + } +} \ No newline at end of file From 5fd1e4c65aafe0f5c6a3e4fb27552662a6086884 Mon Sep 17 00:00:00 2001 From: SangWookie Date: Tue, 29 Oct 2024 02:20:47 +0900 Subject: [PATCH 11/11] docs($main): add comments --- src/main/java/racingcar/Application.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index 742d978548..4876938544 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,5 @@ package racingcar; -import camp.nextstep.edu.missionutils.Console; - import java.util.ArrayList; import java.util.List; @@ -9,17 +7,21 @@ public class Application { public static void main(String[] args) { InputHandler inputHandler = new InputHandler(); + // 입력 받기 inputHandler.inputNames(); inputHandler.inputCount(); + // 입력을 기반으로 Car 인스턴스 생성 List cars = new ArrayList<>(); for(String name : inputHandler.getNames()){ Car car = new Car(name); cars.add(car); } + // Race 인스턴스 생성 Race race = new Race(cars, inputHandler.getRunCount()); + // 경주 진행 race.runRace(); race.showWinners(); }