Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
10dca15
docs(guide): 구현할 기능목록과 예외처리 목록 추가
oereo Mar 4, 2021
7759d90
test: Car의 move 메서드 호출시 한칸 전진하는 테스트 작성
oereo Mar 4, 2021
29c34ea
feat: 자동차가 움직이는 기능 구현
oereo Mar 4, 2021
a14473d
test: 전진 여부 판단 test code 작성
oereo Mar 4, 2021
a51c4e4
feat: 전진 여부 판단 기능 구현
oereo Mar 4, 2021
d56921b
feat: 0~9 범위의 난수 생성 기능 구현
oereo Mar 4, 2021
3d28c49
test: car 객체를 CarManager에 추가하는 test 작성
oereo Mar 4, 2021
4eebc6d
feat: Car 객체 추가 테스트 통과하는 기능 구현
oereo Mar 4, 2021
69f37d0
test: 중복되는 이름의 Car 객체를 추가할 시 NotDulicateNameException를 던지는 test 작성
oereo Mar 4, 2021
7d614b4
fix: 독립된 테스트케이스 환경 구성
oereo Mar 4, 2021
0c6bb59
feat: 중복되는 이름의 Car 객체를 검사하고 존재하면 NotDuplicateNameException 던지는 기능 구현
oereo Mar 4, 2021
1ff4c7a
test: Car 객체의 상태를 출력 포맷에 맞게 String으로 반환하는 test 작성
oereo Mar 4, 2021
b2daa5d
feat: Car 객체의 상태를 출력 포맷에 맞게 String으로 반환하는 기능 구현
oereo Mar 4, 2021
40b18e4
test: 빈 String의 이름을 가진 Car 객체를 생성하면 NotBlankException을 던지는 test 작성
oereo Mar 4, 2021
e16fdb8
feat: 빈 String의 이름을 가진 Car 객체를 생성하면 NotBlankException을 던지는 기능 구현
oereo Mar 4, 2021
218bed6
refactor: 루트 패키지 racingcar 추가
oereo Mar 4, 2021
f0d1f09
refactor: Discriminator 패키지 위치 변경
oereo Mar 9, 2021
e72ba2f
refactor: 플레이어 추가를 addAllCars method 로 test case 작성
oereo Mar 9, 2021
cf8d6d4
refactor: 플레이어 추가를 addAllCars method 로 구현
oereo Mar 9, 2021
4e74812
test: 랜덤 숫자 리스트 기준에 따라 플레이어가 이동하는 test case 작성
oereo Mar 9, 2021
c6f3b68
feat: 랜덤 숫자 리스트 기준에 따라 플레이어가 이동하는 method 구현
oereo Mar 9, 2021
396584f
refactor: car 객체와 생성된 난수를 dto로 mapping
oereo Mar 9, 2021
c08b45d
test: dto 리스틀를 생성하는 test case 작성
oereo Mar 9, 2021
f982c1d
feat: dto에 car 객체와 난수 생성하는 기능 구현
oereo Mar 9, 2021
bd63d3d
feat: 출력 담당 Printer class 구현
oereo Mar 9, 2021
b9dc073
feat: 전체 car 의 state 를 출력하는 printCarState method 구현
oereo Mar 9, 2021
ec26f16
feat: 사용자의 입력을 받는 역할을 담당하는 Receiver class 구현
oereo Mar 9, 2021
eb40f45
test: 승자가 한명일 때 그 이름을 출력하는 test case 작성
oereo Mar 9, 2021
89965af
test: 승자가 여러명일 때 그 이름들을 comma로 구분하여 출력하는 test case 작성
oereo Mar 9, 2021
a04b488
feat: 승자를 구하고 그 승자이름들을 comma로 구분하여 출력하는 기능 구현
oereo Mar 9, 2021
9db711b
feat: 게임 흐름 제어하는 RacingGameApplication 구현
oereo Mar 9, 2021
267a80a
fix: 정상적이지 않은 입력값에 대한 예외 처리 NotBlankException
oereo Mar 9, 2021
fc8d01c
docs(guide): 예외처리 목록 추가 및 체크사항 수정
oereo Mar 9, 2021
9ceca45
docs(guide): 5글자 이상의 차 이름을 입력했을 때 허용하지 않는 케이스 예외처리 목록에 추가
oereo Mar 16, 2021
01c78c6
test: 5글자 이상의 이름이 주어지면 NotValidNameLengthException 던지는 테스트 케이스 작성
oereo Mar 16, 2021
eb7a7c5
feat: NotValidNameLengthException 예외처리 추가 및 Car 객체 생성 시 예외처리 로직 추가
oereo Mar 18, 2021
1b7f367
fix: Car객체 생성 시 5글자 이상의 name을 넣는 테스트 케이스 일괄 수정
oereo Mar 18, 2021
1e1ce79
fix: Car 객체의 이름이 빈 스트링일 경우 기존 name.equals("")에서 api를 이용한 isBlank() me…
oereo Mar 18, 2021
48dca32
refactor: NotBlankException를 발생시키는 createAllCars()에만 try catch 적용
oereo Mar 19, 2021
d9012d1
fix: Car 이름의 길이 제한하는 기준과 한번 이동할 때의 숫자를 상수화
oereo Mar 19, 2021
107e35f
fix: 컬렉션의 of 메소드가 java8에서 작동이 안되는 문제점 해결하기 위해 Arrays.asList 로 수정
oereo Mar 20, 2021
df55a8c
refactor: CarName class 선언 및 Car 객체 생성시에 예외처리를 해줄 수 있도록 구조 수정
oereo Mar 20, 2021
914a0b5
refactor: createAllCars method 수정
oereo Mar 20, 2021
946fadf
docs(guide): 5글자 이상의 차 이름을 입력했을 때 허용하지 앟는 예외처리 목록 체크 반영
oereo Mar 20, 2021
498d3be
feat: isWinnerPosition method를 Car class 안에 추가
oereo Mar 21, 2021
9857960
fix: getPosition으로 Car 객체의 위치를 바로 가져오는 것이 아닌 Car class 내의 method로 판단하…
oereo Mar 21, 2021
9430694
feat: Round class 추가
oereo Mar 25, 2021
cc8172a
feat: Round 객체 생성 및 RacingGameApplication method 변경
oereo Mar 25, 2021
16aa313
feat: RacingGameApplication 안에서 DELIMITER 로 split 하는 함수 제외 및 Receiver…
oereo Mar 25, 2021
ab0b294
refactor: receiveNumberOfRounds method 에 예외처리 로직 추가
oereo Mar 25, 2021
8f40658
refactor: throwExceptionIfInputIsZero method 와 SplitInputLine method …
oereo Mar 25, 2021
6f57314
feat: Receiver 에서 validate 하지 않은 input 값이 들어올 시 다시 Receiver class로 요청…
oereo Mar 25, 2021
c40921a
delete: random util class의 필요성이 없기 때문에 RandomGenerator 삭제
oereo Mar 25, 2021
735092e
feat: MoveStrategy class 생성 및 RandomMoveStrategy class 생성
oereo Mar 25, 2021
6144be7
feat: RandomMoveStrategy 의 숫자에 의해서 car 객체가 움직일지 말지의 여부를 판단하고 행동하는 For…
oereo Mar 25, 2021
d573258
delete: Discriminator class 삭제 및 test case 삭제
oereo Mar 25, 2021
9169126
refactor: Discriminator class 관련 로직 제거 및 직접 Car 객체를 move() 하는 로직 제거
oereo Mar 25, 2021
761b3dc
refactor: receiveNumberOfRounds validation 와 관련된 로직 분리
oereo Mar 26, 2021
35ed5d8
refactor: round 형태를 variable경 이 아닌 객체로 변
oereo Mar 26, 2021
fec9808
feat: round에 관련된 값을 받을 시에 validate한 값이 들어올 수 있도록 ReceiverValidator cl…
oereo Mar 26, 2021
ea5a4fd
refactor: random number 를 저장할 이유가 없기 때문에 제거 및 class naming 수정
oereo Mar 26, 2021
de3ba25
feat: CarManagerValidator class 추가
oereo Mar 26, 2021
c5eb648
refactor: run() method 간소화 및 createAllCars() method 를 RacingGameAppli…
oereo Mar 26, 2021
8afc5d2
refactor: NotDuplicateNameException 예외처리를 ValidateAddCars method 에서 처리
oereo Mar 26, 2021
8501c47
feat: Winner class 생성
oereo Mar 26, 2021
ea61730
feat: CarManager class 안 createWinnerMessage method 역할 분리
oereo Mar 26, 2021
257a825
refactor: class 이동 및 구조 변경
oereo Mar 26, 2021
8c28348
refactor: class 이동 및 구조 변경
oereo Mar 26, 2021
50063f2
delete: 사용하지 않는 모듈 삭제
oereo Mar 26, 2021
bcf9d28
refactor: 사용하지 않는 모듈 삭제 및 구조 변경
oereo Mar 26, 2021
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
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# 미션 - 자동차 경주 게임

## 구현할 기능 목록
- [x] 차의 이름과 위치를 관리하는 클래스를 구현한다.
- [x] 0부터 9사이의 정수값을 랜덤하게 생성
- [x] 난수가 4이상이면 전진
- [x] 난수가 3이하이면 이동하지 않는다
- [x] 턴이 모두 지났을 때 가장 앞에 있는 차의 이름을 출력한다.
- [x] 턴이 모두 지났을 때 앞에 있는 차가 2개 이상일 경우 전부 출력한다.
- [x] 차의 이름에 대한 입력값을 쉼표로 구분할 수 있다.
- [x] 시도할 횟수를 입력 받을 수 있다.
- [x] 현재 자동차의 위치상황을 이름과 함께 출력할 수 있다.

## 예외 처리 목록
- [x] 빈 문자열 입력은 허용하지 않는다.
- [x] 중복되는 이름의 차를 입력했을 때 허용하지 않는다.
- [x] 시도할 횟수로 숫자가 아닌 값을 입력했을 때 허용하지 않는다.
- [x] 5글자 이상의 차 이름을 입력했을 때 허용하지 않는다.

## 🚀 기능 요구사항

- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
Expand Down
12 changes: 0 additions & 12 deletions src/main/java/domain/Car.java

This file was deleted.

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

import racingcar.domain.Round;
import racingcar.repository.validator.CarManagerValidator;
import racingcar.dto.CarDto;
import racingcar.repository.CarManager;
import racingcar.ui.Printer;

import java.util.List;

public class RacingGameApplication {

private final Printer printer = new Printer();
private final CarManager carManager = new CarManager();
private final CarManagerValidator carManagerValidator = new CarManagerValidator();
public void run() {
printer.requestCarName();
carManagerValidator.ValidateAddCars(carManager);

printer.requestNumberOfRounds();
Round rounds = receiveRounds();
proceedRound(rounds);

printer.printWinner(carManager.createWinnerMessage());
}

private void proceedRound(Round rounds) {
printer.printResultHeader();
for (int i = 0; i < rounds.getRounds(); i++) {
List<CarDto> CarDtos = carManager.generateCarDtos();
carManager.moveAllCars(CarDtos);
carManager.printCarState(printer);
}
}

private Round receiveRounds() {
Round roundObject = new Round();
return roundObject;
}

public static void main(String[] args) {
RacingGameApplication app = new RacingGameApplication();
app.run();
}
}

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

import racingcar.ui.validator.ReceiverValidator;

public class Round {
private final int rounds;
private final ReceiverValidator receiverValidator = new ReceiverValidator();

public Round() {
int round = receiverValidator.getValidateReceiveNumberOfRounds();
this.rounds = round;
}

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

import racingcar.domain.car.Car;

import java.util.List;

public class Winner {
private static final String DELIMITER = ", ";
private final List<Car> winnerNames;

public Winner(List<Car> winnerNames) {
this.winnerNames = winnerNames;
}

public String getWinnerGroups() {
StringBuilder winnerGroups = new StringBuilder();
winnerGroups.append(winnerNames.get(0).getName());

for (int i = 1; i < winnerNames.size(); i++) {
Car winner = winnerNames.get(i);
winnerGroups.append(DELIMITER);
winnerGroups.append(winner.getName());
}
return winnerGroups.toString();
}
}
48 changes: 48 additions & 0 deletions src/main/java/racingcar/domain/car/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package racingcar.domain.car;

import java.util.Objects;

public class Car {
private final String name;
private int position = 0;
private static final int MOVE_INTERVAL = 1;

public Car(String name) {
CarName carName = new CarName(name);
this.name = name;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}

public void move() {
position += MOVE_INTERVAL;
}

@Override
public String toString() {
return name + " : " + "-".repeat(Math.max(0, position));
}

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

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

public boolean isWinnerPosition(int winnerPosition) {
return winnerPosition == position;
}
}
27 changes: 27 additions & 0 deletions src/main/java/racingcar/domain/car/CarName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package racingcar.domain.car;

import racingcar.domain.exception.NotBlankException;
import racingcar.domain.exception.NotValidNameLengthException;

public class CarName {
private static final int CAR_NAME_MAX_LENGTH = 4;
private final String name;

public CarName(String name) {
checkBlankName(name);
checkNameLength(name);
this.name = name;
}

private void checkBlankName(String name) {
if (name.isBlank()) {
throw new NotBlankException();
}
}

private void checkNameLength(String name) {
if (name.length() > CAR_NAME_MAX_LENGTH) {
throw new NotValidNameLengthException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package racingcar.domain.exception;

public class NotBlankException extends RuntimeException {
private static final String MESSAGE = "빈 문자열 이름의 차를 생성할 수는 없습니다.";

public NotBlankException() {
super(MESSAGE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package racingcar.domain.exception;

public class NotValidNameLengthException extends RuntimeException {
private static final String Message = "5자 이상의 이름을 가진 차는 생설할 수 없습니다.";

public NotValidNameLengthException() {
super(Message);
}
}
17 changes: 17 additions & 0 deletions src/main/java/racingcar/dto/CarDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package racingcar.dto;

import racingcar.domain.car.Car;

public class CarDto {
private final Car car;

public CarDto(Car car) {
this.car = car;

}

public Car getCar() {
return car;
}

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

public class NotZeroRoundException extends IllegalArgumentException {
private static final String NOT_ZERO_ROUND_EXCEPTION_MESSAGE = "라운드 회수로 0은 입력하실 수 없습니다.";

public NotZeroRoundException() {
super(NOT_ZERO_ROUND_EXCEPTION_MESSAGE);
}
}
88 changes: 88 additions & 0 deletions src/main/java/racingcar/repository/CarManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package racingcar.repository;

import racingcar.domain.Winner;
import racingcar.domain.car.Car;
import racingcar.dto.CarDto;
import racingcar.repository.Strategy.ForwardMoveStrategy;
import racingcar.repository.exception.NotDuplicateNameException;
import racingcar.ui.Printer;

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

public class CarManager {
private List<Car> cars;
private final ForwardMoveStrategy forwardMoveStrategy = new ForwardMoveStrategy();

public CarManager() {
cars = new ArrayList<>();
}

private void checkDuplicateName(Car car) {
if (cars.contains(car)) {
throw new NotDuplicateNameException("중복되는 이름의 차를 입력하실 수 없습니다.");
}
}

public int size() {
return cars.size();
}

public void addAllCars(List<Car> carGroups) {
cars = new ArrayList<>();
for (Car car : carGroups) {
checkDuplicateName(car);
this.cars.add(car);
}
}

public List<Car> createAllCars(List<String> carNames) {
List<Car> carGroups = new ArrayList<>();

for (String name : carNames) {
carGroups.add(new Car(name));
}
return carGroups;
}

public List<CarDto> generateCarDtos() {
List<CarDto> dtos = new ArrayList<>();
for (Car car: cars) {
dtos.add(new CarDto(car));
}

return dtos;
}

public void moveAllCars(List<CarDto> carNumberList) {
for (CarDto dto : carNumberList) {
forwardMoveStrategy.forwardDeciding(dto.getCar());
}
}

public void printCarState(Printer printer) {
for (Car car : cars) {
printer.printCarState(car);
}
printer.printNewLine();
}

public String createWinnerMessage() {
List<Car> winners = winnerList();
Winner winner = new Winner(winners);

return winner.getWinnerGroups();
}

private List<Car> winnerList() {
int winnerPosition = cars.stream()
.mapToInt(Car::getPosition)
.max()
.orElseThrow(IllegalArgumentException::new);

return cars.stream()
.filter(car -> car.isWinnerPosition(winnerPosition))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package racingcar.repository.Strategy;

import racingcar.domain.car.Car;

public class ForwardMoveStrategy extends RandomMoveStrategy{
public void forwardDeciding(Car car){
if(decideMoving() >= getThreshold()){
car.move();
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/racingcar/repository/Strategy/MoveStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package racingcar.repository.Strategy;

interface MoveStrategy {
int decideMoving();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package racingcar.repository.Strategy;

import java.util.Random;

public class RandomMoveStrategy implements MoveStrategy{
private final int UPPER_BOUND = 10;
private static final int THRESHOLD = 4;

@Override
public int decideMoving(){
return new Random().nextInt(UPPER_BOUND);
}

public int getThreshold(){
return THRESHOLD;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package racingcar.repository.exception;

public class NotDuplicateNameException extends RuntimeException {
public NotDuplicateNameException(String message) {
super(message);
}
}
Loading