diff --git a/docs/README.md b/docs/README.md index e69de29b..77000c44 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,29 @@ +## ✅ 핵심 기능 목록 (체크리스트) + +- [ ] 자동차 이름 입력 검증 (`feat: 자동차 이름 입력 검증 추가`) + - 쉼표 구분 파싱 + - 1~5자 길이 체크 + +- [ ] 시도 횟수 입력 검증 (`feat: 시도 횟수 유효성 체크 구현`) + - 숫자 형식 검증 + - 양수 여부 확인 + +- [ ] 자동차 이동 로직 (`feat: 자동차 이동 조건 구현`) + - 0-9 랜덤 값 생성 + - 4 이상 시 위치 증가 + +- [ ] 경주 진행 관리 (`feat: 라운드별 경주 실행 기능`) + - 지정 횟수만큼 반복 + - 매 라운드 위치 업데이트 + +- [ ] 결과 출력 형식 (`feat: 실행 결과 출력 포맷팅`) + - `이름 : ----` 형태 표시 + - 라운드 구분선 추가 + +- [ ] 우승자 판별 (`feat: 최종 우승자 계산 로직`) + - 최대 위치 계산 + - 공동 승자 처리 + +- [ ] 예외 처리 통합 (`feat: 입력 예외 핸들링 추가`) + - `IllegalArgumentException` throw + - 오류 메시지 출력 \ No newline at end of file diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e7..09ff6e1a 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -1,7 +1,42 @@ package racingcar; +import camp.nextstep.edu.missionutils.Console; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + public class Application { public static void main(String[] args) { - // TODO: 프로그램 구현 + List cars = createCars(); + int attempts = getAttempts(); + Racing racing = new Racing(cars, attempts); + racing.start(); + printWinners(racing.getWinners()); // try-catch 제거 + } + + private static List createCars() { + System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"); + String[] names = Console.readLine().split(","); + return Arrays.stream(names) + .map(Car::new) + .collect(Collectors.toList()); + } + + private static int getAttempts() { + System.out.println("시도할 회수는 몇회인가요?"); + String input = Console.readLine(); + try { + int attempts = Integer.parseInt(input); + if (attempts <= 0) { + throw new IllegalArgumentException("[ERROR] 시도 횟수는 1 이상이어야 합니다"); + } + return attempts; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] 숫자만 입력 가능합니다"); + } + } + + private static void printWinners(List winners) { + System.out.println("최종 우승자 : " + String.join(", ", winners)); } } diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java new file mode 100644 index 00000000..1282f723 --- /dev/null +++ b/src/main/java/racingcar/Car.java @@ -0,0 +1,34 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Randoms; + +public class Car { + private final String name; + private int position; + + public Car(String name) { + validateName(name); // 생성자에서 이름 검증 + this.name = name; + this.position = 0; + } + + private void validateName(String name) { + if (name == null || name.isEmpty() || name.length() > 5) { + throw new IllegalArgumentException("[ERROR] 자동차 이름은 1~5자만 가능합니다"); // 예외 메시지 일치 + } + } + + public void move() { + if (Randoms.pickNumberInRange(0, 9) >= 4) { + position++; + } + } + + public String getName() { + return name; + } + + public int getPosition() { + return position; + } +} diff --git a/src/main/java/racingcar/Racing.java b/src/main/java/racingcar/Racing.java new file mode 100644 index 00000000..d354fbab --- /dev/null +++ b/src/main/java/racingcar/Racing.java @@ -0,0 +1,50 @@ +package racingcar; + +import java.util.List; +import java.util.stream.Collectors; + +public class Racing { + private final List cars; + private final int attempts; + + public Racing(List cars, int attempts) { + this.cars = cars; + this.attempts = attempts; + } + + public void start() { + System.out.println("\n실행 결과"); + for (int i = 0; i < attempts; i++) { + raceRound(); + printPositions(); + } + } + + private void raceRound() { + for (Car car : cars) { + car.move(); + } + } + + private void printPositions() { + for (Car car : cars) { + System.out.printf("%s : %s%n", car.getName(), "-".repeat(car.getPosition())); + } + System.out.println(); + } + + public List getWinners() { + int maxPosition = getMaxPosition(); + return cars.stream() + .filter(car -> car.getPosition() == maxPosition) + .map(Car::getName) + .collect(Collectors.toList()); + } + + private int getMaxPosition() { + return cars.stream() + .mapToInt(Car::getPosition) + .max() + .orElse(0); + } +}