diff --git a/README.md b/README.md index c550c4c2a09..e99e567af60 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,14 @@ * 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다. ## 온라인 코드 리뷰 과정 -* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview) \ No newline at end of file +* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview) + +--- + +## "3단계 - 자동차 경주" 기능 목록 및 요구사항 + +### 기능 요구사항 +- [ ] 자동차 대수를 입력받는다. +- [ ] 이동할 횟수를 입력받는다. +- [ ] 랜덤 값을 생성하여 전진 (값이 4 이상) 혹은 정지 (값이 3 이하) 할지 결정한다. +- [ ] 매 이동 시 마다 자동차 상태를 출력한다. \ No newline at end of file diff --git a/src/main/java/controller/RacingGame.java b/src/main/java/controller/RacingGame.java new file mode 100644 index 00000000000..83cbd72a4bd --- /dev/null +++ b/src/main/java/controller/RacingGame.java @@ -0,0 +1,41 @@ +package controller; + +import domain.Car; +import domain.Cars; +import domain.RandomNumberGenerator; +import view.InputView; +import view.ResultView; + +public class RacingGame { + private final Cars cars; + private final int numberOfRounds; + private final RandomNumberGenerator randomNumberGenerator = new RandomNumberGenerator(); + + public RacingGame(int numberOfCars, int numberOfRounds) { + this.numberOfRounds = numberOfRounds; + this.cars = new Cars(numberOfCars); + } + + private void runOneRound() { + for (Car car : cars.getCars()) { + car.move(randomNumberGenerator); + ResultView.printPosition(car.getCurrentPosition()); + } + ResultView.printMessage(""); + } + + private void run() { + ResultView.printMessage("실행 결과"); + for (int i = 0; i < this.numberOfRounds; i++) { + runOneRound(); + } + } + + public static void main(String[] args) { + int numberOfCars = InputView.getNumberOfCars(); + int numberOfRounds = InputView.getNumberOfRounds(); + + RacingGame game = new RacingGame(numberOfCars, numberOfRounds); + game.run(); + } +} diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java new file mode 100644 index 00000000000..a552f82be6a --- /dev/null +++ b/src/main/java/domain/Car.java @@ -0,0 +1,17 @@ +package domain; + +public class Car { + private static final int MOVE_THRS = 4; + private final Position position = new Position(); + + public void move(NumberGenerator numberGenerator) { + final int number = numberGenerator.generate(); + if (number >= MOVE_THRS) { + this.position.increase(); + } + } + + public Position getCurrentPosition() { + return this.position; + } +} \ No newline at end of file diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java new file mode 100644 index 00000000000..e38e6b2b8d5 --- /dev/null +++ b/src/main/java/domain/Cars.java @@ -0,0 +1,22 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Cars { + private final List<Car> cars = new ArrayList<>(); + + public Cars(int numberOfCars) { + generateCars(numberOfCars); + } + + private void generateCars(int numberOfCars) { + for (int i = 0; i < numberOfCars; i++) { + this.cars.add(new Car()); + } + } + + public List<Car> getCars() { + return this.cars; + } +} diff --git a/src/main/java/domain/NumberGenerator.java b/src/main/java/domain/NumberGenerator.java new file mode 100644 index 00000000000..d1e5b53aa44 --- /dev/null +++ b/src/main/java/domain/NumberGenerator.java @@ -0,0 +1,6 @@ +package domain; + +public interface NumberGenerator { + int generate(); +} + diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java new file mode 100644 index 00000000000..8088d0a9ee4 --- /dev/null +++ b/src/main/java/domain/Position.java @@ -0,0 +1,20 @@ +package domain; + +public class Position { + private int value = 0; + + public void increase() { + this.value++; + } + + @Override + public String toString() { + return "-".repeat(this.value); + } + + private void validate() { + if (this.value < 0) { + throw new IllegalArgumentException("Position value must be greater than or equal to 0."); + } + } +} diff --git a/src/main/java/domain/RandomNumberGenerator.java b/src/main/java/domain/RandomNumberGenerator.java new file mode 100644 index 00000000000..d6d4760497a --- /dev/null +++ b/src/main/java/domain/RandomNumberGenerator.java @@ -0,0 +1,13 @@ +package domain; + +import java.util.Random; + +public class RandomNumberGenerator implements NumberGenerator { + private static final Random random = new Random(); + private static final int MAX_BOUND = 10; + + @Override + public int generate() { + return random.nextInt(MAX_BOUND); + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000000..0803b2fb1c6 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,20 @@ +package view; + +import java.util.Scanner; + +public class InputView { + private static final Scanner scanner = new Scanner(System.in); + + public static int getNumberOfCars() { + return getInput("자동차 대수는 몇 대 인가요?"); + } + + public static int getNumberOfRounds() { + return getInput("시도할 회수는 몇 회 인가요?"); + } + + private static int getInput(String message) { + System.out.println(message); + return scanner.nextInt(); + } +} \ No newline at end of file diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java new file mode 100644 index 00000000000..90aa96aa077 --- /dev/null +++ b/src/main/java/view/ResultView.java @@ -0,0 +1,14 @@ +package view; + +import domain.Position; + +public class ResultView { + + public static void printPosition(Position position) { + printMessage(position.toString()); + } + + public static void printMessage(String message) { + System.out.println(message); + } +} \ No newline at end of file diff --git a/src/test/java/domain/CarTest.java b/src/test/java/domain/CarTest.java new file mode 100644 index 00000000000..bae2f1185d3 --- /dev/null +++ b/src/test/java/domain/CarTest.java @@ -0,0 +1,30 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CarTest { + @DisplayName("숫자가 4 미만이면 움직이지 않는다.") + @Test + void moveTestSmallerThanFour() { + Car car = new Car(); + NumberGenerator numberGenerator = new StaticNumberGenerator(3); + + car.move(numberGenerator); + + assertThat(car.getCurrentPosition()).extracting("value").isEqualTo(0); + } + + @DisplayName("숫자가 4 이상이면 움직인다.") + @Test + void moveTestLargerThanOrEqualToFour() { + Car car = new Car(); + NumberGenerator numberGenerator = new StaticNumberGenerator(5); + + car.move(numberGenerator); + + assertThat(car.getCurrentPosition()).extracting("value").isEqualTo(1); + } +} \ No newline at end of file diff --git a/src/test/java/domain/CarsTest.java b/src/test/java/domain/CarsTest.java new file mode 100644 index 00000000000..097a03368a8 --- /dev/null +++ b/src/test/java/domain/CarsTest.java @@ -0,0 +1,19 @@ +package domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.InstanceOfAssertFactories.list; +import static org.assertj.core.api.Assertions.assertThat; + +public class CarsTest { + @DisplayName("입력받은 숫자만큼 자동차를 생성한다.") + @Test + void generateCarsTest() { + int numberOfCars = 3; + + Cars cars = new Cars(numberOfCars); + + assertThat(cars.getCars()).asInstanceOf(list(Car.class)).hasSize(numberOfCars); + } +} \ No newline at end of file diff --git a/src/test/java/domain/StaticNumberGenerator.java b/src/test/java/domain/StaticNumberGenerator.java new file mode 100644 index 00000000000..f3c5613a54b --- /dev/null +++ b/src/test/java/domain/StaticNumberGenerator.java @@ -0,0 +1,14 @@ +package domain; + +public class StaticNumberGenerator implements NumberGenerator { + private static int NUMBER; + + public StaticNumberGenerator(int number) { + NUMBER = number; + } + + @Override + public int generate() { + return NUMBER; + } +} \ No newline at end of file