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
44 changes: 44 additions & 0 deletions MISSION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 자동차 경주 미션

## 구현

- 어플리케이션
- 유저
- 자동차 객체
- 자동차 일급 컬렉션
- 자동차 생성자
- 결과
- 입 출력 핸들러

### 내용

#### 어플리케이션
1. 유저에게 게임을 진행 할 자동차 목록을 입력 받는다.
2. 자동차가 전진 할 수 있는 횟수를 지정한다.
3. 자동차 경주가 진행 됨에 따라 자동차가 얼만큼 전진 했는지 알려준다.
4. 자동차 경주 결과를 유저에게 알려준다.
5. 게임 진행 여부를 입력 받는다.

#### 유저
1. 유저는 게임을 진행 할 자동차의 이름을 입력한다.
2. 유저는 전진 할 수 있는 기회를 설정한다.
3. 게임이 종료 되면 다시 진행 하거나 종료 할 수 있다.

#### 자동차
1. 자동차는 이름과 위치를 갖는 객체이다.
2. 자동차의 이름은 비어있거나 5글자를 초과 할 수 없다.
3. 경주가 진행 됨에 따라 전진 하거나 그대로 멈춰있어야한다.

- 자동차 일급 컬렉션
1. 자동차 목록을 관리한다.

- 자동차 생성자
1. 문자열을 입력 받아 자동차 일급 컬렉션을 생성한다.

#### 결과
1. 자동차 경주가 끝나면 경기 결과를 반환한다.


#### 입출력 핸들러
1. 유저에게 입력 받은 내용을 반환한다.
2. 유저에게 출력 할 내용을 표현한다.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ repositories {
dependencies {
testImplementation "org.junit.jupiter:junit-jupiter:5.7.2"
testImplementation "org.assertj:assertj-core:3.19.0"
testImplementation "org.mockito:mockito-junit-jupiter:5.2.0"
}

test {
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/CarRaceApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import application.CarRace;
import config.CarRaceConfig;
import io.ConsoleInputHandler;

public class CarRaceApplication {

private static final ConsoleInputHandler inputHandler = new ConsoleInputHandler();

public static void main(String[] args) {
CarRaceConfig config = inputHandler.userInputGameConfig();
CarRace carRaceGame = CarRace.from(config);
carRaceGame.raceStart();
}

}
65 changes: 65 additions & 0 deletions src/main/java/application/CarRace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package application;

import config.CarRaceConfig;
import domain.car.CarFactory;
import domain.car.Cars;
import domain.result.Result;
import domain.result.Results;
import io.ConsoleOutputHandler;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import util.RandomUtil;

public class CarRace {

public static final int BOUND = 9;
private static final ConsoleOutputHandler outputHandler = new ConsoleOutputHandler();
private final RandomUtil randomUtil = new RandomUtil();
private final Cars cars;
private final int lap;


public static CarRace from(CarRaceConfig config) {
Cars cars = CarFactory.from(config.getCarNames());
return new CarRace(cars, config.getLabCount());
}

private CarRace(Cars cars, int lap) {
this.cars = cars;
this.lap = lap;
}

public void raceStart() {
Results raceResult = Results.from(IntStream.range(1, lap + 1)
.mapToObj(this::runOneLab)
.peek(outputHandler::printScreenCarRaceResult)
.collect(Collectors.toList()));

outputHandler.printRaceResult(raceResult.getWinner());
}


private Result runOneLab(int runningLab) {
return Result.of(runningLab, Cars.from(
cars.getCars()
.stream()
.peek(car -> car.moveForward(getRunOneLapMoveNumber()))
.collect(Collectors.toList())
)
);

}

public Cars getCars() {
return cars;
}

public int getLap() {
return lap;
}

public int getRunOneLapMoveNumber() {
return randomUtil.getRandomNumber(BOUND);
}

}
24 changes: 24 additions & 0 deletions src/main/java/config/CarRaceConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package config;

public class CarRaceConfig {

private final String carNames;
private final int labCount;

private CarRaceConfig(String carNames, int labCount) {
this.carNames = carNames;
this.labCount = labCount;
}

public static CarRaceConfig of(String carNames, int labCount) {
return new CarRaceConfig(carNames, labCount);
}

public String getCarNames() {
return carNames;
}

public int getLabCount() {
return labCount;
}
}
86 changes: 86 additions & 0 deletions src/main/java/domain/car/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package domain.car;

import exception.GameException;
import java.util.Objects;
import messages.ErrorMessage;

public class Car {

private static final int CAR_NAME_LIMIT_LENGTH = 5;
private static final int MOVE_FORWARD_THRESOLD = 4;
private final String carName;
private int position;

public static Car from(String carName) {
return new Car(carName, 0);
}

public static Car from(String carName, int position) {
return new Car(carName, position);
}

public void moveForward(int moveThresold) {
if (canMove(moveThresold)) {
this.position++;
}
}

private boolean canMove(int moveThresold) {
if (validateMoveThresold(moveThresold)) {
throw new GameException(ErrorMessage.invalidCarMoveThresold);
}

return moveThresold >= MOVE_FORWARD_THRESOLD;
}

private boolean validateMoveThresold(int moveThresold) {
return moveThresold < 0 || moveThresold > 9;
}

public int getPosition() {
return position;
}

public String getCarName() {
return carName;
}

private Car(String carName, int position) {
if (doesCarNameLengthZeroOrGreaterThanLimit(carName)) {
throw new GameException(ErrorMessage.invalidCarName);
}

this.carName = carName;
this.position = position;
}

private static boolean doesCarNameLengthZeroOrGreaterThanLimit(String carName) {
return isNullOrEmpty(carName) || isGreaterThanLimit(carName);
}

private static boolean isGreaterThanLimit(String carName) {
return carName.length() > CAR_NAME_LIMIT_LENGTH;
}

private static boolean isNullOrEmpty(String carName) {
return carName == null || carName.isEmpty();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Car car = (Car) o;
return position == car.position && Objects.equals(carName, car.carName);
}

@Override
public int hashCode() {
return Objects.hash(carName, position);
}

}
36 changes: 36 additions & 0 deletions src/main/java/domain/car/CarFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package domain.car;

import exception.GameException;
import java.util.List;
import java.util.stream.Collectors;
import messages.ErrorMessage;

public class CarFactory {

private final List<String> carNames;

public static Cars from(String carNames) {
return new CarFactory(carNames).createCars();

}

private CarFactory(String carNames) {
if (carNames == null || carNames.isEmpty()) {
throw new GameException(ErrorMessage.invalidCarName);
}

this.carNames = splitByComma(carNames);
}

private List<String> splitByComma(String carNameString) {
return List.of(carNameString.split(","));
}

private Cars createCars() {
return Cars.from(carNames.stream()
.map(String::trim)
.map(Car::from)
.collect(Collectors.toList()));
}

}
39 changes: 39 additions & 0 deletions src/main/java/domain/car/Cars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package domain.car;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class Cars {

private final List<Car> cars;

public static Cars from(List<Car> cars) {
return new Cars(cars);
}

public List<Car> getCars() {
return new ArrayList<>(cars);
}

private Cars(List<Car> cars) {
this.cars = cars;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Cars cars1 = (Cars) o;
return Objects.equals(cars, cars1.cars);
}

@Override
public int hashCode() {
return Objects.hashCode(cars);
}
}
47 changes: 47 additions & 0 deletions src/main/java/domain/result/Result.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package domain.result;

import domain.car.Car;
import domain.car.Cars;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Result {

private final int runningLap;
private final Cars cars;

public static Result of(int runningLap, Cars cars) {
return new Result(runningLap, cars);
}

public List<String> getResult() {
return cars.getCars().stream()
.map(car -> car.getCarName() + " : " + convertPositionNumberToEmoji(car))
.collect(Collectors.toList());
}

public int getRunningLap() {
return runningLap;
}

public List<Car> getCars() {
return new ArrayList<>(cars.getCars());
}

private Result(int runningLap, Cars cars) {
this.runningLap = runningLap;
this.cars = cars;
}

private String convertPositionNumberToEmoji(Car car) {
StringBuilder sb = new StringBuilder();

for (int i = 0; i < car.getPosition(); i++) {
sb.append("-");
}

return String.valueOf(sb);
}

}
Loading