diff --git a/src/main/java/racing/Application.java b/src/main/java/racing/Application.java new file mode 100644 index 000000000..514eb3c62 --- /dev/null +++ b/src/main/java/racing/Application.java @@ -0,0 +1,16 @@ +package racing; + +import racing.console.ConsoleInputView; +import racing.console.ConsoleOutputView; +import racing.core.Game; +import racing.core.InputView; +import racing.core.OutputView; + +public class Application { + public static void main(String[] args) { + InputView inputView = new ConsoleInputView(); + OutputView outputView = new ConsoleOutputView(); + Game game = new Game(inputView, outputView); + game.play(); + } +} diff --git a/src/main/java/racing/README.md b/src/main/java/racing/README.md new file mode 100644 index 000000000..918a1e716 --- /dev/null +++ b/src/main/java/racing/README.md @@ -0,0 +1,26 @@ +# 요구사항 + +- core + - 게임 + - 횟수 + - 우승자를 판별 + - 자동차 + - 이름: 5자 이하 + - position: 현재 위치 + - move + - 0에서 9 사이에서 random값을 구한 후 random 값이 4이상이면 전진한다 +- 입력 + - 자동차 이름들을 입력받는다. 자동차 이름은 쉼표(,)로 구분한다 + - 게임 실행 횟수를 입력받는다. +- 출력 + - 한 번 실행할 때마다 자동차 이름과 이동 거리를 출력한다. + - 우승자 이름을 출력한다. + +필요한동작 + +- 자동차가 움직인다 Car.move() + +랜덤을 어떻게 테스트하지? + +- 운전 전략을 집어넣자 + - Driver.shouldMove() \ No newline at end of file diff --git a/src/main/java/racing/console/ConsoleInputView.java b/src/main/java/racing/console/ConsoleInputView.java new file mode 100644 index 000000000..85292b86b --- /dev/null +++ b/src/main/java/racing/console/ConsoleInputView.java @@ -0,0 +1,37 @@ +package racing.console; + +import racing.core.Car; +import racing.core.CrazyDriver; +import racing.core.InputView; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class ConsoleInputView implements InputView { + private final Scanner scanner = new Scanner(System.in); + + @Override + public List getCars(String message) { + System.out.println(message); + String line = this.scanner.nextLine(); + String[] names = line.split(","); + + List cars = new ArrayList<>(); + for (String name : names) { + cars.add(new Car(name, new CrazyDriver())); + } + + return cars; + } + + @Override + public int getTrackLength(String message) { + System.out.println(message); + String line = this.scanner.nextLine(); + + int trackLength = Integer.parseInt(line); + + return trackLength; + } +} diff --git a/src/main/java/racing/console/ConsoleOutputView.java b/src/main/java/racing/console/ConsoleOutputView.java new file mode 100644 index 000000000..a7aa4617b --- /dev/null +++ b/src/main/java/racing/console/ConsoleOutputView.java @@ -0,0 +1,25 @@ +package racing.console; + +import racing.core.OutputView; + +public class ConsoleOutputView implements OutputView { + private static final String NEW_LINE = System.lineSeparator(); + private static final StringBuilder buffer = new StringBuilder(); + + @Override + public void print(String message) { + buffer.append(message); + } + + @Override + public void println(String message) { + buffer.append(message); + buffer.append(NEW_LINE); + } + + @Override + public void flush() { + System.out.print(buffer); + buffer.setLength(0); + } +} diff --git a/src/main/java/racing/core/Car.java b/src/main/java/racing/core/Car.java new file mode 100644 index 000000000..09286c0e3 --- /dev/null +++ b/src/main/java/racing/core/Car.java @@ -0,0 +1,36 @@ +package racing.core; + +public class Car { + private final String name; + private final Driver driver; + private int position; + + public Car(String name, Driver driver) { + this.name = name; + this.driver = driver; + this.position = 0; + } + + public void move() { + if (driver.shouldMove()) { + ++this.position; + } + } + + public boolean positionedAt(int position) { + return this.position == position; + } + + public String getName() { + return name; + } + + public int getPosition() { + return this.position; + } + + @Override + public String toString() { + return this.name + " : " + "-".repeat(position); + } +} diff --git a/src/main/java/racing/core/CrazyDriver.java b/src/main/java/racing/core/CrazyDriver.java new file mode 100644 index 000000000..6f6b4003c --- /dev/null +++ b/src/main/java/racing/core/CrazyDriver.java @@ -0,0 +1,14 @@ +package racing.core; + +import java.util.Random; + +public class CrazyDriver implements Driver { + private static final int MOVE_BOUND = 10; + private static final int MOVE_THRESHOLD = 4; + private final Random random = new Random(); + + @Override + public boolean shouldMove() { + return random.nextInt(MOVE_BOUND) > MOVE_THRESHOLD; + } +} diff --git a/src/main/java/racing/core/Driver.java b/src/main/java/racing/core/Driver.java new file mode 100644 index 000000000..bd8dc8535 --- /dev/null +++ b/src/main/java/racing/core/Driver.java @@ -0,0 +1,5 @@ +package racing.core; + +public interface Driver { + boolean shouldMove(); +} diff --git a/src/main/java/racing/core/Game.java b/src/main/java/racing/core/Game.java new file mode 100644 index 000000000..922d4eeec --- /dev/null +++ b/src/main/java/racing/core/Game.java @@ -0,0 +1,51 @@ +package racing.core; + +import java.util.ArrayList; +import java.util.List; + +public class Game { + private static final String ENTER_CAR_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; + private static final String ENTER_TRACK_LENGTH_MESSAGE = "시도할 회수는 몇회인가요?"; + private final InputView inputView; + private final OutputView outputView; + private final List cars; + private final int trackLength; + + public Game(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + + this.cars = inputView.getCars(ENTER_CAR_MESSAGE); + this.trackLength = inputView.getTrackLength(ENTER_TRACK_LENGTH_MESSAGE); + } + + public void play() { + this.outputView.println("실행 결과"); + for (int i = 0; i < this.trackLength; i++) { + for (Car car : this.cars) { + car.move(); + } + for (Car car : this.cars) { + this.outputView.println(car.toString()); + } + this.outputView.println(""); + } + + + List winners = new ArrayList<>(); + int maxPosition = 0; + for (Car car : this.cars) { + maxPosition = Math.max(car.getPosition(), maxPosition); + } + + for (Car car : this.cars) { + if (car.positionedAt(maxPosition)) { + winners.add(car.getName()); + } + } + + this.outputView.println(String.join(", ", winners) + "가 최종 우승했습니다."); + this.outputView.flush(); + } + +} diff --git a/src/main/java/racing/core/InputView.java b/src/main/java/racing/core/InputView.java new file mode 100644 index 000000000..7f0c80886 --- /dev/null +++ b/src/main/java/racing/core/InputView.java @@ -0,0 +1,9 @@ +package racing.core; + +import java.util.List; + +public interface InputView { + List getCars(String message); + + int getTrackLength(String message); +} diff --git a/src/main/java/racing/core/OutputView.java b/src/main/java/racing/core/OutputView.java new file mode 100644 index 000000000..056d685ee --- /dev/null +++ b/src/main/java/racing/core/OutputView.java @@ -0,0 +1,9 @@ +package racing.core; + +public interface OutputView { + void print(String message); + + void println(String message); + + void flush(); +} diff --git a/src/test/java/racing/core/CarTest.java b/src/test/java/racing/core/CarTest.java new file mode 100644 index 000000000..f1e8f42b7 --- /dev/null +++ b/src/test/java/racing/core/CarTest.java @@ -0,0 +1,39 @@ +package racing.core; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class CarTest { + + @Test + void moveTest1() { + Car car = new Car("tester", () -> true); + + car.move(); + + assertThat(car.positionedAt(1)).isTrue(); + assertThat(car.toString()).isEqualTo("tester : -"); + } + + @Test + void moveTest2() { + Car car = new Car("tester", () -> true); + + car.move(); + car.move(); + + assertThat(car.positionedAt(2)).isTrue(); + assertThat(car.toString()).isEqualTo("tester : --"); + } + + @Test + void moveTest3() { + Car car = new Car("tester", () -> false); + + car.move(); + + assertThat(car.positionedAt(0)).isTrue(); + assertThat(car.toString()).isEqualTo("tester : "); + } +} \ No newline at end of file