diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b98083a --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'java-racingcar' \ No newline at end of file diff --git a/src/main/java/RacingMain.java b/src/main/java/RacingMain.java index 4394287..0da4f48 100644 --- a/src/main/java/RacingMain.java +++ b/src/main/java/RacingMain.java @@ -1,7 +1,11 @@ +import controller.RacingController; + public class RacingMain { public static void main(String[] args) { // TODO: MVC 패턴을 기반으로 자동차 경주 미션 구현해보기 - System.out.println("Hello, World!"); + //System.out.println("Hello, World!"); + RacingController racingController = new RacingController(); + racingController.startRacing(); } } diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java new file mode 100644 index 0000000..faf55bf --- /dev/null +++ b/src/main/java/controller/RacingController.java @@ -0,0 +1,38 @@ +package controller; + +import domain.Cars; +import domain.NumberGenerator; +import view.InputView; +import view.OutputView; + +import java.util.List; + +public class RacingController { + //NumberGenerator numberGenerator = new NumberGenerator(); + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + + + public void startRacing() { + Cars cars; + List winners; + int count; + + cars = new Cars(inputView.readCarName()); + count = inputView.readCount(); + + for (int i = 0; i < count; i++) { + race(cars); + } + + winners = cars.findWinner(cars.findMaxPosition()); + outputView.printWinner(winners); + } + + private void race(Cars cars) { + cars.moveAllCars(); + outputView.printStatus(cars.getCars()); + } + + +} diff --git a/src/main/java/domain/Car.java b/src/main/java/domain/Car.java new file mode 100644 index 0000000..cb2e997 --- /dev/null +++ b/src/main/java/domain/Car.java @@ -0,0 +1,30 @@ +package domain; + +public class Car { + private static final int MOVE_POINT = 4; + private String carName; + private int position; + + public Car(String carName) { + this.carName = carName; + position = 0; + } + + public void move(int value) { + if (value >= MOVE_POINT) { + position++; + } + } + + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } + + public String getCarName() { + return carName; + } +} diff --git a/src/main/java/domain/Cars.java b/src/main/java/domain/Cars.java new file mode 100644 index 0000000..82b5211 --- /dev/null +++ b/src/main/java/domain/Cars.java @@ -0,0 +1,58 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Cars { + private List cars; + private NumberGenerator numberGenerator = new NumberGenerator(); + + public Cars(List carNameList) { + cars = makeCarObject(carNameList); + } + + public List makeCarObject(List carNames) { + List cars = new ArrayList<>(); + for (String name : carNames) { + cars.add(new Car(name)); + } + return cars; + } + + public void moveAllCars() { + for (Car car : cars) { + int movePoint = numberGenerator.generate(); + car.move(movePoint); + } + } + + public int findMaxPosition() { + int maxPosition = 0; + for (Car car : cars) { + int carPosition = car.getPosition(); + + if (carPosition > maxPosition) { + maxPosition = carPosition; + } + } + + return maxPosition; + } + + + public List findWinner(int maxPosition) { + List winners = new ArrayList<>(); + for (Car car : cars) { + int carPosition = car.getPosition(); + + if (carPosition == maxPosition) { + winners.add(car.getCarName()); + } + } + return winners; + } + + public List getCars() { + return cars; + } +} diff --git a/src/main/java/domain/NumberGenerator.java b/src/main/java/domain/NumberGenerator.java new file mode 100644 index 0000000..c5ca266 --- /dev/null +++ b/src/main/java/domain/NumberGenerator.java @@ -0,0 +1,8 @@ +package domain; + +public class NumberGenerator { + public int generate() { + int num = (int) (Math.random() * 10); + return num; + } +} diff --git a/src/main/java/domain/StringParser.java b/src/main/java/domain/StringParser.java new file mode 100644 index 0000000..16af5b1 --- /dev/null +++ b/src/main/java/domain/StringParser.java @@ -0,0 +1,10 @@ +package domain; + +import java.util.List; + +public class StringParser { + public static List SplitByComma(String input) { + List carNames = List.of(input.split(",")); + return carNames; + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000..cc5049e --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,55 @@ +package view; + +import domain.StringParser; + +import java.util.InputMismatchException; +import java.util.List; +import java.util.Scanner; + +public class InputView { + private static final String REQUEST_CAR_NAME = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; + private static final String REQEUST_ATTEMPT_NUMBER = "시도할 회수는 몇회인가요?"; + private static final String CAR_NAME_LENGTH_ERROR = "차 이름은 5자 이내여야 합니다."; + private static final String CAR_NAME_BLANK_ERROR = "차 이름은 공백일 수 없습니다."; + + private static final String NOT_VALUABLE_COUNT = "양의 정수만 입력 할 수 있습니다."; + private Scanner scanner = new Scanner(System.in); + + public List readCarName() { + System.out.println(REQUEST_CAR_NAME); + + String name = scanner.nextLine(); + List carNames = StringParser.SplitByComma(name); + validateCarName(carNames); + + return carNames; + } + + public int readCount() { + System.out.println(REQEUST_ATTEMPT_NUMBER); + int count = 0; + + try { + count = scanner.nextInt(); + if (count < 0) { + throw new IllegalArgumentException(NOT_VALUABLE_COUNT); + } + } catch (InputMismatchException e) { + System.out.println(NOT_VALUABLE_COUNT); + } + + return count; + } + + private void validateCarName(List carNames) { + for (String carName : carNames) { + if (carName.length() > 5) { + throw new IllegalArgumentException(carName + CAR_NAME_LENGTH_ERROR); + } + if (carName.length() < 1) { + throw new IllegalArgumentException(carName + CAR_NAME_BLANK_ERROR); + } + } + } + +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000..b865e6b --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,36 @@ +package view; + +import domain.Car; + +import java.util.List; + +public class OutputView { + + private static final String PRINT_WINNER_TEXT = "%s가 최종 우승했습니다."; + + public void printResult() { + System.out.println("실행 결과"); + } + + public void printStatus(List cars) { + for (Car car : cars) { + int currentPosition = car.getPosition(); + String carName = car.getCarName(); + System.out.printf(carName + ":" + ' '); + printPosition(currentPosition); + } + } + + private void printPosition(int count) { + for (int i = 0; i < count; i++) { + System.out.printf("-"); + } + System.out.println(); + } + + public void printWinner(List winners) { + String winnerText = String.join(", ", winners); + System.out.printf(PRINT_WINNER_TEXT, winnerText); + } + +} diff --git a/src/test/java/RacingTest.java b/src/test/java/RacingTest.java new file mode 100644 index 0000000..ed9b48e --- /dev/null +++ b/src/test/java/RacingTest.java @@ -0,0 +1,49 @@ +import domain.Car; +import domain.Cars; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import view.OutputView; + +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class RacingTest { + + @DisplayName("레이싱 진행 테스트") // 차 이름과 현재 포지션이 제대로 출력 되는지 확인 + @Test + public void racingTest() { + List carNameList = Arrays.asList("Tico", "Kia", "Matiz", "Ren"); + Cars cars = new Cars(carNameList); + + List carList = cars.getCars(); + int count = 1; + + for (Car car : carList) { + car.setPosition(count); + count++; + } + + OutputView outputView = new OutputView(); + outputView.printStatus(carList); + } + @Test + @DisplayName("차 이동 성공 테스트") + void moveCarTestSuccess(){ + Car car = new Car("superCar"); + car.setPosition(2); + car.move(6); + assertThat(car.getPosition()).isEqualTo(3); + } + @Test + @DisplayName("차 이동 실패 테스트") + void moveCarTestFalied(){ + Car car = new Car("superCar"); + car.setPosition(2); + car.move(1); + assertThat(car.getPosition()).isEqualTo(3); //차가 이동하지 못해 에러 발생시키기 + } +} diff --git a/src/test/java/StringParserTest.java b/src/test/java/StringParserTest.java new file mode 100644 index 0000000..6ecff0e --- /dev/null +++ b/src/test/java/StringParserTest.java @@ -0,0 +1,40 @@ +import domain.StringParser; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; + +public class StringParserTest { + @DisplayName("콤마 분리 테스트") + @Test + void splitTest() { + //StringParser stringParser = new StringParser(); + String testString = "orange,lemon,apple"; + + List result = StringParser.SplitByComma(testString); + for (String item : result) { + System.out.println(item); + } + assertThat(result).containsExactly("orange", "lemon", "apple"); + } + + @DisplayName("차 이름 길이 테스트") + @Test + void checkCarNameLength() { + List carList = Arrays.asList("Tico", "Kia", "Matiz", "Ren"); + //List carList = Arrays.asList("Ticooo", "Kiaaaa", "Matiz", "Ren"); + + //테스트 성공(5자 초과하는 이름이 없을 때), 테스트 실패(5자 초과하는 이름 존재 시) + carList.forEach(carName -> + assertTrue(carName.length() < 6, carName + "의 길이가 6자 이상.") + ); + + //추후 리스트를 받아와서 그걸로 테스트하게 변경 + } + +}