Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
# java-racingcar-precourse
# 🚗 자동차 경주
<br>

## 1️⃣ 입력 기능
- 이름 입력 기능
- 이동 횟수 입력 기능

## 2️⃣ 유효성 검사 기능
- 자동차 이름 유효성 검사
- 이동 횟수 유효성 검사

## 3️⃣ 자동차 전진 및 멈춤 기능
- 랜덤 값에 따라 전진하는지 멈춰있는지 판단하는 기능
- 조건에 따라 전진 하는 기능

## 4️⃣ 우승자 산출 기능
- 가장 많이 전진한 자동차들을 리스트 형태로 반환

## 5️⃣ 출력 기능
- 차수별 진행 상황을 출력하는 기능
- 최종 우승자를 출력하는 기능
5 changes: 5 additions & 0 deletions src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package racingcar;

import racingcar.controller.RacingController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
RacingController racingController = new RacingController();

racingController.startRacing();
}
}
30 changes: 30 additions & 0 deletions src/main/java/racingcar/controller/RacingController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package racingcar.controller;

import racingcar.model.Car;
import racingcar.model.CarListParser;
import racingcar.model.WinnerSelector;
import racingcar.view.inputView.CarNameInputView;
import racingcar.view.inputView.InputView;
import racingcar.view.inputView.MoveCountInputView;
import racingcar.view.outputView.WinnersOutputView;

import java.util.List;

public class RacingController {
public void startRacing(){
InputView carNameInputView = new CarNameInputView();
InputView moveCountInputView = new MoveCountInputView();
String carListInput = carNameInputView.input();
Integer moveCountInput = Integer.parseInt(moveCountInputView.input());

CarListParser parser = new CarListParser(carListInput);
List<Car> carList = parser.parsingData();

WinnerSelector winnerSelector = new WinnerSelector(carList, moveCountInput);
winnerSelector.racing();
winnerSelector.selectWinners();

WinnersOutputView winnersOutputView = new WinnersOutputView(winnerSelector);
winnersOutputView.print();
}
}
31 changes: 31 additions & 0 deletions src/main/java/racingcar/model/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package racingcar.model;

import camp.nextstep.edu.missionutils.Randoms;

public class Car {
private final String name;
private Integer distance;

public Car(String name){
this.name = name;
this.distance = 0;
}

public void moveForward(){
if(isMoveForward()){
this.distance++;
}
}

private boolean isMoveForward(){
return Randoms.pickNumberInRange(0, 9) >= 4;
}

public String getName() {
return name;
}

public Integer getDistance() {
return distance;
}
}
22 changes: 22 additions & 0 deletions src/main/java/racingcar/model/CarListParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package racingcar.model;

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

public class CarListParser {
private final String input;

public CarListParser(String input){
this.input = input;
}

public List<Car> parsingData(){
List<Car> carList = new ArrayList<>();

for(String carName: input.split(",")){
carList.add(new Car(carName.trim()));
}

return carList;
}
}
53 changes: 53 additions & 0 deletions src/main/java/racingcar/model/WinnerSelector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package racingcar.model;

import racingcar.view.outputView.ProgressOutputView;

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

public class WinnerSelector {
private final List<Car> carList;
private final List<Car> winners;
private final Integer moveCount;
private final ProgressOutputView progressOutputView;

public WinnerSelector(List<Car> carList, Integer moveCount){
this.carList = carList;
this.moveCount = moveCount;
this.winners = new ArrayList<>();
this.progressOutputView = new ProgressOutputView(carList);
}

public void racing(){
for(int i = 0; i < moveCount; i++){
for(Car car: carList){
car.moveForward();
}
progressOutputView.print();
}
}

public void selectWinners(){
Integer maxDistance = Integer.MIN_VALUE;

for(Car car: carList){
maxDistance = selectWinner(car, maxDistance);
}
}

private Integer selectWinner(Car car, Integer maxDistance){
if(car.getDistance() > maxDistance){
winners.clear();
winners.add(car);
}
else if(car.getDistance() == maxDistance){
winners.add(car);
}

return Math.max(car.getDistance(), maxDistance);
}

public List<Car> getWinners() {
return winners;
}
}
43 changes: 43 additions & 0 deletions src/main/java/racingcar/model/validator/CarNameValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package racingcar.model.validator;

public class CarNameValidator {
private static final String EMPTY_NAME_ERROR_MESSAGE = "빈 이름은 입력 할 수 없습니다.";
private static final String START_OR_END_WITH_COMMA_ERROR_MESSAGE = "이름 리스트는 쉼표로 끝나거나 시작 할 수 없습니다.";
private static final String NAME_LENGTH_OVER_FIVE_ERROR_MESSAGE = "자동차 이름은 5자를 넘을 수 없습니다.";

private String input;

public boolean isValidate(String input){
this.input = input;

startOrEndWithComma();
containsEmptyName();
carNameLengthOverFive();

return true;
}

private void startOrEndWithComma(){
if(input.startsWith(",") || input.endsWith(",")) {
throw new IllegalArgumentException(START_OR_END_WITH_COMMA_ERROR_MESSAGE);
}
}

private void containsEmptyName(){
if(input.replaceAll("\\s+", "").contains(",,")) {
throw new IllegalArgumentException(EMPTY_NAME_ERROR_MESSAGE);
}
}

private void carNameLengthOverFive(){
for(String carName: input.split(",")){
if(carName.trim().length() > 5){
throw new IllegalArgumentException(NAME_LENGTH_OVER_FIVE_ERROR_MESSAGE);
}
}
}

public void setInput(String input) {
this.input = input;
}
}
5 changes: 5 additions & 0 deletions src/main/java/racingcar/model/validator/InputValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package racingcar.model.validator;

public interface InputValidator {
public void isValidate();
}
39 changes: 39 additions & 0 deletions src/main/java/racingcar/model/validator/MoveCountValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package racingcar.model.validator;

public class MoveCountValidator {
private static final String INPUT_NOT_NUMBER_ERROR_MESSAGE = "이동 횟수는 숫자만 입력 할 수 있습니다.";
private static final String INPUT_MINUS_NUMBER_ERROR_MESSAGE = "이동 횟수에는 음수를 입력 할 수 없습니다.";
private static final String INPUT_NUMBER_OVER_RANGE_ERROR_MESSAGE = "이동 횟수는"+Integer.MAX_VALUE +"범위를 넘을 수 없습니다.";

private String input;

public boolean isValidate(String input){
this.input = input;

isNumber();
isMinus();
isInRange();

return true;
}

private void isNumber(){
if(!input.matches("-?[0-9]+")){
throw new IllegalArgumentException(INPUT_NOT_NUMBER_ERROR_MESSAGE);
}
}

private void isMinus(){
if(input.startsWith("-")){
throw new IllegalArgumentException(INPUT_MINUS_NUMBER_ERROR_MESSAGE);
}
}

private void isInRange(){
try{
Integer.parseInt(input);
}catch (Exception e){
throw new IllegalArgumentException(INPUT_NUMBER_OVER_RANGE_ERROR_MESSAGE);
}
}
}
30 changes: 30 additions & 0 deletions src/main/java/racingcar/view/inputView/CarNameInputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package racingcar.view.inputView;

import camp.nextstep.edu.missionutils.Console;
import racingcar.model.validator.CarNameValidator;

public class CarNameInputView implements InputView {
private static final String CAR_NAME_INPUT_MESSAGE= "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)";

private final CarNameValidator validator;

public CarNameInputView(){
this.validator = new CarNameValidator();
}

@Override
public String input(){
System.out.println(CAR_NAME_INPUT_MESSAGE);

String input = Console.readLine();

isValidate(input);

return input;
}

@Override
public void isValidate(String input) {
validator.isValidate(input);
}
}
6 changes: 6 additions & 0 deletions src/main/java/racingcar/view/inputView/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package racingcar.view.inputView;

public interface InputView {
public String input();
public void isValidate(String input);
}
29 changes: 29 additions & 0 deletions src/main/java/racingcar/view/inputView/MoveCountInputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package racingcar.view.inputView;

import camp.nextstep.edu.missionutils.Console;
import racingcar.model.validator.MoveCountValidator;

public class MoveCountInputView implements InputView {
private static final String MOVE_COUNT_INPUT_MESSAGE = "시도할 횟수는 몇 회인가요?";

private final MoveCountValidator validator;

public MoveCountInputView(){
this.validator = new MoveCountValidator();
}

@Override
public String input(){
System.out.println(MOVE_COUNT_INPUT_MESSAGE);
String input = Console.readLine();

isValidate(input);

return input;
}

@Override
public void isValidate(String input) {
validator.isValidate(input);
}
}
5 changes: 5 additions & 0 deletions src/main/java/racingcar/view/outputView/OutputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package racingcar.view.outputView;

public interface OutputView {
public void print();
}
27 changes: 27 additions & 0 deletions src/main/java/racingcar/view/outputView/ProgressOutputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package racingcar.view.outputView;

import racingcar.model.Car;

import java.util.List;

public class ProgressOutputView implements OutputView {
private List<Car> carList;

public ProgressOutputView(List<Car> carList){
this.carList = carList;
}

public void print() {
for(Car car: carList){
System.out.println(makePrintFormat(car));
}

System.out.println();
}

private String makePrintFormat(Car car){
String format = String.format("%s : %s", car.getName(), "-".repeat(car.getDistance()));

return format;
}
}
Loading