diff --git a/src/main/java/ApplicationMain.java b/src/main/java/ApplicationMain.java index d427d41efe8..d4d41be7707 100644 --- a/src/main/java/ApplicationMain.java +++ b/src/main/java/ApplicationMain.java @@ -1,15 +1,11 @@ -import java.util.List; +import controller.GameController; + public class ApplicationMain { public static void main(String[] args) { - List carNames = InputView.getCarName(); - int tryCount = InputView.getTryCount(); - InputView.closeScanner(); - - Racing racing = new Racing(carNames, tryCount); - - racing.start(); + GameController gameController = new GameController(); + gameController.play(); } } diff --git a/src/main/java/Car.java b/src/main/java/Car.java deleted file mode 100644 index 8a3a9f1414c..00000000000 --- a/src/main/java/Car.java +++ /dev/null @@ -1,32 +0,0 @@ - -public class Car { - - private String name; - private int position; - - private final static int RANDOM_BOUND = 10; - private final static int MOVE_BOUND = 4; - private final static int MOVE_STEP = 1; - - public Car(String name) { - this.name = name; - } - - /** - * 자동차를 앞으로 전진시킵니다. - */ - public void move() { - int num = RandomUtil.nextInt(RANDOM_BOUND); - if (num >= MOVE_BOUND) { - position += MOVE_STEP; - } - } - - public int getPosition() { - return position; - } - - public String getName() { - return name; - } -} diff --git a/src/main/java/Racing.java b/src/main/java/Racing.java deleted file mode 100644 index 11100511020..00000000000 --- a/src/main/java/Racing.java +++ /dev/null @@ -1,66 +0,0 @@ -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; -import java.util.stream.Collectors; - -public class Racing { - - private final List carList = new ArrayList<>(); // 자동차 리스트 - - private final int tryCount; // 시도 횟수 - - private static final List winners = new ArrayList<>(); //우승 자동차 - - /** - * @param carNames - * @param tryCount - * 레이싱 초기화 - */ - public Racing(List carNames, int tryCount) { - carListSetting(carNames); - this.tryCount = tryCount; - } - - /** - * @param carNames - * 자동차 리스트 초기화 - */ - private void carListSetting(List carNames) { - for (String name : carNames) { - carList.add(new Car(name)); - } - } - - /** - * 레이싱 시작 - */ - public void start() { - ResultView.printExecuteResult(); - - for (int i = 0; i < tryCount; i++) { - race(); - ResultView.printRaceRound(carList); - } - - ResultView.printWinner(findWinner()); - } - - /** - * @return 우승자를 찾습니다. - */ - private List findWinner() { - int maxScore = carList.stream().mapToInt(Car::getPosition).max().orElse(0); - - return carList.stream().filter(car -> car.getPosition() == maxScore).collect(Collectors.toList()); - } - - /** - * 레이싱 점수를 저장합니다. - */ - private void race() { - for (Car car : carList) { - car.move(); - } - } - -} diff --git a/src/main/java/RandomUtil.java b/src/main/java/RandomUtil.java deleted file mode 100644 index 8ace4657b52..00000000000 --- a/src/main/java/RandomUtil.java +++ /dev/null @@ -1,9 +0,0 @@ -import java.util.Random; - -public class RandomUtil { - private static final Random random = new Random(); - - public static int nextInt(int bound) { - return random.nextInt(bound); - } -} diff --git a/src/main/java/ResultView.java b/src/main/java/ResultView.java deleted file mode 100644 index 783e057d4e1..00000000000 --- a/src/main/java/ResultView.java +++ /dev/null @@ -1,22 +0,0 @@ -import java.util.List; -import java.util.stream.Collectors; - -public class ResultView { - - public static void printRaceRound(List carList) { - for (Car car : carList) { - System.out.println(car.getName() + " : " + "-".repeat(car.getPosition())); - } - System.out.println("\n"); - } - - public static void printExecuteResult() { - System.out.println("실행 결과"); - } - - public static void printWinner(List carList) { - String result = carList.stream().map(Car::getName).collect(Collectors.joining(", ")); - - System.out.println(result + "가 최종 우승했습니다."); - } -} diff --git a/src/main/java/controller/GameController.java b/src/main/java/controller/GameController.java new file mode 100644 index 00000000000..74b010e73b6 --- /dev/null +++ b/src/main/java/controller/GameController.java @@ -0,0 +1,26 @@ +package controller; + +import domain.Racing; +import java.util.List; +import view.InputView; +import view.ResultView; + +public class GameController { + public void play() { + List carNames = InputView.getCarName(); + int tryCount = InputView.getTryCount(); + InputView.closeScanner(); + + Racing racing = new Racing(carNames); + + ResultView.printExecuteResult(); + + for (int i = 0; i < tryCount; i++) { + racing.start(); + ResultView.printRaceRound(racing); + } + + ResultView.printWinner(racing); + + } +} diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java new file mode 100644 index 00000000000..e96f9c60536 --- /dev/null +++ b/src/main/java/domain/Car.java @@ -0,0 +1,45 @@ +package domain; + + +public class Car { + private final static int MOVE_BOUND = 4; + private final static int MOVE_STEP = 1; + + private final CarName name; + private final Position position; + + public Car(String name) { + this.name = new CarName(name); + this.position = new Position(0); + } + + public Car(String name, int position) { + this.name = new CarName(name); + this.position = new Position(position); + } + + /** + * 자동차를 앞으로 전진시킵니다. + */ + public void move(int randomNo) { + if (randomNo >= MOVE_BOUND) { + this.position.add(MOVE_STEP); + } + } + + public int maxComparedTo(int maxScore) { + return this.position.maxComparedTo(maxScore); + } + + public String getName() { + return name.getName(); + } + + public Boolean isSame(int input) { + return this.position.isSame(input); + } + + public int getPosition() { + return position.getPosition(); + } +} diff --git a/src/main/java/domain/CarName.java b/src/main/java/domain/CarName.java new file mode 100644 index 00000000000..2e1712a560d --- /dev/null +++ b/src/main/java/domain/CarName.java @@ -0,0 +1,23 @@ +package domain; + +public class CarName { + + private static final int MAX_LENGTH = 5; + private final String value; + + public CarName(String value) { + if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException("자동차 이름은 비어 있을 수 없습니다"); + } + + if (value.trim().length() > 5) { + throw new IllegalArgumentException("자동차 이름은 5자를 초과할 수 없습니다"); + } + + this.value = value; + } + + public String getName() { + return value; + } +} diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java new file mode 100644 index 00000000000..e29bda4c6d1 --- /dev/null +++ b/src/main/java/domain/Position.java @@ -0,0 +1,28 @@ +package domain; + +public class Position { + private int value; + + public Position(int value) { + if (value < 0) { + throw new IllegalArgumentException("위치 값은 음수가 올 수 없습니다"); + } + this.value = value; + } + + public void add(int moveStep) { + this.value += moveStep; + } + + public int maxComparedTo(int input) { + return Math.max(this.value, input); + } + + public Boolean isSame(int input) { + return value == input; + } + + public int getPosition() { + return value; + } +} diff --git a/src/main/java/domain/Racing.java b/src/main/java/domain/Racing.java new file mode 100644 index 00000000000..09a8fb082ff --- /dev/null +++ b/src/main/java/domain/Racing.java @@ -0,0 +1,33 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; +import util.RandomUtil; + +public class Racing { + private final List carList = new ArrayList<>(); // 자동차 리스트 + + /** + * @param carNames + * 레이싱 초기화 + */ + public Racing(List carNames) { + for (String name : carNames) { + carList.add(new Car(name)); + } + } + + /** + * 레이싱 시작 + */ + public void start() { + for (Car car : carList) { + int randomNo = RandomUtil.generate(); + car.move(randomNo); + } + } + + public List getCarList() { + return carList; + } +} diff --git a/src/main/java/domain/Winners.java b/src/main/java/domain/Winners.java new file mode 100644 index 00000000000..45f80ef38ff --- /dev/null +++ b/src/main/java/domain/Winners.java @@ -0,0 +1,27 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class Winners { + + /** + * 우승자를 찾습니다. + * @param cars + * @return + */ + public static List findWinners(List cars) { + + int maxScore = 0; + for (Car car : cars) { + maxScore = car.maxComparedTo(maxScore); + } + + int finalMaxScore = maxScore; + + return cars.stream() + .filter(car -> car.isSame(finalMaxScore)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/util/RandomUtil.java b/src/main/java/util/RandomUtil.java new file mode 100644 index 00000000000..93bf29a68cc --- /dev/null +++ b/src/main/java/util/RandomUtil.java @@ -0,0 +1,11 @@ +package util; + +import java.util.Random; + +public class RandomUtil { + private static final int BOUND = 10; + + public static int generate() { + return new Random().nextInt(BOUND); + } +} diff --git a/src/main/java/InputView.java b/src/main/java/view/InputView.java similarity index 97% rename from src/main/java/InputView.java rename to src/main/java/view/InputView.java index 9634607300d..56f4263fb50 100644 --- a/src/main/java/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,3 +1,5 @@ +package view; + import java.util.ArrayList; import java.util.Scanner; import java.util.List; diff --git a/src/main/java/view/ResultView.java b/src/main/java/view/ResultView.java new file mode 100644 index 00000000000..75ad14ec56d --- /dev/null +++ b/src/main/java/view/ResultView.java @@ -0,0 +1,31 @@ +package view; + +import domain.Car; +import domain.Racing; +import domain.Winners; +import java.util.List; +import java.util.stream.Collectors; + +public class ResultView { + + public static void printRaceRound(Racing racing) { + for (Car car : racing.getCarList()) { + System.out.println(car.getName() + " : " + "-".repeat(car.getPosition())); + } + System.out.println("\n"); + } + + public static void printExecuteResult() { + System.out.println("실행 결과"); + } + + public static void printWinner(Racing racing) { + List winners = Winners.findWinners(racing.getCarList()); + + String winnerNames = winners.stream() + .map(Car::getName) + .collect(Collectors.joining(", ")); + + System.out.println(winnerNames + "가 최종 우승했습니다."); + } +} diff --git a/src/test/java/CarTest.java b/src/test/java/CarTest.java deleted file mode 100644 index f5c59d11666..00000000000 --- a/src/test/java/CarTest.java +++ /dev/null @@ -1,70 +0,0 @@ -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.when; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.InjectMocks; -import org.mockito.MockedStatic; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -@DisplayName("자동차 메소드 테스트") -class CarTest { - - @InjectMocks - private Car car; - - @Test - @DisplayName("자동차를 생성합니다") - void create_car() { - //given - String carName = "car1"; - - //when - Car car = new Car(carName); - - //then - assertThat(car.getName()).isEqualTo(carName); - } - - @DisplayName("숫자가 4보다 같거나 크면 앞으로 전진한다.") - @ParameterizedTest - @ValueSource(ints = {4,5,6,7,8,9}) - void move_greater_equal_four(int input) { - - try (MockedStatic mockedStatic = mockStatic(RandomUtil.class)) { - //given - when(RandomUtil.nextInt(10)).thenReturn(input); - - //when - car.move(); - - //then - assertThat(car.getPosition()).isEqualTo(1); - } - - } - - @DisplayName("숫자가 4보다 작으면 전진하지 않는다.") - @ParameterizedTest - @ValueSource(ints = {1,2,3}) - void move_less_four(int input) { - - try (MockedStatic mockedStatic = mockStatic(RandomUtil.class)) { - //given - when(RandomUtil.nextInt(10)).thenReturn(input); - - //when - car.move(); - - //then - assertThat(car.getPosition()).isEqualTo(0); - } - - } - -} \ No newline at end of file diff --git a/src/test/java/RacingTest.java b/src/test/java/RacingTest.java deleted file mode 100644 index 4e7d4aee37d..00000000000 --- a/src/test/java/RacingTest.java +++ /dev/null @@ -1,15 +0,0 @@ -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.List; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -@DisplayName("레이싱 메소드 테스트") -class RacingTest { -} \ 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..4a1a8934f34 --- /dev/null +++ b/src/test/java/domain/CarTest.java @@ -0,0 +1,74 @@ +package domain; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.mockito.Mockito.mockStatic; + +import domain.Car; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName("자동차 메소드 테스트") +class CarTest { + + @Test + @DisplayName("자동차를 생성합니다") + void create_car() { + //given + String carName = "car1"; + + //when + Car car = new Car(carName); + + //then + assertThat(car.getName()).isEqualTo(carName); + } + + @Test + @DisplayName("자동차 이름은 비어있을 수 없습니다.") + void create_car_자동차_이름_빈_값() { + String name = ""; + + assertThatThrownBy(() -> { + Car car = new Car(name); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage("자동차 이름은 비어 있을 수 없습니다"); + + } + + @Test + @DisplayName("자동차 이름은 5자를 초과할 수 없습니다.") + void create_car_자동차_이름_5자_초과() { + String name = "abcdef"; + + assertThatThrownBy(() -> { + Car car = new Car(name); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage("자동차 이름은 5자를 초과할 수 없습니다"); + + } + + @DisplayName("숫자가 4보다 같거나 크면 앞으로 전진한다.") + @ParameterizedTest + @ValueSource(ints = {4, 5, 6, 7, 8, 9}) + void move_greater_equal_four(int input) { + Car car = new Car("a"); + + car.move(input); + + assertThat(car.isSame(1)).isTrue(); + + } + + @DisplayName("숫자가 4보다 작으면 전진하지 않는다.") + @ParameterizedTest + @ValueSource(ints = {1,2,3}) + void move_less_four(int input) { + Car car = new Car("a"); + car.move(input); + assertThat(car.isSame(0)).isTrue(); + } + +} \ No newline at end of file diff --git a/src/test/java/domain/WinnersTest.java b/src/test/java/domain/WinnersTest.java new file mode 100644 index 00000000000..98f0ada7003 --- /dev/null +++ b/src/test/java/domain/WinnersTest.java @@ -0,0 +1,27 @@ +package domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class WinnersTest { + @Test + @DisplayName("레이싱 경기 우승자를 찾습니다") + void 레이싱_경기_우승자_찾기() { + Car a = new Car("a",3); + Car b = new Car("b",4); + Car c = new Car("c",4); + + List cars = Arrays.asList(a,b,c); + + List winners = Winners.findWinners(cars); + + assertThat(winners.size()).isEqualTo(2); + assertThat(winners).isEqualTo(List.of(b,c)); + } +} \ No newline at end of file