-
Notifications
You must be signed in to change notification settings - Fork 451
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[1단계 - 자동차 경주 구현] 저문(유정훈) 미션 제출합니다. (#519)
* test: 페어와 JUnit 학습하기 * docs: 기능 목록 초안 정리 * feat: 입력받는 기능 추가 * feat: 쉼표를 기준으로 이름을 받아 자동차를 생성하는 기능 추가 * feat: 자동차 이름 길이에 대한 예외처리 * test: 자동차 이름 길이 예외처리에 대한 테스트 * feat: 시도 횟수는 양수로만 가능하도록 예외처리 * feat: 랜덤 값을 받아 자동자 위치를 이동하는 기능 추가 * test: 값에 따른 자동차 위치를 이동하는 테스트 * feat: 최종 우승 자동차를 확인하는 기능 추가 * feat: 최종 결과를 가져오는 기능 추가 * feat: 각 자동차별 경주 실행결과 출력 기능 추가 * feat: 최종 우승 자동차 출력 기능 추가 * feat: 컨트롤러 프로그램 실행 로직 추가 * docs: 기능 목록 정리 최신화 * feat: 자동차 경주 시도 횟수는 1~100으로 제한하는 기능 추가 * refactor: 예외 메시지 추가 및 메소드 분리 * style: 전체적인 코드 스타일 수정 * refactor: 하드 코딩된 값을 제거 * test: CarGroup에 대한 테스트 * test: Car에 대한 테스트 * test: RacingResult에 대한 테스트 * docs: 기능 목록 정리 최신화 * style: 전체적인 코드 스타일 수정 * refactor: 예외 발생 시 그 부분부터 다시 입력을 받는 기능 수정 * refactor: 테스트 코드 접근자 제거 * refactor: RandomNumberGenerator를 NumberGenerator를 implement하도록 구현 * refactor: CarTest에서의 Car를 전진하도록 하는 메서드의 설계 변경으로 인한 코드 수정 * refactor: RacingGame객체의 생성을 controller로 이전 * refactor: RacingGame의 race메서드 로직을 CarGroup으로 이전 * refactor: CarGroup의 setUp메소드가 List를 반환하도록 수정 * refactor: Car클래스 getter위치 변경 * refactor: getter와 혼동될 수 있는 메서드 네이밍 변경 * refactor: Car에서 move의 매개변수를 boolean타입으로 변경 * refactor: 정규표현식 성능 개선을 위해 메서드 변경 * refactor: NumberGenerator인터페이스 삭제 후 RandomNumberGenerator만으로 운영되도록 변경 * refactor: CarTest의 test로직 변경에 따라 DisplayName변경
- Loading branch information
Showing
17 changed files
with
613 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package racing; | ||
|
||
import java.io.IOException; | ||
|
||
import racing.controller.RacingGameController; | ||
|
||
public class Application { | ||
|
||
public static void main(String[] args) throws IOException { | ||
RacingGameController racingGameController = new RacingGameController(); | ||
racingGameController.run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package racing.controller; | ||
|
||
import java.io.IOException; | ||
|
||
import racing.domain.RacingGame; | ||
import racing.handler.InputHandler; | ||
import racing.view.OutputView; | ||
|
||
public class RacingGameController { | ||
|
||
private final InputHandler inputHandler; | ||
private final OutputView outputView; | ||
|
||
public RacingGameController() { | ||
this.inputHandler = new InputHandler(); | ||
this.outputView = new OutputView(); | ||
} | ||
|
||
public void run() throws IOException { | ||
String[] carNames = inputHandler.readCars(); | ||
int movingTrial = inputHandler.readMovingTrial(); | ||
|
||
RacingGame racingGame = new RacingGame(carNames); | ||
|
||
outputView.printNotice(); | ||
raceWithHistory(movingTrial, racingGame); | ||
outputView.printWinner(racingGame.produceRacingResult().pickWinner()); | ||
} | ||
|
||
private void raceWithHistory(int movingTrial, RacingGame racingGame) { | ||
//TODO: 인덱스를 쓰지 않는데 개선할 방법 | ||
for (int i = 0; i < movingTrial; i++) { | ||
racingGame.race(); | ||
|
||
outputView.printRacingResult(racingGame.produceRacingResult().getHistory()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package racing.domain; | ||
|
||
public class Car { | ||
|
||
private static final int INITIAL_VALUE = 0; | ||
private static final int MINIMUM_LENGTH_OF_CAR_NAME = 1; | ||
private static final int MAXIMUM_LENGTH_OF_CAR_NAME = 5; | ||
private static final String LENGTH_OF_CAR_NAME_ERROR = "[ERROR] 자동차이름의 길이는 1-5자까지 가능합니다."; | ||
|
||
private final String name; | ||
private int position; | ||
|
||
public Car(String name) { | ||
validateLengthOfName(name); | ||
this.name = name; | ||
this.position = INITIAL_VALUE; | ||
} | ||
|
||
public void move(boolean isMovable) { | ||
if (isMovable) { | ||
this.position++; | ||
} | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public int getPosition() { | ||
return position; | ||
} | ||
|
||
private void validateLengthOfName(String name) { | ||
if (name.length() < MINIMUM_LENGTH_OF_CAR_NAME || name.length() > MAXIMUM_LENGTH_OF_CAR_NAME) { | ||
throw new IllegalArgumentException(LENGTH_OF_CAR_NAME_ERROR); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package racing.domain; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
//TODO: ERROR 패키지 분리 | ||
public class CarGroup { | ||
|
||
private static final String DUPLICATED_CAR_NAME_ERROR = "[ERROR] 자동차 이름에는 중복이 허용되지 않습니다."; | ||
private static final String RANGE_OF_CAR_GROUP_ERROR = "[ERROR] 자동차 대수는 2-50대 사이입니다."; | ||
private static final int MINIMUM_NUMBER_OF_CARS = 2; | ||
private static final int MAXIMUM_NUMBER_OF_CARS = 50; | ||
|
||
private final List<Car> cars; | ||
|
||
public CarGroup(String[] names){ | ||
validateDuplicatedName(names); | ||
validateNumberOfCars(names); | ||
this.cars = setUp(names); | ||
} | ||
|
||
public void race(boolean isMovable) { | ||
for (Car car : cars) { | ||
car.move(isMovable); | ||
} | ||
} | ||
|
||
public List<Car> getCars() { | ||
return cars; | ||
} | ||
|
||
private List<Car> setUp(String[] names) { | ||
return Arrays.stream(names) | ||
.map(Car::new) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private void validateDuplicatedName(String[] names) { | ||
if (names.length != Arrays.stream(names).distinct().count()) { | ||
throw new IllegalArgumentException(DUPLICATED_CAR_NAME_ERROR); | ||
} | ||
} | ||
|
||
private void validateNumberOfCars(String[] names) { | ||
if (names.length < MINIMUM_NUMBER_OF_CARS || names.length > MAXIMUM_NUMBER_OF_CARS){ | ||
throw new IllegalArgumentException(RANGE_OF_CAR_GROUP_ERROR); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package racing.domain; | ||
|
||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
public class RacingGame { | ||
|
||
private static final int MOVABLE_CONDITION = 4; | ||
|
||
private final CarGroup carGroup; | ||
private final RandomNumberGenerator numberGenerator; | ||
|
||
public RacingGame(String[] names) { | ||
this.carGroup = new CarGroup(names); | ||
this.numberGenerator = new RandomNumberGenerator(); | ||
} | ||
|
||
//TODO: 테스트 | ||
public void race() { | ||
carGroup.race(isMovable()); | ||
} | ||
|
||
public RacingResult produceRacingResult() { | ||
Map<String, Integer> history = new LinkedHashMap<>(); | ||
for (Car car : carGroup.getCars()) { | ||
history.put(car.getName(), car.getPosition()); | ||
} | ||
|
||
return new RacingResult(history); | ||
} | ||
|
||
private boolean isMovable() { | ||
return (numberGenerator.generate() >= MOVABLE_CONDITION); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package racing.domain; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
public class RacingResult { | ||
|
||
private final Map<String, Integer> history; | ||
|
||
public RacingResult(Map<String, Integer> history) { | ||
this.history = history; | ||
} | ||
|
||
public Map<String, Integer> getHistory() { | ||
return history; | ||
} | ||
|
||
public List<String> pickWinner() { | ||
Integer maxValue = Collections.max(history.values()); | ||
|
||
return history.entrySet() | ||
.stream() | ||
.filter(entry -> entry.getValue().equals(maxValue)) | ||
.map(Map.Entry::getKey) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package racing.domain; | ||
|
||
public class RandomNumberGenerator { | ||
|
||
public int generate(){ | ||
return (int)(Math.random() * 10); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package racing.handler; | ||
|
||
import java.io.IOException; | ||
import java.util.regex.Pattern; | ||
|
||
import racing.view.InputView; | ||
|
||
public class InputHandler { | ||
|
||
private static final String COMMA = ","; | ||
private static final Pattern REGEX = Pattern.compile("^[0-9]+$"); | ||
private static final int MINIMUM_LENGTH_OF_MOVING_TRIAL = 1; | ||
private static final int MAXIMUM_LENGTH_OF_MOVING_TRIAL = 100; | ||
private static final String MOVING_TRIAL_NOT_INTEGER_ERROR = "[ERROR] 시도할 횟수는 숫자만 가능합니다."; | ||
private static final String MOVING_TRIAL_RANGE_ERROR = "[ERROR] 시도할 횟수의 범위는 1이상 100이하만 가능합니다."; | ||
|
||
private final InputView inputView; | ||
|
||
public InputHandler() { | ||
this.inputView = new InputView(); | ||
} | ||
|
||
public String[] readCars() throws IOException { | ||
try { | ||
String inputName = inputView.readCarNames(); | ||
String[] names = inputName.split(COMMA); | ||
|
||
return names; | ||
} catch (IllegalArgumentException e) { | ||
System.out.println(e.getMessage()); | ||
return readCars(); | ||
} | ||
} | ||
|
||
public int readMovingTrial() throws IOException { | ||
try { | ||
String input = inputView.readMovingTrial(); | ||
validateInteger(input); | ||
int movingTrial = Integer.parseInt(input); | ||
validateTrialRange(movingTrial); | ||
|
||
return movingTrial; | ||
} catch (IllegalArgumentException e) { | ||
System.out.println(e.getMessage()); | ||
return readMovingTrial(); | ||
} | ||
} | ||
|
||
private void validateTrialRange(int movingTrial) { | ||
if (movingTrial < MINIMUM_LENGTH_OF_MOVING_TRIAL || movingTrial > MAXIMUM_LENGTH_OF_MOVING_TRIAL) { | ||
throw new IllegalArgumentException(MOVING_TRIAL_RANGE_ERROR); | ||
} | ||
} | ||
|
||
private void validateInteger(String movingTrial) { | ||
if (!REGEX.matcher(movingTrial).matches()) { | ||
throw new IllegalArgumentException(MOVING_TRIAL_NOT_INTEGER_ERROR); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package racing.util; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
|
||
public class InputUtil { | ||
|
||
public static String readLine() throws IOException { | ||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); | ||
|
||
return bufferedReader.readLine(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package racing.view; | ||
|
||
import java.io.IOException; | ||
|
||
import racing.util.InputUtil; | ||
|
||
public class InputView { | ||
|
||
private static final String CAR_NAME_INPUT_MESSAGE = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."; | ||
private static final String MOVING_TRIAL_INPUT_MESSAGE = "시도할 회수는 몇회인가요?"; | ||
|
||
public String readCarNames() throws IOException { | ||
System.out.println(CAR_NAME_INPUT_MESSAGE); | ||
|
||
return InputUtil.readLine(); | ||
} | ||
|
||
public String readMovingTrial() throws IOException { | ||
System.out.println(MOVING_TRIAL_INPUT_MESSAGE); | ||
|
||
return InputUtil.readLine(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package racing.view; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class OutputView { | ||
private static final String RESULT_MESSAGE = "\n실행 결과"; | ||
private static final String WINNER_MESSAGE = "%s가 최종 우승했습니다."; | ||
|
||
public void printNotice() { | ||
System.out.println(RESULT_MESSAGE); | ||
} | ||
|
||
public void printRacingResult(Map<String, Integer> history) { | ||
for (String name : history.keySet()) { | ||
Integer positionValue = history.get(name); | ||
System.out.println(name + " : " + "-".repeat(positionValue)); | ||
} | ||
System.out.println(); | ||
} | ||
|
||
public void printWinner(List<String> winners) { | ||
String winnerNames = winners.toString(); | ||
System.out.printf(WINNER_MESSAGE, winnerNames.substring(1, winnerNames.length()-1)); | ||
} | ||
} |
Oops, something went wrong.