diff --git a/docs/README.md b/docs/README.md index e69de29..9acf915 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,28 @@ +자동차 경주 +- + +`기능` + +입력 기능 +- 각 자동차에 이름 부여(쉼표를 기준으로 구분하여 입력) +- 몇 번의 이동을 할 것인지 입력 + +차수별 실행 결과 출력 기능 +- 사용자 입력값에 기반해 차수만큼 자동차 진행결과 출력 + +자동차 전진 기능 +- [전진] : 0~9 사이에서 무작위 값을 구한 후 4 이상이면 자동차 '-' 출력 +- [멈춤] : 4미만이면 정지. 출력X + +우승자 안내 문구 출력 기능 +- 우승자 안내, 쉼표로 우승자 나열 + +`예외처리` + +- 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생 +- 자동차 이름 5자 초과 +- 이름 공백 포함 +- 이름 빈값 +- 이름 중복 +- 시도 횟수 0이하 +- 시도 횟수 숫자 아님 diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e..d529a4c 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,95 @@ package racingcar; +import java.util.HashSet; + +import static camp.nextstep.edu.missionutils.Console.readLine; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + HashSet uniqueElements = new HashSet<>(); + + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + String carName = readLine(); + + nameException(carName); // 예외처리 + + String[] tokens = carName.split(","); + + equalNameException(tokens, uniqueElements); // 예외처리 + eachNameException(tokens); // 예외처리 + + Car[] cars = new Car[tokens.length]; + for (int i = 0; i < tokens.length; i++) { + cars[i] = new Car(tokens[i]); + } + + System.out.println("시도할 횟수는 몇 회인가요?"); + String racingCount = readLine(); + int counts = tryCountNumCheckException(racingCount); // 예외처리 + tryCountException(counts); // 예외처리 + + System.out.println(); + System.out.println("실행 결과"); + Racing race = new Racing(); + View view = new View(); + for (int i = 0; i < counts; i++) { + for (int j = 0; j < tokens.length; j++) { + race.goOrStrop(cars[j]); + view.racingCurrentView(cars[j]); + } + System.out.println(); + } + + view.winner(cars); + } + + public static void nameException(String carName) { + if (carName == null || carName.isBlank()) { + throw new IllegalArgumentException("이름을 입력하지 않았습니다."); + } + + if (carName.endsWith(",")) { + throw new IllegalArgumentException("마지막은 쉼표로 끝날 수 없습니다."); + } + } + + public static void eachNameException(String[] tokens) { + if (tokens.length == 0) { + throw new IllegalArgumentException("자동차를 적어야합니다."); + } + for (int i = 0; i < tokens.length; i++) { + if (tokens[i].length() > 5) { + throw new IllegalArgumentException("자동차 이름은 5자 이하만 가능합니다."); + } + if (tokens[i].isBlank()) { + throw new IllegalArgumentException("자동차 이름을 적어야 합니다."); + } + if (tokens[i].contains(" ")) { + throw new IllegalArgumentException("자동차 이름에 공백은 불가능합니다."); + } + } + } + + public static void equalNameException(String[] tokens, HashSet uniqueElements) { + for (String token : tokens) { + if (!uniqueElements.add(token)) { + throw new IllegalArgumentException("자동차 이름이 중복됩니다."); + } + } + } + + public static void tryCountException(int counts) { + if (counts < 1) { + throw new IllegalArgumentException("시도 횟수는 0보다 커야합니다."); + } + } + + public static int tryCountNumCheckException(String racingCount) { + try { + int box = Integer.parseInt(racingCount); + return box; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("시도 횟수는 숫자여야합니다."); + } } } diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java new file mode 100644 index 0000000..606d3fa --- /dev/null +++ b/src/main/java/racingcar/Car.java @@ -0,0 +1,23 @@ +package racingcar; + +public class Car { + private String carName; + private int movement; + + public Car(String carName) { + this.carName = carName; + this.movement = 0; + } + + public void move() { + movement += 1; + } + + public String checkCarName() { + return carName; + } + + public int checkMovement() { + return movement; + } +} diff --git a/src/main/java/racingcar/Racing.java b/src/main/java/racingcar/Racing.java new file mode 100644 index 0000000..e7de3fd --- /dev/null +++ b/src/main/java/racingcar/Racing.java @@ -0,0 +1,13 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Randoms; + +public class Racing { + + public void goOrStrop(Car car) { + int randomNum = Randoms.pickNumberInRange(0, 9); + if (randomNum >= 4) { + car.move(); + } + } +} diff --git a/src/main/java/racingcar/View.java b/src/main/java/racingcar/View.java new file mode 100644 index 0000000..6726005 --- /dev/null +++ b/src/main/java/racingcar/View.java @@ -0,0 +1,30 @@ +package racingcar; + +public class View { + + public void racingCurrentView(Car car) { + System.out.println(car.checkCarName() + " : " + "-".repeat(car.checkMovement())); + } + + public void winner(Car[] cars) { + int max = cars[0].checkMovement(); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < cars.length; i++) { + if (max < cars[i].checkMovement()) { + max = cars[i].checkMovement(); + } + } + + for (int j = 0; j < cars.length; j++) { + if (cars[j].checkMovement() == max) { + if (sb.length() > 0) { + sb.append(", "); + } + sb.append(cars[j].checkCarName()); + } + } + + System.out.println("최종 우승자 : " + sb); + } +} diff --git a/src/test/java/racingcar/ApplicationTest.java b/src/test/java/racingcar/ApplicationTest.java index 03aa74b..43a717e 100644 --- a/src/test/java/racingcar/ApplicationTest.java +++ b/src/test/java/racingcar/ApplicationTest.java @@ -20,6 +20,7 @@ class ApplicationTest extends NsTest { assertThat(output()).contains("pobi : -", "woni : ", "최종 우승자 : pobi"); }, MOVING_FORWARD, STOP + ); }