diff --git a/README.md b/README.md index d0286c859f..6311f23a7f 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ # java-racingcar-precourse + +--- + +## 구현 기능 목록 + +- [x] 자동차 이름 입력 +- [x] 시도할 횟수 입력 +- [x] 자동차 이름 쉼표 구분 +- [x] 입력이 유효하지 않을 경우 오류 발생 +- [x] 자동차 전진 내용 출력 +- [ ] 우승자 안내 문구 출력 \ No newline at end of file diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e724..577d0c76f6 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,9 @@ package racingcar; +import racingcar.controller.RacingController; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + RacingController.run(); } } diff --git a/src/main/java/racingcar/controller/RacingController.java b/src/main/java/racingcar/controller/RacingController.java new file mode 100644 index 0000000000..5a4c786e8b --- /dev/null +++ b/src/main/java/racingcar/controller/RacingController.java @@ -0,0 +1,23 @@ +package racingcar.controller; + +import racingcar.domain.Cars; +import racingcar.view.RacingView; + +public class RacingController { + public static void run() { + String carNames = RacingView.getCarsInput(); + int tryingCount = RacingView.getTryingCountInput(); + + Cars cars = new Cars(carNames); + System.out.println("실행 결과"); + runRacing(cars, tryingCount); + } + + private static void runRacing(Cars cars, int tryingCount) { + for (int i = 0; i < tryingCount; i++) { + cars.race(); + RacingView.printResults(cars.getRacingResults()); + } + RacingView.printWinners(cars.getWinners()); + } +} diff --git a/src/main/java/racingcar/domain/Car.java b/src/main/java/racingcar/domain/Car.java new file mode 100644 index 0000000000..84e9560430 --- /dev/null +++ b/src/main/java/racingcar/domain/Car.java @@ -0,0 +1,40 @@ +package racingcar.domain; + +public class Car { + private static final int MAX_NAME_LENGTH = 5; + private static final int MOVE_THRESHOLD = 4; + + private final String name; + private int moveCount = 0; + + public Car(String name) { + this.name = name; + validateName(name); + } + + public int getMoveCount() { + return moveCount; + } + + public String getName() { + return name; + } + + public void increaseMoveCount(int randomNum) { + if (randomNum >= MOVE_THRESHOLD) { + moveCount++; + } + } + + @Override + public String toString() { + return name + " : " + "-".repeat(moveCount); + } + + public static void validateName(String name) { + if (name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("이름은 5자를 초과할 수 없습니다."); + } + } + +} diff --git a/src/main/java/racingcar/domain/Cars.java b/src/main/java/racingcar/domain/Cars.java new file mode 100644 index 0000000000..c058910d51 --- /dev/null +++ b/src/main/java/racingcar/domain/Cars.java @@ -0,0 +1,47 @@ +package racingcar.domain; + +import java.util.Arrays; +import java.util.List; +import racingcar.utils.RandomGenerator; + +import java.util.stream.Collectors; + +public class Cars { + private final List cars; + private final RandomGenerator randomGenerator = new RandomGenerator(); + + public Cars(String rawNames) { + validateNames(rawNames); + cars = Arrays.stream(rawNames.split(",")) + .map(Car::new) + .toList(); + } + + public static void validateNames(String rawNames) { + if (rawNames == null || rawNames.trim().isEmpty()) { + throw new IllegalArgumentException("자동차 이름 목록이 비어있습니다."); + } + } + + public void race() { + cars.forEach(car -> car.increaseMoveCount(randomGenerator.generateRandomNumber(0, 9))); + } + + public String getRacingResults() { + return cars.stream() + .map(Car::toString) + .collect(Collectors.joining("\n")); + } + + public String getWinners() { + int maxMovedCount = cars.stream() + .map(Car::getMoveCount) + .max(Integer::compareTo) + .orElse(0); + + return cars.stream() + .filter(car -> car.getMoveCount() == maxMovedCount) + .map(Car::getName) + .collect(Collectors.joining(",")); + } +} diff --git a/src/main/java/racingcar/utils/RandomGenerator.java b/src/main/java/racingcar/utils/RandomGenerator.java new file mode 100644 index 0000000000..822d139161 --- /dev/null +++ b/src/main/java/racingcar/utils/RandomGenerator.java @@ -0,0 +1,9 @@ +package racingcar.utils; + +import camp.nextstep.edu.missionutils.Randoms; + +public class RandomGenerator { + public int generateRandomNumber(int min, int max) { + return Randoms.pickNumberInRange(min, max); + } +} diff --git a/src/main/java/racingcar/view/RacingView.java b/src/main/java/racingcar/view/RacingView.java new file mode 100644 index 0000000000..48e8c78ff0 --- /dev/null +++ b/src/main/java/racingcar/view/RacingView.java @@ -0,0 +1,23 @@ +package racingcar.view; + +import camp.nextstep.edu.missionutils.Console; + +public class RacingView { + public static String getCarsInput() { + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + return Console.readLine(); + } + + public static int getTryingCountInput() { + System.out.println("시도할 횟수는 몇 회인가요?"); + return Integer.parseInt(Console.readLine()); + } + + public static void printResults(String result) { + System.out.println(result + "\n"); + } + + public static void printWinners(String winners) { + System.out.println("최종 우승자 : " + winners); + } +} diff --git a/src/test/java/racingcar/CarNamesTest.java b/src/test/java/racingcar/CarNamesTest.java new file mode 100644 index 0000000000..521f631a7f --- /dev/null +++ b/src/test/java/racingcar/CarNamesTest.java @@ -0,0 +1,36 @@ +package racingcar; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import racingcar.domain.Car; +import racingcar.domain.Cars; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class CarNamesTest { + @Test + void 입력값_null_검증() { + assertThatThrownBy(() -> Cars.validateNames(null)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 입력값_빈_문자열_검증() { + assertThatThrownBy(() -> Cars.validateNames(" ")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 입력값_파싱_테스트() { + Assertions.assertDoesNotThrow(() -> Cars.validateNames("pobi,woni,jun")); + } + + @Test + void 이름_길이_테스트() { + Assertions.assertThrows( + IllegalArgumentException.class, () -> new Car("abcdef") + ); + } + +}