From 86ddf10571c2937fc85b81ec04f14978b3cb0c64 Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Wed, 17 Sep 2025 00:32:54 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=203=EB=8B=A8=EA=B3=84=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 --- src/main/java/io/suhan/racingcar/Car.java | 4 ++- src/main/java/io/suhan/racingcar/Game.java | 19 +++++++++-- src/main/java/io/suhan/racingcar/Main.java | 32 +++++++++++++++++++ src/test/java/io/suhan/racingcar/CarTest.java | 8 +++++ .../java/io/suhan/racingcar/GameTest.java | 2 +- 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/suhan/racingcar/Main.java diff --git a/src/main/java/io/suhan/racingcar/Car.java b/src/main/java/io/suhan/racingcar/Car.java index f4e2d848..6529325a 100644 --- a/src/main/java/io/suhan/racingcar/Car.java +++ b/src/main/java/io/suhan/racingcar/Car.java @@ -5,6 +5,7 @@ public class Car { private static final int CAR_MOVE_THRESHOLD = 4; + private static final int CAR_NAME_MAXIMUM_LENGTH = 5; private final String name; private final NumberGenerator generator; @@ -17,10 +18,11 @@ private Car(String name, NumberGenerator generator) { } public static Car of(String name) { - return new Car(name, new RandomNumberGenerator()); + return Car.of(name, new RandomNumberGenerator()); } public static Car of(String name, NumberGenerator generator) { + if (name.length() > CAR_NAME_MAXIMUM_LENGTH) throw new IllegalArgumentException("Car name length must be shorter than " + CAR_NAME_MAXIMUM_LENGTH); return new Car(name, generator); } diff --git a/src/main/java/io/suhan/racingcar/Game.java b/src/main/java/io/suhan/racingcar/Game.java index e7f828c3..b78a0be4 100644 --- a/src/main/java/io/suhan/racingcar/Game.java +++ b/src/main/java/io/suhan/racingcar/Game.java @@ -1,6 +1,7 @@ package io.suhan.racingcar; import java.util.List; +import java.util.stream.Collectors; public class Game { private final CarRegistry carRegistry; @@ -19,11 +20,17 @@ public static Game of(int rounds) { return new Game(rounds); } - public void start() { + public void execute() { + System.out.println("\n실행 결과"); for (int i = 0; i < this.rounds; i++) { carRegistry.moveCars(); + carRegistry.getRegisteredCars().forEach(this::printCurrentPosition); + System.out.println(); } - // TODO: 우승자 출력 + + List winners = getWinners(); + + System.out.println(winners.stream().map(Car::getName).collect(Collectors.joining(", ")) + "가 최종 우승했습니다."); } public List getWinners() { @@ -38,4 +45,12 @@ public List getWinners() { public CarRegistry getCarRegistry() { return carRegistry; } + + private void printCurrentPosition(Car car) { + System.out.println(car.getName() + " : " + buildProgressBar(car.getPosition())); + } + + private String buildProgressBar(int value) { + return "-".repeat(Math.max(0, value)); + } } diff --git a/src/main/java/io/suhan/racingcar/Main.java b/src/main/java/io/suhan/racingcar/Main.java new file mode 100644 index 00000000..c08144eb --- /dev/null +++ b/src/main/java/io/suhan/racingcar/Main.java @@ -0,0 +1,32 @@ +package io.suhan.racingcar; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); + String nameInput = scanner.next(); + + + System.out.println("시도할 회수는 몇회인가요?"); + int count = scanner.nextInt(); + + List names = extractCarNames(nameInput); + Game game = Game.of(count); + + for (String name : names) { + Car car = Car.of(name); + game.getCarRegistry().register(car); + } + + game.execute(); + } + + private static List extractCarNames(String input) { + return Arrays.stream(input.split(",")).toList(); + } +} diff --git a/src/test/java/io/suhan/racingcar/CarTest.java b/src/test/java/io/suhan/racingcar/CarTest.java index 2f82e606..4a9d4d1f 100644 --- a/src/test/java/io/suhan/racingcar/CarTest.java +++ b/src/test/java/io/suhan/racingcar/CarTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import io.suhan.racingcar.generator.FixedNumberGenerator; import org.junit.jupiter.api.DisplayNameGeneration; @@ -43,4 +44,11 @@ public class CarTest { assertEquals(0, position); } + + @Test + void 자동차의_이름은_5자_이하만_가능하다() { + assertThrows(IllegalArgumentException.class, () -> { + Car car = Car.of("123456"); + }); + } } diff --git a/src/test/java/io/suhan/racingcar/GameTest.java b/src/test/java/io/suhan/racingcar/GameTest.java index c0f7d0d2..0a09f52f 100644 --- a/src/test/java/io/suhan/racingcar/GameTest.java +++ b/src/test/java/io/suhan/racingcar/GameTest.java @@ -47,7 +47,7 @@ public class GameTest { List expectedNames = List.of("neo", "brown"); // when - game.start(); + game.execute(); List winnerNames = game.getWinners().stream().map(Car::getName).toList(); // then From d37e4ef387fe3229fc777e772020f4527b9f6985 Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Wed, 17 Sep 2025 02:27:52 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=204=EB=8B=A8=EA=B3=84=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 --- src/main/java/io/suhan/racingcar/Main.java | 32 ++++++---------- .../io/suhan/racingcar/{ => domain}/Car.java | 7 +++- .../racingcar/{ => domain}/CarRegistry.java | 2 +- .../io/suhan/racingcar/{ => domain}/Game.java | 37 ++++++++++--------- .../suhan/racingcar/domain/RoundResult.java | 19 ++++++++++ .../io/suhan/racingcar/view/InputView.java | 22 +++++++++++ .../io/suhan/racingcar/view/ResultView.java | 30 +++++++++++++++ .../suhan/racingcar/{ => domain}/CarTest.java | 6 +-- .../racingcar/{ => domain}/GameTest.java | 2 +- 9 files changed, 112 insertions(+), 45 deletions(-) rename src/main/java/io/suhan/racingcar/{ => domain}/Car.java (81%) rename src/main/java/io/suhan/racingcar/{ => domain}/CarRegistry.java (95%) rename src/main/java/io/suhan/racingcar/{ => domain}/Game.java (50%) create mode 100644 src/main/java/io/suhan/racingcar/domain/RoundResult.java create mode 100644 src/main/java/io/suhan/racingcar/view/InputView.java create mode 100644 src/main/java/io/suhan/racingcar/view/ResultView.java rename src/test/java/io/suhan/racingcar/{ => domain}/CarTest.java (90%) rename src/test/java/io/suhan/racingcar/{ => domain}/GameTest.java (98%) diff --git a/src/main/java/io/suhan/racingcar/Main.java b/src/main/java/io/suhan/racingcar/Main.java index c08144eb..f6458968 100644 --- a/src/main/java/io/suhan/racingcar/Main.java +++ b/src/main/java/io/suhan/racingcar/Main.java @@ -1,32 +1,24 @@ package io.suhan.racingcar; -import java.util.Arrays; +import io.suhan.racingcar.domain.Car; +import io.suhan.racingcar.domain.Game; +import io.suhan.racingcar.domain.RoundResult; +import io.suhan.racingcar.view.InputView; +import io.suhan.racingcar.view.ResultView; import java.util.List; -import java.util.Scanner; public class Main { public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); + List names = InputView.getCarNames(); + int count = InputView.getTrialsCount(); - System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); - String nameInput = scanner.next(); - - - System.out.println("시도할 회수는 몇회인가요?"); - int count = scanner.nextInt(); - - List names = extractCarNames(nameInput); Game game = Game.of(count); + game.registerCars(names); - for (String name : names) { - Car car = Car.of(name); - game.getCarRegistry().register(car); - } - - game.execute(); - } + List results = game.execute(); + List winners = game.getWinners(); - private static List extractCarNames(String input) { - return Arrays.stream(input.split(",")).toList(); + ResultView.printExecutionResult(results); + ResultView.printWinners(winners); } } diff --git a/src/main/java/io/suhan/racingcar/Car.java b/src/main/java/io/suhan/racingcar/domain/Car.java similarity index 81% rename from src/main/java/io/suhan/racingcar/Car.java rename to src/main/java/io/suhan/racingcar/domain/Car.java index 6529325a..175d77e4 100644 --- a/src/main/java/io/suhan/racingcar/Car.java +++ b/src/main/java/io/suhan/racingcar/domain/Car.java @@ -1,4 +1,4 @@ -package io.suhan.racingcar; +package io.suhan.racingcar.domain; import io.suhan.racingcar.generator.NumberGenerator; import io.suhan.racingcar.generator.RandomNumberGenerator; @@ -22,7 +22,10 @@ public static Car of(String name) { } public static Car of(String name, NumberGenerator generator) { - if (name.length() > CAR_NAME_MAXIMUM_LENGTH) throw new IllegalArgumentException("Car name length must be shorter than " + CAR_NAME_MAXIMUM_LENGTH); + if (name.length() > CAR_NAME_MAXIMUM_LENGTH) { + throw new IllegalArgumentException("자동차의 이름은 " + CAR_NAME_MAXIMUM_LENGTH + "자 이하만 가능합니다."); + } + return new Car(name, generator); } diff --git a/src/main/java/io/suhan/racingcar/CarRegistry.java b/src/main/java/io/suhan/racingcar/domain/CarRegistry.java similarity index 95% rename from src/main/java/io/suhan/racingcar/CarRegistry.java rename to src/main/java/io/suhan/racingcar/domain/CarRegistry.java index 2f01a054..84a80c71 100644 --- a/src/main/java/io/suhan/racingcar/CarRegistry.java +++ b/src/main/java/io/suhan/racingcar/domain/CarRegistry.java @@ -1,4 +1,4 @@ -package io.suhan.racingcar; +package io.suhan.racingcar.domain; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/io/suhan/racingcar/Game.java b/src/main/java/io/suhan/racingcar/domain/Game.java similarity index 50% rename from src/main/java/io/suhan/racingcar/Game.java rename to src/main/java/io/suhan/racingcar/domain/Game.java index b78a0be4..2b166206 100644 --- a/src/main/java/io/suhan/racingcar/Game.java +++ b/src/main/java/io/suhan/racingcar/domain/Game.java @@ -1,9 +1,11 @@ -package io.suhan.racingcar; +package io.suhan.racingcar.domain; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; public class Game { + private static final int GAME_ROUNDS_MINIMUM = 1; + private final CarRegistry carRegistry; private final int rounds; @@ -13,24 +15,26 @@ private Game(int rounds) { } public static Game of() { - return new Game(0); + return Game.of(1); } public static Game of(int rounds) { + if (rounds < GAME_ROUNDS_MINIMUM) { + throw new IllegalArgumentException("시도 회수는 " + GAME_ROUNDS_MINIMUM + " 이상이어야 합니다."); + } + return new Game(rounds); } - public void execute() { - System.out.println("\n실행 결과"); - for (int i = 0; i < this.rounds; i++) { + public List execute() { + List results = new ArrayList<>(); + + for (int i = 0; i < rounds; i++) { carRegistry.moveCars(); - carRegistry.getRegisteredCars().forEach(this::printCurrentPosition); - System.out.println(); + results.add(RoundResult.of(carRegistry.getRegisteredCars())); } - List winners = getWinners(); - - System.out.println(winners.stream().map(Car::getName).collect(Collectors.joining(", ")) + "가 최종 우승했습니다."); + return results; } public List getWinners() { @@ -46,11 +50,10 @@ public CarRegistry getCarRegistry() { return carRegistry; } - private void printCurrentPosition(Car car) { - System.out.println(car.getName() + " : " + buildProgressBar(car.getPosition())); - } - - private String buildProgressBar(int value) { - return "-".repeat(Math.max(0, value)); + public void registerCars(List names) { + for (String name : names) { + Car car = Car.of(name); + carRegistry.register(car); + } } } diff --git a/src/main/java/io/suhan/racingcar/domain/RoundResult.java b/src/main/java/io/suhan/racingcar/domain/RoundResult.java new file mode 100644 index 00000000..4058ce24 --- /dev/null +++ b/src/main/java/io/suhan/racingcar/domain/RoundResult.java @@ -0,0 +1,19 @@ +package io.suhan.racingcar.domain; + +import java.util.List; + +public class RoundResult { + private final List cars; + + private RoundResult(List cars) { + this.cars = cars; + } + + public static RoundResult of(List cars) { + return new RoundResult(cars); + } + + public List getCars() { + return cars; + } +} diff --git a/src/main/java/io/suhan/racingcar/view/InputView.java b/src/main/java/io/suhan/racingcar/view/InputView.java new file mode 100644 index 00000000..c2f96dfb --- /dev/null +++ b/src/main/java/io/suhan/racingcar/view/InputView.java @@ -0,0 +1,22 @@ +package io.suhan.racingcar.view; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + private static final Scanner scanner = new Scanner(System.in); + + public static List getCarNames() { + System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); + String input = scanner.next(); + + return Arrays.stream(input.split(",")).toList(); + } + + public static int getTrialsCount() { + System.out.println("시도할 회수는 몇회인가요?"); + + return scanner.nextInt(); + } +} diff --git a/src/main/java/io/suhan/racingcar/view/ResultView.java b/src/main/java/io/suhan/racingcar/view/ResultView.java new file mode 100644 index 00000000..626bc568 --- /dev/null +++ b/src/main/java/io/suhan/racingcar/view/ResultView.java @@ -0,0 +1,30 @@ +package io.suhan.racingcar.view; + +import io.suhan.racingcar.domain.Car; +import io.suhan.racingcar.domain.RoundResult; +import java.util.List; +import java.util.stream.Collectors; + +public class ResultView { + public static void printExecutionResult(List results) { + System.out.println("\n실행 결과"); + results.forEach((result) -> printRoundResult(result.getCars())); + } + + private static void printRoundResult(List cars) { + cars.forEach(ResultView::printCurrentPosition); + System.out.println(); // newline + } + + public static void printWinners(List winners) { + System.out.println(winners.stream().map(Car::getName).collect(Collectors.joining(", ")) + "가 최종 우승했습니다."); + } + + private static void printCurrentPosition(Car car) { + System.out.println(car.getName() + " : " + buildProgressBar(car.getPosition())); + } + + private static String buildProgressBar(int value) { + return "-".repeat(Math.max(0, value)); + } +} diff --git a/src/test/java/io/suhan/racingcar/CarTest.java b/src/test/java/io/suhan/racingcar/domain/CarTest.java similarity index 90% rename from src/test/java/io/suhan/racingcar/CarTest.java rename to src/test/java/io/suhan/racingcar/domain/CarTest.java index 4a9d4d1f..3c6e0e48 100644 --- a/src/test/java/io/suhan/racingcar/CarTest.java +++ b/src/test/java/io/suhan/racingcar/domain/CarTest.java @@ -1,4 +1,4 @@ -package io.suhan.racingcar; +package io.suhan.racingcar.domain; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -47,8 +47,6 @@ public class CarTest { @Test void 자동차의_이름은_5자_이하만_가능하다() { - assertThrows(IllegalArgumentException.class, () -> { - Car car = Car.of("123456"); - }); + assertThrows(IllegalArgumentException.class, () -> Car.of("123456")); } } diff --git a/src/test/java/io/suhan/racingcar/GameTest.java b/src/test/java/io/suhan/racingcar/domain/GameTest.java similarity index 98% rename from src/test/java/io/suhan/racingcar/GameTest.java rename to src/test/java/io/suhan/racingcar/domain/GameTest.java index 0a09f52f..c048dcb9 100644 --- a/src/test/java/io/suhan/racingcar/GameTest.java +++ b/src/test/java/io/suhan/racingcar/domain/GameTest.java @@ -1,4 +1,4 @@ -package io.suhan.racingcar; +package io.suhan.racingcar.domain; import static org.junit.jupiter.api.Assertions.assertIterableEquals; From 654d8d95d411ab6ddd992504896136d1d7d3fa99 Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:22:03 +0900 Subject: [PATCH 3/8] =?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=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/io/suhan/racingcar/domain/GameTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/io/suhan/racingcar/domain/GameTest.java b/src/test/java/io/suhan/racingcar/domain/GameTest.java index c048dcb9..ba87ff65 100644 --- a/src/test/java/io/suhan/racingcar/domain/GameTest.java +++ b/src/test/java/io/suhan/racingcar/domain/GameTest.java @@ -1,6 +1,7 @@ package io.suhan.racingcar.domain; import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import io.suhan.racingcar.generator.FixedNumberGenerator; import java.util.List; @@ -53,4 +54,9 @@ public class GameTest { // then assertIterableEquals(expectedNames, winnerNames); } + + @Test + void 시도_횟수는_1_이상만_가능하다() { + assertThrows(IllegalArgumentException.class, () -> Game.of(0)); + } } From 051622b3a2d5e575cf3d4be1e7ce8c5046ba9d69 Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:16:06 +0900 Subject: [PATCH 4/8] =?UTF-8?q?chore:=20README.md=20=EB=82=B4=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EA=B5=AC=EC=A1=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9afa7d38..dff5e7fd 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,18 @@ ## 프로젝트 구조 ``` +- domain/ + - Car.java : 자동차 객체 및 관련 메소드 정의 + - CarRegistry.java : 자동차 목록 관리 + - Game.java : 전반적인 게임 실행 담당 + - RoundResult.java : 게임 결과를 담는 객체 - generator/ - - NumberGenerator.java : 숫자 생성기 Interface 정의 - - FixedNumberGenerator.java : 고정 숫자 생성기 - - RandomNumberGenerator.java : 랜덤 숫자 생성기 -- Car.java : 자동차 객체 정의 -- CarRegistry.java : 자동차 목록 관리 -- Game.java : 전반적인 게임 실행 담당 + - NumberGenerator.java : 숫자 생성기 Interface 정의 + - RandomNumberGenerator.java : 랜덤 숫자 생성기 +- view/ + - InputView.java : 사용자로부터 입력 받는 기능 수행 + - ResultView.java : 사용자에게 출력 하는 기능 수행 +- Main.java : Main Entrypoint ``` ## 시작하기 From 2be8939daf5a6d06548a797ca4fa3afe042cb1a2 Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:17:51 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20Game,=20CarRegistry=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/io/suhan/racingcar/Main.java | 2 +- .../{CarRegistry.java => CarManager.java} | 24 +++++++++++++--- .../java/io/suhan/racingcar/domain/Game.java | 28 ++++++------------- .../io/suhan/racingcar/domain/GameTest.java | 14 ++++------ 4 files changed, 34 insertions(+), 34 deletions(-) rename src/main/java/io/suhan/racingcar/domain/{CarRegistry.java => CarManager.java} (52%) diff --git a/src/main/java/io/suhan/racingcar/Main.java b/src/main/java/io/suhan/racingcar/Main.java index f6458968..d4096a49 100644 --- a/src/main/java/io/suhan/racingcar/Main.java +++ b/src/main/java/io/suhan/racingcar/Main.java @@ -13,7 +13,7 @@ public static void main(String[] args) { int count = InputView.getTrialsCount(); Game game = Game.of(count); - game.registerCars(names); + game.getCarManager().registerCars(names); List results = game.execute(); List winners = game.getWinners(); diff --git a/src/main/java/io/suhan/racingcar/domain/CarRegistry.java b/src/main/java/io/suhan/racingcar/domain/CarManager.java similarity index 52% rename from src/main/java/io/suhan/racingcar/domain/CarRegistry.java rename to src/main/java/io/suhan/racingcar/domain/CarManager.java index 84a80c71..ecee01fe 100644 --- a/src/main/java/io/suhan/racingcar/domain/CarRegistry.java +++ b/src/main/java/io/suhan/racingcar/domain/CarManager.java @@ -3,15 +3,15 @@ import java.util.ArrayList; import java.util.List; -public class CarRegistry { +public class CarManager { private final List cars; - private CarRegistry() { + private CarManager() { this.cars = new ArrayList<>(); } - public static CarRegistry of() { - return new CarRegistry(); + public static CarManager of() { + return new CarManager(); } public void register(Car car) { @@ -28,6 +28,22 @@ public void moveCars() { } } + public void registerCars(List names) { + for (String name : names) { + Car car = Car.of(name); + cars.add(car); + } + } + + public List getCarsWithBestPosition() { + int bestPosition = getBestPosition(); + + return getRegisteredCars() + .stream() + .filter((car) -> car.getPosition() == bestPosition) + .toList(); + } + public int getBestPosition() { return cars .stream() diff --git a/src/main/java/io/suhan/racingcar/domain/Game.java b/src/main/java/io/suhan/racingcar/domain/Game.java index 2b166206..d3f12339 100644 --- a/src/main/java/io/suhan/racingcar/domain/Game.java +++ b/src/main/java/io/suhan/racingcar/domain/Game.java @@ -6,11 +6,11 @@ public class Game { private static final int GAME_ROUNDS_MINIMUM = 1; - private final CarRegistry carRegistry; + private final CarManager carManager; private final int rounds; private Game(int rounds) { - this.carRegistry = CarRegistry.of(); + this.carManager = CarManager.of(); this.rounds = rounds; } @@ -20,7 +20,7 @@ public static Game of() { public static Game of(int rounds) { if (rounds < GAME_ROUNDS_MINIMUM) { - throw new IllegalArgumentException("시도 회수는 " + GAME_ROUNDS_MINIMUM + " 이상이어야 합니다."); + throw new IllegalArgumentException("시도 횟수는 " + GAME_ROUNDS_MINIMUM + " 이상이어야 합니다."); } return new Game(rounds); @@ -30,30 +30,18 @@ public List execute() { List results = new ArrayList<>(); for (int i = 0; i < rounds; i++) { - carRegistry.moveCars(); - results.add(RoundResult.of(carRegistry.getRegisteredCars())); + carManager.moveCars(); + results.add(RoundResult.of(carManager.getRegisteredCars())); } return results; } public List getWinners() { - int bestPosition = carRegistry.getBestPosition(); - - return carRegistry.getRegisteredCars() - .stream() - .filter((car) -> car.getPosition() == bestPosition) - .toList(); - } - - public CarRegistry getCarRegistry() { - return carRegistry; + return carManager.getCarsWithBestPosition(); } - public void registerCars(List names) { - for (String name : names) { - Car car = Car.of(name); - carRegistry.register(car); - } + public CarManager getCarManager() { + return carManager; } } diff --git a/src/test/java/io/suhan/racingcar/domain/GameTest.java b/src/test/java/io/suhan/racingcar/domain/GameTest.java index ba87ff65..0b41b36c 100644 --- a/src/test/java/io/suhan/racingcar/domain/GameTest.java +++ b/src/test/java/io/suhan/racingcar/domain/GameTest.java @@ -18,13 +18,9 @@ public class GameTest { Game game = Game.of(); - for (String name : names) { - Car car = Car.of(name); + game.getCarManager().registerCars(names); - game.getCarRegistry().register(car); - } - - List registeredNames = game.getCarRegistry().getRegisteredCars().stream().map(Car::getName).toList(); + List registeredNames = game.getCarManager().getRegisteredCars().stream().map(Car::getName).toList(); assertIterableEquals(names, registeredNames); } @@ -41,9 +37,9 @@ public class GameTest { Car brie = Car.of("brie", stopGenerator); Car brown = Car.of("brown", forwardGenerator); - game.getCarRegistry().register(neo); - game.getCarRegistry().register(brie); - game.getCarRegistry().register(brown); + game.getCarManager().register(neo); + game.getCarManager().register(brie); + game.getCarManager().register(brown); List expectedNames = List.of("neo", "brown"); From f4e759e9ee758dfc0a2aa2d660619ce66d01319d Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:19:44 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20RoundResult=EA=B0=92=EC=9D=B4=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/io/suhan/racingcar/domain/Car.java | 7 +++++++ src/main/java/io/suhan/racingcar/domain/Game.java | 3 ++- src/main/java/io/suhan/racingcar/domain/RoundResult.java | 5 ++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/suhan/racingcar/domain/Car.java b/src/main/java/io/suhan/racingcar/domain/Car.java index 175d77e4..46ae78f5 100644 --- a/src/main/java/io/suhan/racingcar/domain/Car.java +++ b/src/main/java/io/suhan/racingcar/domain/Car.java @@ -48,4 +48,11 @@ public String getName() { public int getPosition() { return position; } + + public Car copy() { + Car copy = Car.of(this.name, this.generator); + copy.position = this.position; + + return copy; + } } diff --git a/src/main/java/io/suhan/racingcar/domain/Game.java b/src/main/java/io/suhan/racingcar/domain/Game.java index d3f12339..36e4133e 100644 --- a/src/main/java/io/suhan/racingcar/domain/Game.java +++ b/src/main/java/io/suhan/racingcar/domain/Game.java @@ -31,7 +31,8 @@ public List execute() { for (int i = 0; i < rounds; i++) { carManager.moveCars(); - results.add(RoundResult.of(carManager.getRegisteredCars())); + RoundResult result = RoundResult.of(carManager.getRegisteredCars()); + results.add(result); } return results; diff --git a/src/main/java/io/suhan/racingcar/domain/RoundResult.java b/src/main/java/io/suhan/racingcar/domain/RoundResult.java index 4058ce24..3e07585e 100644 --- a/src/main/java/io/suhan/racingcar/domain/RoundResult.java +++ b/src/main/java/io/suhan/racingcar/domain/RoundResult.java @@ -1,6 +1,7 @@ package io.suhan.racingcar.domain; import java.util.List; +import java.util.stream.Collectors; public class RoundResult { private final List cars; @@ -10,7 +11,9 @@ private RoundResult(List cars) { } public static RoundResult of(List cars) { - return new RoundResult(cars); + List copied = cars.stream().map(Car::copy).collect(Collectors.toList()); + + return new RoundResult(copied); } public List getCars() { From 29333723b3d65b2b7696aaeb9305f71f313736fa Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:26:40 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20CarManager=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/io/suhan/racingcar/Main.java | 2 +- .../domain/{CarManager.java => CarRegistry.java} | 8 ++++---- src/main/java/io/suhan/racingcar/domain/Game.java | 14 +++++++------- .../io/suhan/racingcar/domain/RoundResult.java | 2 +- .../java/io/suhan/racingcar/domain/GameTest.java | 10 +++++----- 5 files changed, 18 insertions(+), 18 deletions(-) rename src/main/java/io/suhan/racingcar/domain/{CarManager.java => CarRegistry.java} (89%) diff --git a/src/main/java/io/suhan/racingcar/Main.java b/src/main/java/io/suhan/racingcar/Main.java index d4096a49..4417e1c9 100644 --- a/src/main/java/io/suhan/racingcar/Main.java +++ b/src/main/java/io/suhan/racingcar/Main.java @@ -13,7 +13,7 @@ public static void main(String[] args) { int count = InputView.getTrialsCount(); Game game = Game.of(count); - game.getCarManager().registerCars(names); + game.getCarRegistry().registerCars(names); List results = game.execute(); List winners = game.getWinners(); diff --git a/src/main/java/io/suhan/racingcar/domain/CarManager.java b/src/main/java/io/suhan/racingcar/domain/CarRegistry.java similarity index 89% rename from src/main/java/io/suhan/racingcar/domain/CarManager.java rename to src/main/java/io/suhan/racingcar/domain/CarRegistry.java index ecee01fe..06f9774d 100644 --- a/src/main/java/io/suhan/racingcar/domain/CarManager.java +++ b/src/main/java/io/suhan/racingcar/domain/CarRegistry.java @@ -3,15 +3,15 @@ import java.util.ArrayList; import java.util.List; -public class CarManager { +public class CarRegistry { private final List cars; - private CarManager() { + private CarRegistry() { this.cars = new ArrayList<>(); } - public static CarManager of() { - return new CarManager(); + public static CarRegistry of() { + return new CarRegistry(); } public void register(Car car) { diff --git a/src/main/java/io/suhan/racingcar/domain/Game.java b/src/main/java/io/suhan/racingcar/domain/Game.java index 36e4133e..9fde4d31 100644 --- a/src/main/java/io/suhan/racingcar/domain/Game.java +++ b/src/main/java/io/suhan/racingcar/domain/Game.java @@ -6,11 +6,11 @@ public class Game { private static final int GAME_ROUNDS_MINIMUM = 1; - private final CarManager carManager; + private final CarRegistry carRegistry; private final int rounds; private Game(int rounds) { - this.carManager = CarManager.of(); + this.carRegistry = CarRegistry.of(); this.rounds = rounds; } @@ -30,8 +30,8 @@ public List execute() { List results = new ArrayList<>(); for (int i = 0; i < rounds; i++) { - carManager.moveCars(); - RoundResult result = RoundResult.of(carManager.getRegisteredCars()); + carRegistry.moveCars(); + RoundResult result = RoundResult.of(carRegistry.getRegisteredCars()); results.add(result); } @@ -39,10 +39,10 @@ public List execute() { } public List getWinners() { - return carManager.getCarsWithBestPosition(); + return carRegistry.getCarsWithBestPosition(); } - public CarManager getCarManager() { - return carManager; + public CarRegistry getCarRegistry() { + return carRegistry; } } diff --git a/src/main/java/io/suhan/racingcar/domain/RoundResult.java b/src/main/java/io/suhan/racingcar/domain/RoundResult.java index 3e07585e..fd7256fc 100644 --- a/src/main/java/io/suhan/racingcar/domain/RoundResult.java +++ b/src/main/java/io/suhan/racingcar/domain/RoundResult.java @@ -12,7 +12,7 @@ private RoundResult(List cars) { public static RoundResult of(List cars) { List copied = cars.stream().map(Car::copy).collect(Collectors.toList()); - + return new RoundResult(copied); } diff --git a/src/test/java/io/suhan/racingcar/domain/GameTest.java b/src/test/java/io/suhan/racingcar/domain/GameTest.java index 0b41b36c..f7411b0a 100644 --- a/src/test/java/io/suhan/racingcar/domain/GameTest.java +++ b/src/test/java/io/suhan/racingcar/domain/GameTest.java @@ -18,9 +18,9 @@ public class GameTest { Game game = Game.of(); - game.getCarManager().registerCars(names); + game.getCarRegistry().registerCars(names); - List registeredNames = game.getCarManager().getRegisteredCars().stream().map(Car::getName).toList(); + List registeredNames = game.getCarRegistry().getRegisteredCars().stream().map(Car::getName).toList(); assertIterableEquals(names, registeredNames); } @@ -37,9 +37,9 @@ public class GameTest { Car brie = Car.of("brie", stopGenerator); Car brown = Car.of("brown", forwardGenerator); - game.getCarManager().register(neo); - game.getCarManager().register(brie); - game.getCarManager().register(brown); + game.getCarRegistry().register(neo); + game.getCarRegistry().register(brie); + game.getCarRegistry().register(brown); List expectedNames = List.of("neo", "brown"); From ea16ae08345edf9691de733dcd0c737fbf76630a Mon Sep 17 00:00:00 2001 From: Suhan Ha <10433434+chemistryx@users.noreply.github.com> Date: Tue, 23 Sep 2025 12:23:49 +0900 Subject: [PATCH 8/8] =?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=EB=82=B4=20=EB=A7=A4=EC=A7=81=20=EB=84=98?= =?UTF-8?q?=EB=B2=84=20=EC=83=81=EC=88=98=EB=A1=9C=20=EB=8C=80=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/io/suhan/racingcar/domain/Car.java | 4 ++-- src/test/java/io/suhan/racingcar/domain/CarTest.java | 5 +++-- src/test/java/io/suhan/racingcar/domain/GameTest.java | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/suhan/racingcar/domain/Car.java b/src/main/java/io/suhan/racingcar/domain/Car.java index 46ae78f5..82aa3931 100644 --- a/src/main/java/io/suhan/racingcar/domain/Car.java +++ b/src/main/java/io/suhan/racingcar/domain/Car.java @@ -4,8 +4,8 @@ import io.suhan.racingcar.generator.RandomNumberGenerator; public class Car { - private static final int CAR_MOVE_THRESHOLD = 4; - private static final int CAR_NAME_MAXIMUM_LENGTH = 5; + public static final int CAR_MOVE_THRESHOLD = 4; + public static final int CAR_NAME_MAXIMUM_LENGTH = 5; private final String name; private final NumberGenerator generator; diff --git a/src/test/java/io/suhan/racingcar/domain/CarTest.java b/src/test/java/io/suhan/racingcar/domain/CarTest.java index 3c6e0e48..8f4e9e03 100644 --- a/src/test/java/io/suhan/racingcar/domain/CarTest.java +++ b/src/test/java/io/suhan/racingcar/domain/CarTest.java @@ -1,5 +1,6 @@ package io.suhan.racingcar.domain; +import static io.suhan.racingcar.domain.Car.CAR_MOVE_THRESHOLD; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -23,7 +24,7 @@ public class CarTest { @Test void 생성된_값이_4_이상일_경우_자동차가_움직일_수_있다() { - FixedNumberGenerator generator = new FixedNumberGenerator(4); + FixedNumberGenerator generator = new FixedNumberGenerator(CAR_MOVE_THRESHOLD); Car car = Car.of("neo", generator); car.move(); @@ -35,7 +36,7 @@ public class CarTest { @Test void 생성된_값이_3_이하일_경우_자동차가_멈춘다() { - FixedNumberGenerator generator = new FixedNumberGenerator(3); + FixedNumberGenerator generator = new FixedNumberGenerator(CAR_MOVE_THRESHOLD - 1); Car car = Car.of("neo", generator); car.move(); diff --git a/src/test/java/io/suhan/racingcar/domain/GameTest.java b/src/test/java/io/suhan/racingcar/domain/GameTest.java index f7411b0a..d0f8bea0 100644 --- a/src/test/java/io/suhan/racingcar/domain/GameTest.java +++ b/src/test/java/io/suhan/racingcar/domain/GameTest.java @@ -1,5 +1,6 @@ package io.suhan.racingcar.domain; +import static io.suhan.racingcar.domain.Car.CAR_MOVE_THRESHOLD; import static org.junit.jupiter.api.Assertions.assertIterableEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -30,8 +31,8 @@ public class GameTest { // given Game game = Game.of(5); - FixedNumberGenerator forwardGenerator = new FixedNumberGenerator(4); - FixedNumberGenerator stopGenerator = new FixedNumberGenerator(3); + FixedNumberGenerator forwardGenerator = new FixedNumberGenerator(CAR_MOVE_THRESHOLD); + FixedNumberGenerator stopGenerator = new FixedNumberGenerator(CAR_MOVE_THRESHOLD - 1); Car neo = Car.of("neo", forwardGenerator); Car brie = Car.of("brie", stopGenerator);