Skip to content

Commit

Permalink
[1단계 - 자동차 경주 구현] 채채(신채원) 미션 제출합니다. (#472)
Browse files Browse the repository at this point in the history
* test: String 클래스에 대한 학습 테스트

* test: Set 클래스에 대한 학습 테스트

* docs: 기능 명세서 작성

* feat: 자동차 이름 구현

* feat: 자동차의 위치 구현

* feat: 랜덤숫자 생성 기능 구현

* feat: 이름에 대한 equals & hashcode 구현

* feat: 위치에 대한 equals & hashcode 구현

* test: 깨진 테스트 수정

* feat: 자동차 도메인 구현

* refactor: add final keyword

* feat: 자동차들을 관리하는 Cars 구현

* feat: 바퀴수를 관리하는 Lap 구현

* test: String의 split() 메서드 학습 테스트 추가

* feat: 기본 게임 단계 인터페이스 & 추상클래스 생성

* feat: 자동차 이름을 입력받는 View 구현

* feat: 문자열을 받아 자동차를 생성하는 컨트롤러 기능 구현

* feat: 자동차를 입력받는 단계 구현

* feat: 전체 바퀴수 입력받는 View 구현

* feat: 전체 바퀴수를 생성하는 Controller 기능 구현

* feat: 전체 바퀴수를 입력받는 단계 구현

* feat: "실행 결과"를 출력하는 View 구현

* feat: "실행 결과"를 출력하는 단계 구현

* refactor: 컨트롤러 테스트 이름 상세한 예시 작성

* feat: 자동차들을 움직이는 컨트롤러 기능 구현

* refactor: 하드코딩한 문자열대신 상수로 사용

* feat: 현재 상태를 출력하는 View 구현

* feat: 자동차를 움직이는 단계 구현

* feat: 자동차들 중 우승한 자동자를 반환하는 기능 구현

* fix: 누락된 커밋 추가 (자동차들 중 우승한 자동차를 반환하는 기능 구현)

* feat: 우승자 이름리스트를 반환하는 컨트롤러 기능 구현

* fix: 누락된 커밋 추가 (자동차들 중 우승한 자동차를 반환하는 기능 구현)

* feat: 우승자를 보여주는 단계 구현

* feat: 게임 종료 단계 구현

* fix: 누락된 커밋 추가 (자동차들을 움직이는 컨트롤러 기능 구현)

* feat: 게임 메인 메서드 구현 (기능 구현 완료)
  • Loading branch information
chaewon121 authored Feb 9, 2023
1 parent 5cbd219 commit 483b509
Show file tree
Hide file tree
Showing 31 changed files with 1,287 additions and 0 deletions.
31 changes: 31 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## 📈 기능 목록

## 도메인

### 자동차

- [x] 0에서 9 사이의 random 값에 따라 움직인다.
- [x] 0에서 9 사이에서 random 값을 구한다.
- [x] 4 이상인 경우 전진한다.
- [x] 3 이하인 경우 멈춘다.

- [x] [예외처리] 자동차의 이름은 5글자 이아만 가능하다.

## 게임

### 게임 준비

- [x] 경주할 자동차 이름을 입력받는다.
- [x] [예외처리] 자동차가 1대 이하인 경우

- [x] 시도할 횟수를 입력받는다.
- [x] [예외처리] 숫자가 아닌 경우

### 게임 진행

- [x] lap만큼 반복한다.

### 결과 출력

- [x] 게임을 끝났을 경우
- [x] 가장 많이 전진한 자동차를 출력한다.
22 changes: 22 additions & 0 deletions src/main/java/racingcar/RacingCarApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package racingcar;

import racingcar.controller.RacingCarController;
import racingcar.domain.NumberGenerator;
import racingcar.step.CreateCarStep;
import racingcar.step.Step;

public class RacingCarApplication {

public static void main(String[] args) {
NumberGenerator generator = new NumberGenerator();
RacingCarController racingCarController = new RacingCarController(generator);
Step step = new CreateCarStep(racingCarController);
run(step);
}

private static void run(Step step) {
while (step.executable()) {
step = step.execute();
}
}
}
43 changes: 43 additions & 0 deletions src/main/java/racingcar/controller/RacingCarController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package racingcar.controller;

import racingcar.controller.response.MovedResultResponse;
import racingcar.domain.Cars;
import racingcar.domain.Lap;
import racingcar.domain.NumberGenerator;

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

import static java.util.stream.Collectors.toUnmodifiableList;

public class RacingCarController {

private static final String DELIMITER = ",";
private final NumberGenerator generator;

public RacingCarController(final NumberGenerator generator) {
this.generator = generator;
}

public Cars createCars(final String carNames) {
return new Cars(Arrays.stream(carNames.split(DELIMITER))
.collect(toUnmodifiableList()));
}

public Lap confirmTotalLap(final int totalLap) {
return new Lap(totalLap);
}

public MovedResultResponse moveCars(final Cars cars, final Lap lap) {
cars.move(generator);
lap.next();
return new MovedResultResponse(cars);
}

public List<String> winners(Cars cars) {
return cars.winners().stream()
.map(it -> it.getName().getName())
.collect(Collectors.toUnmodifiableList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package racingcar.controller.response;

import racingcar.domain.Cars;

import java.util.Map;
import java.util.stream.Collectors;

public class MovedResultResponse {

private final Map<String, Integer> positionMap;

public MovedResultResponse(final Cars cars) {
positionMap = cars.getCars()
.stream()
.collect(Collectors.toMap(
car -> car.getName().getName(),
car -> car.getPosition().getValue())
);
}

public Map<String, Integer> getPositionMap() {
return positionMap;
}
}
24 changes: 24 additions & 0 deletions src/main/java/racingcar/domain/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package racingcar.domain;

public class Car {

private final Name name;
private Position position;

public Car(final String name) {
this.name = new Name(name);
this.position = Position.init();
}

public Name getName() {
return name;
}

public Position getPosition() {
return position;
}

public void move(final int randomNumber) {
this.position = this.position.move(randomNumber);
}
}
49 changes: 49 additions & 0 deletions src/main/java/racingcar/domain/Cars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package racingcar.domain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class Cars {

private static final int FIRST_INDEX = 0;
private static final int MIN_NUMBER = 0;
private static final int MAX_NUMBER = 9;
private static final int MIN_SIZE = 2;
private final List<Car> cars;

public Cars(final List<String> cars) {
if (cars.size() < MIN_SIZE) {
throw new IllegalArgumentException();
}
this.cars = cars.stream()
.map(Car::new)
.collect(Collectors.toUnmodifiableList());
}

public void move(final NumberGenerator generator) {
cars.forEach(car -> car.move(generator.generate(MIN_NUMBER, MAX_NUMBER)));
}

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

public List<Car> winners() {
List<Car> cars = sortedCars();
Car winner = cars.get(FIRST_INDEX);

return cars.stream()
.filter(it -> it.getPosition().equals(winner.getPosition()))
.collect(Collectors.toList());
}

private List<Car> sortedCars() {
List<Car> cars = new ArrayList<>(this.cars);
cars.sort(Comparator.comparing(Car::getPosition));
Collections.reverse(cars);
return cars;
}
}
30 changes: 30 additions & 0 deletions src/main/java/racingcar/domain/Lap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package racingcar.domain;

public class Lap {

private final int totalLap;
private int currentLap;

public Lap(final int totalLap) {
this.totalLap = totalLap;
}

public boolean hasNext() {
return currentLap < totalLap;
}

public void next() {
if (!hasNext()) {
throw new IllegalStateException();
}
this.currentLap++;
}

public int getTotalLap() {
return totalLap;
}

public int getCurrentLap() {
return currentLap;
}
}
42 changes: 42 additions & 0 deletions src/main/java/racingcar/domain/Name.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package racingcar.domain;

import java.util.Objects;

public class Name {

private static final int MAX_LENGTH = 5;
private static final int MIN_LENGTH = 0;

private final String name;

public Name(final String name) {
validate(name);
this.name = name;
}

private void validate(final String name) {
if (name == null) {
throw new IllegalArgumentException();
}
if (name.length() > MAX_LENGTH || name.length() == MIN_LENGTH) {
throw new IllegalArgumentException();
}
}

public String getName() {
return name;
}

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

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

public class NumberGenerator {

private static final int ONE = 1;

public int generate(final int minNumber, final int maxNumber) {
return (int) ((Math.random() * (maxNumber - minNumber + ONE)) + minNumber);
}
}
63 changes: 63 additions & 0 deletions src/main/java/racingcar/domain/Position.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package racingcar.domain;

import java.util.Objects;

public class Position implements Comparable<Position> {

private static final int INIT_VALUE = 0;
private static final int BOUNDARY_NUMBER = 4;
private static final int MOVE_INTERVAL = 1;
private static final int MIN_RANGE = 0;
private static final int MAX_RANGE = 9;

private final int value;

private Position(final int value) {
this.value = value;
}

public static Position init() {
return new Position(INIT_VALUE);
}

public int getValue() {
return this.value;
}

public Position move(final int randomNumber) {
validateRange(randomNumber);

return nextPosition(randomNumber);
}

private Position nextPosition(final int randomNumber) {
if (randomNumber >= BOUNDARY_NUMBER) {
return new Position(this.value + MOVE_INTERVAL);
}
return this;
}

private void validateRange(final int randomNumber) {
if (randomNumber < MIN_RANGE || randomNumber > MAX_RANGE) {
throw new IllegalArgumentException();
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Position position = (Position) o;
return value == position.value;
}

@Override
public int hashCode() {
return Objects.hash(value);
}

@Override
public int compareTo(final Position position) {
return this.value - position.value;
}
}
24 changes: 24 additions & 0 deletions src/main/java/racingcar/step/CreateCarStep.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package racingcar.step;

import racingcar.controller.RacingCarController;
import racingcar.domain.Cars;
import racingcar.view.InputView;

public class CreateCarStep extends RacingCarApplicationStep {

public CreateCarStep(final RacingCarController controller) {
super(controller);
}

@Override
public boolean executable() {
return true;
}

@Override
public Step execute() {
String carNames = InputView.inputCarNames();
Cars cars = controller.createCars(carNames);
return new InputTotalLapStep(controller, cars);
}
}
21 changes: 21 additions & 0 deletions src/main/java/racingcar/step/Exit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package racingcar.step;

import racingcar.controller.RacingCarController;

public class Exit extends RacingCarApplicationStep {

protected Exit(RacingCarController controller) {
super(controller);
}

@Override
public boolean executable() {
return false;
}

@Override
public Step execute() {
System.out.println("Exit.execute");
return null;
}
}
Loading

0 comments on commit 483b509

Please sign in to comment.