From 9fee122411e159161a20357ad50d3537a0889014 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sat, 14 Mar 2026 10:41:46 +0900 Subject: [PATCH 01/35] =?UTF-8?q?docs:=20README.md=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 0 src/main/java/controller.java | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 README.md create mode 100644 src/main/java/controller.java diff --git a/README.md b/README.md new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/controller.java b/src/main/java/controller.java new file mode 100644 index 00000000..8d8809fb --- /dev/null +++ b/src/main/java/controller.java @@ -0,0 +1,4 @@ +package PACKAGE_NAME; + +public class controller { +} From 10775345d4e6b22a254c8a907256d799054b1ae2 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 13:47:51 +0900 Subject: [PATCH 02/35] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8(Car)?= =?UTF-8?q?=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=AA=A8=EB=8D=B8=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/{ => racingcar}/controller.java | 2 +- src/main/java/racingcar/domain/Car.java | 4 ++++ src/main/java/racingcar/domain/Race.java | 4 ++++ src/main/java/racingcar/view.java | 4 ++++ 4 files changed, 13 insertions(+), 1 deletion(-) rename src/main/java/{ => racingcar}/controller.java (56%) create mode 100644 src/main/java/racingcar/domain/Car.java create mode 100644 src/main/java/racingcar/domain/Race.java create mode 100644 src/main/java/racingcar/view.java diff --git a/src/main/java/controller.java b/src/main/java/racingcar/controller.java similarity index 56% rename from src/main/java/controller.java rename to src/main/java/racingcar/controller.java index 8d8809fb..6520313c 100644 --- a/src/main/java/controller.java +++ b/src/main/java/racingcar/controller.java @@ -1,4 +1,4 @@ -package PACKAGE_NAME; +package racingcar; public class controller { } diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java new file mode 100644 index 00000000..a4523d1a --- /dev/null +++ b/src/main/java/racingcar/domain/Car.java @@ -0,0 +1,4 @@ +package racingcar.domain; + +public class Car { +} diff --git a/src/main/java/racingcar/domain/Race.java b/src/main/java/racingcar/domain/Race.java new file mode 100644 index 00000000..472e94e3 --- /dev/null +++ b/src/main/java/racingcar/domain/Race.java @@ -0,0 +1,4 @@ +package racingcar.domain; + +public class race { +} diff --git a/src/main/java/racingcar/view.java b/src/main/java/racingcar/view.java new file mode 100644 index 00000000..a537a59f --- /dev/null +++ b/src/main/java/racingcar/view.java @@ -0,0 +1,4 @@ +package racingcar; + +public class view { +} From 5c22eaebe8572281aae13f05d49c5a26d0673dbf Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 14:24:24 +0900 Subject: [PATCH 03/35] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EA=B3=BC=20=EC=8B=9C=EB=8F=84=ED=9A=9F?= =?UTF-8?q?=EC=88=98=EB=A5=BC=20=EC=9E=85=EB=A0=A5=EB=B0=9B=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Car.java | 7 +++++++ src/main/java/{racingcar => }/domain/Race.java | 2 +- src/main/java/racingcar/controller.java | 4 ---- src/main/java/racingcar/domain/Car.java | 4 ---- src/main/java/racingcar/view.java | 4 ---- src/main/java/racingcar/view/InputView.java | 4 ++++ 6 files changed, 12 insertions(+), 13 deletions(-) create mode 100644 src/main/java/domain/Car.java rename src/main/java/{racingcar => }/domain/Race.java (59%) delete mode 100644 src/main/java/racingcar/controller.java delete mode 100644 src/main/java/racingcar/domain/Car.java delete mode 100644 src/main/java/racingcar/view.java create mode 100644 src/main/java/racingcar/view/InputView.java diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java new file mode 100644 index 00000000..0a57459c --- /dev/null +++ b/src/main/java/domain/Car.java @@ -0,0 +1,7 @@ +package racingcar.domain; + +public class Car { + private final String name; + private int position = 0; + private boolean isWinner = false; +} diff --git a/src/main/java/racingcar/domain/Race.java b/src/main/java/domain/Race.java similarity index 59% rename from src/main/java/racingcar/domain/Race.java rename to src/main/java/domain/Race.java index 472e94e3..0bba1ab1 100644 --- a/src/main/java/racingcar/domain/Race.java +++ b/src/main/java/domain/Race.java @@ -1,4 +1,4 @@ package racingcar.domain; -public class race { +public class Race { } diff --git a/src/main/java/racingcar/controller.java b/src/main/java/racingcar/controller.java deleted file mode 100644 index 6520313c..00000000 --- a/src/main/java/racingcar/controller.java +++ /dev/null @@ -1,4 +0,0 @@ -package racingcar; - -public class controller { -} diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java deleted file mode 100644 index a4523d1a..00000000 --- a/src/main/java/racingcar/domain/Car.java +++ /dev/null @@ -1,4 +0,0 @@ -package racingcar.domain; - -public class Car { -} diff --git a/src/main/java/racingcar/view.java b/src/main/java/racingcar/view.java deleted file mode 100644 index a537a59f..00000000 --- a/src/main/java/racingcar/view.java +++ /dev/null @@ -1,4 +0,0 @@ -package racingcar; - -public class view { -} diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java new file mode 100644 index 00000000..ff253912 --- /dev/null +++ b/src/main/java/racingcar/view/InputView.java @@ -0,0 +1,4 @@ +package racingcar.view; + +public class input { +} From 4480a210b81aae15135a92865e6b9981dd9899d4 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 14:41:31 +0900 Subject: [PATCH 04/35] =?UTF-8?q?feat:=20controller=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=EC=99=80=20=EC=8B=9C=EB=8F=84?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Race.java | 4 --- .../java/racing/controller/Controller.java | 4 +++ src/main/java/{ => racing}/domain/Car.java | 2 +- src/main/java/racing/domain/Race.java | 4 +++ src/main/java/racing/view/InputView.java | 28 +++++++++++++++++++ src/main/java/racingcar/view/InputView.java | 4 --- 6 files changed, 37 insertions(+), 9 deletions(-) delete mode 100644 src/main/java/domain/Race.java create mode 100644 src/main/java/racing/controller/Controller.java rename src/main/java/{ => racing}/domain/Car.java (82%) create mode 100644 src/main/java/racing/domain/Race.java create mode 100644 src/main/java/racing/view/InputView.java delete mode 100644 src/main/java/racingcar/view/InputView.java diff --git a/src/main/java/domain/Race.java b/src/main/java/domain/Race.java deleted file mode 100644 index 0bba1ab1..00000000 --- a/src/main/java/domain/Race.java +++ /dev/null @@ -1,4 +0,0 @@ -package racingcar.domain; - -public class Race { -} diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java new file mode 100644 index 00000000..f406e60d --- /dev/null +++ b/src/main/java/racing/controller/Controller.java @@ -0,0 +1,4 @@ +package controller; + +public class Controller { +} diff --git a/src/main/java/domain/Car.java b/src/main/java/racing/domain/Car.java similarity index 82% rename from src/main/java/domain/Car.java rename to src/main/java/racing/domain/Car.java index 0a57459c..b98b9925 100644 --- a/src/main/java/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -1,4 +1,4 @@ -package racingcar.domain; +package domain; public class Car { private final String name; diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java new file mode 100644 index 00000000..34a105bf --- /dev/null +++ b/src/main/java/racing/domain/Race.java @@ -0,0 +1,4 @@ +package domain; + +public class Race { +} diff --git a/src/main/java/racing/view/InputView.java b/src/main/java/racing/view/InputView.java new file mode 100644 index 00000000..bfffdbda --- /dev/null +++ b/src/main/java/racing/view/InputView.java @@ -0,0 +1,28 @@ +package racingcar.view; +import java.util.Scanner; + +public class InputView { + + private static final String INPUT_CAR_NAME_MASSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분."; + private static final String INPUT_CAR_COUNT_MASSAGE = "시도할 회수는 몇회인가요?"; + private static final Scanner scanner = new Scanner(System.in); + + public static String inputCarName() { + System.out.println(INPUT_CAR_COUNT_MASSAGE); + return scanner.nextLine(); + } + + public static int inputTrialNumberCount() { + System.out.println(INPUT_CAR_COUNT_MASSAGE); + String input = scanner.nextLine(); + return parseTrialCount(input); + } + + private static int parseTrialCount(String input) { + try { + return Integer.parseInt(input); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] 시도 횟수는 숫자여야합니다."); + } + } +} diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java deleted file mode 100644 index ff253912..00000000 --- a/src/main/java/racingcar/view/InputView.java +++ /dev/null @@ -1,4 +0,0 @@ -package racingcar.view; - -public class input { -} From b566e31e6d3fdf8fc4f168d7b6c7d5bbc0521cd0 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 15:23:21 +0900 Subject: [PATCH 05/35] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8?= =?UTF-8?q?=EB=93=A4=20=EA=B0=9D=EC=B2=B4=EB=A1=9C=20=EB=B0=B0=EC=97=B4=20?= =?UTF-8?q?=EB=A7=8C=EB=93=9C=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racing/controller/Controller.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index f406e60d..cb3bc7d3 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -1,4 +1,27 @@ -package controller; +package racing.controller; + +import racing.view.InputView; +import racing.domain.Car; + +import java.util.ArrayList; +import java.util.List; public class Controller { + public void run(){ + //[1] 자동차, 경기진행 횟수 입력 + String carNameInput = InputView.inputCarName(); + int trialNumber = InputView.inputTrialNumberCount(); + + //[2] 데이터 변환 : 문자열 -> 자동차 객체 배열 + List cars = createCars(carNameInput); + } + private List createCars(String input){ + String[] names = input.split(","); + List cars = new ArrayList<>(); + + for(String name : names) { + cars.add(new Car(name.trim())); + } + return cars; + } } From 159e617990140ae4f749f9bdec1143261893e786 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 15:24:10 +0900 Subject: [PATCH 06/35] =?UTF-8?q?refactor:=20racing=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/view/InputView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/racing/view/InputView.java b/src/main/java/racing/view/InputView.java index bfffdbda..d4286882 100644 --- a/src/main/java/racing/view/InputView.java +++ b/src/main/java/racing/view/InputView.java @@ -1,4 +1,4 @@ -package racingcar.view; +package racing.view; import java.util.Scanner; public class InputView { From 1c4dfe54fd6097acc19e8c1167c5485d1820cf0f Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 15:24:41 +0900 Subject: [PATCH 07/35] =?UTF-8?q?feat:=20car=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=B6=94=EA=B0=80=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Car.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index b98b9925..388b1072 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -1,7 +1,11 @@ -package domain; +package racing.domain; public class Car { private final String name; private int position = 0; private boolean isWinner = false; + + public Car(String name){ + this.name = name; + } } From 7877f6cda398a3aee81f22a22358be4e51993633 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 17:54:39 +0900 Subject: [PATCH 08/35] =?UTF-8?q?fix:=20application=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=97=90=EC=84=9C=20psvm=EC=9C=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/controller/Controller.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index cb3bc7d3..6fbfc3a1 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -7,21 +7,22 @@ import java.util.List; public class Controller { - public void run(){ - //[1] 자동차, 경기진행 횟수 입력 + public static void main(String[] args) { + + // [1] 자동차 이름 및 시도 횟수 입력 받기 String carNameInput = InputView.inputCarName(); int trialNumber = InputView.inputTrialNumberCount(); - - //[2] 데이터 변환 : 문자열 -> 자동차 객체 배열 + System.out.println("입력된 이름: " + carNameInput); //디버깅용 + // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 List cars = createCars(carNameInput); } - private List createCars(String input){ + + private static List createCars(String input) { String[] names = input.split(","); List cars = new ArrayList<>(); - - for(String name : names) { + for (String name : names) { cars.add(new Car(name.trim())); } return cars; } -} +} \ No newline at end of file From 11a0d073b7d8f6607ef94f150dad0e97e1c2d922 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 18:25:02 +0900 Subject: [PATCH 09/35] =?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=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Car.java | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index 388b1072..52737598 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -8,4 +8,38 @@ public class Car { public Car(String name){ this.name = name; } + + private void validateName(String name) { + if (name == null || name.isBlank() || name.length() > 5) { + throw new IllegalArgumentException("[ERROR] 자동차 이름은 1자 이상 5자 이하여야 합니다."); + } + } + + public void move() { + this.position++; + } + + public String getPositionVisualized() { + StringBuilder visualPath = new StringBuilder(); + for (int i = 0; i < position; i++) { + visualPath.append("-"); + } + return visualPath.toString(); + } + + public String getName() { + return name; + } + + public int getPosition() { + return position; + } + + public boolean isWinner() { + return isWinner; + } + + public void setWinner(boolean winner) { + isWinner = winner; + } } From 82e46fbb50f471b0e94646cccd7b8b8171499f34 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 20:56:01 +0900 Subject: [PATCH 10/35] =?UTF-8?q?refactor:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20=ED=98=B8=EC=B6=9C=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/racing/view/InputView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/racing/view/InputView.java b/src/main/java/racing/view/InputView.java index d4286882..d740e736 100644 --- a/src/main/java/racing/view/InputView.java +++ b/src/main/java/racing/view/InputView.java @@ -8,7 +8,7 @@ public class InputView { private static final Scanner scanner = new Scanner(System.in); public static String inputCarName() { - System.out.println(INPUT_CAR_COUNT_MASSAGE); + System.out.println(INPUT_CAR_NAME_MASSAGE); return scanner.nextLine(); } From 059c10aeb8fd7e6e265f283f0d70187227f6ad41 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 21:33:04 +0900 Subject: [PATCH 11/35] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=84=20=EA=B2=80=EC=82=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Car.java | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index 52737598..ba0ced55 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -6,12 +6,25 @@ public class Car { private boolean isWinner = false; public Car(String name){ + + validateName(name); this.name = name; } private void validateName(String name) { - if (name == null || name.isBlank() || name.length() > 5) { - throw new IllegalArgumentException("[ERROR] 자동차 이름은 1자 이상 5자 이하여야 합니다."); + if (name == null || name.isBlank()) { + throw new IllegalArgumentException("[ERROR] 자동차 이름은 1자 이상이어야 합니다."); + } + if (name.length() > 5) { + throw new IllegalArgumentException("[ERROR] 자동차 이름은 5자 이하여야 합니다."); + } + // [추가] 이름 중간에 공백이 포함된 경우를 잡아냅니다. + if (name.contains(" ")) { + throw new IllegalArgumentException("[ERROR] 자동차 이름에 공백을 포함할 수 없습니다."); + } + // [추가] 정규표현식을 통해 특수문자를 검사합니다 (한글, 영문, 숫자만 허용). + if (!name.matches("^[a-zA-Z0-9가-힣]*$")) { + throw new IllegalArgumentException("[ERROR] 자동차 이름에 특수문자를 포함할 수 없습니다."); } } @@ -19,14 +32,6 @@ public void move() { this.position++; } - public String getPositionVisualized() { - StringBuilder visualPath = new StringBuilder(); - for (int i = 0; i < position; i++) { - visualPath.append("-"); - } - return visualPath.toString(); - } - public String getName() { return name; } @@ -39,7 +44,4 @@ public boolean isWinner() { return isWinner; } - public void setWinner(boolean winner) { - isWinner = winner; - } } From 9dd00ba6949f7cb9bb6c16afc2e6ed65c6282b56 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 21:33:50 +0900 Subject: [PATCH 12/35] =?UTF-8?q?feat:=20=EA=B2=BD=EA=B8=B0=EB=A7=88?= =?UTF-8?q?=EB=8B=A4=20=EC=9E=90=EB=8F=99=EC=B0=A8=20=EA=B1=B0=EB=A6=AC?= =?UTF-8?q?=EB=A5=BC=20=EC=B6=9C=EB=A0=A5=ED=95=98=EA=B3=A0=20=EC=B5=9C?= =?UTF-8?q?=EC=A2=85=20=EC=9A=B0=EC=8A=B9=EC=9E=90=EB=A5=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/view/OutputView.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/racing/view/OutputView.java diff --git a/src/main/java/racing/view/OutputView.java b/src/main/java/racing/view/OutputView.java new file mode 100644 index 00000000..ac114bc9 --- /dev/null +++ b/src/main/java/racing/view/OutputView.java @@ -0,0 +1,22 @@ +package racing.view; +import racing.domain.Car; +import java.util.List; + +public class OutputView { + public static void printRoundResult(Car car) { + int position = car.getPosition(); + StringBuilder visualPath = new StringBuilder(); + for (int i = 0; i < position; i++) { + visualPath.append("-"); + } + System.out.println(car.getName() + " : " + visualPath.toString()); + } + + public static void printWinners(List winnerNames) { + if (winnerNames == null || winnerNames.isEmpty()) { + return; + } + String result = String.join(", ", winnerNames); + System.out.println("최종 우승자 : " + result); + } +} From 03accdd7fb955b27fa9081b2c5b9c1c3bc5ca72e Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 21:34:30 +0900 Subject: [PATCH 13/35] =?UTF-8?q?feat:=20=EA=B2=BD=EA=B8=B0=EB=A5=BC=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=ED=95=98=EA=B3=A0=20=EC=9A=B0=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=EB=A5=BC=20=EB=BD=91=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Race.java | 43 ++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java index 34a105bf..2c126002 100644 --- a/src/main/java/racing/domain/Race.java +++ b/src/main/java/racing/domain/Race.java @@ -1,4 +1,45 @@ -package domain; +package racing.domain; + +import java.util.Random; +import java.util.List; +import java.util.stream.Collectors; + +import racing.view.OutputView; public class Race { + // 경기 실행후 출력하는 메서드 + private static final int RANDOM_RANGE = 10; // 0~9 + private static final int MOVE_THRESHOLD = 4; // 4 이상일 때 전진 + private static final Random random = new Random(); + + public static void start(List cars, int trialCount) { + for (int i = 0; i < trialCount; i++) { + runRound(cars); + System.out.println(); // + } + } + + private static void runRound(List cars) { + for (Car car : cars) { + if (shouldMove()) { + car.move(); + OutputView.printRoundResult(car); + } + } + } + private static boolean shouldMove() { + return random.nextInt(RANDOM_RANGE) >= MOVE_THRESHOLD; + } + + public static List getWinners(List cars) { + int maxPosition = cars.stream() + .mapToInt(Car::getPosition) + .max() + .orElse(0); + + return cars.stream() + .filter(car -> car.getPosition() == maxPosition) + .map(Car::getName) + .collect(Collectors.toList()); + } } From 23abbbe5016497a59cb131711e0af18807f0b3a5 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 21:34:54 +0900 Subject: [PATCH 14/35] =?UTF-8?q?feat:=20=EA=B2=BD=EA=B8=B0=EB=A5=BC=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=EC=8B=9C=ED=82=A4=EA=B3=A0=20=EC=9A=B0?= =?UTF-8?q?=EC=8A=B9=EC=9E=90=EB=A5=BC=20=EC=B6=9C=EB=A0=A5=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racing/controller/Controller.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index 6fbfc3a1..6bdc9204 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -1,27 +1,33 @@ package racing.controller; import racing.view.InputView; +import racing.view.OutputView; + import racing.domain.Car; +import racing.domain.Race; + import java.util.ArrayList; import java.util.List; public class Controller { public static void main(String[] args) { - // [1] 자동차 이름 및 시도 횟수 입력 받기 String carNameInput = InputView.inputCarName(); int trialNumber = InputView.inputTrialNumberCount(); - System.out.println("입력된 이름: " + carNameInput); //디버깅용 // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 - List cars = createCars(carNameInput); + var cars = createCars(carNameInput); //cars 라는 자동차 객체 배열 생성 + //[3] 레이씽 경기 시작 + Race.start(cars,trialNumber); + //[4] 결과 출력 + List winners = Race.getWinners(cars); + OutputView.printWinners(winners); } - private static List createCars(String input) { String[] names = input.split(","); - List cars = new ArrayList<>(); + var cars = new ArrayList(); for (String name : names) { - cars.add(new Car(name.trim())); + cars.add(new Car(name)); } return cars; } From cb031fe4e8146eb897f0e4ca2b4236d61b439907 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 22:10:20 +0900 Subject: [PATCH 15/35] =?UTF-8?q?refactor:=20for=EB=AC=B8=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8A=94=20=EA=B2=83?= =?UTF-8?q?=EC=9D=B4=20=EC=95=84=EB=8B=88=EB=9D=BC=20=EC=9E=90=EB=B0=94=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EA=B2=8C=20=EB=B0=94=EA=BF=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Car.java | 12 ++++-------- src/main/java/racing/view/OutputView.java | 7 +------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index ba0ced55..db14d8f6 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -3,10 +3,8 @@ public class Car { private final String name; private int position = 0; - private boolean isWinner = false; public Car(String name){ - validateName(name); this.name = name; } @@ -18,11 +16,9 @@ private void validateName(String name) { if (name.length() > 5) { throw new IllegalArgumentException("[ERROR] 자동차 이름은 5자 이하여야 합니다."); } - // [추가] 이름 중간에 공백이 포함된 경우를 잡아냅니다. if (name.contains(" ")) { throw new IllegalArgumentException("[ERROR] 자동차 이름에 공백을 포함할 수 없습니다."); } - // [추가] 정규표현식을 통해 특수문자를 검사합니다 (한글, 영문, 숫자만 허용). if (!name.matches("^[a-zA-Z0-9가-힣]*$")) { throw new IllegalArgumentException("[ERROR] 자동차 이름에 특수문자를 포함할 수 없습니다."); } @@ -32,6 +28,10 @@ public void move() { this.position++; } + public String getPositionVisualized() { + return "-".repeat(position); + } + public String getName() { return name; } @@ -40,8 +40,4 @@ public int getPosition() { return position; } - public boolean isWinner() { - return isWinner; - } - } diff --git a/src/main/java/racing/view/OutputView.java b/src/main/java/racing/view/OutputView.java index ac114bc9..1d013168 100644 --- a/src/main/java/racing/view/OutputView.java +++ b/src/main/java/racing/view/OutputView.java @@ -4,12 +4,7 @@ public class OutputView { public static void printRoundResult(Car car) { - int position = car.getPosition(); - StringBuilder visualPath = new StringBuilder(); - for (int i = 0; i < position; i++) { - visualPath.append("-"); - } - System.out.println(car.getName() + " : " + visualPath.toString()); + System.out.println(car.getName() + " : " + car.getPositionVisualized()); } public static void printWinners(List winnerNames) { From bfc8e29899247ee0d0d7b102c273c4b461ddf631 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 22:32:41 +0900 Subject: [PATCH 16/35] =?UTF-8?q?refactor:=20=EC=B4=88=EA=B8=B0=EA=B0=92?= =?UTF-8?q?=200=EC=9C=BC=EB=A1=9C=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/racing/domain/Car.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index db14d8f6..b59d9f93 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -7,6 +7,7 @@ public class Car { public Car(String name){ validateName(name); this.name = name; + this.position = 0; } private void validateName(String name) { From 2fa8c6465156bce60addcea159a798be8671daf4 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 22:33:20 +0900 Subject: [PATCH 17/35] =?UTF-8?q?feat:=20CarManager=EB=A5=BC=20=ED=86=B5?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EC=9E=90=EB=8F=99=EC=B0=A8=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/CarManager.java | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/racing/domain/CarManager.java diff --git a/src/main/java/racing/domain/CarManager.java b/src/main/java/racing/domain/CarManager.java new file mode 100644 index 00000000..2d01c382 --- /dev/null +++ b/src/main/java/racing/domain/CarManager.java @@ -0,0 +1,24 @@ +package racing.domain; + +import java.util.ArrayList; +import java.util.List; + +public class CarManager { + public static List createCars(String input) { + String[] names = input.split(","); + var cars = new ArrayList(); + for (String name : names) { + cars.add(new Car(name)); + } + return cars; + } + public static void Duplicate(List cars){ + long distinctCount = cars.stream() + .map(Car::getName) // Car 객체에서 이름을 추출한다고 가정 + .distinct() + .count(); + if (distinctCount != cars.size()) { + throw new IllegalArgumentException("[ERROR]중복된 자동차 이름이 존재합니다."); + } + } +} From e1ad11472a680ac56bfb635bda0f630727f1d8d3 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 22:33:44 +0900 Subject: [PATCH 18/35] =?UTF-8?q?refactor:=20=EC=98=A4=ED=83=80=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/view/InputView.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/racing/view/InputView.java b/src/main/java/racing/view/InputView.java index d740e736..f775fd1d 100644 --- a/src/main/java/racing/view/InputView.java +++ b/src/main/java/racing/view/InputView.java @@ -3,26 +3,30 @@ public class InputView { - private static final String INPUT_CAR_NAME_MASSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분."; - private static final String INPUT_CAR_COUNT_MASSAGE = "시도할 회수는 몇회인가요?"; + private static final String INPUT_CAR_NAME_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분."; + private static final String INPUT_CAR_COUNT_MESSAGE = "시도할 회수는 몇회인가요?"; private static final Scanner scanner = new Scanner(System.in); public static String inputCarName() { - System.out.println(INPUT_CAR_NAME_MASSAGE); + System.out.println(INPUT_CAR_NAME_MESSAGE); return scanner.nextLine(); } public static int inputTrialNumberCount() { - System.out.println(INPUT_CAR_COUNT_MASSAGE); + System.out.println(INPUT_CAR_COUNT_MESSAGE); String input = scanner.nextLine(); return parseTrialCount(input); } private static int parseTrialCount(String input) { try { - return Integer.parseInt(input); + int count = Integer.parseInt(input); + if (count <= 0) { + throw new IllegalArgumentException("[ERROR] 시도 횟수는 1 이상이어야 합니다."); + } + return count; } catch (NumberFormatException e) { - throw new IllegalArgumentException("[ERROR] 시도 횟수는 숫자여야합니다."); + throw new IllegalArgumentException("[ERROR] 시도 횟수는 숫자여야 합니다."); } } } From de9a01b8d0e0b35af02a8eb9b17553c444e05b0d Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 22:34:12 +0900 Subject: [PATCH 19/35] =?UTF-8?q?feat:=20=EC=A4=91=EB=B3=B5=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/controller/Controller.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index 6bdc9204..6d4362ea 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -3,11 +3,9 @@ import racing.view.InputView; import racing.view.OutputView; -import racing.domain.Car; import racing.domain.Race; +import racing.domain.CarManager; - -import java.util.ArrayList; import java.util.List; public class Controller { @@ -16,19 +14,12 @@ public static void main(String[] args) { String carNameInput = InputView.inputCarName(); int trialNumber = InputView.inputTrialNumberCount(); // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 - var cars = createCars(carNameInput); //cars 라는 자동차 객체 배열 생성 + var cars = CarManager.createCars(carNameInput); //cars 라는 자동차 객체 배열 생성 + CarManager.Duplicate(cars); //[3] 레이씽 경기 시작 Race.start(cars,trialNumber); //[4] 결과 출력 List winners = Race.getWinners(cars); OutputView.printWinners(winners); } - private static List createCars(String input) { - String[] names = input.split(","); - var cars = new ArrayList(); - for (String name : names) { - cars.add(new Car(name)); - } - return cars; - } } \ No newline at end of file From 3f90b898c100a724d479ab9acfbb32660371f39e Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 22:34:38 +0900 Subject: [PATCH 20/35] =?UTF-8?q?refactor:=20=EC=B6=9C=EB=A0=A5=ED=98=95?= =?UTF-8?q?=EC=8B=9D=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/racing/view/OutputView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/racing/view/OutputView.java b/src/main/java/racing/view/OutputView.java index 1d013168..0c4f3d21 100644 --- a/src/main/java/racing/view/OutputView.java +++ b/src/main/java/racing/view/OutputView.java @@ -12,6 +12,6 @@ public static void printWinners(List winnerNames) { return; } String result = String.join(", ", winnerNames); - System.out.println("최종 우승자 : " + result); + System.out.println(result + "가 최종 우승했습니다."); } } From f8eb16ba25aa089b4849d277cb47a0ea8cf6f49e Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Sun, 15 Mar 2026 22:34:58 +0900 Subject: [PATCH 21/35] =?UTF-8?q?refactor:=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EC=97=90=EC=84=9C=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Race.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java index 2c126002..21b412c5 100644 --- a/src/main/java/racing/domain/Race.java +++ b/src/main/java/racing/domain/Race.java @@ -3,7 +3,6 @@ import java.util.Random; import java.util.List; import java.util.stream.Collectors; - import racing.view.OutputView; public class Race { @@ -23,8 +22,8 @@ private static void runRound(List cars) { for (Car car : cars) { if (shouldMove()) { car.move(); - OutputView.printRoundResult(car); } + OutputView.printRoundResult(car); } } private static boolean shouldMove() { From c79e89fcae14d992b6a4a971f52db1bd5bd17642 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Mon, 16 Mar 2026 09:19:43 +0900 Subject: [PATCH 22/35] =?UTF-8?q?docs:=20=EA=B8=B0=EB=8A=A5=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EB=AA=A9=EB=A1=9D,=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EA=B7=9C=EC=B9=99,=20=ED=94=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=9E=A8=20=EC=A7=84=ED=96=89=20=EB=B0=A9=EC=8B=9D=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README.md b/README.md index e69de29b..14d24702 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,41 @@ +# 🏎️ 자동차 경주 게임 (Car Racing) + +## 🚀 기능 구현 목록 + +### 1. 입력 및 데이터 처리 +- [ ] **자동차 이름 입력**: 쉼표(`,`)를 기준으로 구분하여 경주에 참여할 자동차 이름을 입력받는다. +- [ ] **데이터 변환**: 입력된 문자열을 분리하여 `Car` 객체 리스트로 생성한다. +- [ ] **시도 횟수 입력**: 전체 자동차가 이동을 시도할 총 횟수를 입력받는다. + +### 2. 레이싱 로직 +- [ ] **전진 조건 확인**: 매 라운드마다 각 자동차별로 무작위 값을 생성하여 전진 여부를 결정한다. +- [ ] **위치 업데이트**: 전진 조건을 만족하는 경우 자동차의 위치를 $1$ 씩 증가시킨다. +- [ ] **우승자 판별**: 모든 라운드 종료 후 전진 거리가 가장 긴 자동차를 우승자로 선정한다. (공동 우승 가능) + +### 3. 출력 +- [ ] **라운드 결과**: 매 라운드 종료 시점의 자동차별 이름과 전진 상태(`-`)를 출력한다. +- [ ] **최종 우승자**: 경주 종료 후 최종 우승자의 이름을 출력한다. (공동 우승 시 쉼표로 구분) + +--- + +## ⚠️ 예외 처리 규칙 (Exception Handling) +잘못된 값 입력 시 `IllegalArgumentException`을 발생시키며, 프로그램은 즉시 종료되거나 에러 메시지를 출력해야 한다. + +### [자동차 이름 관련] +1. **형식 오류**: 알파벳과 한글 이외의 문자(특수문자, 숫자 등)가 포함된 경우. +2. **공백 포함**: 이름 내부에 공백이 있거나, 입력값이 공백으로만 구성된 경우. +3. **입력 부재**: 자동차 이름을 입력하지 않고 진행하려 하는 경우. +4. **중복 발생**: 동일한 이름을 가진 자동차가 리스트 내에 중복으로 존재하는 경우. + +### [시도 횟수 관련] +1. **타입 오류**: 숫자 이외의 문자, 특수기호, 공백이 포함된 경우. +2. **범위 오류**: 입력값이 $0$ 이하의 정수인 경우 (최소 $1$ 회 이상 필요). +3. **미입력**: 시도 횟수를 입력하지 않고 엔터를 입력한 경우. + +--- + +## 💻 프로그램 진행 방식 +1. **[Step 1]** `InputView`를 통한 자동차 이름 및 시도 횟수 입력. +2. **[Step 2]** 입력 데이터 검증 및 `List` 객체 생성. +3. **[Step 3]** 설정된 횟수만큼 경주 실행 및 실시간 결과 출력. +4. **[Step 4]** 최종 우승자 연산 및 `OutputView`를 통한 결과 발표. \ No newline at end of file From 07834914b5926eaac6403c488f658c454bf8308f Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Wed, 18 Mar 2026 21:59:20 +0900 Subject: [PATCH 23/35] =?UTF-8?q?refactor:=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Race.java | 3 +-- src/main/java/racing/view/OutputView.java | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java index 21b412c5..658c3338 100644 --- a/src/main/java/racing/domain/Race.java +++ b/src/main/java/racing/domain/Race.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.stream.Collectors; import racing.view.OutputView; - public class Race { // 경기 실행후 출력하는 메서드 private static final int RANDOM_RANGE = 10; // 0~9 @@ -14,7 +13,7 @@ public class Race { public static void start(List cars, int trialCount) { for (int i = 0; i < trialCount; i++) { runRound(cars); - System.out.println(); // + OutputView.println(); } } diff --git a/src/main/java/racing/view/OutputView.java b/src/main/java/racing/view/OutputView.java index 0c4f3d21..495ec87f 100644 --- a/src/main/java/racing/view/OutputView.java +++ b/src/main/java/racing/view/OutputView.java @@ -14,4 +14,9 @@ public static void printWinners(List winnerNames) { String result = String.join(", ", winnerNames); System.out.println(result + "가 최종 우승했습니다."); } + + public static void println(){ + System.out.println(); + } + } From 00c629658b734f6a58e434cdc24475c45d3ce9d4 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Wed, 18 Mar 2026 21:59:56 +0900 Subject: [PATCH 24/35] =?UTF-8?q?chore:=20=EC=98=A4=ED=83=80=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 --- src/main/java/racing/controller/Controller.java | 2 +- src/main/java/racing/domain/CarManager.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index 6d4362ea..12bf73d1 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -15,7 +15,7 @@ public static void main(String[] args) { int trialNumber = InputView.inputTrialNumberCount(); // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 var cars = CarManager.createCars(carNameInput); //cars 라는 자동차 객체 배열 생성 - CarManager.Duplicate(cars); + CarManager.duplicate(cars); //[3] 레이씽 경기 시작 Race.start(cars,trialNumber); //[4] 결과 출력 diff --git a/src/main/java/racing/domain/CarManager.java b/src/main/java/racing/domain/CarManager.java index 2d01c382..c9f94643 100644 --- a/src/main/java/racing/domain/CarManager.java +++ b/src/main/java/racing/domain/CarManager.java @@ -12,7 +12,7 @@ public static List createCars(String input) { } return cars; } - public static void Duplicate(List cars){ + public static void duplicate(List cars){ long distinctCount = cars.stream() .map(Car::getName) // Car 객체에서 이름을 추출한다고 가정 .distinct() From 63eb12b02ba7f658a6b7a1766b1967eb7edb10ab Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Wed, 18 Mar 2026 22:18:24 +0900 Subject: [PATCH 25/35] =?UTF-8?q?refactor:=20=EC=B0=B8=EC=A1=B0=EC=9E=90?= =?UTF-8?q?=EB=A3=8C=ED=98=95=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/controller/Controller.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index 12bf73d1..02c42959 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -1,5 +1,6 @@ package racing.controller; +import racing.domain.Car; import racing.view.InputView; import racing.view.OutputView; @@ -14,7 +15,7 @@ public static void main(String[] args) { String carNameInput = InputView.inputCarName(); int trialNumber = InputView.inputTrialNumberCount(); // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 - var cars = CarManager.createCars(carNameInput); //cars 라는 자동차 객체 배열 생성 + List cars = CarManager.createCars(carNameInput); //cars 라는 자동차 객체 배열 생성 CarManager.duplicate(cars); //[3] 레이씽 경기 시작 Race.start(cars,trialNumber); From 6f1f03f2ad698562f5a6f6fbeaefd95782f6acda Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 08:55:33 +0900 Subject: [PATCH 26/35] =?UTF-8?q?refactor:=20Domain=EA=B3=BC=20InputView?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=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/racing/domain/Race.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java index 658c3338..ae176c0b 100644 --- a/src/main/java/racing/domain/Race.java +++ b/src/main/java/racing/domain/Race.java @@ -11,6 +11,7 @@ public class Race { private static final Random random = new Random(); public static void start(List cars, int trialCount) { + validateTrialCount(trialCount); for (int i = 0; i < trialCount; i++) { runRound(cars); OutputView.println(); @@ -25,6 +26,13 @@ private static void runRound(List cars) { OutputView.printRoundResult(car); } } + + public static void validateTrialCount(int trialCount){ + if(trialCount <= 0){ + throw new IllegalArgumentException("[ERROR] 시도 횟수는 1회 이상이여야합니다."); + } + } + private static boolean shouldMove() { return random.nextInt(RANDOM_RANGE) >= MOVE_THRESHOLD; } From f0535c2dc8a2a3a9bbba626ae898d4f29f66a3db Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 08:55:44 +0900 Subject: [PATCH 27/35] =?UTF-8?q?refactor:=20Domain=EA=B3=BC=20InputView?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=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/racing/view/InputView.java | 25 +++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/racing/view/InputView.java b/src/main/java/racing/view/InputView.java index f775fd1d..74268544 100644 --- a/src/main/java/racing/view/InputView.java +++ b/src/main/java/racing/view/InputView.java @@ -9,7 +9,10 @@ public class InputView { public static String inputCarName() { System.out.println(INPUT_CAR_NAME_MESSAGE); - return scanner.nextLine(); + String carName = scanner.nextLine(); + validateCarNameFormat(carName); + + return carName; } public static int inputTrialNumberCount() { @@ -18,15 +21,23 @@ public static int inputTrialNumberCount() { return parseTrialCount(input); } + private static void validateCarNameFormat(String input){ + if(input.isBlank()){ + throw new IllegalArgumentException("[ERROR] 입력값이 없습니다."); + } + if(input.contains(",,")){ + throw new IllegalArgumentException("[ERROR] 쉼표가 연속으로 입력되었습니다."); + } + if(input.startsWith(",")||input.endsWith(",")){ + throw new IllegalArgumentException("[ERROR] 입력값의 시작이나 끝에 쉼표가 있습니다."); + } + } private static int parseTrialCount(String input) { try { - int count = Integer.parseInt(input); - if (count <= 0) { - throw new IllegalArgumentException("[ERROR] 시도 횟수는 1 이상이어야 합니다."); - } - return count; + return Integer.parseInt(input); } catch (NumberFormatException e) { - throw new IllegalArgumentException("[ERROR] 시도 횟수는 숫자여야 합니다."); + throw new IllegalArgumentException("[ERROR] 시도 횟수는 정수 형의 숫자여야 합니다."); } } } + From 480d3f6ec2544514354d1085de14bec6402318ed Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 09:04:19 +0900 Subject: [PATCH 28/35] =?UTF-8?q?feat:=20,=EA=B0=80=20=EB=91=90=EB=B3=80?= =?UTF-8?q?=EC=97=B0=EC=86=8D=20=EB=82=98=EC=99=94=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=ED=95=A9=EC=B9=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/view/InputView.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/racing/view/InputView.java b/src/main/java/racing/view/InputView.java index 74268544..071dc540 100644 --- a/src/main/java/racing/view/InputView.java +++ b/src/main/java/racing/view/InputView.java @@ -25,7 +25,8 @@ private static void validateCarNameFormat(String input){ if(input.isBlank()){ throw new IllegalArgumentException("[ERROR] 입력값이 없습니다."); } - if(input.contains(",,")){ + String noSpaceInput = input.replace(" ",""); + if(noSpaceInput.contains(",,")){ throw new IllegalArgumentException("[ERROR] 쉼표가 연속으로 입력되었습니다."); } if(input.startsWith(",")||input.endsWith(",")){ From a3aae797325455755309df1b1931105b707517a3 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 09:09:47 +0900 Subject: [PATCH 29/35] =?UTF-8?q?refactor:=20domain=EC=97=90=EC=84=9C=20-?= =?UTF-8?q?=EB=A1=9C=20=ED=91=9C=EC=8B=9C=EB=90=9C=20=EA=B8=B8=EC=9D=84=20?= =?UTF-8?q?outputView=EC=97=90=EC=84=9C=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Car.java | 9 +++++---- src/main/java/racing/view/OutputView.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index b59d9f93..4d5ea985 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -2,12 +2,12 @@ public class Car { private final String name; - private int position = 0; + private int position = 0; - public Car(String name){ + public Car(String name) { validateName(name); this.name = name; - this.position = 0; + this.position = 0; } private void validateName(String name) { @@ -41,4 +41,5 @@ public int getPosition() { return position; } -} + +} \ No newline at end of file diff --git a/src/main/java/racing/view/OutputView.java b/src/main/java/racing/view/OutputView.java index 495ec87f..d0b0aa84 100644 --- a/src/main/java/racing/view/OutputView.java +++ b/src/main/java/racing/view/OutputView.java @@ -4,7 +4,7 @@ public class OutputView { public static void printRoundResult(Car car) { - System.out.println(car.getName() + " : " + car.getPositionVisualized()); + System.out.println(car.getName() + " : " + "-".repeat(car.getPosition())); } public static void printWinners(List winnerNames) { From 7ff14c64eaee10cd2c98113695d6556eba153ce6 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 09:16:54 +0900 Subject: [PATCH 30/35] =?UTF-8?q?refactor:=20=EB=B9=84=EC=A7=80=EB=8B=88?= =?UTF-8?q?=EC=8A=A4=20=EA=B7=9C=EC=B9=99=EC=9D=B8=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/view/InputView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/racing/view/InputView.java b/src/main/java/racing/view/InputView.java index 071dc540..b5543ea3 100644 --- a/src/main/java/racing/view/InputView.java +++ b/src/main/java/racing/view/InputView.java @@ -32,6 +32,7 @@ private static void validateCarNameFormat(String input){ if(input.startsWith(",")||input.endsWith(",")){ throw new IllegalArgumentException("[ERROR] 입력값의 시작이나 끝에 쉼표가 있습니다."); } + } private static int parseTrialCount(String input) { try { From 4e5c715b03681cec3540c8d67be62de5293e2652 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 14:24:13 +0900 Subject: [PATCH 31/35] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Car.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index 4d5ea985..5cf8bdda 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -29,9 +29,6 @@ public void move() { this.position++; } - public String getPositionVisualized() { - return "-".repeat(position); - } public String getName() { return name; From beec64eabadc7515bd4ac27be07078e33f0c0c49 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 15:49:00 +0900 Subject: [PATCH 32/35] =?UTF-8?q?refactor:=20static=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B0=9D=EC=B2=B4=20=ED=98=95=ED=83=9C?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racing/controller/Controller.java | 26 +++--- .../domain/{CarManager.java => Cars.java} | 18 ++-- src/main/java/racing/domain/Race.java | 85 ++++++++++--------- 3 files changed, 72 insertions(+), 57 deletions(-) rename src/main/java/racing/domain/{CarManager.java => Cars.java} (66%) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index 02c42959..f28ac493 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -2,25 +2,31 @@ import racing.domain.Car; import racing.view.InputView; -import racing.view.OutputView; -import racing.domain.Race; -import racing.domain.CarManager; - -import java.util.List; +import racing.domain.Cars; public class Controller { public static void main(String[] args) { // [1] 자동차 이름 및 시도 횟수 입력 받기 String carNameInput = InputView.inputCarName(); int trialNumber = InputView.inputTrialNumberCount(); + + // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 - List cars = CarManager.createCars(carNameInput); //cars 라는 자동차 객체 배열 생성 - CarManager.duplicate(cars); + Cars cars = new Cars(carNameInput); + for (Car car : cars.getCarList()){ // 디버깅용 + System.out.println(car.getName()); + } + //Race race = new Race(CarManager); + //[3] 레이씽 경기 시작 - Race.start(cars,trialNumber); + // Race.start(cars,trialNumber); + + //[4] 결과 출력 - List winners = Race.getWinners(cars); - OutputView.printWinners(winners); + // List winners = Race.getWinners(cars); + // OutputView.printWinners(winners); + + } } \ No newline at end of file diff --git a/src/main/java/racing/domain/CarManager.java b/src/main/java/racing/domain/Cars.java similarity index 66% rename from src/main/java/racing/domain/CarManager.java rename to src/main/java/racing/domain/Cars.java index c9f94643..9c3d715b 100644 --- a/src/main/java/racing/domain/CarManager.java +++ b/src/main/java/racing/domain/Cars.java @@ -3,16 +3,18 @@ import java.util.ArrayList; import java.util.List; -public class CarManager { - public static List createCars(String input) { +public class Cars { + private final List cars; + + public Cars(String input) { String[] names = input.split(","); - var cars = new ArrayList(); + this.cars = new ArrayList<>(); for (String name : names) { - cars.add(new Car(name)); + this.cars.add(new Car(name)); } - return cars; + validateDuplicate(); } - public static void duplicate(List cars){ + private void validateDuplicate(){ long distinctCount = cars.stream() .map(Car::getName) // Car 객체에서 이름을 추출한다고 가정 .distinct() @@ -21,4 +23,8 @@ public static void duplicate(List cars){ throw new IllegalArgumentException("[ERROR]중복된 자동차 이름이 존재합니다."); } } + + public List getCarList(){ + return cars; + } } diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java index ae176c0b..f66d13fe 100644 --- a/src/main/java/racing/domain/Race.java +++ b/src/main/java/racing/domain/Race.java @@ -1,51 +1,54 @@ -package racing.domain; - -import java.util.Random; -import java.util.List; -import java.util.stream.Collectors; -import racing.view.OutputView; -public class Race { - // 경기 실행후 출력하는 메서드 - private static final int RANDOM_RANGE = 10; // 0~9 - private static final int MOVE_THRESHOLD = 4; // 4 이상일 때 전진 - private static final Random random = new Random(); - - public static void start(List cars, int trialCount) { - validateTrialCount(trialCount); - for (int i = 0; i < trialCount; i++) { - runRound(cars); - OutputView.println(); + package racing.domain; + + import java.util.Random; + import java.util.List; + import java.util.stream.Collectors; + import racing.view.OutputView; + public class Race { + // 경기 실행후 출력하는 메서드 + private static final int RANDOM_RANGE = 10; // 0~9 + private static final int MOVE_THRESHOLD = 4; // 4 이상일 때 전진 + private static final Random random = new Random(); + + + + + public static void start(List cars, int trialCount) { + validateTrialCount(trialCount); + for (int i = 0; i < trialCount; i++) { + runRound(cars); + OutputView.println(); + } } - } - private static void runRound(List cars) { - for (Car car : cars) { - if (shouldMove()) { - car.move(); + private static void runRound(List cars) { + for (Car car : cars) { + if (shouldMove()) { + car.move(); + } + OutputView.printRoundResult(car); } - OutputView.printRoundResult(car); } - } - public static void validateTrialCount(int trialCount){ - if(trialCount <= 0){ - throw new IllegalArgumentException("[ERROR] 시도 횟수는 1회 이상이여야합니다."); + public static void validateTrialCount(int trialCount){ + if(trialCount <= 0){ + throw new IllegalArgumentException("[ERROR] 시도 횟수는 1회 이상이여야합니다."); + } } - } - private static boolean shouldMove() { - return random.nextInt(RANDOM_RANGE) >= MOVE_THRESHOLD; - } + private static boolean shouldMove() { + return random.nextInt(RANDOM_RANGE) >= MOVE_THRESHOLD; + } - public static List getWinners(List cars) { - int maxPosition = cars.stream() - .mapToInt(Car::getPosition) - .max() - .orElse(0); + public static List getWinners(List cars) { + int maxPosition = cars.stream() + .mapToInt(Car::getPosition) + .max() + .orElse(0); - return cars.stream() - .filter(car -> car.getPosition() == maxPosition) - .map(Car::getName) - .collect(Collectors.toList()); + return cars.stream() + .filter(car -> car.getPosition() == maxPosition) + .map(Car::getName) + .collect(Collectors.toList()); + } } -} From 2383aca5db7e3ece8468a3bf1f8a4371d904c1b2 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 16:43:23 +0900 Subject: [PATCH 33/35] =?UTF-8?q?refactor:=20=EC=B4=88=EA=B8=B0=EA=B0=92?= =?UTF-8?q?=200=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/domain/Car.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index 5cf8bdda..d764fcd8 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -2,7 +2,7 @@ public class Car { private final String name; - private int position = 0; + private int position; public Car(String name) { validateName(name); From f84be8af7d9210f51345d7a71d1e68165d460397 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 16:47:34 +0900 Subject: [PATCH 34/35] =?UTF-8?q?refactor:=20=EB=9E=9C=EB=8D=A4=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=EC=9D=84=20=EA=B2=80=EC=A6=9D=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=B4,=20static=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=97=90=EC=84=9C=20race=20=EA=B0=9D=EC=B2=B4=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racing/controller/Controller.java | 19 +++++--- src/main/java/racing/domain/Cars.java | 7 +++ src/main/java/racing/domain/MoveStrategy.java | 6 +++ src/main/java/racing/domain/Race.java | 44 ++++++------------- .../racing/domain/RandomMoveStrategy.java | 14 ++++++ src/main/java/racing/view/OutputView.java | 7 ++- 6 files changed, 58 insertions(+), 39 deletions(-) create mode 100644 src/main/java/racing/domain/MoveStrategy.java create mode 100644 src/main/java/racing/domain/RandomMoveStrategy.java diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index f28ac493..5ede2675 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -4,27 +4,32 @@ import racing.view.InputView; import racing.domain.Cars; +import racing.domain.Race; +import racing.domain.RandomMoveStrategy; +import racing.view.OutputView; public class Controller { public static void main(String[] args) { // [1] 자동차 이름 및 시도 횟수 입력 받기 String carNameInput = InputView.inputCarName(); int trialNumber = InputView.inputTrialNumberCount(); - + Race.validateTrialCount(trialNumber); // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 Cars cars = new Cars(carNameInput); - for (Car car : cars.getCarList()){ // 디버깅용 - System.out.println(car.getName()); - } - //Race race = new Race(CarManager); + Race race = new Race(cars); //[3] 레이씽 경기 시작 - // Race.start(cars,trialNumber); + RandomMoveStrategy moveStrategy = new RandomMoveStrategy(); + for (int i = 0; i < trialNumber; i++) { + race.playRound(moveStrategy); + OutputView.printRoundResult(race.getParticipatingCars()); + OutputView.println(); + } //[4] 결과 출력 - // List winners = Race.getWinners(cars); + OutputView.printWinners(race.getWinners()); // OutputView.printWinners(winners); diff --git a/src/main/java/racing/domain/Cars.java b/src/main/java/racing/domain/Cars.java index 9c3d715b..4a3faf75 100644 --- a/src/main/java/racing/domain/Cars.java +++ b/src/main/java/racing/domain/Cars.java @@ -23,6 +23,13 @@ private void validateDuplicate(){ throw new IllegalArgumentException("[ERROR]중복된 자동차 이름이 존재합니다."); } } + public void moveAll(MoveStrategy moveStrategy) { + for (Car car : cars) { + if (moveStrategy.isMovable()) { + car.move(); + } + } + } public List getCarList(){ return cars; diff --git a/src/main/java/racing/domain/MoveStrategy.java b/src/main/java/racing/domain/MoveStrategy.java new file mode 100644 index 00000000..51b5f4ae --- /dev/null +++ b/src/main/java/racing/domain/MoveStrategy.java @@ -0,0 +1,6 @@ +package racing.domain; + +// 무작위 값에 의존하지 않고 테스트를 가능하게 하는 전략 인터페이스 +public interface MoveStrategy { + boolean isMovable(); +} \ No newline at end of file diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java index f66d13fe..9b9c2b00 100644 --- a/src/main/java/racing/domain/Race.java +++ b/src/main/java/racing/domain/Race.java @@ -1,52 +1,36 @@ package racing.domain; - import java.util.Random; import java.util.List; import java.util.stream.Collectors; - import racing.view.OutputView; public class Race { - // 경기 실행후 출력하는 메서드 - private static final int RANDOM_RANGE = 10; // 0~9 - private static final int MOVE_THRESHOLD = 4; // 4 이상일 때 전진 - private static final Random random = new Random(); + private final Cars cars; - - - - public static void start(List cars, int trialCount) { - validateTrialCount(trialCount); - for (int i = 0; i < trialCount; i++) { - runRound(cars); - OutputView.println(); - } + public Race(Cars cars){ + this.cars = cars; } - private static void runRound(List cars) { - for (Car car : cars) { - if (shouldMove()) { - car.move(); - } - OutputView.printRoundResult(car); - } + public void playRound(MoveStrategy moveStrategy) { + cars.moveAll(moveStrategy); + } + public List getParticipatingCars() { + return cars.getCarList(); } - public static void validateTrialCount(int trialCount){ - if(trialCount <= 0){ + public static void validateTrialCount(int tryNumber){ + if(tryNumber <= 0){ throw new IllegalArgumentException("[ERROR] 시도 횟수는 1회 이상이여야합니다."); } } - private static boolean shouldMove() { - return random.nextInt(RANDOM_RANGE) >= MOVE_THRESHOLD; - } - public static List getWinners(List cars) { - int maxPosition = cars.stream() + public List getWinners() { + List carList = cars.getCarList(); + int maxPosition = carList.stream() .mapToInt(Car::getPosition) .max() .orElse(0); - return cars.stream() + return carList.stream() .filter(car -> car.getPosition() == maxPosition) .map(Car::getName) .collect(Collectors.toList()); diff --git a/src/main/java/racing/domain/RandomMoveStrategy.java b/src/main/java/racing/domain/RandomMoveStrategy.java new file mode 100644 index 00000000..ae9ff531 --- /dev/null +++ b/src/main/java/racing/domain/RandomMoveStrategy.java @@ -0,0 +1,14 @@ +package racing.domain; + +import java.util.Random; + +public class RandomMoveStrategy implements MoveStrategy { + private static final int RANDOM_RANGE = 10; + private static final int MOVE_THRESHOLD = 4; + private static final Random random = new Random(); + + @Override + public boolean isMovable() { + return random.nextInt(RANDOM_RANGE) >= MOVE_THRESHOLD; + } +} \ No newline at end of file diff --git a/src/main/java/racing/view/OutputView.java b/src/main/java/racing/view/OutputView.java index d0b0aa84..0041eb29 100644 --- a/src/main/java/racing/view/OutputView.java +++ b/src/main/java/racing/view/OutputView.java @@ -3,8 +3,10 @@ import java.util.List; public class OutputView { - public static void printRoundResult(Car car) { - System.out.println(car.getName() + " : " + "-".repeat(car.getPosition())); + public static void printRoundResult(List cars) { + for (Car car : cars) { + System.out.println(car.getName() + " : " + "-".repeat(car.getPosition())); + } } public static void printWinners(List winnerNames) { @@ -15,6 +17,7 @@ public static void printWinners(List winnerNames) { System.out.println(result + "가 최종 우승했습니다."); } + public static void println(){ System.out.println(); } From 16f3a0974c1ae5aa00b57e5cf499d539535620e6 Mon Sep 17 00:00:00 2001 From: hapdaypy Date: Thu, 19 Mar 2026 17:52:33 +0900 Subject: [PATCH 35/35] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EA=B3=B5=EB=B0=B1=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racing/controller/Controller.java | 6 ------ src/main/java/racing/domain/Car.java | 4 ---- src/main/java/racing/domain/Cars.java | 1 - src/main/java/racing/domain/MoveStrategy.java | 1 - src/main/java/racing/domain/Race.java | 4 ---- src/main/java/racing/domain/RandomMoveStrategy.java | 1 - 6 files changed, 17 deletions(-) diff --git a/src/main/java/racing/controller/Controller.java b/src/main/java/racing/controller/Controller.java index 5ede2675..f57eee42 100644 --- a/src/main/java/racing/controller/Controller.java +++ b/src/main/java/racing/controller/Controller.java @@ -14,24 +14,18 @@ public static void main(String[] args) { String carNameInput = InputView.inputCarName(); int trialNumber = InputView.inputTrialNumberCount(); Race.validateTrialCount(trialNumber); - // [2] 데이터 변환: 문자열 -> 자동차 객체 리스트 Cars cars = new Cars(carNameInput); Race race = new Race(cars); - //[3] 레이씽 경기 시작 RandomMoveStrategy moveStrategy = new RandomMoveStrategy(); - for (int i = 0; i < trialNumber; i++) { race.playRound(moveStrategy); OutputView.printRoundResult(race.getParticipatingCars()); OutputView.println(); } - //[4] 결과 출력 OutputView.printWinners(race.getWinners()); - // OutputView.printWinners(winners); - } } \ No newline at end of file diff --git a/src/main/java/racing/domain/Car.java b/src/main/java/racing/domain/Car.java index d764fcd8..4206bd48 100644 --- a/src/main/java/racing/domain/Car.java +++ b/src/main/java/racing/domain/Car.java @@ -9,7 +9,6 @@ public Car(String name) { this.name = name; this.position = 0; } - private void validateName(String name) { if (name == null || name.isBlank()) { throw new IllegalArgumentException("[ERROR] 자동차 이름은 1자 이상이어야 합니다."); @@ -24,12 +23,9 @@ private void validateName(String name) { throw new IllegalArgumentException("[ERROR] 자동차 이름에 특수문자를 포함할 수 없습니다."); } } - public void move() { this.position++; } - - public String getName() { return name; } diff --git a/src/main/java/racing/domain/Cars.java b/src/main/java/racing/domain/Cars.java index 4a3faf75..598aa8dd 100644 --- a/src/main/java/racing/domain/Cars.java +++ b/src/main/java/racing/domain/Cars.java @@ -30,7 +30,6 @@ public void moveAll(MoveStrategy moveStrategy) { } } } - public List getCarList(){ return cars; } diff --git a/src/main/java/racing/domain/MoveStrategy.java b/src/main/java/racing/domain/MoveStrategy.java index 51b5f4ae..dd2f1df2 100644 --- a/src/main/java/racing/domain/MoveStrategy.java +++ b/src/main/java/racing/domain/MoveStrategy.java @@ -1,6 +1,5 @@ package racing.domain; -// 무작위 값에 의존하지 않고 테스트를 가능하게 하는 전략 인터페이스 public interface MoveStrategy { boolean isMovable(); } \ No newline at end of file diff --git a/src/main/java/racing/domain/Race.java b/src/main/java/racing/domain/Race.java index 9b9c2b00..e2cd7149 100644 --- a/src/main/java/racing/domain/Race.java +++ b/src/main/java/racing/domain/Race.java @@ -8,21 +8,17 @@ public class Race { public Race(Cars cars){ this.cars = cars; } - public void playRound(MoveStrategy moveStrategy) { cars.moveAll(moveStrategy); } public List getParticipatingCars() { return cars.getCarList(); } - public static void validateTrialCount(int tryNumber){ if(tryNumber <= 0){ throw new IllegalArgumentException("[ERROR] 시도 횟수는 1회 이상이여야합니다."); } } - - public List getWinners() { List carList = cars.getCarList(); int maxPosition = carList.stream() diff --git a/src/main/java/racing/domain/RandomMoveStrategy.java b/src/main/java/racing/domain/RandomMoveStrategy.java index ae9ff531..507ccc64 100644 --- a/src/main/java/racing/domain/RandomMoveStrategy.java +++ b/src/main/java/racing/domain/RandomMoveStrategy.java @@ -6,7 +6,6 @@ public class RandomMoveStrategy implements MoveStrategy { private static final int RANDOM_RANGE = 10; private static final int MOVE_THRESHOLD = 4; private static final Random random = new Random(); - @Override public boolean isMovable() { return random.nextInt(RANDOM_RANGE) >= MOVE_THRESHOLD;