diff --git a/build.gradle b/build.gradle index 8172fb73f..db3cac738 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'eclipse' group = 'camp.nextstep' version = '1.0.0' -sourceCompatibility = '1.8' +sourceCompatibility = "11" repositories { mavenCentral() @@ -12,8 +12,11 @@ repositories { dependencies { testImplementation "org.junit.jupiter:junit-jupiter:5.7.2" testImplementation "org.assertj:assertj-core:3.19.0" + implementation 'org.apache.commons:commons-lang3:3.6' + } test { useJUnitPlatform() } +targetCompatibility = JavaVersion.VERSION_11 diff --git a/src/main/java/game/CarRacingGameMain.java b/src/main/java/game/CarRacingGameMain.java new file mode 100644 index 000000000..7da9f3939 --- /dev/null +++ b/src/main/java/game/CarRacingGameMain.java @@ -0,0 +1,21 @@ +package game; + +import game.domain.Car; +import game.domain.CarRacingGame; +import game.domain.Cars; +import game.views.InputView; +import game.views.OutputView; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Scanner; + +public class CarRacingGameMain { + + public static void main(String[] args) { + CarRacingGame carRacingGame = new CarRacingGame(); + carRacingGame.inputData(); + carRacingGame.gameResult(); + carRacingGame.findWinners(); + } +} \ No newline at end of file diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java new file mode 100644 index 000000000..67eccf549 --- /dev/null +++ b/src/main/java/game/domain/Car.java @@ -0,0 +1,41 @@ +package game.domain; + + +import game.utils.CarName; +import game.utils.InputValid; +import game.utils.RandomNum; + +public class Car { + + private CarName carName; + private int position; + + + public Car(String carName) { + this.carName = new CarName(carName); + } + + public Car(int position) { + this.position = position; + } + + public int move(int distance) { + if (InputValid.validMove(distance)) { + return plusCarDistance(); + } + return getCarPosition(); + } + + public String getCarName() { + return carName.getCarName(); + } + + public int getCarPosition() { + return this.position; + } + + private int plusCarDistance() { + return this.position += 1; + } + +} diff --git a/src/main/java/game/domain/CarRacingGame.java b/src/main/java/game/domain/CarRacingGame.java new file mode 100644 index 000000000..a564594d3 --- /dev/null +++ b/src/main/java/game/domain/CarRacingGame.java @@ -0,0 +1,38 @@ +package game.domain; + +import game.utils.InputValid; +import game.views.InputView; +import game.views.OutputView; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Scanner; + +public class CarRacingGame { + private int repetition; + public List carList; + Scanner scanner = new Scanner(System.in); + + public void inputData() { + OutputView.printInitCars(); + String carNames = scanner.nextLine(); + InputValid.isNullCarNames(carNames); + this.carList = InputView.inputCars(carNames); + OutputView.printInitRepete(); + this.repetition = InputView.inputRepetition(); + } + + public void gameResult() { + OutputView.printBeforeGame(); + for (int i = 0; i < repetition; i++) { + OutputView.printRacingCars(carList); + } + } + + public void findWinners() { + List winners = Cars.findWinners(); + OutputView.printWinners(winners); + } + + +} diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java new file mode 100644 index 000000000..c9562358e --- /dev/null +++ b/src/main/java/game/domain/Cars.java @@ -0,0 +1,38 @@ +package game.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.stream.Collectors; + +public class Cars { + + private static List carList; + + public static List carsInit(String[] carNames) { + ArrayList cars = new ArrayList<>(); + for (String carName : carNames) { + cars.add(new Car(carName)); + } + return carList = cars; + } + + public static List findWinners() { + int maxDistance = getMaxDistance(carList); + return carList.stream() + .filter(car -> equalCarsWithMaxDistance(maxDistance, car)) + .collect(Collectors.toList()); + } + + private static boolean equalCarsWithMaxDistance(int maxDistance, Car car) { + return car.getCarPosition() == maxDistance; + } + + private static int getMaxDistance(List carList) { + return carList.stream() + .mapToInt(Car::getCarPosition) + .max() + .orElseThrow(NoSuchElementException::new); + } + +} diff --git a/src/main/java/game/utils/CarName.java b/src/main/java/game/utils/CarName.java new file mode 100644 index 000000000..8ad89f28b --- /dev/null +++ b/src/main/java/game/utils/CarName.java @@ -0,0 +1,18 @@ +package game.utils; + +public class CarName { + + private final int MAX_LEN = 5; + private String carName; + + + public CarName(String carName) { + if (carName.length() > MAX_LEN) { + throw new IllegalArgumentException("자동차 이름의 길이는 5보다 작아야 합니다."); + } + this.carName = carName; + } + public String getCarName() { + return carName; + } +} diff --git a/src/main/java/game/utils/InputValid.java b/src/main/java/game/utils/InputValid.java new file mode 100644 index 000000000..d2e0ddda2 --- /dev/null +++ b/src/main/java/game/utils/InputValid.java @@ -0,0 +1,23 @@ +package game.utils; + +import org.apache.commons.lang3.StringUtils; + +public class InputValid { + private static final int MAX_MOVE = 9; + private static final int MIN_MOVE = 4; + + public static void isNullCarNames(String carNames) { + if (StringUtils.isBlank(carNames)) { + throw new IllegalArgumentException("자동차 이름을 입력해 주세요."); + } + } + + public static boolean validMove(int moveNum) { + if (moveNum > MAX_MOVE || moveNum < 0) { + throw new IllegalArgumentException("0이상 9이하에 해당하는 랜덤값이 주어져야 합니다."); + } else if (moveNum < MIN_MOVE) { + return false; + } + return true; + } +} diff --git a/src/main/java/game/utils/RandomNum.java b/src/main/java/game/utils/RandomNum.java new file mode 100644 index 000000000..aa30b8e08 --- /dev/null +++ b/src/main/java/game/utils/RandomNum.java @@ -0,0 +1,8 @@ +package game.utils; + +public class RandomNum { + + public static int RandomMove() { + return (int)(Math.random() * 10000 % 9); + } +} diff --git a/src/main/java/game/views/InputView.java b/src/main/java/game/views/InputView.java new file mode 100644 index 000000000..d65391705 --- /dev/null +++ b/src/main/java/game/views/InputView.java @@ -0,0 +1,22 @@ +package game.views; + +import game.domain.Car; +import game.domain.Cars; + +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private static Scanner scanner = new Scanner(System.in); + + + public static List inputCars(String names) { + String[] carNames = names.split(","); + return Cars.carsInit(carNames); + } + + public static int inputRepetition() { + return scanner.nextInt(); + } +} diff --git a/src/main/java/game/views/OutputView.java b/src/main/java/game/views/OutputView.java new file mode 100644 index 000000000..838bc0336 --- /dev/null +++ b/src/main/java/game/views/OutputView.java @@ -0,0 +1,48 @@ +package game.views; + +import game.domain.Car; +import game.utils.RandomNum; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class OutputView { + + public static void printInitCars() { + System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); + } + + public static void printInitRepete() { + System.out.println("시도할 회수는 몇회인가요?"); + } + + public static void printBeforeGame() { + System.out.println("실행 결과"); + } + + public static void printRacingCars(List carList) { + for (Car car : carList) { + int randomNum = RandomNum.RandomMove(); + int position = car.move(randomNum); + System.out.format("%s : %s", car.getCarName(), "-".repeat(position)+"\n"); + } + System.out.println(); + } + + public static void printWinners(List Cars) { + StringBuilder winnerBuilder = new StringBuilder(); + for (Car car : Cars) { + winnerBuilder.append(String.format("%s, ", car.getCarName())); + } + String winners = winnerToStr(winnerBuilder); + System.out.println(winners + "가 최종 우승했습니다."); + } + + private static String winnerToStr(StringBuilder winners) { + int length = winners.length(); + String result = winners.substring(0, length-2); + return result; + } +} diff --git a/src/test/java/game/domain/CarTest.java b/src/test/java/game/domain/CarTest.java new file mode 100644 index 000000000..bfb6e1d7b --- /dev/null +++ b/src/test/java/game/domain/CarTest.java @@ -0,0 +1,35 @@ +package game.domain; + +import game.domain.Car; +import org.assertj.core.api.Assertions; +import org.assertj.core.api.ThrowableAssert; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; + +public class CarTest { + + private ThrowableAssert.ThrowingCallable IllegalArgumentException; + + @Test + void carname_5자이하() { + Car car = new Car("pobi"); + assertThat(car).isNotNull(); + } + + @Test + void car_move_4이상9이하() { + Car car = new Car(5); + int position = car.move(4); + assertThat(position).isEqualTo(6); + } + + @Test + void car_move_0미만() { + Car car = new Car(5); + assertThatThrownBy(() -> car.move(-1)) + .isInstanceOf(java.lang.IllegalArgumentException.class) + .hasMessageContaining("0이상 9이하에 해당하는 랜덤값이 주어져야 합니다"); + } +} +