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
56 changes: 55 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,55 @@
# java-racingcar-precourse
# java-racingcar-precourse

# 기능 목록

## 자동차 게임

- 주어진 횟수 동안 n 대의 자동차는 전진 또는 멈출 수 있다.

## 전진 룰

- 값이 4 이상이면 자동차를 전진 시킨다.

## 숫자 뽑기 룰

- 0에서 9 사이에서 무작위 값을 구한다.

## 자동차 목록

- 우승자를 구한다.
- 우승자는 한 명 이상일 수 있다.
- 우승자는 위치의 숫자가 가장 높은 자동차이다.

- 포지션이 같은 자동차 목록을 반환한다.

- 포지션이 가장 높은 자동차의 포지션을 반환한다.

## 자동차

- 자동차는 이름을 가진다.
- 자동차는 위치를 가진다.
- 자동차의 위치를 전진 시키면 위치를 1 증가 시킨다.

## 이름

- 자동차 이름은 5자 이하만 가능하다.
- 자동차 이름이 5자 초과면 IllegalStateException 를 발생시킨다.

## 위치

- 위치를 1 증가 시킨다.
- 위치 값보다 함수로 전달받은 위치 값이 작으면 false 를 반환한다.

# 입출력 요구사항

## 입력 요구사항

- 주어진 문자열을 쉼표를 기준으로 구분한다.
- 숫자를 입력 받는다.
- 잘못된 값을 입력할 경우 IllegalArgumentException 을 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다 시 받는다.

## 출력 요구사항

- 문자열을 출력한다.
- 문자열이 여러 개일 경우 쉼표를 이용하여 구분한다.

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

import racingcar.adapter.ConsoleController;
import racingcar.application.RacingCarService;
import racingcar.application.port.in.RacingCarPlayUseCase;
import racingcar.domain.ForwardRules;
import racingcar.domain.PickNumberRules;
import racingcar.domain.WinnerRules;

public class RacingCarMain {
public static void main(String[] args) {
RacingCarPlayUseCase racingCarPlayUseCase = new RacingCarService(
PickNumberRules.RANDOM,
ForwardRules.MORE_THAN_FOUR,
WinnerRules.HIGHEST_POSITION
);

ConsoleController consoleController = new ConsoleController(racingCarPlayUseCase);

consoleController.play();
}
}
77 changes: 77 additions & 0 deletions src/main/java/racingcar/adapter/ConsoleController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package racingcar.adapter;

import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import racingcar.application.port.ActivityResponse;
import racingcar.application.port.CarResponse;
import racingcar.application.port.RacingCarResultResponse;
import racingcar.application.port.in.RacingCarPlayUseCase;

public class ConsoleController {
private static final String NAME_SEPARATOR = ",";
private static final String WINNER_DELIMITER = ", ";
private static final String CAR_RESPONSE_DELIMITER = " : ";
private static final String POSITION_TEXT = "-";
private static final String NEW_LINE = "\n";

private static final Scanner scanner = new Scanner(System.in);

private final RacingCarPlayUseCase racingCarPlayUseCase;

public ConsoleController(final RacingCarPlayUseCase racingCarPlayUseCase) {
this.racingCarPlayUseCase = racingCarPlayUseCase;
}

public void play() {
String[] names = inputNames();
int number = inputNumber();
RacingCarResultResponse racingCarResultResponse = this.racingCarPlayUseCase.play(number, names);
print(racingCarResultResponse);
}

private void print(final RacingCarResultResponse racingCarResultResponse) {
System.out.println("실행결과");
printCarActivities(racingCarResultResponse);
printWinner(racingCarResultResponse.winners());
}

private void printCarActivities(final RacingCarResultResponse racingCarResultResponse) {
racingCarResultResponse.activities().stream()
.map(ActivityResponse::carResponses)
.map(this::printCarResponse)
.forEach(System.out::println);
}

private void printWinner(final List<CarResponse> winners) {
String winnerText = winners.stream().map(CarResponse::name).collect(Collectors.joining(WINNER_DELIMITER));
System.out.println("최종 우승자 : " + winnerText);
}

private String printCarResponse(List<CarResponse> carResponses) {
return carResponses.stream()
.map(carResponse -> String
.join(CAR_RESPONSE_DELIMITER, carResponse.name(), positionText(carResponse.position())))
.collect(Collectors.joining(NEW_LINE)) + NEW_LINE;
}

private String positionText(final int position) {
return POSITION_TEXT.repeat(position);
}

private String[] inputNames() {
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
String text = scanner.nextLine();
return text.split(NAME_SEPARATOR);
}

private int inputNumber() {
try {
System.out.println("시도할 회수는 몇회인가요?");
return Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException exception) {
System.out.println("[ERROR] 숫자만 입력 가능합니다.");
return inputNumber();
}
}
}
51 changes: 51 additions & 0 deletions src/main/java/racingcar/application/RacingCarService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package racingcar.application;

import java.util.Arrays;
import java.util.List;
import racingcar.application.port.RacingCarResultResponse;
import racingcar.application.port.in.RacingCarPlayUseCase;
import racingcar.domain.Activity;
import racingcar.domain.Car;
import racingcar.domain.ForwardRule;
import racingcar.domain.Name;
import racingcar.domain.PickNumberRule;
import racingcar.domain.RacingCar;
import racingcar.domain.WinnerRule;

public class RacingCarService implements RacingCarPlayUseCase {
private final PickNumberRule pickNumberRule;
private final ForwardRule forwardRule;
private final WinnerRule winnerRule;

public RacingCarService(
final PickNumberRule pickNumberRule,
final ForwardRule forwardRule,
final WinnerRule winnerRule
) {
this.pickNumberRule = pickNumberRule;
this.forwardRule = forwardRule;
this.winnerRule = winnerRule;
}

@Override
public RacingCarResultResponse play(final int number, final String... names) {
RacingCar racingCar = createDefaultRacingCar(names);
racingCar.play(number);
return createRacingCarResultResponse(racingCar);
}

private RacingCar createDefaultRacingCar(final String[] names) {
return new RacingCar(
this.pickNumberRule,
this.forwardRule,
this.winnerRule,
Arrays.stream(names).map(Name::new).toArray(Name[]::new)
);
}

private RacingCarResultResponse createRacingCarResultResponse(final RacingCar racingCar) {
List<Activity> activities = racingCar.activities();
List<Car> winners = racingCar.winner().value();
return new RacingCarResultResponse(activities, winners);
}
}
18 changes: 18 additions & 0 deletions src/main/java/racingcar/application/port/ActivityResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package racingcar.application.port;

import java.util.List;
import racingcar.domain.Activity;

public class ActivityResponse {
private final List<CarResponse> carResponses;

public ActivityResponse(final Activity activity) {
this.carResponses = activity.value().stream()
.map(CarResponse::new)
.toList();
}

public List<CarResponse> carResponses() {
return carResponses;
}
}
21 changes: 21 additions & 0 deletions src/main/java/racingcar/application/port/CarResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package racingcar.application.port;

import racingcar.domain.Car;

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

public CarResponse(final Car car) {
this.name = car.name().value();
this.position = car.position().value();
}

public String name() {
return this.name;
}

public int position() {
return this.position;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package racingcar.application.port;

import java.util.List;
import racingcar.domain.Activity;
import racingcar.domain.Car;

public class RacingCarResultResponse {
private final List<ActivityResponse> activities;
private final List<CarResponse> winners;

public RacingCarResultResponse(final List<Activity> activities, final List<Car> winners) {
this.activities = activities.stream().map(ActivityResponse::new).toList();
this.winners = winners.stream().map(CarResponse::new).toList();
}

public List<ActivityResponse> activities() {
return this.activities;
}

public List<CarResponse> winners() {
return this.winners;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package racingcar.application.port.in;

import racingcar.application.port.RacingCarResultResponse;

public interface RacingCarPlayUseCase {
RacingCarResultResponse play(final int number, final String... names);
}
16 changes: 16 additions & 0 deletions src/main/java/racingcar/domain/Activity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package racingcar.domain;

import java.util.Collections;
import java.util.List;

public class Activity {
private final List<Car> cars;

public Activity(final List<Car> cars) {
this.cars = cars;
}

public List<Car> value() {
return Collections.unmodifiableList(this.cars);
}
}
42 changes: 42 additions & 0 deletions src/main/java/racingcar/domain/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package racingcar.domain;

import java.util.Objects;

public class Car {
private final Name name;
private final Position position;

public Car(final Name name, final Position position) {
this.name = name;
this.position = position;
}

public Car forward() {
return new Car(name, position.forward());
}

public Position position() {
return this.position;
}

public Name name() {
return this.name;
}

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

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