From f30198555535c64ab9e2eb87ad2b50bcde0a4132 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 29 Mar 2026 21:44:46 +0900 Subject: [PATCH 01/22] =?UTF-8?q?=EA=B5=AC=ED=98=84=ED=95=A0=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=AA=A9=EB=A1=9D=EC=9D=84=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/README.md b/docs/README.md index e69de29..146e53f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,21 @@ +# 기능 목록 + +## 입력 +- 경주할 자동차 이름을 ,기준으로 입력받는다. +- 시도할 횟수를 입력받는다. + +## 입력 검증 +- 자동차 이름이 공백이거나 빈값이면 `IllegalArgumentException`을 발생시킨다. +- 자동차 이름이 5자를 초과하면 `IllegalArgumentException`을 발생시킨다. +- 자동차 이름이 중복되면 `IllegalArgumentException`을 발생시킨다. +- 시도할 횟수가 숫자가 아니면 `IllegalArgumentException`을 발생시킨다. +- 시도할 횟수가 1 미만이면 `IllegalArgumentException`을 발생시킨다. + +## 자동차 이동 +- 0~9 사이의 무작위 값을 발생시킨다. +- 무작위 값이 4 이상이면 전진한다. + +## 출력 +- 각 횟수별 실행 결과를 자동차 이름과 함께 출력한다. +- 최종 우승자를 출력한다. +- 우승자가 여러 명일 경우 ,로 구분하여 출력한다. \ No newline at end of file From 10a498c9870dfa76b3185cfab5bdf33535c4f854 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 29 Mar 2026 21:57:12 +0900 Subject: [PATCH 02/22] =?UTF-8?q?1.=20=EA=B2=BD=EC=A3=BC=ED=95=A0=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=B0=A8=20=EC=9D=B4=EB=A6=84=EC=9D=84=20,?= =?UTF-8?q?=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=B0=9B=EB=8A=94=EB=8B=A4.=202.=20=EC=8B=9C=EB=8F=84=ED=95=A0?= =?UTF-8?q?=20=ED=9A=9F=EC=88=98=EB=A5=BC=20=EC=9E=85=EB=A0=A5=EB=B0=9B?= =?UTF-8?q?=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Application.java | 3 ++- src/main/java/racingcar/RunRacingGame.java | 12 ++++++++++++ src/main/java/racingcar/util/Utils.java | 17 +++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/RunRacingGame.java create mode 100644 src/main/java/racingcar/util/Utils.java diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e..22e50b8 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -3,5 +3,6 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + new RunRacingGame().run(); } -} +} \ No newline at end of file diff --git a/src/main/java/racingcar/RunRacingGame.java b/src/main/java/racingcar/RunRacingGame.java new file mode 100644 index 0000000..be3b832 --- /dev/null +++ b/src/main/java/racingcar/RunRacingGame.java @@ -0,0 +1,12 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Console; + +import static racingcar.util.Utils.splitNames; + +public class RunRacingGame { + public void run() { + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + String[] carNames = splitNames(Console.readLine()); + System.out.println("시도할 회수는 몇회인가요?");} +} diff --git a/src/main/java/racingcar/util/Utils.java b/src/main/java/racingcar/util/Utils.java new file mode 100644 index 0000000..edf7f3b --- /dev/null +++ b/src/main/java/racingcar/util/Utils.java @@ -0,0 +1,17 @@ +package racingcar.util; + +import java.util.HashSet; + +public class Utils { + + public static String[] splitNames(String input) { + String[] names = input.split(","); + HashSet set = new HashSet<>(); + for (String name : names) { + if (!set.add(name)) { + throw new IllegalArgumentException("이름 중복은 허용 안됩니다."); + } + } + return names; + } +} From e9062b9e6febc701ee929084d9f567dc8e81f032 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 29 Mar 2026 21:58:29 +0900 Subject: [PATCH 03/22] =?UTF-8?q?1.=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EA=B3=B5=EB=B0=B1/=EB=B9=88=EA=B0=92=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=202.=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=205=EC=9E=90=20=EC=B4=88=EA=B3=BC=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=203.=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=A4=91=EB=B3=B5=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?4.=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F=EC=88=98=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=EC=97=AC=EB=B6=80=20=EA=B2=80=EC=A6=9D=205.=20?= =?UTF-8?q?=EC=8B=9C=EB=8F=84=20=ED=9A=9F=EC=88=98=201=20=EB=AF=B8?= =?UTF-8?q?=EB=A7=8C=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/util/Utils.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/racingcar/util/Utils.java b/src/main/java/racingcar/util/Utils.java index edf7f3b..be8143f 100644 --- a/src/main/java/racingcar/util/Utils.java +++ b/src/main/java/racingcar/util/Utils.java @@ -4,6 +4,27 @@ public class Utils { + public static void isValidName(String name) { + if (name.isBlank() || name.contains(" ")) { + throw new IllegalArgumentException("이름 공백 또는 빈값은 안됩니다."); + } + if (name.length() > 5) { + throw new IllegalArgumentException("5글자 초과했습니다."); + } + } + + public static int isValidNumber(String input) { + try { + int number = Integer.parseInt(input); + if (number < 1) { + throw new IllegalArgumentException("1 미만의 숫자는 입력할 수 없습니다."); + } + return number; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자를 입력해야 합니다."); + } + } + public static String[] splitNames(String input) { String[] names = input.split(","); HashSet set = new HashSet<>(); From 7fb3d416003f3695745b54885014205d3376d42b Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 29 Mar 2026 22:00:28 +0900 Subject: [PATCH 04/22] =?UTF-8?q?=201.=200~9=20=EC=82=AC=EC=9D=B4=20?= =?UTF-8?q?=EB=AC=B4=EC=9E=91=EC=9C=84=20=EA=B0=92=20=EB=B0=9C=EC=83=9D=20?= =?UTF-8?q?=202.=20=EB=AC=B4=EC=9E=91=EC=9C=84=20=EA=B0=92=204=20=EC=9D=B4?= =?UTF-8?q?=EC=83=81=EC=9D=B4=EB=A9=B4=20=EC=A0=84=EC=A7=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/entity/Car.java | 29 ++++++++++++++++++++++++ src/main/java/racingcar/entity/Cars.java | 17 ++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/racingcar/entity/Car.java create mode 100644 src/main/java/racingcar/entity/Cars.java diff --git a/src/main/java/racingcar/entity/Car.java b/src/main/java/racingcar/entity/Car.java new file mode 100644 index 0000000..0dce94d --- /dev/null +++ b/src/main/java/racingcar/entity/Car.java @@ -0,0 +1,29 @@ +package racingcar.entity; + +import camp.nextstep.edu.missionutils.Randoms; +import racingcar.util.Utils; + +public class Car { + private final String name; + private int moveCnt; + + public Car(String name) { + Utils.isValidName(this.name = name); + this.moveCnt = 0; + } + + public String getName() { + return this.name; + } + + public int getMoveCnt() { + return this.moveCnt; + } + + public void setMoveCnt() { + int RandomNum = Randoms.pickNumberInRange(0, 9); + if (RandomNum >= 4) { + this.moveCnt += 1; + } + } +} diff --git a/src/main/java/racingcar/entity/Cars.java b/src/main/java/racingcar/entity/Cars.java new file mode 100644 index 0000000..6df538f --- /dev/null +++ b/src/main/java/racingcar/entity/Cars.java @@ -0,0 +1,17 @@ +package racingcar.entity; + +import java.util.ArrayList; + +public class Cars { + private ArrayList cars; + + public Cars(ArrayList cars) { + this.cars = cars; + } + + public void moveAllCars() { + for (Car car : this.cars) { + car.setMoveCnt(); + } + } +} From 7863cdfa3b646a32254474af422e98544985af02 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 29 Mar 2026 22:01:38 +0900 Subject: [PATCH 05/22] =?UTF-8?q?=201.=20=EA=B0=81=20=ED=9A=9F=EC=88=98?= =?UTF-8?q?=EB=B3=84=20=EC=8B=A4=ED=96=89=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=202.=20=EC=B5=9C=EC=A2=85=20=EC=9A=B0=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=20=EC=B6=9C=EB=A0=A5=20=203.=20=EA=B3=B5=EB=8F=99=20?= =?UTF-8?q?=EC=9A=B0=EC=8A=B9=EC=9E=90=20,=20=EA=B5=AC=EB=B6=84=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/RunRacingGame.java | 23 +++++++++++++++- src/main/java/racingcar/entity/Cars.java | 32 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/RunRacingGame.java b/src/main/java/racingcar/RunRacingGame.java index be3b832..3d3e639 100644 --- a/src/main/java/racingcar/RunRacingGame.java +++ b/src/main/java/racingcar/RunRacingGame.java @@ -1,12 +1,33 @@ package racingcar; import camp.nextstep.edu.missionutils.Console; +import racingcar.entity.Car; +import racingcar.entity.Cars; +import java.util.ArrayList; + +import static racingcar.util.Utils.isValidNumber; import static racingcar.util.Utils.splitNames; public class RunRacingGame { public void run() { System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); String[] carNames = splitNames(Console.readLine()); - System.out.println("시도할 회수는 몇회인가요?");} + System.out.println("시도할 회수는 몇회인가요?"); + int number = isValidNumber(Console.readLine()); + + ArrayList carsList = new ArrayList<>(); + for (String carName : carNames) { + Car car = new Car(carName); + carsList.add(car); + } + + System.out.println("\n실행 결과"); + Cars cars = new Cars(carsList); + for (int i = 0; i < number; i++) { + cars.moveAllCars(); + cars.printMoveResult(); + } + cars.printWinner(); + } } diff --git a/src/main/java/racingcar/entity/Cars.java b/src/main/java/racingcar/entity/Cars.java index 6df538f..c286bf9 100644 --- a/src/main/java/racingcar/entity/Cars.java +++ b/src/main/java/racingcar/entity/Cars.java @@ -14,4 +14,36 @@ public void moveAllCars() { car.setMoveCnt(); } } + + public void printMoveResult() { + for (Car car : this.cars) { + System.out.println(car.getName() + " : " + "-".repeat(car.getMoveCnt())); + } + System.out.println(); + } + + private int findMaxMoveCnt() { + int max = 0; + for (Car car : this.cars) { + if (car.getMoveCnt() > max) { + max = car.getMoveCnt(); + } + } + return max; + } + + private ArrayList findWinners(int max) { + ArrayList winners = new ArrayList<>(); + for (Car car : this.cars) { + if (car.getMoveCnt() == max) { + winners.add(car.getName()); + } + } + return winners; + } + + public void printWinner() { + ArrayList winners = findWinners(findMaxMoveCnt()); + System.out.println("최종 우승자 : " + String.join(", ", winners)); + } } From 24cb63df6dfc4b4d192dc2a55f6e6d1d4f8f244a Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 20:47:55 +0900 Subject: [PATCH 06/22] =?UTF-8?q?refactor:=20[input=20=EA=B0=92=EA=B3=BC?= =?UTF-8?q?=20output=EA=B2=B0=EA=B3=BC=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EC=B1=85=EC=9E=84=EC=9D=84=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/racingcar/RunRacingGame.java | 29 +++------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/src/main/java/racingcar/RunRacingGame.java b/src/main/java/racingcar/RunRacingGame.java index 3d3e639..66b4a21 100644 --- a/src/main/java/racingcar/RunRacingGame.java +++ b/src/main/java/racingcar/RunRacingGame.java @@ -1,33 +1,10 @@ package racingcar; -import camp.nextstep.edu.missionutils.Console; -import racingcar.entity.Car; -import racingcar.entity.Cars; - -import java.util.ArrayList; - -import static racingcar.util.Utils.isValidNumber; -import static racingcar.util.Utils.splitNames; public class RunRacingGame { public void run() { - System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); - String[] carNames = splitNames(Console.readLine()); - System.out.println("시도할 회수는 몇회인가요?"); - int number = isValidNumber(Console.readLine()); - - ArrayList carsList = new ArrayList<>(); - for (String carName : carNames) { - Car car = new Car(carName); - carsList.add(car); - } - - System.out.println("\n실행 결과"); - Cars cars = new Cars(carsList); - for (int i = 0; i < number; i++) { - cars.moveAllCars(); - cars.printMoveResult(); - } - cars.printWinner(); + //TODO : Input과 Output 출력하는 책임을 분리 진행 + private racingCarInput input = new racingCarInput(); + private racingCarOutput output = new racingCarOutput(); } } From 7eaa067c8894f456407c15373223d46d89caa6bd Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 20:50:35 +0900 Subject: [PATCH 07/22] =?UTF-8?q?feature:=20=EA=B2=BD=EC=A3=BC=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=B0=A8=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/RunRacingGame.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/racingcar/RunRacingGame.java b/src/main/java/racingcar/RunRacingGame.java index 66b4a21..2acef9a 100644 --- a/src/main/java/racingcar/RunRacingGame.java +++ b/src/main/java/racingcar/RunRacingGame.java @@ -1,6 +1,8 @@ package racingcar; +import racingcar.view.racingCarInput; + public class RunRacingGame { public void run() { //TODO : Input과 Output 출력하는 책임을 분리 진행 From b5637730647caadb13128b1219d049d9b7672b34 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 20:52:43 +0900 Subject: [PATCH 08/22] =?UTF-8?q?feature:=20=EA=B2=BD=EC=A3=BC=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=B0=A8=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F=EC=88=98=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/view/racingCarInput.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/racingcar/view/racingCarInput.java diff --git a/src/main/java/racingcar/view/racingCarInput.java b/src/main/java/racingcar/view/racingCarInput.java new file mode 100644 index 0000000..7aa33d2 --- /dev/null +++ b/src/main/java/racingcar/view/racingCarInput.java @@ -0,0 +1,14 @@ +package racingcar.view; + +import camp.nextstep.edu.missionutils.Console; + +public class racingCarInput { + public String[] readCarNames() { + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + return Console.readLine().split(","); + } + public int readTryCount() { + System.out.println("시도할 회수는 몇회인가요?"); + return TryCountValidator.validate(Console.readLine()); + } +} \ No newline at end of file From 6dcddaafe308190d3029c32073a6e0c9f94e6549 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 20:55:42 +0900 Subject: [PATCH 09/22] =?UTF-8?q?refactor=20:=20=EC=B0=A8=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EA=B2=80=EC=A6=9D=EC=9D=80=20Car,=20Cars=EA=B0=80?= =?UTF-8?q?=20=EC=A7=81=EC=A0=91=20=EA=B2=80=EC=A6=9D,=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EA=B2=80=EC=A6=9D=EC=9D=80=20util=EC=9D=B4=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20validation=EC=9D=B4=20=EB=8B=B4=EB=8B=B9?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B2=83=EC=9C=BC=EB=A1=9C=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/racingcar/util/Utils.java | 38 ------------------------- 1 file changed, 38 deletions(-) diff --git a/src/main/java/racingcar/util/Utils.java b/src/main/java/racingcar/util/Utils.java index be8143f..e69de29 100644 --- a/src/main/java/racingcar/util/Utils.java +++ b/src/main/java/racingcar/util/Utils.java @@ -1,38 +0,0 @@ -package racingcar.util; - -import java.util.HashSet; - -public class Utils { - - public static void isValidName(String name) { - if (name.isBlank() || name.contains(" ")) { - throw new IllegalArgumentException("이름 공백 또는 빈값은 안됩니다."); - } - if (name.length() > 5) { - throw new IllegalArgumentException("5글자 초과했습니다."); - } - } - - public static int isValidNumber(String input) { - try { - int number = Integer.parseInt(input); - if (number < 1) { - throw new IllegalArgumentException("1 미만의 숫자는 입력할 수 없습니다."); - } - return number; - } catch (NumberFormatException e) { - throw new IllegalArgumentException("숫자를 입력해야 합니다."); - } - } - - public static String[] splitNames(String input) { - String[] names = input.split(","); - HashSet set = new HashSet<>(); - for (String name : names) { - if (!set.add(name)) { - throw new IllegalArgumentException("이름 중복은 허용 안됩니다."); - } - } - return names; - } -} From 39dd8b9a869bdb0cffa4f737f16ba79cb2a47cf8 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 20:57:49 +0900 Subject: [PATCH 10/22] =?UTF-8?q?feature=20:=20=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=ED=9A=9F=EC=88=98=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../racingcar/validation/TryCountValidation.java | 15 +++++++++++++++ src/main/java/racingcar/view/racingCarInput.java | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/validation/TryCountValidation.java diff --git a/src/main/java/racingcar/validation/TryCountValidation.java b/src/main/java/racingcar/validation/TryCountValidation.java new file mode 100644 index 0000000..364af0b --- /dev/null +++ b/src/main/java/racingcar/validation/TryCountValidation.java @@ -0,0 +1,15 @@ +package racingcar.validation; + +public class TryCountValidation { + public static int validate(String input) { + try { + int number = Integer.parseInt(input); + if (number < 1) { + throw new IllegalArgumentException("1 미만의 숫자는 입력할 수 없습니다."); + } + return number; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자를 입력해야 합니다."); + } + } +} \ No newline at end of file diff --git a/src/main/java/racingcar/view/racingCarInput.java b/src/main/java/racingcar/view/racingCarInput.java index 7aa33d2..099a4c9 100644 --- a/src/main/java/racingcar/view/racingCarInput.java +++ b/src/main/java/racingcar/view/racingCarInput.java @@ -1,6 +1,7 @@ package racingcar.view; import camp.nextstep.edu.missionutils.Console; +import racingcar.validation.TryCountValidation; public class racingCarInput { public String[] readCarNames() { @@ -9,6 +10,6 @@ public String[] readCarNames() { } public int readTryCount() { System.out.println("시도할 회수는 몇회인가요?"); - return TryCountValidator.validate(Console.readLine()); + return TryCountValidation.validate(Console.readLine()); } } \ No newline at end of file From a3968934c147b2461b838d923a00ec89cc83fd5f Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:13:14 +0900 Subject: [PATCH 11/22] =?UTF-8?q?refactor=20:=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EC=B5=9C=EC=86=8C=20=ED=9A=9F=EC=88=98=EB=A5=BC=20=EC=83=81?= =?UTF-8?q?=EC=88=98=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/racingcar/entity/Car.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/racingcar/entity/Car.java b/src/main/java/racingcar/entity/Car.java index 0dce94d..544d0f1 100644 --- a/src/main/java/racingcar/entity/Car.java +++ b/src/main/java/racingcar/entity/Car.java @@ -6,6 +6,7 @@ public class Car { private final String name; private int moveCnt; + private final int MOVE_THRESHOLD = 4; public Car(String name) { Utils.isValidName(this.name = name); @@ -21,9 +22,8 @@ public int getMoveCnt() { } public void setMoveCnt() { - int RandomNum = Randoms.pickNumberInRange(0, 9); - if (RandomNum >= 4) { - this.moveCnt += 1; + if (Randoms.pickNumberInRange(0, 9) >= MOVE_THRESHOLD) { + this.moveCnt++; } } } From 1de88aaa16a6e120759e75b5a9554b5f0b74de11 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:14:36 +0900 Subject: [PATCH 12/22] =?UTF-8?q?refactor=20:=20Car=20=EC=9E=90=EC=8B=A0?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A6=84=EC=9D=84=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=ED=95=98=EA=B2=8C=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/racingcar/entity/Car.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/entity/Car.java b/src/main/java/racingcar/entity/Car.java index 544d0f1..17b68e8 100644 --- a/src/main/java/racingcar/entity/Car.java +++ b/src/main/java/racingcar/entity/Car.java @@ -1,7 +1,6 @@ package racingcar.entity; import camp.nextstep.edu.missionutils.Randoms; -import racingcar.util.Utils; public class Car { private final String name; @@ -9,7 +8,7 @@ public class Car { private final int MOVE_THRESHOLD = 4; public Car(String name) { - Utils.isValidName(this.name = name); + validateName(this.name = name); this.moveCnt = 0; } @@ -26,4 +25,13 @@ public void setMoveCnt() { this.moveCnt++; } } + + private void validateName(String name) { + if (name.isBlank() || name.contains(" ")) { + throw new IllegalArgumentException("이름 공백 또는 빈값은 안됩니다."); + } + if (name.length() > 5) { + throw new IllegalArgumentException("5글자 초과했습니다."); + } + } } From 3829a1606827eaf2f990924b984cf3650281923e Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:17:41 +0900 Subject: [PATCH 13/22] =?UTF-8?q?refactor=20:=20Cars=20=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=B4=20=EC=A4=91=EB=B3=B5=EC=9D=B4=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=EC=A7=80=20=EC=9E=90=EC=8B=A0=EC=9D=B4=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=ED=95=98=EB=8F=84=EB=A1=9D=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/racingcar/entity/Cars.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/entity/Cars.java b/src/main/java/racingcar/entity/Cars.java index c286bf9..cb8b9bf 100644 --- a/src/main/java/racingcar/entity/Cars.java +++ b/src/main/java/racingcar/entity/Cars.java @@ -1,11 +1,13 @@ package racingcar.entity; import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; public class Cars { - private ArrayList cars; + private List cars; - public Cars(ArrayList cars) { + public Cars(List cars) { this.cars = cars; } @@ -46,4 +48,13 @@ public void printWinner() { ArrayList winners = findWinners(findMaxMoveCnt()); System.out.println("최종 우승자 : " + String.join(", ", winners)); } + + private void validateDuplicate(List cars) { + HashSet set = new HashSet<>(); + for (Car car : cars) { + if (!set.add(car.getName())) { + throw new IllegalArgumentException("이름 중복은 허용 안됩니다."); + } + } + } } From 5c4d720a7ea8abdaac228af6ce8905bd4923309c Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:23:24 +0900 Subject: [PATCH 14/22] =?UTF-8?q?refactor=20:=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=8B=B1=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=EC=9D=84=20?= =?UTF-8?q?Output=EC=9D=B4=20=EB=8B=B4=EB=8B=B9=ED=95=98=EA=B2=8C=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/racingcar/view/racingCarOutput.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/racingcar/view/racingCarOutput.java diff --git a/src/main/java/racingcar/view/racingCarOutput.java b/src/main/java/racingcar/view/racingCarOutput.java new file mode 100644 index 0000000..72aa52c --- /dev/null +++ b/src/main/java/racingcar/view/racingCarOutput.java @@ -0,0 +1,14 @@ +package racingcar.view; + +import racingcar.domain.Car; +import racingcar.domain.Cars; + +public class racingCarOutput { + + public void printRaceResult(Cars cars) { + for (Car car : cars.getCars()) { + System.out.println(car.getName() + " : " + "-".repeat(car.getMoveCnt())); + } + System.out.println(); + } +} \ No newline at end of file From 548efdec04898eaed89279825161e0ed7ef54e00 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:24:39 +0900 Subject: [PATCH 15/22] =?UTF-8?q?refactor=20:=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=8B=B1=20=EC=B5=9C=EC=A2=85=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20Output=EC=9D=B4=20=EB=8B=B4=EB=8B=B9?= =?UTF-8?q?=ED=95=98=EA=B2=8C=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/racingcar/view/racingCarOutput.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/racingcar/view/racingCarOutput.java b/src/main/java/racingcar/view/racingCarOutput.java index 72aa52c..6089545 100644 --- a/src/main/java/racingcar/view/racingCarOutput.java +++ b/src/main/java/racingcar/view/racingCarOutput.java @@ -1,5 +1,6 @@ package racingcar.view; +import java.util.List; import racingcar.domain.Car; import racingcar.domain.Cars; @@ -11,4 +12,8 @@ public void printRaceResult(Cars cars) { } System.out.println(); } + + public void printWinner(List winners) { + System.out.println("최종 우승자 : " + String.join(", ", winners)); + } } \ No newline at end of file From 28096547d336fb6c360de5e39ae541b6ea65d5f2 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:26:09 +0900 Subject: [PATCH 16/22] =?UTF-8?q?refactor=20:=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=8B=B1=20=EC=B5=9C=EC=A2=85=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=EC=9D=84=20Output=EC=9D=B4=20=EB=8B=B4=EB=8B=B9?= =?UTF-8?q?=ED=95=98=EA=B2=8C=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/racingcar/entity/Cars.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/main/java/racingcar/entity/Cars.java b/src/main/java/racingcar/entity/Cars.java index cb8b9bf..f3f3179 100644 --- a/src/main/java/racingcar/entity/Cars.java +++ b/src/main/java/racingcar/entity/Cars.java @@ -8,6 +8,7 @@ public class Cars { private List cars; public Cars(List cars) { + validateDuplicate(cars); this.cars = cars; } @@ -17,13 +18,6 @@ public void moveAllCars() { } } - public void printMoveResult() { - for (Car car : this.cars) { - System.out.println(car.getName() + " : " + "-".repeat(car.getMoveCnt())); - } - System.out.println(); - } - private int findMaxMoveCnt() { int max = 0; for (Car car : this.cars) { @@ -44,11 +38,6 @@ private ArrayList findWinners(int max) { return winners; } - public void printWinner() { - ArrayList winners = findWinners(findMaxMoveCnt()); - System.out.println("최종 우승자 : " + String.join(", ", winners)); - } - private void validateDuplicate(List cars) { HashSet set = new HashSet<>(); for (Car car : cars) { From 8a07464ddd7a12462eaf74b10b3aeae025d6d519 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:37:26 +0900 Subject: [PATCH 17/22] =?UTF-8?q?refactor=20:=20util=20class=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/util/Utils.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/racingcar/util/Utils.java diff --git a/src/main/java/racingcar/util/Utils.java b/src/main/java/racingcar/util/Utils.java deleted file mode 100644 index e69de29..0000000 From 9386a79a6bf521ae63141fae9101b455b27425a0 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:38:30 +0900 Subject: [PATCH 18/22] =?UTF-8?q?feature=20:=20getCars=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/entity/Cars.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/racingcar/entity/Cars.java b/src/main/java/racingcar/entity/Cars.java index f3f3179..5b73552 100644 --- a/src/main/java/racingcar/entity/Cars.java +++ b/src/main/java/racingcar/entity/Cars.java @@ -11,7 +11,9 @@ public Cars(List cars) { validateDuplicate(cars); this.cars = cars; } - + public List getCars() { + return cars; + } public void moveAllCars() { for (Car car : this.cars) { car.setMoveCnt(); From ff9702ffa7c655e7029fc0dc623896987e2ec5da Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:40:11 +0900 Subject: [PATCH 19/22] =?UTF-8?q?refactor=20:=20=EC=B5=9C=EA=B3=A0=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9A=9F=EC=88=98,=20=EC=9A=B0=EC=8A=B9?= =?UTF-8?q?=EC=9E=90=20=EC=B0=BE=EB=8A=94=20=ED=95=A8=EC=88=98=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/entity/Cars.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/racingcar/entity/Cars.java b/src/main/java/racingcar/entity/Cars.java index 5b73552..d962177 100644 --- a/src/main/java/racingcar/entity/Cars.java +++ b/src/main/java/racingcar/entity/Cars.java @@ -30,8 +30,9 @@ private int findMaxMoveCnt() { return max; } - private ArrayList findWinners(int max) { - ArrayList winners = new ArrayList<>(); + public List getWinners() { + int max = findMaxMoveCnt(); + List winners = new ArrayList<>(); for (Car car : this.cars) { if (car.getMoveCnt() == max) { winners.add(car.getName()); From 6edddbb12287cbd35b3b8b3c612a78e01cc6bd82 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:41:50 +0900 Subject: [PATCH 20/22] =?UTF-8?q?refactor=20:=20input/output=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=EC=9A=B4=EC=98=81=20=EC=B1=85=EC=9E=84?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/RunRacingGame.java | 29 +++++++++++++++++-- .../java/racingcar/view/racingCarOutput.java | 4 +-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main/java/racingcar/RunRacingGame.java b/src/main/java/racingcar/RunRacingGame.java index 2acef9a..7b38046 100644 --- a/src/main/java/racingcar/RunRacingGame.java +++ b/src/main/java/racingcar/RunRacingGame.java @@ -1,12 +1,37 @@ package racingcar; +import java.util.ArrayList; +import java.util.List; +import racingcar.entity.Car; +import racingcar.entity.Cars; import racingcar.view.racingCarInput; +import racingcar.view.racingCarOutput; public class RunRacingGame { + private racingCarInput input = new racingCarInput(); + private racingCarOutput output = new racingCarOutput(); + public void run() { //TODO : Input과 Output 출력하는 책임을 분리 진행 - private racingCarInput input = new racingCarInput(); - private racingCarOutput output = new racingCarOutput(); + String[] carNames = input.readCarNames(); + int tryCount = input.readTryCount(); + + Cars cars = createCars(carNames); + + System.out.println("\n실행 결과"); + for (int i = 0; i < tryCount; i++) { + cars.moveAllCars(); + output.printRaceResult(cars); + } + output.printWinner(cars.getWinners()); + } + + private Cars createCars(String[] carNames) { + List carList = new ArrayList<>(); + for (String name : carNames) { + carList.add(new Car(name)); + } + return new Cars(carList); } } diff --git a/src/main/java/racingcar/view/racingCarOutput.java b/src/main/java/racingcar/view/racingCarOutput.java index 6089545..584eb60 100644 --- a/src/main/java/racingcar/view/racingCarOutput.java +++ b/src/main/java/racingcar/view/racingCarOutput.java @@ -1,8 +1,8 @@ package racingcar.view; import java.util.List; -import racingcar.domain.Car; -import racingcar.domain.Cars; +import racingcar.entity.Car; +import racingcar.entity.Cars; public class racingCarOutput { From cf14d0d7929ebbe0321a0eceaeddcb12138abac7 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 21:42:29 +0900 Subject: [PATCH 21/22] =?UTF-8?q?Todo=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/RunRacingGame.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/racingcar/RunRacingGame.java b/src/main/java/racingcar/RunRacingGame.java index 7b38046..eded30d 100644 --- a/src/main/java/racingcar/RunRacingGame.java +++ b/src/main/java/racingcar/RunRacingGame.java @@ -13,7 +13,6 @@ public class RunRacingGame { private racingCarOutput output = new racingCarOutput(); public void run() { - //TODO : Input과 Output 출력하는 책임을 분리 진행 String[] carNames = input.readCarNames(); int tryCount = input.readTryCount(); From 20906f22cbd20e73dc6269ca3d9cc24f9482f115 Mon Sep 17 00:00:00 2001 From: sungchan12 Date: Sun, 5 Apr 2026 22:00:57 +0900 Subject: [PATCH 22/22] =?UTF-8?q?=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81=20?= =?UTF-8?q?=EA=B3=84=ED=9A=8D=EC=84=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/README.md | 16 +++++++++++++++- src/main/java/racingcar/entity/Car.java | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 146e53f..86f4864 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,4 +18,18 @@ ## 출력 - 각 횟수별 실행 결과를 자동차 이름과 함께 출력한다. - 최종 우승자를 출력한다. -- 우승자가 여러 명일 경우 ,로 구분하여 출력한다. \ No newline at end of file +- 우승자가 여러 명일 경우 ,로 구분하여 출력한다. + +## 리팩토링 +- `Input` : 사용자 입력을 받는 책임만 담당하도록 분리한다. +- `Output` : 경기 결과 및 우승자 출력 책임만 담당하도록 분리한다. +- `RunRacingGame` : 게임 흐름 제어 책임만 담당하도록 분리한다. +- `Utils` 클래스를 삭제하고 각 도메인이 자신의 책임을 직접 수행하도록 변경한다. + +### 도메인은 자신이 검증 +- `Car` : 자동차 이름의 유효성(공백, 길이)을 Car 스스로 검증한다. +- `Cars` : 자동차 이름 중복 여부를 Cars 스스로 검증한다. +- `validation` : 시도 횟수 검증은 입력 경계에서 담당한다. + +### 이동횟수 관리 +- 이동 기준값을 매직넘버로 관리한다. \ No newline at end of file diff --git a/src/main/java/racingcar/entity/Car.java b/src/main/java/racingcar/entity/Car.java index 17b68e8..6af4d52 100644 --- a/src/main/java/racingcar/entity/Car.java +++ b/src/main/java/racingcar/entity/Car.java @@ -5,7 +5,7 @@ public class Car { private final String name; private int moveCnt; - private final int MOVE_THRESHOLD = 4; + private static final int MOVE_THRESHOLD = 4; public Car(String name) { validateName(this.name = name);