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
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@
- 미션은 **기능 요구사항, 프로그래밍 요구사항, 과제 진행 요구사항** 세 가지로 구성되어 있다.
- 세 개의 요구사항을 만족하기 위해 노력한다. 특히 기능을 구현하기 전에 기능 목록을 만들고, 기능 단위로 커밋 하는 방식으로 진행한다.



## 기능 목록
- 게임
- 주어진 횟수 동안 게임을 진행한다.
- 심판
- 우승자를 판단한다
- 화면
- 경주할 자동차 이름을 입력하라는 메시지를 출력한다.
- 각 차수별 실행 결과를 출력한다.
- 시도할 회수를 입력하라는 메시지를 출력한다.
- 최종 우승자를 출력한다.
- 자동차
- 이름을 설정한다.
- 전진 또는 멈춘다.
- 자신의 이름과 위치를 반환한다.
- 유효성 검사기
- 사용자가 잘못된 값을 입력한지 판단한다.
- 시도 횟수로 정수가 아닌 값을 입력한 경우
- 자동차 이름이 5를 넘어가는 경우


## ✉️ 미션 제출 방법

- 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다.
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public class Application {
public static void main(String[] args) {
// TODO 구현 진행
Game game = new Game();
game.proceed();
}
}
13 changes: 13 additions & 0 deletions src/main/java/racingcar/Car.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package racingcar;

import camp.nextstep.edu.missionutils.Randoms;

public class Car {
private final String name;
private int position = 0;
Expand All @@ -9,4 +11,15 @@ public Car(String name) {
}

// 추가 기능 구현
public void move() {
int randomNumber = Randoms.pickNumberInRange(0, 9);

if (randomNumber >= 4) {
position += 1;
}
}

public CarState getCarState() {
return new CarState(name, position);
}
}
31 changes: 31 additions & 0 deletions src/main/java/racingcar/CarState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package racingcar;

public class CarState {
private final String name;

private final int position;

public CarState(String name, int position) {
this.name = name;
this.position = position;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}

@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(name);
stringBuilder.append(" : ");
for (int i = 0; i < position; i++) {
stringBuilder.append("-");
}
return stringBuilder.toString();
}
}
107 changes: 107 additions & 0 deletions src/main/java/racingcar/Game.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package racingcar;

import camp.nextstep.edu.missionutils.Console;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

public class Game {

private List<Car> cars;

private Referee referee;

private int leftTrialTimes;


public void proceed() {
initializeProperty();
doBeforeRun();
while (leftTrialTimes > 0) {
run();
}
close();
}

private void initializeProperty() {
initializeCar();
initializeReferee();
initializeTrialTimes();
}

private void initializeCar() {
View.print(Message.INPUT_CAR_NAME);
String inputCarNames = Console.readLine();
String[] carNames = inputCarNames.split(",");

try {
Validator.checkCarNameLength(carNames);
createCars(carNames);
} catch (IllegalArgumentException e) {
View.print(e.getMessage());
initializeCar();
}
}

private void createCars(String[] carNames) {
cars = new LinkedList<>();
for (String carName : carNames) {
cars.add(new Car(carName));
}
}

private void initializeReferee() {
referee = new Referee();
}

private void initializeTrialTimes() {
View.print(Message.INQUIRY_TRY_TIMES);
String inputTryTimes = Console.readLine();

try {
Validator.checkTypeConverting(inputTryTimes);
leftTrialTimes = Integer.parseInt(inputTryTimes);
} catch (IllegalArgumentException e) {
View.print(e.getMessage());
initializeTrialTimes();
}
}

private void doBeforeRun() {
printInitialMessage();
}

private void printInitialMessage() {
View.print(Message.EXECUTION_RESULT);
}

private void run() {
moveCars();
printCarStates();
decreaseTrialTimes();
}

private void moveCars() {
for(Car car: cars) {
car.move();
}
}

private void printCarStates() {
List<CarState> carStates = cars.stream().map(it -> it.getCarState()).collect(Collectors.toList());
View.print(carStates);
}

private void decreaseTrialTimes() {
leftTrialTimes -= 1;
}

private void close() {
JudgementResult judgementResult = referee.judge(cars);
printWinner(judgementResult);
}

private void printWinner(JudgementResult judgementResult) {
View.print(judgementResult);
}
}
16 changes: 16 additions & 0 deletions src/main/java/racingcar/JudgementResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package racingcar;

import java.util.List;

public class JudgementResult {

private List<String> winnerNames;

public JudgementResult(List<String> winnerNames) {
this.winnerNames = winnerNames;
}

public List<String> getWinnerNames() {
return winnerNames;
}
}
24 changes: 24 additions & 0 deletions src/main/java/racingcar/Message.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package racingcar;

public enum Message {

INPUT_CAR_NAME("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"),

INQUIRY_TRY_TIMES("시도할 회수는 몇회인가요?"),

EXECUTION_RESULT("실행 결과"),

CAR_NAME_LENGTH_ERROR("[ERROR] 자동차 이름은 5자 이하만 가능하다."),
TRIAL_TIMES_NOT_NUMBER_ERROR("[ERROR] 시도 횟수는 숫자여야 한다.");


private String body;

Message(String body) {
this.body = body;
}

public String getBody() {
return this.body;
}
}
13 changes: 13 additions & 0 deletions src/main/java/racingcar/Referee.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package racingcar;

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

public class Referee {

public JudgementResult judge(List<Car> cars) {
int maxPosition = cars.stream().mapToInt(car -> car.getCarState().getPosition()).max().orElse(-1);
List<String> winnerCarNames = cars.stream().filter(it -> it.getCarState().getPosition() == maxPosition).map(it -> it.getCarState().getName()).collect(Collectors.toList());
return new JudgementResult(winnerCarNames);
}
}
23 changes: 23 additions & 0 deletions src/main/java/racingcar/Validator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package racingcar;

import java.util.Arrays;

import static racingcar.Message.CAR_NAME_LENGTH_ERROR;
import static racingcar.Message.TRIAL_TIMES_NOT_NUMBER_ERROR;

public class Validator {

public static void checkTypeConverting(String input) {
if (input == null || !input.matches("[0-9]+")) {
throw new IllegalArgumentException(TRIAL_TIMES_NOT_NUMBER_ERROR.getBody());
}
}

public static void checkCarNameLength(String[] names) {
boolean isCarNameLengthOverFive = Arrays.stream(names).anyMatch(it -> it.length() > 5);

if (isCarNameLengthOverFive) {
throw new IllegalArgumentException(CAR_NAME_LENGTH_ERROR.getBody());
}
}
}
25 changes: 25 additions & 0 deletions src/main/java/racingcar/View.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package racingcar;

import java.util.List;

public class View {

public static void print(String message) {
System.out.println(message);
}
public static void print(Message message) {
System.out.println(message.getBody());
}

public static void print(List<CarState> carStates) {
for (CarState carState : carStates) {
System.out.println(carState);
}
System.out.println();
}

public static void print(JudgementResult judgementResult) {
String winnerMessage = "최종 우승자 : " + String.join(", ", judgementResult.getWinnerNames());
System.out.println(winnerMessage);
}
}