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
42 changes: 42 additions & 0 deletions src/main/java/RaceController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import domain.Attempts;
import domain.RacingGame;
import dto.ResultDto;
import view.InputView;
import view.OutputView;

import java.io.IOException;
import java.util.List;

public class RaceController {
private static final InputView inputView = new InputView(System.in);

public static void main(String[] args) {
final RacingGame racingGame = repeatUntilGetValidCarNames();
final Attempts attempts = repeatUntilGetValidAttempts();

List<ResultDto> raceProcess = racingGame.race(attempts);

OutputView.printRaceProcess(raceProcess);
OutputView.printResult(racingGame.getWinners());
}

private static RacingGame repeatUntilGetValidCarNames() {
try {
final String[] carNames = inputView.readCarNames();
return new RacingGame(carNames);
} catch (IOException | IllegalArgumentException e) {
OutputView.printExceptionMessage(e);
return repeatUntilGetValidCarNames();
}
}

private static Attempts repeatUntilGetValidAttempts() {
try {
final Integer numberOfAttempts = inputView.readNumberOfAttempts();
return new Attempts(numberOfAttempts);
} catch (IOException | IllegalArgumentException e) {
OutputView.printExceptionMessage(e);
return repeatUntilGetValidAttempts();
}
}
}
7 changes: 0 additions & 7 deletions src/main/java/RacingMain.java

This file was deleted.

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

import java.util.Objects;

public class Attempts {
private static final int MIN_ATTEMPTS = 1;
private static final int MAX_ATTEMPTS = 10;

private int numberOfAttempts;


public Attempts(final int numberOfAttempts) {
if (isNumberOfAttemptsOutOfRange(numberOfAttempts)) {
throw new IllegalArgumentException(MIN_ATTEMPTS + "부터 " + MAX_ATTEMPTS + " 이하의 숫자를 입력하세요.\n");
}

this.numberOfAttempts = numberOfAttempts;
}

public boolean isEnd() {
return numberOfAttempts == 0;
}

public void decrease() {
numberOfAttempts--;
}

private boolean isNumberOfAttemptsOutOfRange(final int numberOfAttempts) {
return numberOfAttempts < MIN_ATTEMPTS || numberOfAttempts > MAX_ATTEMPTS;
}

@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Attempts attempts = (Attempts) o;
return numberOfAttempts == attempts.numberOfAttempts;
}

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

import java.util.Objects;

public class Car {
private final String name;
private int position;

public Car(final String name) {
validate(name);
position = 0;
this.name = name;
}

Car(final String name, final int position) {
this(name);
this.position = position;
}

public void move(final int number) {
if (number >= 4) {
position++;
}
}

public boolean isPositionedAt(final int position) {
return this.position == position;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}

private void validate(final String name) {
if (isNameLengthOutOfRange(name)) {
throw new IllegalArgumentException("1이상 5이하의 이름을 입력하세요.\n");
}
}

private boolean isNameLengthOutOfRange(final String name) {
return name.length() < 1 || name.length() > 5;
}

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

@Override
public int hashCode() {
return Objects.hash(name, position);
}
}
56 changes: 56 additions & 0 deletions src/main/java/domain/CarGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package domain;

import dto.CarDto;
import dto.ResultDto;
import utils.PowerGenerator;
import utils.RandomPowerGenerator;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CarGroup {
private final List<Car> carGroup;
private final PowerGenerator powerGenerator;

public CarGroup(final String[] carNames) {
this.carGroup = Arrays.stream(carNames)
.map(Car::new)
.collect(Collectors.toList());
this.powerGenerator = new RandomPowerGenerator();
}

CarGroup(final String[] carNames, final PowerGenerator powerGenerator) {
this.carGroup = Arrays.stream(carNames)
.map(Car::new)
.collect(Collectors.toList());
this.powerGenerator = powerGenerator;
}

public ResultDto move() {
for (Car car : carGroup) {
car.move(powerGenerator.getNumber());
}
return ResultDto.toDto(carGroup);
}

public List<CarDto> getWinners() {
final int positionMax = getPositionMax();

if (positionMax == 0) {
return List.of();
}

return carGroup.stream()
.filter(car -> car.isPositionedAt(positionMax))
.map(CarDto::toDto)
.toList();
}

private int getPositionMax() {
return carGroup.stream()
.mapToInt(Car::getPosition)
.max()
.orElse(0);
}
}
35 changes: 35 additions & 0 deletions src/main/java/domain/RacingGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package domain;

import dto.CarDto;
import dto.ResultDto;
import utils.PowerGenerator;

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

public class RacingGame {
private final CarGroup carGroup;

public RacingGame(final String[] carNames) {
this.carGroup = new CarGroup(carNames);
}

RacingGame(final String[] carNames, final PowerGenerator powerGenerator) {
this.carGroup = new CarGroup(carNames, powerGenerator);
}

public List<ResultDto> race(final Attempts attempts) {
List<ResultDto> result = new ArrayList<>();

while (!attempts.isEnd()) {
result.add(carGroup.move());
attempts.decrease();
}

return result;
}

public List<CarDto> getWinners() {
return carGroup.getWinners();
}
}
11 changes: 11 additions & 0 deletions src/main/java/dto/CarDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dto;

import domain.Car;

public record CarDto(String name, int position) {

public static CarDto toDto(final Car car) {
return new CarDto(car.getName(), car.getPosition());
}

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

import domain.Car;

import java.util.List;

public record ResultDto(List<CarDto> carGroup) {

public static ResultDto toDto(final List<Car> carGroup) {
return new ResultDto(carGroup.stream()
.map(CarDto::toDto)
.toList());
}

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

public interface PowerGenerator {
int getNumber();
}
11 changes: 11 additions & 0 deletions src/main/java/utils/RandomPowerGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package utils;

import java.util.Random;

public class RandomPowerGenerator implements PowerGenerator {
private static final Random random = new Random();

public int getNumber() {
return random.nextInt(10);
}
}
55 changes: 55 additions & 0 deletions src/main/java/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package view;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Pattern;

public class InputView {
private static final String CAR_NAME_DELIMITER = ",";
private final BufferedReader reader;

public InputView(final InputStream inputStream) {
this.reader = new BufferedReader(new InputStreamReader(inputStream));
}

public String[] readCarNames() throws IOException {
System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).");
final String userInput = removeBlank(reader.readLine());

validateCarNamesFormat(userInput);

return userInput.split(CAR_NAME_DELIMITER);
}

public Integer readNumberOfAttempts() throws IOException {
System.out.println("시도할 회수는 몇회인가요?");
final String userInput = removeBlank(reader.readLine());

validateNumberOfAttempts(userInput);

return Integer.parseInt(userInput);
}

private void validateCarNamesFormat(final String names) {
if (!Pattern.matches("^[A-z0-9,]+$", names)) {
throw new IllegalArgumentException("형식에 맞게 다시 입력하세요.\n");
}
}

private void validateNumberOfAttempts(final String text) {
try {
Integer.parseInt(text);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("1부터 10 이하의 숫자를 입력하세요.\n");
}
}

private String removeBlank(final String text) {
if (text == null) {
return null;
}
return text.replaceAll(" ", "");
}
}
Loading