diff --git a/src/main/java/.gitkeep b/README.md similarity index 100% rename from src/main/java/.gitkeep rename to README.md diff --git a/src/main/java/RacingGame.java b/src/main/java/RacingGame.java new file mode 100644 index 00000000..5050a938 --- /dev/null +++ b/src/main/java/RacingGame.java @@ -0,0 +1,8 @@ +import controller.RacingController; + +public class RacingGame { + public static void main(String[] args) { + RacingController racingController = new RacingController(); + racingController.run(); + } +} diff --git a/src/main/java/controller/RacingController.java b/src/main/java/controller/RacingController.java new file mode 100644 index 00000000..cffc130a --- /dev/null +++ b/src/main/java/controller/RacingController.java @@ -0,0 +1,23 @@ +package controller; + +import model.Cars; +import model.CarsWinner; +import view.InputView; +import view.OutputView; + + +public class RacingController { + public void run() { + String[] carNames = InputView.getCarNames(); + int raceCount = InputView.getRaceCount(); + + Cars cars = new Cars(carNames); + CarsWinner carsWinner = new CarsWinner(); + + OutputView.printResultMessage(); + RacingService racingService = new RacingService(); + racingService.startRace(cars, raceCount); + + OutputView.printWinners(carsWinner.findWinners(cars)); + } +} diff --git a/src/main/java/controller/RacingService.java b/src/main/java/controller/RacingService.java new file mode 100644 index 00000000..739882d1 --- /dev/null +++ b/src/main/java/controller/RacingService.java @@ -0,0 +1,19 @@ +package controller; + +import model.Cars; +import model.CarsWinner; +import model.Number.IsMovable; +import view.OutputView; + +public class RacingService { + public void startRace(Cars cars, int raceCount) { + IsMovable isMovable = new IsMovable(); + CarsWinner carsWinner = new CarsWinner(); + + for (int i = 0; i < raceCount; i++) { + cars.moveAll(isMovable); // Model의 상태 변경 요청 + OutputView.printRoundResult(cars.getCars()); // View에 출력 요청 + } + carsWinner.findWinners(cars); + } +} diff --git a/src/main/java/model/Car.java b/src/main/java/model/Car.java new file mode 100644 index 00000000..92fbab4f --- /dev/null +++ b/src/main/java/model/Car.java @@ -0,0 +1,27 @@ +package model; + +import java.util.ArrayList; + +public class Car { + + private final String name; + private int position = 0; + + public Car(String name) { + this.name = name; + } + + public void move() { + this.position++; + } + + public String getName() { + return name; + } + + public int getPosition() { + return position; + } +} + + diff --git a/src/main/java/model/Cars.java b/src/main/java/model/Cars.java new file mode 100644 index 00000000..55f5fae6 --- /dev/null +++ b/src/main/java/model/Cars.java @@ -0,0 +1,39 @@ +package model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import model.Number.IsMovable; + +public class Cars { + private final List cars; + + public Cars(String[] carNames) { + this.cars = new ArrayList<>(); + for (String name : carNames) { + cars.add(new Car(name)); + } + } + + public void moveAll(IsMovable isMovable) { + for (Car car : cars) { + move(car, isMovable); + } + } + + private void move(Car car, IsMovable isMovable) { + if (isMovable.getcheck()) { + car.move(); + } + } + + public List getCars() { + return Collections.unmodifiableList(cars); + + /*return this.cars; + *위 방식을 안쓴 이유는 객체를 받아서 다른 메소드나 클래스에서 + *수정이 가능해 지기 때문에 위 컬렉션 메소드로 반환값 설정 + * */ + } +} diff --git a/src/main/java/model/CarsWinner.java b/src/main/java/model/CarsWinner.java new file mode 100644 index 00000000..d0d62495 --- /dev/null +++ b/src/main/java/model/CarsWinner.java @@ -0,0 +1,32 @@ +package model; + + +import java.util.ArrayList; +import java.util.List; + +public class CarsWinner { + private final List winners = new ArrayList<>(); + + + public List findWinners(Cars cars) { + int maxPosition = findMaxPosition(cars); + for (Car car : cars.getCars()) { + checkAndAddWinner(winners, car, maxPosition); + } + return winners; + } + + private void checkAndAddWinner(List winners, Car car, int maxPosition) { + if (car.getPosition() == maxPosition) { + winners.add(car.getName()); + } + } + + private int findMaxPosition(Cars cars) { + int maxPosition = 0; + for (Car car : cars.getCars()) { + maxPosition = Math.max(car.getPosition(), maxPosition); + } + return maxPosition; + } +} diff --git a/src/main/java/model/Number/FixedNumberGenerator.java b/src/main/java/model/Number/FixedNumberGenerator.java new file mode 100644 index 00000000..9817f370 --- /dev/null +++ b/src/main/java/model/Number/FixedNumberGenerator.java @@ -0,0 +1,10 @@ +package model.Number; + +public class FixedNumberGenerator implements NumberGenerator { + private static final int NOT_MOVE_CONITION = 1; + + @Override + public int genrator() { + return NOT_MOVE_CONITION; + } +} diff --git a/src/main/java/model/Number/IsMovable.java b/src/main/java/model/Number/IsMovable.java new file mode 100644 index 00000000..0ba60f47 --- /dev/null +++ b/src/main/java/model/Number/IsMovable.java @@ -0,0 +1,15 @@ +package model.Number; + +public class IsMovable { + private NumberGenerator movable = new RandomNumberGenerator(); + private NumberGenerator notNovable = new FixedNumberGenerator(); + + private static final int MOVE_CONITION = 4; + + public Boolean getcheck() { + //return movable.genrator() > MOVE_CONITION; + return notNovable.genrator() > MOVE_CONITION; + } + + +} diff --git a/src/main/java/model/Number/NumberGenerator.java b/src/main/java/model/Number/NumberGenerator.java new file mode 100644 index 00000000..5940fdc1 --- /dev/null +++ b/src/main/java/model/Number/NumberGenerator.java @@ -0,0 +1,5 @@ +package model.Number; + +public interface NumberGenerator { + int genrator(); +} diff --git a/src/main/java/model/Number/RandomNumberGenerator.java b/src/main/java/model/Number/RandomNumberGenerator.java new file mode 100644 index 00000000..44673268 --- /dev/null +++ b/src/main/java/model/Number/RandomNumberGenerator.java @@ -0,0 +1,13 @@ +package model.Number; + +import java.util.Random; + +public class RandomNumberGenerator implements NumberGenerator { + + @Override + public int genrator() + { + final Random random = new Random(); + return random.nextInt(10); + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 00000000..b3c4545b --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,55 @@ +package view; + +import java.util.Scanner; + +public class InputView { + private static final Scanner scanner = new Scanner(System.in); + + public static String[] getCarNames() { + String[] splits = null; + boolean splitsCheck = false; + while (true) { + try { + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + splits = scanner.nextLine().split(",", -1); + + // 예외가 발생할 수 있는 검증 메서드를 호출 + splitsCheck = isValid(splits); + } catch (IllegalArgumentException e) { + // validateCarNames에서 예외를 던지면 이 코드가 실행됨 + // 예외에 담긴 메시지를 출력하고, while 루프의 처음으로 돌아감 + System.out.println(e.getMessage()); + } + if (splits != null && splitsCheck) return splits; + } + } + + private static String[] getStrings(String[] splitCar) { + if (isValid(splitCar)) { + return splitCar; + } + return null; + } + + public static int getRaceCount() { + System.out.println("시도할 회수는 몇회인가요?"); + int count = scanner.nextInt(); + scanner.nextLine(); // 개행 문자 제거 + return count; + } + + public static boolean isValid(String[] cars) { + if (cars.length <= 1) { + // boolean을 반환하는 대신, 예외를 생성하고 던집니다. + throw new IllegalArgumentException("[ERROR] 두 개 이상의 자동차를 입력해주세요!"); + } + + for (String car : cars) { + if (car.trim().isEmpty()) { + System.out.println("자동차의 이름이 공백일 순 없습니다!"); + return false; + } + } + return true; + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 00000000..64a37259 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,30 @@ +package view; + +import model.Car; + +import java.util.List; + +public class OutputView { + + public static void printResultMessage() { + System.out.println("\n실행 결과"); + } + + public static void printRoundResult(List cars) { + for (Car car : cars) { + System.out.print(car.getName() + " : "); + printCarPosition(car); + System.out.println(); + } + System.out.println(); + } + + private static void printCarPosition(Car car) { + System.out.print("-".repeat(car.getPosition())); + } + + public static void printWinners(List winners) { + String winnerNames = String.join(", ", winners); + System.out.println("최종 우승자 : " + winnerNames); + } +} diff --git a/src/test/java/model/CarTest.java b/src/test/java/model/CarTest.java new file mode 100644 index 00000000..db6a162b --- /dev/null +++ b/src/test/java/model/CarTest.java @@ -0,0 +1,51 @@ +package model; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class CarTest { + + @Test + @DisplayName("자동차 생성 시 이름과 초기 위치(0)를 올바르게 설정한다.") + void createCar() { + // given: "pobi"라는 이름을 가진 자동차를 준비하고 + String carName = "pobi"; + + // when: 해당 이름으로 자동차를 생성하면 + Car car = new Car(carName); + + // then: 이름은 "pobi"이고 위치는 0이어야 한다. + assertEquals(carName, car.getName()); + assertEquals(0, car.getPosition()); + } + + @Test + @DisplayName("move 메서드를 호출하면 위치가 1 증가한다.") + void moveCar() { + // given: "woni"라는 이름의 자동차를 생성하고 + Car car = new Car("woni"); + + // when: move 메서드를 한 번 호출하면 + car.move(); + + // then: 자동차의 위치는 1이 되어야 한다. + assertEquals(1, car.getPosition()); + } + + @Test + @DisplayName("move 메서드를 여러 번 호출하면 호출한 횟수만큼 위치가 증가한다.") + void moveCarMultipleTimes() { + // given: "jun"이라는 이름의 자동차를 생성하고 + Car car = new Car("jun"); + int moveCount = 5; + + // when: move 메서드를 5번 호출하면 + for (int i = 0; i < moveCount; i++) { + car.move(); + } + + // then: 자동차의 위치는 5가 되어야 한다. + assertEquals(moveCount, car.getPosition()); + } +} diff --git a/src/test/java/model/random/RandomMoveStrategyTest.java b/src/test/java/model/random/RandomMoveStrategyTest.java new file mode 100644 index 00000000..b7f0d49a --- /dev/null +++ b/src/test/java/model/random/RandomMoveStrategyTest.java @@ -0,0 +1,19 @@ +package model.random; + +import model.random.*; +import model.Car; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class RandomMoveStrategyTest { + + @Test + @DisplayName("값이 랜덤한지 확인") + void checkRandom (){ + // given: "pobi"라는 이름을 가진 자동차를 준비하고 + String carName = "pobi"; + + } + +}