Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# java-racingcar-precourse

---

## 구현 기능 목록

- [x] 자동차 이름 입력
- [x] 시도할 횟수 입력
- [x] 자동차 이름 쉼표 구분
- [x] 입력이 유효하지 않을 경우 오류 발생
- [x] 자동차 전진 내용 출력
- [ ] 우승자 안내 문구 출력
4 changes: 3 additions & 1 deletion src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package racingcar;

import racingcar.controller.RacingController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
RacingController.run();
}
}
23 changes: 23 additions & 0 deletions src/main/java/racingcar/controller/RacingController.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
40 changes: 40 additions & 0 deletions src/main/java/racingcar/domain/Car.java
Original file line number Diff line number Diff line change
@@ -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자를 초과할 수 없습니다.");
}
}

}
47 changes: 47 additions & 0 deletions src/main/java/racingcar/domain/Cars.java
Original file line number Diff line number Diff line change
@@ -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<Car> 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(","));
}
}
9 changes: 9 additions & 0 deletions src/main/java/racingcar/utils/RandomGenerator.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
23 changes: 23 additions & 0 deletions src/main/java/racingcar/view/RacingView.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
36 changes: 36 additions & 0 deletions src/test/java/racingcar/CarNamesTest.java
Original file line number Diff line number Diff line change
@@ -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")
);
}

}