diff --git a/README.md b/README.md index d0286c859f..f4b6ae4beb 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ # java-racingcar-precourse + +- [x] 각 자동차에 이름을 부여할 수 있다. +- [x] 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- [x] 자동차 이름은 쉼표(,)를 기준으로 구분한다. +- [x] 이름은 5자 이하만 가능하다. +- [x] 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +- [x] 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다. +- [x] 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. +- [x] 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다. +- [ ] 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다. +- 추후에 클래스를 나누자. 일단은 동작하도록 구현하자. \ No newline at end of file diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e724..957f670f3e 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,18 @@ package racingcar; +import racingcar.controller.GameController; +import racingcar.model.CarNameValidator; +import racingcar.view.InputView; +import racingcar.view.OutputView; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + CarNameValidator carNameValidator = new CarNameValidator(); + + GameController gameController = new GameController(inputView, outputView, carNameValidator); + gameController.run(); } + } diff --git a/src/main/java/racingcar/controller/GameController.java b/src/main/java/racingcar/controller/GameController.java new file mode 100644 index 0000000000..50ee0fad7b --- /dev/null +++ b/src/main/java/racingcar/controller/GameController.java @@ -0,0 +1,47 @@ +package racingcar.controller; + +import racingcar.model.CarNameValidator; +import racingcar.model.Cars; +import racingcar.view.InputView; +import racingcar.view.OutputView; + +import java.util.List; + +public class GameController { + private final InputView inputView; + private final OutputView outputView; + private final CarNameValidator carNameValidator; + private Cars cars; + private int tryCount; + + public GameController(InputView inputView, OutputView outputView, CarNameValidator carNameValidator) { + this.inputView = inputView; + this.outputView = outputView; + this.carNameValidator = carNameValidator; + } + + public void run() { + init(); + play(); + showWinners(); + } + + public void init() { + String input = inputView.inputCarNames(); + String[] carNames = input.split(","); + carNameValidator.validate(carNames); + cars = new Cars(carNames); + tryCount = inputView.inputTryCount(); + } + + public void play() { + outputView.printPlayMessage(); + cars.playRound(tryCount); + outputView.printPlayResults(cars.getResults()); + } + + public void showWinners() { + List winners = cars.getWinners(); + outputView.printWinners(winners); + } +} diff --git a/src/main/java/racingcar/model/Car.java b/src/main/java/racingcar/model/Car.java new file mode 100644 index 0000000000..57de952bf4 --- /dev/null +++ b/src/main/java/racingcar/model/Car.java @@ -0,0 +1,33 @@ +package racingcar.model; + +import racingcar.util.RandomNumber; + +public class Car { + private final String name; + private int forward = 0; + + public Car(String carName) { + this.name = carName; + } + + public void moveForward() { + if (RandomNumber.getRandomNumber() >= 4) { + forward = forward + 1; + } + } + + public String getResult() { + StringBuilder result = new StringBuilder(name + " : "); + result.append("-".repeat(Math.max(0, forward))); + return String.valueOf(result); + } + + public String getName() { + return name; + } + + public int getForward() { + return forward; + } + +} diff --git a/src/main/java/racingcar/model/CarNameValidator.java b/src/main/java/racingcar/model/CarNameValidator.java new file mode 100644 index 0000000000..9300392c7d --- /dev/null +++ b/src/main/java/racingcar/model/CarNameValidator.java @@ -0,0 +1,11 @@ +package racingcar.model; + +public class CarNameValidator { + public void validate(String[] carNames) { + for (String carName : carNames) { + if (carName.length() > 5) { + throw new IllegalArgumentException(); + } + } + } +} diff --git a/src/main/java/racingcar/model/Cars.java b/src/main/java/racingcar/model/Cars.java new file mode 100644 index 0000000000..696e947f54 --- /dev/null +++ b/src/main/java/racingcar/model/Cars.java @@ -0,0 +1,48 @@ +package racingcar.model; + +import java.util.ArrayList; +import java.util.List; + +public class Cars { + private final List cars = new ArrayList<>(); + + public Cars(String[] carNames) { + for (String carName : carNames) { + cars.add(new Car(carName)); + } + } + + public void playRound(int tryCount) { + while (tryCount > 0) { + moveCarsWithRandomCondition(); + tryCount = tryCount - 1; + } + } + + private void moveCarsWithRandomCondition() { + for (Car car : cars) { + car.moveForward(); + } + } + + public List getResults() { + List results = new ArrayList<>(); + for (Car car : cars) { + results.add(car.getResult()); + } + return results; + } + + public List getWinners() { + int maxForward = cars.stream() + .mapToInt(Car::getForward) + .max() + .orElseThrow(() -> new IllegalArgumentException("최대값을 찾을 수 없습니다.")); + + return cars.stream() + .filter(car -> car.getForward() == maxForward) + .map(Car::getName) + .toList(); + } + +} diff --git a/src/main/java/racingcar/util/RandomNumber.java b/src/main/java/racingcar/util/RandomNumber.java new file mode 100644 index 0000000000..c420e4bc9c --- /dev/null +++ b/src/main/java/racingcar/util/RandomNumber.java @@ -0,0 +1,9 @@ +package racingcar.util; + +import camp.nextstep.edu.missionutils.Randoms; + +public class RandomNumber { + public static int getRandomNumber() { + return Randoms.pickNumberInRange(0, 9); + } +} diff --git a/src/main/java/racingcar/view/InputView.java b/src/main/java/racingcar/view/InputView.java new file mode 100644 index 0000000000..ed240ac425 --- /dev/null +++ b/src/main/java/racingcar/view/InputView.java @@ -0,0 +1,15 @@ +package racingcar.view; + +import camp.nextstep.edu.missionutils.Console; + +public class InputView { + public String inputCarNames() { + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + return Console.readLine(); + } + + public int inputTryCount() { + System.out.println("시도할 횟수는 몇 회인가요?"); + return Integer.parseInt(Console.readLine()); + } +} diff --git a/src/main/java/racingcar/view/OutputView.java b/src/main/java/racingcar/view/OutputView.java new file mode 100644 index 0000000000..7f0f6bd659 --- /dev/null +++ b/src/main/java/racingcar/view/OutputView.java @@ -0,0 +1,35 @@ +package racingcar.view; + +import java.util.List; + +public class OutputView { + public void printPlayMessage() { + System.out.println(); + System.out.println("실행결과"); + } + + public void printPlayResults(List results) { + for (String result : results) { + System.out.println(result); + } + System.out.println(); + } + + public void printWinners(List winners) { + String message = "최종 우승자 : "; + if (winners.size() == 1) { + printSingleWinner(message, winners); + return; + } + printMultipleWinners(message, winners); + + } + + private void printSingleWinner(String message, List winners) { + System.out.println(message + winners.get(0)); + } + + private void printMultipleWinners(String message, List winners) { + System.out.println(message + String.join(", ", winners)); + } +}