Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seokwoo #2410

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

seokwoo #2410

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
5 changes: 4 additions & 1 deletion src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package racingcar;

import racingcar.controller.GameController;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
GameController controller = new GameController();
controller.start();
}
}
32 changes: 32 additions & 0 deletions src/main/java/racingcar/controller/GameController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package racingcar.controller;

import racingcar.domain.Race;
import racingcar.view.InputView;

import static racingcar.view.OutputView.*;

public class GameController {
public void start() {
PrintMessage(ASK_CAR_NAMES);
String carNames = InputView.InputCarNames();

Race race = new Race(carNames);

PrintMessage(ASK_NUMBER_OF_ATTEMPTS);
race.setAttempt(Integer.parseInt(InputView.InputAttemptNumber()));

play(race);
}

private static void play(Race race) {
PrintMessage(EXECUTION_RESULT);

do {
race.startRace();
PrintRaceResult(race);
} while(!race.isGameOver());

PrintFinalResult(race);
}

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

import camp.nextstep.edu.missionutils.Randoms;

import static racingcar.domain.Constant.MAX_RANDOM_NUMBER;
import static racingcar.domain.Constant.MIN_RANDOM_NUMBER;

public class Car {
private final String carName;
private int moveCount = 0;

// Race를 통해서만 생성 가능
protected Car(String carName) {
this.carName = carName;
}

public void attempt() {
if (isMoved()) moveCount++;
}

private static boolean isMoved() {
int randomNumber = Randoms.pickNumberInRange(MIN_RANDOM_NUMBER, MAX_RANDOM_NUMBER);
return randomNumber >= 4;
}

public int getMoveCount() {
return moveCount;
}

public String getCarName() {
return carName;
}
}
7 changes: 7 additions & 0 deletions src/main/java/racingcar/domain/Constant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package racingcar.domain;

public class Constant {
public static int MIN_RANDOM_NUMBER = 0;
public static int MAX_RANDOM_NUMBER = 9;
public static int MAX_CAR_NAME_LENGTH = 5;
}
65 changes: 65 additions & 0 deletions src/main/java/racingcar/domain/Race.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package racingcar.domain;

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

public class Race {
private final List<Car> cars;
private int attemptNum;

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

public Race(String carNames) {
this.cars = convertCarList(carNames);
}

private List<Car> convertCarList(String carNames) {
return Arrays.stream(carNames.split(","))
.map(Car::new)
.collect(Collectors.toList());
}

public void startRace() {
cars.forEach(Car::attempt);
attemptNum--;
}

public void setAttempt(int attemptNum) {
this.attemptNum = attemptNum;
}

public boolean isGameOver() {
return attemptNum == 0;
}

public String findWinner() {
List<Car> winners = new ArrayList<>();
int max = maximumMoveCount();

for (Car car : cars) {
if (car.getMoveCount() == max) winners.add(car);
}

return ListToString(winners);
}

private int maximumMoveCount() {
int max = 0;

for(Car car : cars) {
if(car.getMoveCount() > max) {
max = car.getMoveCount();
}
}

return max;
}

private String ListToString(List<Car> cars) {
return cars.stream().map(Car::getCarName).collect(Collectors.joining(", "));
}
}
48 changes: 48 additions & 0 deletions src/main/java/racingcar/validator/InputValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package racingcar.validator;

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

import static racingcar.domain.Constant.MAX_CAR_NAME_LENGTH;

public class InputValidator {
private final static String CAR_NAME_LENGTH_ERROR = "[ERROR] 5자 이상인 자동차 이름이 존재합니다.";
private final static String CAR_NAME_EMPTY_ERROR = "[ERROR] 올바른 자동차 이름을 입력해주세요. 자동차 이름에는 쉼표(,)가 들어갈 수 없습니다.";
private final static String ATTEMPT_NUMBER_ERROR = "[ERROR] 시도할 회수는 1이상 숫자만 유효합니다.";

public static void validateCarNameLength(String input) {
List<String> carNameList = Arrays.stream(input.split(","))
.collect(Collectors.toList());

for (String name : carNameList) {
if(!isValidNameLength(name)) throw new IllegalArgumentException(CAR_NAME_LENGTH_ERROR);
}
}

public static void validateCarNameEmpty(String input) {
List<String> carNameList = Arrays.stream(input.split(","))
.map(String::trim)
.collect(Collectors.toList());

for (String name : carNameList) {
if(isEmpty(name)) throw new IllegalArgumentException(CAR_NAME_EMPTY_ERROR);
}
}

public static void validateAttemptNumber(String input) {
if(!isValidAttemptNumber(input)) throw new IllegalArgumentException(ATTEMPT_NUMBER_ERROR);
}

private static boolean isValidNameLength(String name) {
return name.length() <= MAX_CAR_NAME_LENGTH;
}

private static boolean isEmpty(String input) {
return input.isEmpty();
}

private static boolean isValidAttemptNumber(String input) {
return input.chars().allMatch(Character::isDigit);
}
}
25 changes: 25 additions & 0 deletions src/main/java/racingcar/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package racingcar.view;

import racingcar.validator.InputValidator;

import static camp.nextstep.edu.missionutils.Console.readLine;


public class InputView {
public static String InputCarNames() {
String carNames = readLine();

InputValidator.validateCarNameLength(carNames);
InputValidator.validateCarNameEmpty(carNames);

return carNames;
}

public static String InputAttemptNumber() {
String attemptNumber = readLine();

InputValidator.validateAttemptNumber(attemptNumber);

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

import racingcar.domain.Car;
import racingcar.domain.Race;

import java.util.List;

import static java.lang.String.format;

public class OutputView {

public static final String ASK_CAR_NAMES = "경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)";
public static final String ASK_NUMBER_OF_ATTEMPTS = "시도할 회수는 몇회인가요?";
public static final String EXECUTION_RESULT = "\n실행 결과";
public static final String FINAL_RESULT = "최종 우승자 : %s";

public static void PrintMessage(String message) {
System.out.println(message);
}

public static void PrintRaceResult(Race race) {
List<Car> cars = race.getCars();

for (Car car : cars) {
String carName = car.getCarName();
int moveCount = car.getMoveCount();

System.out.println(format("%s : %s", carName, PrintLocation(moveCount)));
}

System.out.println();
}

private static String PrintLocation(int moveCount) {
String Position;

Position = "-".repeat(moveCount);

return Position;
}

public static void PrintFinalResult(Race race) {
String winners = race.findWinner();
System.out.println(format(FINAL_RESULT, winners));
}
}