diff --git a/README.md b/README.md index d0286c8..c6a43ed 100644 --- a/README.md +++ b/README.md @@ -1 +1,20 @@ # java-racingcar-precourse + +### 1. 입력 받기 + +- 경주 할 자동차 이름 +- 시도할 회수 + +### 2. 전진 조건 생성 + +- 랜덤 값 생성 후 자동차에 적용 + +### 3. 출력 + +- 진행 상황 표시 +- 최종 결과 표시 + +### 0. 예외 케이스 처리 + +- 자동차 이름이 5자 초과된 경우 +- 자동차 이름이 같은 경우 \ No newline at end of file diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e..a0c1ffd 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,24 @@ package racingcar; +import camp.nextstep.edu.missionutils.Console; +import racingcar.Game; +import racingcar.InputValidator; +import java.util.List; +import java.lang.String; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + + // 경주 할 자동차 입력받기 + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + List carNames = InputValidator.validateCarNames(Console.readLine()); + + // 시도 할 횟수 입력받기 + System.out.println("시도할 회수는 몇회인가요?"); + int attempts = InputValidator.validateAttempts(Console.readLine()); + + // 게임 진행 + Game game = new Game(carNames, attempts); + game.start(); } } diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java new file mode 100644 index 0000000..8eec0e0 --- /dev/null +++ b/src/main/java/racingcar/Car.java @@ -0,0 +1,36 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Randoms; + +public class Car { + private final String carName; + private int position = 0; + + // Car 클래스 생성자 + public Car(String name) { + if(name.length() > 5) { // 자동차 이름의 길이가 5 초과일 경우 예외 발생 + throw new IllegalArgumentException("Car name cannot be longer than 5 characters"); + } + this.carName = name; + } + + // 객체 움직임 정의 : + public void move() { + int value = Randoms.pickNumberInRange(0,9); + if(value >= 4) { + this.position++; + } + } + + public int getPosition() { + return position; + } + + public String getName() { + return carName; + } + + public String getStatus() { + return carName + " : " + "-".repeat(position); + } +} diff --git a/src/main/java/racingcar/Game.java b/src/main/java/racingcar/Game.java new file mode 100644 index 0000000..beb12c7 --- /dev/null +++ b/src/main/java/racingcar/Game.java @@ -0,0 +1,53 @@ +package racingcar; + +import racingcar.Car; +import java.util.List; +import java.util.stream.Collectors; + +public class Game { + private final List cars; + private final int attempts; + + // Game 클래스의 생성자 + public Game(List carNames, int counts) { + this.cars = carNames.stream().map(name -> new Car(name)).collect(Collectors.toList()); + this.attempts = counts; + } + + // 게임 시작 메소드 + public void start() { + System.out.println("실행 결과"); + run(); + } + + // 게임 진행 메소드 + private void run() { + for(int i = 0; i < attempts; i++) { + for(Car car : cars) { + car.move(); + } + printStatus(); + } + printWinner(); + } + + // 게임 과정 출력 메소드 + private void printStatus() { + for(Car car : cars) { + System.out.println(car.getStatus()); + } + System.out.println(); + } + + // 최종 우승자 출력 메소드 + private void printWinner() { + // 1. 최고 거리 찾기 + int winnerDistance = cars.stream().mapToInt(Car::getPosition).max().orElse(0); + + // 2. 최고 거리를 간 자동차 찾기 + List winnerNames = cars.stream().filter(car -> car.getPosition() == winnerDistance).map(Car::getName).collect(Collectors.toList()); + + // 3. 최종 우승자 출력 + System.out.println("최종 우승자 : " + String.join(", ", winnerNames)); + } +} diff --git a/src/main/java/racingcar/InputValidator.java b/src/main/java/racingcar/InputValidator.java new file mode 100644 index 0000000..aa211dc --- /dev/null +++ b/src/main/java/racingcar/InputValidator.java @@ -0,0 +1,40 @@ +package racingcar; + +import java.util.List; +import java.util.Arrays; + +// 올바르지 않은 입력의 경우 +// 1. 자동차 이름이 1~5 글자를 벗어날 경우 +// 2. 시도 횟수가 숫자가 아닌 경우 +// 3. 시도 횟수가 0인 경우 + +public class InputValidator { + + // 경주할 자동차 입력과 관련한 예외 + public static List validateCarNames(String input) { + List carNames = Arrays.asList(input.split(",")); + + // 1. 자동차 이름이 1~5 글자를 벗어날 경우 + if(carNames.stream().anyMatch(name -> name.length() > 5 || name.length() < 1)) { + throw new IllegalArgumentException("Car name cannot be longer than 5 and shorter than 1 characters"); + } + return carNames; + } + + // 시도 횟수 입력과 관련한 예외 + public static int validateAttempts(String input) { + if (input == null || input.trim().isEmpty()) { + throw new IllegalArgumentException("Attempt number cannot be empty."); + } + + try { // 3. 시도 횟수가 0인 경우 + int attempts = Integer.parseInt(input); + if (attempts < 1) { + throw new IllegalArgumentException("Attempt number cannot be less than 1"); + } + return attempts; + } catch (NumberFormatException e) { // 2. 시도 횟수가 숫자가 아닌 경우 + throw new IllegalArgumentException("Attempt number must be a number"); + } + } +}