From 37574eb0f689fa05ad2017bc8030da42b5a6a885 Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Tue, 26 Mar 2024 15:45:31 +0900 Subject: [PATCH 01/14] =?UTF-8?q?feat:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/RacingMain.java | 5 ++++- src/main/java/controller/RacingController.java | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/main/java/controller/RacingController.java diff --git a/src/main/java/RacingMain.java b/src/main/java/RacingMain.java index 4394287..43d673d 100644 --- a/src/main/java/RacingMain.java +++ b/src/main/java/RacingMain.java @@ -1,7 +1,10 @@ +import controller.RacingController; + public class RacingMain { public static void main(String[] args) { // TODO: MVC 패턴을 기반으로 자동차 경주 미션 구현해보기 - System.out.println("Hello, World!"); + final var racingController = new RacingController(); + racingController.run(); } } diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java new file mode 100644 index 0000000..787596f --- /dev/null +++ b/src/main/java/controller/RacingController.java @@ -0,0 +1,7 @@ +package controller; + +public class RacingController { + public void run() { + + } +} From 7ccbcf784c3233213ab0597cc0d46362e6059675 Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Tue, 26 Mar 2024 16:25:40 +0900 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20controller=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ .../java/controller/RacingController.java | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/README.md b/README.md index 1969313..fed3a2a 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,7 @@ 자동차 경주 미션 저장소 +1. 자동차 정보 입력 +2. 시도 횟수 입력 +3. 실행 결과 출력 +4. 우승자 출력 \ No newline at end of file diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java index 787596f..46e0e47 100644 --- a/src/main/java/controller/RacingController.java +++ b/src/main/java/controller/RacingController.java @@ -2,6 +2,25 @@ public class RacingController { public void run() { + initializeRacingCar(); + setRacingCount(); + racingResult(); + printWinner(); + } + + private void initializeRacingCar() { + + } + + private void setRacingCount() { + + } + + private void racingResult() { + + } + + private void printWinner() { } } From 599bb05ecbb13cfee8388c4937d3f8fe25d5ef14 Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Tue, 26 Mar 2024 16:34:53 +0900 Subject: [PATCH 03/14] =?UTF-8?q?feat:=20RacingCar=20=EB=B0=8F=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=EB=90=9C=20domain=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Name.java | 5 +++++ src/main/java/domain/Position.java | 5 +++++ src/main/java/domain/RacingCar.java | 5 +++++ src/main/java/domain/RacingCars.java | 5 +++++ 4 files changed, 20 insertions(+) create mode 100644 src/main/java/domain/Name.java create mode 100644 src/main/java/domain/Position.java create mode 100644 src/main/java/domain/RacingCar.java create mode 100644 src/main/java/domain/RacingCars.java diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java new file mode 100644 index 0000000..6f3d8ac --- /dev/null +++ b/src/main/java/domain/Name.java @@ -0,0 +1,5 @@ +package domain; + +public class Name { + // 자동차 이름 +} diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java new file mode 100644 index 0000000..87c53d3 --- /dev/null +++ b/src/main/java/domain/Position.java @@ -0,0 +1,5 @@ +package domain; + +public class Position { + // 자동차 위치 +} diff --git a/src/main/java/domain/RacingCar.java b/src/main/java/domain/RacingCar.java new file mode 100644 index 0000000..33b983d --- /dev/null +++ b/src/main/java/domain/RacingCar.java @@ -0,0 +1,5 @@ +package domain; + +public class RacingCar { + // 자동차 +} diff --git a/src/main/java/domain/RacingCars.java b/src/main/java/domain/RacingCars.java new file mode 100644 index 0000000..ee17c9c --- /dev/null +++ b/src/main/java/domain/RacingCars.java @@ -0,0 +1,5 @@ +package domain; + +public class RacingCars { + // 자동차 경주에 참여하는 자동차들 +} From da898d33d642618afc678faed10173bd2d49597f Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Tue, 26 Mar 2024 17:28:25 +0900 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=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/RacingMain.java | 4 +++- .../java/controller/RacingController.java | 14 ++++++++---- src/main/java/domain/Car.java | 20 +++++++++++++++++ src/main/java/domain/Cars.java | 19 ++++++++++++++++ src/main/java/domain/Name.java | 9 ++++++++ src/main/java/domain/Position.java | 9 ++++++++ src/main/java/domain/RacingCar.java | 5 ----- src/main/java/domain/RacingCars.java | 5 ----- src/main/java/view/InputView.java | 22 +++++++++++++++++++ src/main/java/view/OutputView.java | 4 ++++ 10 files changed, 96 insertions(+), 15 deletions(-) create mode 100644 src/main/java/domain/Car.java create mode 100644 src/main/java/domain/Cars.java delete mode 100644 src/main/java/domain/RacingCar.java delete mode 100644 src/main/java/domain/RacingCars.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/OutputView.java diff --git a/src/main/java/RacingMain.java b/src/main/java/RacingMain.java index 43d673d..dad37bb 100644 --- a/src/main/java/RacingMain.java +++ b/src/main/java/RacingMain.java @@ -1,8 +1,10 @@ import controller.RacingController; +import java.io.IOException; + public class RacingMain { - public static void main(String[] args) { + public static void main(String[] args) throws IOException { // TODO: MVC 패턴을 기반으로 자동차 경주 미션 구현해보기 final var racingController = new RacingController(); racingController.run(); diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java index 46e0e47..3c52a6b 100644 --- a/src/main/java/controller/RacingController.java +++ b/src/main/java/controller/RacingController.java @@ -1,15 +1,21 @@ package controller; +import domain.Cars; +import view.InputView; + +import java.io.IOException; +import java.util.List; + public class RacingController { - public void run() { - initializeRacingCar(); + public void run() throws IOException { + final Cars Cars = new Cars(initializeCar()); setRacingCount(); racingResult(); printWinner(); } - private void initializeRacingCar() { - + private List initializeCar() throws IOException { + return InputView.getCarName(); } private void setRacingCount() { diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java new file mode 100644 index 0000000..061c168 --- /dev/null +++ b/src/main/java/domain/Car.java @@ -0,0 +1,20 @@ +package domain; + +public class Car { + // 자동차 + private Name name; + private Position position; + + public Car(String name) { + this.name = new Name(name); + this.position = new Position(); + } + + public String getCarName() { + return name.getName(); + } + + public int getCarPosition() { + return position.getPosition(); + } +} diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java new file mode 100644 index 0000000..de2031b --- /dev/null +++ b/src/main/java/domain/Cars.java @@ -0,0 +1,19 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Cars { + // 자동차 경주에 참여하는 자동차들 + private List cars; + public Cars(List carNames) { + cars = new ArrayList<>(); + } + + private void generateCars(List carNames, List cars) { + for(String name: carNames) { + Car car = new Car(name); + cars.add(car); + } + } +} diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java index 6f3d8ac..d693412 100644 --- a/src/main/java/domain/Name.java +++ b/src/main/java/domain/Name.java @@ -2,4 +2,13 @@ public class Name { // 자동차 이름 + private String name; + + public Name(String name) { + this.name = name; + } + + public String getName() { + return name; + } } diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index 87c53d3..d567d4e 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -2,4 +2,13 @@ public class Position { // 자동차 위치 + private int position; + + public Position() { + position = 0; + } + + public int getPosition() { + return position; + } } diff --git a/src/main/java/domain/RacingCar.java b/src/main/java/domain/RacingCar.java deleted file mode 100644 index 33b983d..0000000 --- a/src/main/java/domain/RacingCar.java +++ /dev/null @@ -1,5 +0,0 @@ -package domain; - -public class RacingCar { - // 자동차 -} diff --git a/src/main/java/domain/RacingCars.java b/src/main/java/domain/RacingCars.java deleted file mode 100644 index ee17c9c..0000000 --- a/src/main/java/domain/RacingCars.java +++ /dev/null @@ -1,5 +0,0 @@ -package domain; - -public class RacingCars { - // 자동차 경주에 참여하는 자동차들 -} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000..57815d1 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,22 @@ +package view; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class InputView { + private static final String INPUT_CAR_NAME = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; + private static final String SEPARATOR_VALUE = ","; + + private static final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); + + public static List getCarName() throws IOException { + System.out.println(INPUT_CAR_NAME); + return Arrays.stream(bufferedReader.readLine().split(SEPARATOR_VALUE)) + .map(String::trim) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000..d8f9743 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,4 @@ +package view; + +public class OutputView { +} From 79287dba08c7725d632680a3333392661c484670 Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Thu, 28 Mar 2024 01:04:31 +0900 Subject: [PATCH 05/14] =?UTF-8?q?feat:=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EC=9E=85=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/RacingController.java | 16 +++++++++------- src/main/java/domain/Cars.java | 3 ++- src/main/java/domain/TryCount.java | 18 ++++++++++++++++++ src/main/java/view/InputView.java | 10 ++++++++-- 4 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 src/main/java/domain/TryCount.java diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java index 3c52a6b..b32ff95 100644 --- a/src/main/java/controller/RacingController.java +++ b/src/main/java/controller/RacingController.java @@ -1,6 +1,7 @@ package controller; import domain.Cars; +import domain.TryCount; import view.InputView; import java.io.IOException; @@ -8,25 +9,26 @@ public class RacingController { public void run() throws IOException { - final Cars Cars = new Cars(initializeCar()); - setRacingCount(); + final Cars Cars = new Cars(createCars()); + final TryCount tryCount = new TryCount(setTryCount()); racingResult(); - printWinner(); + findWinners(); } - private List initializeCar() throws IOException { + // + private List createCars() throws IOException { return InputView.getCarName(); } - private void setRacingCount() { - + private int setTryCount() throws IOException { + return InputView.getTryCount(); } private void racingResult() { } - private void printWinner() { + private void findWinners() { } } diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index de2031b..539be34 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -5,9 +5,10 @@ public class Cars { // 자동차 경주에 참여하는 자동차들 - private List cars; + private final List cars; public Cars(List carNames) { cars = new ArrayList<>(); + generateCars(carNames, cars); } private void generateCars(List carNames, List cars) { diff --git a/src/main/java/domain/TryCount.java b/src/main/java/domain/TryCount.java new file mode 100644 index 0000000..f5ddc4f --- /dev/null +++ b/src/main/java/domain/TryCount.java @@ -0,0 +1,18 @@ +package domain; + +public class TryCount { + private static final int PLAYABLE_LOWER_BOUND = 1; + private int tryCount; + + public TryCount(int tryCount) { + this.tryCount = tryCount; + } + + public void decreaseTryCount() { + tryCount--; + } + + public boolean isPlayable() { + return PLAYABLE_LOWER_BOUND <= tryCount; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 57815d1..3d463b7 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -8,15 +8,21 @@ import java.util.stream.Collectors; public class InputView { - private static final String INPUT_CAR_NAME = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; + private static final String INPUT_CAR_NAME_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; + private static final String TRY_COUNT_MESSAGE = "시도할 횟수는 몇회인가요?"; private static final String SEPARATOR_VALUE = ","; private static final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); public static List getCarName() throws IOException { - System.out.println(INPUT_CAR_NAME); + System.out.println(INPUT_CAR_NAME_MESSAGE); return Arrays.stream(bufferedReader.readLine().split(SEPARATOR_VALUE)) .map(String::trim) .collect(Collectors.toList()); } + + public static int getTryCount() throws IOException { + System.out.println(TRY_COUNT_MESSAGE); + return bufferedReader.read(); + } } From 6bbe8cff2d1aa659b093855aa16a5046b0e5a249 Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Thu, 28 Mar 2024 01:49:51 +0900 Subject: [PATCH 06/14] =?UTF-8?q?feat:=20=EC=8B=9C=ED=96=89=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/RacingController.java | 18 ++++++++++++---- src/main/java/domain/Car.java | 11 ++++++++-- src/main/java/domain/Cars.java | 11 ++++++++++ src/main/java/domain/Position.java | 4 ++++ src/main/java/domain/RandomNumber.java | 12 +++++++++++ src/main/java/view/OutputView.java | 21 +++++++++++++++++++ 6 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 src/main/java/domain/RandomNumber.java diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java index b32ff95..ae7c126 100644 --- a/src/main/java/controller/RacingController.java +++ b/src/main/java/controller/RacingController.java @@ -3,31 +3,41 @@ import domain.Cars; import domain.TryCount; import view.InputView; +import view.OutputView; import java.io.IOException; import java.util.List; public class RacingController { public void run() throws IOException { - final Cars Cars = new Cars(createCars()); + final Cars cars = new Cars(createCars()); final TryCount tryCount = new TryCount(setTryCount()); - racingResult(); + racingResult(tryCount, cars); findWinners(); } - // + // 자동차 정보 입력 private List createCars() throws IOException { return InputView.getCarName(); } + // 시도 횟수 입력 private int setTryCount() throws IOException { return InputView.getTryCount(); } - private void racingResult() { + // 시행 결과 출력 + private void racingResult(TryCount tryCount, Cars cars) { + OutputView.printRacingResult(); + while(tryCount.isPlayable()) { + tryCount.decreaseTryCount(); + cars.moveCars(); + OutputView.printRacingStatus(cars.getCars()); + } } + // 우승자 출력 private void findWinners() { } diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java index 061c168..863d908 100644 --- a/src/main/java/domain/Car.java +++ b/src/main/java/domain/Car.java @@ -2,8 +2,9 @@ public class Car { // 자동차 - private Name name; - private Position position; + private static final int MINIMUM_MOVE_POWER = 4; + private final Name name; + private final Position position; public Car(String name) { this.name = new Name(name); @@ -17,4 +18,10 @@ public String getCarName() { public int getCarPosition() { return position.getPosition(); } + + public void moveCar(int number) { + if (number >= MINIMUM_MOVE_POWER) { + position.increasePosition(); + } + } } diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index 539be34..e95a441 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -17,4 +17,15 @@ private void generateCars(List carNames, List cars) { cars.add(car); } } + + public List getCars() { + return cars; + } + + public void moveCars() { + for (Car c: cars) { + int number = RandomNumber.getRandomNumber(); + c.moveCar(number); + } + } } diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index d567d4e..db8ff92 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -11,4 +11,8 @@ public Position() { public int getPosition() { return position; } + + public void increasePosition() { + position++; + } } diff --git a/src/main/java/domain/RandomNumber.java b/src/main/java/domain/RandomNumber.java new file mode 100644 index 0000000..5b55048 --- /dev/null +++ b/src/main/java/domain/RandomNumber.java @@ -0,0 +1,12 @@ +package domain; + +import java.util.Random; + +public class RandomNumber { + private static final int NUMBER_UPPER_BOUND = 10; + private static final Random random = new Random(); + + public static int getRandomNumber() { + return random.nextInt(NUMBER_UPPER_BOUND); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index d8f9743..f02931b 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -1,4 +1,25 @@ package view; +import domain.Car; + +import java.util.List; + public class OutputView { + private static final String TRY_RESULT_MESSAGE = "실행 결과"; + private static final String STATUS_MESSAGE_FORMAT = "%s : %s\n"; + private static final String POSITION_SYMBOL = "-"; + + public static void printRacingResult() { + System.out.println(TRY_RESULT_MESSAGE); + } + + public static void printRacingStatus(List cars) { + for (Car c: cars) { + System.out.printf(STATUS_MESSAGE_FORMAT, c.getCarName(), getCurrentPosition(c.getCarPosition())); + } + } + + private static String getCurrentPosition(int position) { + return POSITION_SYMBOL.repeat(position); + } } From 2b9ae3f4cf3a8b42cfa49786805716f40da3803d Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Thu, 28 Mar 2024 11:07:01 +0900 Subject: [PATCH 07/14] =?UTF-8?q?feat:=20=EC=9A=B0=EC=8A=B9=EC=9E=90=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/RacingController.java | 6 ++--- src/main/java/domain/Cars.java | 22 +++++++++++++++++++ src/main/java/view/OutputView.java | 10 +++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java index ae7c126..d49b04c 100644 --- a/src/main/java/controller/RacingController.java +++ b/src/main/java/controller/RacingController.java @@ -13,7 +13,7 @@ public void run() throws IOException { final Cars cars = new Cars(createCars()); final TryCount tryCount = new TryCount(setTryCount()); racingResult(tryCount, cars); - findWinners(); + findWinners(cars); } // 자동차 정보 입력 @@ -38,7 +38,7 @@ private void racingResult(TryCount tryCount, Cars cars) { } // 우승자 출력 - private void findWinners() { - + private void findWinners(Cars cars) { + OutputView.printRacingWinner(cars.findWinnerName()); } } diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index e95a441..d34249b 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -2,9 +2,11 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class Cars { // 자동차 경주에 참여하는 자동차들 + private static final int DEFAULT_POSITION = 0; private final List cars; public Cars(List carNames) { cars = new ArrayList<>(); @@ -28,4 +30,24 @@ public void moveCars() { c.moveCar(number); } } + + public List findWinnerName() { + return findWinner().stream() + .map(Car::getCarName) + .collect(Collectors.toList()); + } + + private List findWinner() { + int winnerPosition = getWinnerPosition(); + return cars.stream() + .filter(car -> car.getCarPosition() == winnerPosition) + .collect(Collectors.toList()); + } + + private int getWinnerPosition() { + return cars.stream() + .mapToInt(Car::getCarPosition) + .max() + .orElse(DEFAULT_POSITION); + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index f02931b..1e55a51 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -8,6 +8,8 @@ public class OutputView { private static final String TRY_RESULT_MESSAGE = "실행 결과"; private static final String STATUS_MESSAGE_FORMAT = "%s : %s\n"; private static final String POSITION_SYMBOL = "-"; + private static final String WINNER_MESSAGE_FORMAT = "%s가 최종 우승했습니다."; + private static final String WINNER_DELIMITER = ", "; public static void printRacingResult() { System.out.println(TRY_RESULT_MESSAGE); @@ -22,4 +24,12 @@ public static void printRacingStatus(List cars) { private static String getCurrentPosition(int position) { return POSITION_SYMBOL.repeat(position); } + + public static void printRacingWinner(List winners) { + System.out.printf(WINNER_MESSAGE_FORMAT, getCombinedWinner(winners)); + } + + private static String getCombinedWinner(List winners) { + return String.join(WINNER_DELIMITER, winners); + } } From 77316a590f84b563d9b5ec7a3c91d27fb6b496fb Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Thu, 28 Mar 2024 11:38:04 +0900 Subject: [PATCH 08/14] =?UTF-8?q?refactor:=20OutputView=EC=9D=98=20getTryC?= =?UTF-8?q?ount=EC=97=90=EC=84=9C=20=EC=9E=98=EB=AA=BB=EB=90=9C=20?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20=EB=B0=9B=EC=95=84=EC=98=A4=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=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/view/InputView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 3d463b7..1464be4 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -23,6 +23,6 @@ public static List getCarName() throws IOException { public static int getTryCount() throws IOException { System.out.println(TRY_COUNT_MESSAGE); - return bufferedReader.read(); + return Integer.parseInt(bufferedReader.readLine()); } } From 457e49f795625477c1f2f870eaf1fe9bf05dd6da Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Thu, 28 Mar 2024 15:26:11 +0900 Subject: [PATCH 09/14] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Car.java | 3 ++ src/main/java/domain/Cars.java | 5 +++ src/main/java/domain/TryCount.java | 3 ++ src/main/java/util/ErrorMessage.java | 21 ++++++++++ src/main/java/util/Validation.java | 58 ++++++++++++++++++++++++++++ src/main/java/view/InputView.java | 4 +- src/main/java/view/OutputView.java | 1 + 7 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/main/java/util/ErrorMessage.java create mode 100644 src/main/java/util/Validation.java diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java index 863d908..67d7e76 100644 --- a/src/main/java/domain/Car.java +++ b/src/main/java/domain/Car.java @@ -1,5 +1,7 @@ package domain; +import util.Validation; + public class Car { // 자동차 private static final int MINIMUM_MOVE_POWER = 4; @@ -7,6 +9,7 @@ public class Car { private final Position position; public Car(String name) { + Validation.validationNameSize(name); this.name = new Name(name); this.position = new Position(); } diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index d34249b..6acbe1e 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -1,5 +1,7 @@ package domain; +import util.Validation; + import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -14,6 +16,9 @@ public Cars(List carNames) { } private void generateCars(List carNames, List cars) { + Validation.validationCarNumber(carNames); + Validation.validationDuplicatedName(carNames); + for(String name: carNames) { Car car = new Car(name); cars.add(car); diff --git a/src/main/java/domain/TryCount.java b/src/main/java/domain/TryCount.java index f5ddc4f..690c860 100644 --- a/src/main/java/domain/TryCount.java +++ b/src/main/java/domain/TryCount.java @@ -1,10 +1,13 @@ package domain; +import util.Validation; + public class TryCount { private static final int PLAYABLE_LOWER_BOUND = 1; private int tryCount; public TryCount(int tryCount) { + Validation.validationTryCount(tryCount); this.tryCount = tryCount; } diff --git a/src/main/java/util/ErrorMessage.java b/src/main/java/util/ErrorMessage.java new file mode 100644 index 0000000..7770a88 --- /dev/null +++ b/src/main/java/util/ErrorMessage.java @@ -0,0 +1,21 @@ +package util; + +public enum ErrorMessage { + NAME_SIZE_ERROR("이름은 1글자 이상 5글자 이하로 작성해주세요."), + NAME_DUPLICATE_ERROR("이름은 중복될 수 없습니다."), + CAR_NUMBER_ERROR("자동차는 100대 이하여야 합니다."), + TRY_TYPE_ERROR("입력값은 정수여야 합니다."), + TRY_RANGE_ERROR("시도 횟수는 양의 정수여야 합니다."), + TRY_LIMIT_ERROR("시도 횟수는 100회 이하여야 합니다."); + + private final String message; + private static final String START_ERROR = "[ERROR] "; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return START_ERROR + message; + } +} diff --git a/src/main/java/util/Validation.java b/src/main/java/util/Validation.java new file mode 100644 index 0000000..cb54155 --- /dev/null +++ b/src/main/java/util/Validation.java @@ -0,0 +1,58 @@ +package util; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static util.ErrorMessage.*; + +public class Validation { + private static final int NUMBER_LOWER_BOUND = 0; + private static final int NUMBER_UPPER_BOUND = 100; + private static final int NAME_MAX_SIZE = 5; + + public static void validationNameSize(String name) { + if (name.isEmpty() || name.length() > NAME_MAX_SIZE) { + throw new IllegalArgumentException(NAME_SIZE_ERROR.getMessage()); + } + } + + public static void validationCarNumber(List names) { + if (checkUpperBound(names.size())) { + throw new IllegalArgumentException(CAR_NUMBER_ERROR.getMessage()); + } + } + + public static void validationDuplicatedName(List names) { + Set deduplicate = new HashSet<>(names); + if (deduplicate.size() != names.size()) { + throw new IllegalArgumentException(NAME_DUPLICATE_ERROR.getMessage()); + } + } + + public static Integer parseInteger(String input) { + try { + return Integer.parseInt(input); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(TRY_TYPE_ERROR.getMessage()); + } + } + + public static void validationTryCount(int tryCount) { + if (checkLowerBound(tryCount)) { + throw new IllegalArgumentException(TRY_RANGE_ERROR.getMessage()); + } + + if (checkUpperBound(tryCount)) { + throw new IllegalArgumentException(TRY_LIMIT_ERROR.getMessage()); + } + } + + private static boolean checkLowerBound(int number) { + return number <= NUMBER_LOWER_BOUND; + } + + private static boolean checkUpperBound(int number) { + return number >= NUMBER_UPPER_BOUND; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 1464be4..05ab8d0 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,5 +1,7 @@ package view; +import util.Validation; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -23,6 +25,6 @@ public static List getCarName() throws IOException { public static int getTryCount() throws IOException { System.out.println(TRY_COUNT_MESSAGE); - return Integer.parseInt(bufferedReader.readLine()); + return Validation.parseInteger(bufferedReader.readLine()); } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 1e55a51..78ae005 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -19,6 +19,7 @@ public static void printRacingStatus(List cars) { for (Car c: cars) { System.out.printf(STATUS_MESSAGE_FORMAT, c.getCarName(), getCurrentPosition(c.getCarPosition())); } + System.out.println(); } private static String getCurrentPosition(int position) { From 91992abff03d0ba2c65df9d9f779caa61bc6b745 Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Thu, 28 Mar 2024 15:36:40 +0900 Subject: [PATCH 10/14] =?UTF-8?q?refactor:=20ViewMessage=20enum=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/view/InputView.java | 11 +++++------ src/main/java/view/OutputView.java | 18 ++++++++---------- src/main/java/view/ViewMessage.java | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 src/main/java/view/ViewMessage.java diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 05ab8d0..d391e56 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -9,22 +9,21 @@ import java.util.List; import java.util.stream.Collectors; +import static view.ViewMessage.*; + public class InputView { - private static final String INPUT_CAR_NAME_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; - private static final String TRY_COUNT_MESSAGE = "시도할 횟수는 몇회인가요?"; - private static final String SEPARATOR_VALUE = ","; private static final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); public static List getCarName() throws IOException { - System.out.println(INPUT_CAR_NAME_MESSAGE); - return Arrays.stream(bufferedReader.readLine().split(SEPARATOR_VALUE)) + System.out.println(INPUT_CAR_NAME_MESSAGE.getMessage()); + return Arrays.stream(bufferedReader.readLine().split(SEPARATOR_VALUE.getMessage())) .map(String::trim) .collect(Collectors.toList()); } public static int getTryCount() throws IOException { - System.out.println(TRY_COUNT_MESSAGE); + System.out.println(TRY_COUNT_MESSAGE.getMessage()); return Validation.parseInteger(bufferedReader.readLine()); } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 78ae005..b3ae549 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -4,33 +4,31 @@ import java.util.List; +import static view.ViewMessage.*; + public class OutputView { - private static final String TRY_RESULT_MESSAGE = "실행 결과"; - private static final String STATUS_MESSAGE_FORMAT = "%s : %s\n"; - private static final String POSITION_SYMBOL = "-"; - private static final String WINNER_MESSAGE_FORMAT = "%s가 최종 우승했습니다."; - private static final String WINNER_DELIMITER = ", "; public static void printRacingResult() { - System.out.println(TRY_RESULT_MESSAGE); + System.out.println(TRY_RESULT_MESSAGE.getMessage()); } public static void printRacingStatus(List cars) { for (Car c: cars) { - System.out.printf(STATUS_MESSAGE_FORMAT, c.getCarName(), getCurrentPosition(c.getCarPosition())); + String position = getCurrentPosition(c.getCarPosition()); + System.out.printf(STATUS_MESSAGE_FORMAT.getMessage(), c.getCarName(), position); } System.out.println(); } private static String getCurrentPosition(int position) { - return POSITION_SYMBOL.repeat(position); + return POSITION_SYMBOL.getMessage().repeat(position); } public static void printRacingWinner(List winners) { - System.out.printf(WINNER_MESSAGE_FORMAT, getCombinedWinner(winners)); + System.out.printf(WINNER_MESSAGE_FORMAT.getMessage(), getCombinedWinner(winners)); } private static String getCombinedWinner(List winners) { - return String.join(WINNER_DELIMITER, winners); + return String.join(DELIMITER_VALUE.getMessage(), winners); } } diff --git a/src/main/java/view/ViewMessage.java b/src/main/java/view/ViewMessage.java new file mode 100644 index 0000000..58550b1 --- /dev/null +++ b/src/main/java/view/ViewMessage.java @@ -0,0 +1,22 @@ +package view; + +public enum ViewMessage { + INPUT_CAR_NAME_MESSAGE("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."), + TRY_COUNT_MESSAGE("시도할 횟수는 몇회인가요?"), + SEPARATOR_VALUE(","), + TRY_RESULT_MESSAGE("실행 결과"), + STATUS_MESSAGE_FORMAT("%s : %s\n"), + POSITION_SYMBOL("-"), + WINNER_MESSAGE_FORMAT("%s가 최종 우승했습니다."), + DELIMITER_VALUE(", "); + + private final String message; + + ViewMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} From 4a4d856b686832871b85cf1eed9861d9148f42eb Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Sat, 30 Mar 2024 15:28:56 +0900 Subject: [PATCH 11/14] =?UTF-8?q?feat:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/controller/RacingController.java | 4 +- src/main/java/domain/Car.java | 2 +- src/main/java/domain/Cars.java | 6 +-- src/main/java/domain/Name.java | 15 ++---- src/main/java/domain/Position.java | 3 +- src/main/java/util/ErrorMessage.java | 5 +- src/main/java/util/Validation.java | 21 ++------ src/main/java/view/InputView.java | 6 ++- src/test/java/domain/CarTest.java | 27 ++++++++++ src/test/java/domain/CarsTest.java | 52 +++++++++++++++++++ src/test/java/domain/PositionTest.java | 19 +++++++ src/test/java/domain/TryCountTest.java | 27 ++++++++++ src/test/java/util/IntegerParserTest.java | 27 ++++++++++ 13 files changed, 175 insertions(+), 39 deletions(-) create mode 100644 src/test/java/domain/CarTest.java create mode 100644 src/test/java/domain/CarsTest.java create mode 100644 src/test/java/domain/PositionTest.java create mode 100644 src/test/java/domain/TryCountTest.java create mode 100644 src/test/java/util/IntegerParserTest.java diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java index d49b04c..50adb05 100644 --- a/src/main/java/controller/RacingController.java +++ b/src/main/java/controller/RacingController.java @@ -10,8 +10,8 @@ public class RacingController { public void run() throws IOException { - final Cars cars = new Cars(createCars()); - final TryCount tryCount = new TryCount(setTryCount()); + Cars cars = new Cars(createCars()); + TryCount tryCount = new TryCount(setTryCount()); racingResult(tryCount, cars); findWinners(cars); } diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java index 67d7e76..c005f2a 100644 --- a/src/main/java/domain/Car.java +++ b/src/main/java/domain/Car.java @@ -15,7 +15,7 @@ public Car(String name) { } public String getCarName() { - return name.getName(); + return name.name(); } public int getCarPosition() { diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index 6acbe1e..4dcf61e 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -11,14 +11,14 @@ public class Cars { private static final int DEFAULT_POSITION = 0; private final List cars; public Cars(List carNames) { + Validation.validationCarNumber(carNames); + Validation.validationDuplicatedName(carNames); + cars = new ArrayList<>(); generateCars(carNames, cars); } private void generateCars(List carNames, List cars) { - Validation.validationCarNumber(carNames); - Validation.validationDuplicatedName(carNames); - for(String name: carNames) { Car car = new Car(name); cars.add(car); diff --git a/src/main/java/domain/Name.java b/src/main/java/domain/Name.java index d693412..5298811 100644 --- a/src/main/java/domain/Name.java +++ b/src/main/java/domain/Name.java @@ -1,14 +1,7 @@ package domain; -public class Name { - // 자동차 이름 - private String name; - - public Name(String name) { - this.name = name; - } - - public String getName() { - return name; - } +/** + * @param name 자동차 이름 + */ +public record Name(String name) { } diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index db8ff92..67b56e8 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -2,10 +2,11 @@ public class Position { // 자동차 위치 + private static final int INITIAL_POSITION = 0; private int position; public Position() { - position = 0; + position = INITIAL_POSITION; } public int getPosition() { diff --git a/src/main/java/util/ErrorMessage.java b/src/main/java/util/ErrorMessage.java index 7770a88..28b6b4e 100644 --- a/src/main/java/util/ErrorMessage.java +++ b/src/main/java/util/ErrorMessage.java @@ -3,10 +3,9 @@ public enum ErrorMessage { NAME_SIZE_ERROR("이름은 1글자 이상 5글자 이하로 작성해주세요."), NAME_DUPLICATE_ERROR("이름은 중복될 수 없습니다."), - CAR_NUMBER_ERROR("자동차는 100대 이하여야 합니다."), + CAR_NUMBER_ERROR("자동차는 1대 이상이어야 합니다."), TRY_TYPE_ERROR("입력값은 정수여야 합니다."), - TRY_RANGE_ERROR("시도 횟수는 양의 정수여야 합니다."), - TRY_LIMIT_ERROR("시도 횟수는 100회 이하여야 합니다."); + TRY_RANGE_ERROR("시도 횟수는 양의 정수여야 합니다."); private final String message; private static final String START_ERROR = "[ERROR] "; diff --git a/src/main/java/util/Validation.java b/src/main/java/util/Validation.java index cb54155..5824b55 100644 --- a/src/main/java/util/Validation.java +++ b/src/main/java/util/Validation.java @@ -7,18 +7,17 @@ import static util.ErrorMessage.*; public class Validation { - private static final int NUMBER_LOWER_BOUND = 0; - private static final int NUMBER_UPPER_BOUND = 100; + private static final int COUNT_LOWER_BOUND = 0; private static final int NAME_MAX_SIZE = 5; public static void validationNameSize(String name) { - if (name.isEmpty() || name.length() > NAME_MAX_SIZE) { + if (name == null || name.isEmpty() || name.length() > NAME_MAX_SIZE) { throw new IllegalArgumentException(NAME_SIZE_ERROR.getMessage()); } } public static void validationCarNumber(List names) { - if (checkUpperBound(names.size())) { + if (names.isEmpty()) { throw new IllegalArgumentException(CAR_NUMBER_ERROR.getMessage()); } } @@ -39,20 +38,8 @@ public static Integer parseInteger(String input) { } public static void validationTryCount(int tryCount) { - if (checkLowerBound(tryCount)) { + if (tryCount <= COUNT_LOWER_BOUND) { throw new IllegalArgumentException(TRY_RANGE_ERROR.getMessage()); } - - if (checkUpperBound(tryCount)) { - throw new IllegalArgumentException(TRY_LIMIT_ERROR.getMessage()); - } - } - - private static boolean checkLowerBound(int number) { - return number <= NUMBER_LOWER_BOUND; - } - - private static boolean checkUpperBound(int number) { - return number >= NUMBER_UPPER_BOUND; } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index d391e56..87057b3 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -17,7 +17,11 @@ public class InputView { public static List getCarName() throws IOException { System.out.println(INPUT_CAR_NAME_MESSAGE.getMessage()); - return Arrays.stream(bufferedReader.readLine().split(SEPARATOR_VALUE.getMessage())) + return splitNames(bufferedReader.readLine()); + } + + private static List splitNames(String names) { + return Arrays.stream(names.split(SEPARATOR_VALUE.getMessage())) .map(String::trim) .collect(Collectors.toList()); } diff --git a/src/test/java/domain/CarTest.java b/src/test/java/domain/CarTest.java new file mode 100644 index 0000000..2e5d4d3 --- /dev/null +++ b/src/test/java/domain/CarTest.java @@ -0,0 +1,27 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; + +class CarTest { + @DisplayName("자동차 이름이 1~5글자면 유효") + @ParameterizedTest + @CsvSource(value = {"a", "ab", "abc"}) + void should_DoesNotThrowException_When_ValidNameSIze(String name) { + assertThatCode(() -> new Car(name)) + .doesNotThrowAnyException(); + } + + @DisplayName("자동차 이름이 1~5글자가 아니라면 예외를 던진다") + @ParameterizedTest + @CsvSource(value = {"''", "qwertyuio", "abcdef", "null"}, nullValues = "null") + void should_ThrowException_When_InvalidNameSize(String name) { + assertThatThrownBy(() -> new Car(name)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR]"); + } +} diff --git a/src/test/java/domain/CarsTest.java b/src/test/java/domain/CarsTest.java new file mode 100644 index 0000000..10a3a38 --- /dev/null +++ b/src/test/java/domain/CarsTest.java @@ -0,0 +1,52 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +class CarsTest { + @DisplayName("자동차가 1대 이상이고 이름 중복이 없으면 유효") + @ParameterizedTest + @CsvSource(value = {"1, 50, 100"}) + void should_DoesNotThrowException_When_ValidCar(int size) { + List carNames = new ArrayList<>(); + for (int i=0; i new Cars(carNames)) + .doesNotThrowAnyException(); + } + + @DisplayName("자동차가 0대면 예외를 던진다") + @Test + void should_ThrowException_When_InvalidCarNumber() { + List carNames = Collections.emptyList(); + + assertThatThrownBy(() -> new Cars(carNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR]"); + } + + @DisplayName("자동차 이름이 중복되면 예외를 던진다") + @ParameterizedTest + @CsvSource(value = {"2", "5", "10"}) + void should_ThrowException_When_DuplicatedName(int size) { + List carNames = new ArrayList<>(); + for(int i=0; i new Cars(carNames)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR]"); + } +} diff --git a/src/test/java/domain/PositionTest.java b/src/test/java/domain/PositionTest.java new file mode 100644 index 0000000..49c1df0 --- /dev/null +++ b/src/test/java/domain/PositionTest.java @@ -0,0 +1,19 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PositionTest { + @DisplayName("increasePosition은 position을 1 증가시킨다") + @ParameterizedTest + @CsvSource(value = {"1"}) + void should_IncreasePosition_When_UsingIncresePosition(int movedPosition) { + Position position = new Position(); + position.increasePosition(); + + assertEquals(position.getPosition(), movedPosition); + } +} diff --git a/src/test/java/domain/TryCountTest.java b/src/test/java/domain/TryCountTest.java new file mode 100644 index 0000000..6dabab1 --- /dev/null +++ b/src/test/java/domain/TryCountTest.java @@ -0,0 +1,27 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +public class TryCountTest { + @DisplayName("TryCount가 양의 정수면 유효") + @ParameterizedTest + @CsvSource(value = {"1", "5", "100"}) + void should_DoesNotThrowException_When_PositiveTryCount(int number) { + assertThatCode(() -> new TryCount(number)) + .doesNotThrowAnyException(); + } + + @DisplayName("TryCount가 0 이하면 예외를 던진다") + @ParameterizedTest + @CsvSource(value = {"0", "-1", "-100"}) + void should_ThrowException_When_InvalidTryCount(int number) { + assertThatThrownBy(()-> new TryCount(number)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR]"); + } +} diff --git a/src/test/java/util/IntegerParserTest.java b/src/test/java/util/IntegerParserTest.java new file mode 100644 index 0000000..58c3a8b --- /dev/null +++ b/src/test/java/util/IntegerParserTest.java @@ -0,0 +1,27 @@ +package util; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +public class IntegerParserTest { + @DisplayName("정수가 들어오면 유효") + @ParameterizedTest + @CsvSource(value = {"1", "5", "100"}) + void should_DoesNotThrowException_When_InputIsInteger(String input) { + assertThatCode(() -> Validation.parseInteger(input)) + .doesNotThrowAnyException(); + } + + @DisplayName("정수가 아닌 값이 들어오면 예외를 던진다") + @ParameterizedTest + @CsvSource(value = {"a", "5.5", "''", "***"}) + void should_ThrowException_When_InputIsNotInteger(String input) { + assertThatThrownBy(() -> Validation.parseInteger(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR]"); + } +} From c1b1db89370c8edf166872a15a0d93dc60bbb351 Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Sat, 30 Mar 2024 16:00:50 +0900 Subject: [PATCH 12/14] =?UTF-8?q?docs:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EC=84=A4=EB=AA=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +--- docs/README.md | 40 +++++++++++++++++++ src/main/java/domain/Car.java | 3 ++ src/main/java/domain/Cars.java | 6 +++ src/main/java/domain/Position.java | 2 + src/main/java/domain/RandomNumber.java | 1 + src/main/java/domain/TryCount.java | 2 + src/main/java/util/Validation.java | 5 +++ src/main/java/view/InputView.java | 3 ++ src/main/java/view/OutputView.java | 5 +++ src/test/java/domain/PositionTest.java | 2 +- ...gerParserTest.java => ValidationTest.java} | 2 +- 12 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 docs/README.md rename src/test/java/util/{IntegerParserTest.java => ValidationTest.java} (96%) diff --git a/README.md b/README.md index fed3a2a..45d1581 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,3 @@ # java-racingcar -자동차 경주 미션 저장소 - -1. 자동차 정보 입력 -2. 시도 횟수 입력 -3. 실행 결과 출력 -4. 우승자 출력 \ No newline at end of file +자동차 경주 미션 저장소 \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..7a622fa --- /dev/null +++ b/docs/README.md @@ -0,0 +1,40 @@ +# JAVA-RACINGCAR + +## 패키지 구조 +### [Model] +#### Car +- Name과 Position을 담은 객체 +#### Cars +- 게임에 참여하는 Car들을 묶은 객체 +#### Name +- Car의 이름을 담은 객체 +#### Position +- Car의 위치를 담은 객체 +#### RandomNumber +- 전진 조건이 되는 수를 생성하는 객체 +#### TryCount +- 게임 진행 횟수를 담은 객체 + +### [View] +#### InputView +- 사용자의 입력을 받음 +#### OutputView +- 안내 문구 및 결과 출력 +#### ViewMessage(enum) +- 입출력 문구 모음 + +### [Controller] +#### RacingController +- 게임 진행 + +### [Util] +#### ErrorMessage(enum) +- 에러 문구 모음 +#### Validation +- Model과 View 검증 + +## 필요 기능 +1. 자동차 정보 입력 +2. 시도 횟수 입력 +3. 실행 결과 출력 +4. 우승자 출력 \ No newline at end of file diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java index c005f2a..99aae11 100644 --- a/src/main/java/domain/Car.java +++ b/src/main/java/domain/Car.java @@ -14,14 +14,17 @@ public Car(String name) { this.position = new Position(); } + // 자동차 이름 반환 public String getCarName() { return name.name(); } + // 자동차 위치 반환 public int getCarPosition() { return position.getPosition(); } + // 자동차 전진 public void moveCar(int number) { if (number >= MINIMUM_MOVE_POWER) { position.increasePosition(); diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java index 4dcf61e..8e91dfc 100644 --- a/src/main/java/domain/Cars.java +++ b/src/main/java/domain/Cars.java @@ -18,6 +18,7 @@ public Cars(List carNames) { generateCars(carNames, cars); } + // 자동차 생성 private void generateCars(List carNames, List cars) { for(String name: carNames) { Car car = new Car(name); @@ -25,10 +26,12 @@ private void generateCars(List carNames, List cars) { } } + // 자동차 리스트 반환 public List getCars() { return cars; } + // 자동차 전진 public void moveCars() { for (Car c: cars) { int number = RandomNumber.getRandomNumber(); @@ -36,12 +39,14 @@ public void moveCars() { } } + // 우승자 이름 반환 public List findWinnerName() { return findWinner().stream() .map(Car::getCarName) .collect(Collectors.toList()); } + // 우승자 반환 private List findWinner() { int winnerPosition = getWinnerPosition(); return cars.stream() @@ -49,6 +54,7 @@ private List findWinner() { .collect(Collectors.toList()); } + // 우승자 위치 반환 private int getWinnerPosition() { return cars.stream() .mapToInt(Car::getCarPosition) diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index 67b56e8..e235874 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -9,10 +9,12 @@ public Position() { position = INITIAL_POSITION; } + // 위치 반환 public int getPosition() { return position; } + // 위치 증가(전진) public void increasePosition() { position++; } diff --git a/src/main/java/domain/RandomNumber.java b/src/main/java/domain/RandomNumber.java index 5b55048..e544aa6 100644 --- a/src/main/java/domain/RandomNumber.java +++ b/src/main/java/domain/RandomNumber.java @@ -6,6 +6,7 @@ public class RandomNumber { private static final int NUMBER_UPPER_BOUND = 10; private static final Random random = new Random(); + // 1~10 난수 반환 public static int getRandomNumber() { return random.nextInt(NUMBER_UPPER_BOUND); } diff --git a/src/main/java/domain/TryCount.java b/src/main/java/domain/TryCount.java index 690c860..4fa03f9 100644 --- a/src/main/java/domain/TryCount.java +++ b/src/main/java/domain/TryCount.java @@ -11,10 +11,12 @@ public TryCount(int tryCount) { this.tryCount = tryCount; } + // 시도 횟수 감소 public void decreaseTryCount() { tryCount--; } + // 시도 가능 여부 반환 public boolean isPlayable() { return PLAYABLE_LOWER_BOUND <= tryCount; } diff --git a/src/main/java/util/Validation.java b/src/main/java/util/Validation.java index 5824b55..86ff87c 100644 --- a/src/main/java/util/Validation.java +++ b/src/main/java/util/Validation.java @@ -10,18 +10,21 @@ public class Validation { private static final int COUNT_LOWER_BOUND = 0; private static final int NAME_MAX_SIZE = 5; + // 이름 길이 유효 여부 검사 public static void validationNameSize(String name) { if (name == null || name.isEmpty() || name.length() > NAME_MAX_SIZE) { throw new IllegalArgumentException(NAME_SIZE_ERROR.getMessage()); } } + // 자동차 존재 여부 검사 public static void validationCarNumber(List names) { if (names.isEmpty()) { throw new IllegalArgumentException(CAR_NUMBER_ERROR.getMessage()); } } + // 자동차 이름 중복 검사 public static void validationDuplicatedName(List names) { Set deduplicate = new HashSet<>(names); if (deduplicate.size() != names.size()) { @@ -29,6 +32,7 @@ public static void validationDuplicatedName(List names) { } } + // 정수 입력 검사 public static Integer parseInteger(String input) { try { return Integer.parseInt(input); @@ -37,6 +41,7 @@ public static Integer parseInteger(String input) { } } + // 시도 횟수가 양의 정수인지 검사 public static void validationTryCount(int tryCount) { if (tryCount <= COUNT_LOWER_BOUND) { throw new IllegalArgumentException(TRY_RANGE_ERROR.getMessage()); diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 87057b3..14e6535 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -15,17 +15,20 @@ public class InputView { private static final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); + // 자동차 이름 입력 public static List getCarName() throws IOException { System.out.println(INPUT_CAR_NAME_MESSAGE.getMessage()); return splitNames(bufferedReader.readLine()); } + // 분리된 자동차 이름 반환 private static List splitNames(String names) { return Arrays.stream(names.split(SEPARATOR_VALUE.getMessage())) .map(String::trim) .collect(Collectors.toList()); } + // 시도 횟수 입력 public static int getTryCount() throws IOException { System.out.println(TRY_COUNT_MESSAGE.getMessage()); return Validation.parseInteger(bufferedReader.readLine()); diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index b3ae549..798c2cf 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -8,10 +8,12 @@ public class OutputView { + // 실행 결과 메시지 출력 public static void printRacingResult() { System.out.println(TRY_RESULT_MESSAGE.getMessage()); } + // 실행 결과 출력 public static void printRacingStatus(List cars) { for (Car c: cars) { String position = getCurrentPosition(c.getCarPosition()); @@ -20,14 +22,17 @@ public static void printRacingStatus(List cars) { System.out.println(); } + // 심볼로 표현된 위치 반환 private static String getCurrentPosition(int position) { return POSITION_SYMBOL.getMessage().repeat(position); } + // 우승자 출력 public static void printRacingWinner(List winners) { System.out.printf(WINNER_MESSAGE_FORMAT.getMessage(), getCombinedWinner(winners)); } + // 합쳐진 우승자 이름 반환 private static String getCombinedWinner(List winners) { return String.join(DELIMITER_VALUE.getMessage(), winners); } diff --git a/src/test/java/domain/PositionTest.java b/src/test/java/domain/PositionTest.java index 49c1df0..d4922c4 100644 --- a/src/test/java/domain/PositionTest.java +++ b/src/test/java/domain/PositionTest.java @@ -10,7 +10,7 @@ public class PositionTest { @DisplayName("increasePosition은 position을 1 증가시킨다") @ParameterizedTest @CsvSource(value = {"1"}) - void should_IncreasePosition_When_UsingIncresePosition(int movedPosition) { + void should_IncreasePosition_When_UsingIncreasePosition(int movedPosition) { Position position = new Position(); position.increasePosition(); diff --git a/src/test/java/util/IntegerParserTest.java b/src/test/java/util/ValidationTest.java similarity index 96% rename from src/test/java/util/IntegerParserTest.java rename to src/test/java/util/ValidationTest.java index 58c3a8b..51391d6 100644 --- a/src/test/java/util/IntegerParserTest.java +++ b/src/test/java/util/ValidationTest.java @@ -7,7 +7,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; -public class IntegerParserTest { +public class ValidationTest { @DisplayName("정수가 들어오면 유효") @ParameterizedTest @CsvSource(value = {"1", "5", "100"}) From 267c45996be90fdc17afcb1866542f37fdfdd49b Mon Sep 17 00:00:00 2001 From: ihtblwFIZ Date: Sat, 30 Mar 2024 16:16:32 +0900 Subject: [PATCH 13/14] =?UTF-8?q?docs:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EC=84=A4=EB=AA=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 45d1581..a97175b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,42 @@ # java-racingcar -자동차 경주 미션 저장소 \ No newline at end of file +자동차 경주 미션 저장소 + +## 패키지 구조 +### [Model] +#### Car +- 'Name'과 'Position'을 담은 객체 +#### Cars +- 게임에 참여하는 'Car'들을 묶은 객체 +#### Name +- 'Car'의 이름을 담은 객체 +#### Position +- 'Car'의 위치를 담은 객체 +#### RandomNumber +- 전진 조건이 되는 수를 생성하는 객체 +#### TryCount +- 게임 진행 횟수를 담은 객체 + +### [View] +#### InputView +- 사용자의 입력을 받음 +#### OutputView +- 안내 문구 및 결과 출력 +#### ViewMessage(enum) +- 입출력 문구 모음 + +### [Controller] +#### RacingController +- 게임 진행 + +### [Util] +#### ErrorMessage(enum) +- 에러 문구 모음 +#### Validation +- Model과 View 검증 + +## 필요 기능 +1. 자동차 정보 입력 +2. 시도 횟수 입력 +3. 실행 결과 출력 +4. 우승자 출력 \ No newline at end of file From f6ebf6bbe066f39ec024edbac2c16002fd38794c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=95=98=EC=97=B0?= Date: Sat, 30 Mar 2024 16:19:53 +0900 Subject: [PATCH 14/14] =?UTF-8?q?refactor:=20readme=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 | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 7a622fa..0000000 --- a/docs/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# JAVA-RACINGCAR - -## 패키지 구조 -### [Model] -#### Car -- Name과 Position을 담은 객체 -#### Cars -- 게임에 참여하는 Car들을 묶은 객체 -#### Name -- Car의 이름을 담은 객체 -#### Position -- Car의 위치를 담은 객체 -#### RandomNumber -- 전진 조건이 되는 수를 생성하는 객체 -#### TryCount -- 게임 진행 횟수를 담은 객체 - -### [View] -#### InputView -- 사용자의 입력을 받음 -#### OutputView -- 안내 문구 및 결과 출력 -#### ViewMessage(enum) -- 입출력 문구 모음 - -### [Controller] -#### RacingController -- 게임 진행 - -### [Util] -#### ErrorMessage(enum) -- 에러 문구 모음 -#### Validation -- Model과 View 검증 - -## 필요 기능 -1. 자동차 정보 입력 -2. 시도 횟수 입력 -3. 실행 결과 출력 -4. 우승자 출력 \ No newline at end of file