-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
3단계 자동차 경주 #5351
base: hj-rich
Are you sure you want to change the base?
3단계 자동차 경주 #5351
Changes from all commits
4a34587
8665775
74a5216
26830d5
011b986
9a6465f
8d8e1dd
b90d914
45a61db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package racingcar; | ||
|
||
import racingcar.application.RacingCarGame; | ||
import racingcar.domain.CarMoveGenerator; | ||
import racingcar.domain.SixtyPercentAdvanceGenerator; | ||
import racingcar.presentation.ConsoleRacingCarClient; | ||
import racingcar.presentation.RacingCarClient; | ||
|
||
public class Main { | ||
public static void main(String[] args) { | ||
final RacingCarClient racingCarClient = new ConsoleRacingCarClient(); | ||
final CarMoveGenerator randomCarMoveGenerator = new SixtyPercentAdvanceGenerator(); | ||
|
||
final RacingCarGame racingCarGame = new RacingCarGame(racingCarClient, randomCarMoveGenerator); | ||
racingCarGame.play(); | ||
} | ||
Comment on lines
+10
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. view 를 잘 분리해서 구현해주셨네요 👍 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package racingcar.application; | ||
|
||
import racingcar.domain.Car; | ||
import racingcar.domain.CarMoveGenerator; | ||
import racingcar.domain.Cars; | ||
import racingcar.domain.dto.RacingCarRequest; | ||
import racingcar.domain.dto.RacingCarResult; | ||
import racingcar.domain.vo.NumberOfCars; | ||
import racingcar.domain.vo.NumberOfTrials; | ||
import racingcar.presentation.RacingCarClient; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
public class RacingCarGame { | ||
private final RacingCarClient racingCarClient; | ||
private final CarMoveGenerator carMoveGenerator; | ||
|
||
public RacingCarGame(final RacingCarClient racingCarClient, final CarMoveGenerator carMoveGenerator) { | ||
this.racingCarClient = racingCarClient; | ||
this.carMoveGenerator = carMoveGenerator; | ||
} | ||
|
||
public void play() { | ||
final RacingCarRequest racingCarInput = racingCarClient.getRacingCarInput(); | ||
final Cars cars = createCars(racingCarInput); | ||
|
||
final NumberOfTrials numberOfTrials = racingCarInput.getNumberOfTrials(); | ||
|
||
racingCarClient.showResultHeader(); | ||
playRounds(numberOfTrials, cars); | ||
} | ||
Comment on lines
+25
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 자동차 경주의 핵심기능인 play 에 대한 테스트가 없네요..! 🤔 |
||
|
||
private Cars createCars(final RacingCarRequest racingCarRequest) { | ||
final NumberOfCars numberOfCars = racingCarRequest.getNumberOfCars(); | ||
final List<Car> car = createCar(numberOfCars.getValue()); | ||
|
||
return new Cars(car); | ||
} | ||
|
||
private List<Car> createCar(final int value) { | ||
return IntStream.rangeClosed(1, value) | ||
.mapToObj(i -> new Car()) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private void playRounds(final NumberOfTrials numberOfTrials, final Cars cars) { | ||
for (int i = 0; i < numberOfTrials.getValue(); i++) { | ||
cars.tryAdvance(this.carMoveGenerator); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 전략패턴을 통해 잘 구현해주셨네요 👏 지금은 RacingGame 전체가 하나의 전략으로 동작하게 구현하셨는데, 각각의 Car가 다른 전략을 구현해서 사용할수도 있을것 같아요! 요구사항중 어떤차량은 30% 확률로 전진하고, 어떤 차량은 90% 확률로 전진한다면 이런 구조가 더 알맞을 수도 있을것 같아요! 그리고 외부에서 전진하는 차량만 만들어서 RacingGame 에 전달한다면, Play에 대한 테스트도 수월할지도 모르곘어요 🤔 |
||
final RacingCarResult racingCarResult = new RacingCarResult(cars.getCars()); | ||
racingCarClient.showRacingCarResult(racingCarResult); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package racingcar.domain; | ||
|
||
public class Car { | ||
private int position = 1; | ||
|
||
public void advance(final boolean advance) { | ||
if (advance) { | ||
this.position++; | ||
} | ||
} | ||
|
||
public int getPosition() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 객체지향 생활 체조 원칙 게터를 사용하셨군요!! getPositionForPrint() 와 같이 변경해서 사용합니다 :) 지금은 현재 위치를 리턴하는거니 |
||
return position; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package racingcar.domain; | ||
|
||
@FunctionalInterface | ||
public interface CarMoveGenerator { | ||
boolean advance(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package racingcar.domain; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class Cars { | ||
private final List<Car> cars; | ||
|
||
public Cars(final List<Car> cars) { | ||
if (cars == null || cars.isEmpty()) { | ||
throw new RuntimeException("자동차 목록이 비어있습니다"); | ||
} | ||
|
||
this.cars = new ArrayList<>(cars); | ||
} | ||
|
||
public void tryAdvance(final CarMoveGenerator carMoveGenerator) { | ||
cars.forEach(car -> car.advance(carMoveGenerator.advance())); | ||
} | ||
|
||
public List<Car> getCars() { | ||
return cars; | ||
} | ||
Comment on lines
+21
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 일급컬렉션으로 작성해주셨네요! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package racingcar.domain; | ||
|
||
import java.util.Random; | ||
|
||
public class SixtyPercentAdvanceGenerator implements CarMoveGenerator { | ||
private static final int UPPER_BOUND_EXCLUSIVE = 10; | ||
private static final int ADVANCE_STANDARD = 4; | ||
private final Random random = new Random(); | ||
|
||
@Override | ||
public boolean advance() { | ||
return random.nextInt(UPPER_BOUND_EXCLUSIVE) >= ADVANCE_STANDARD; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package racingcar.domain.dto; | ||
|
||
import racingcar.domain.vo.NumberOfCars; | ||
import racingcar.domain.vo.NumberOfTrials; | ||
|
||
public class RacingCarRequest { | ||
private final NumberOfCars numberOfCars; | ||
private final NumberOfTrials numberOfTrials; | ||
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 원시값 포장 👍 |
||
|
||
public RacingCarRequest(final NumberOfCars numberOfCars, final NumberOfTrials numberOfTrials) { | ||
this.numberOfCars = numberOfCars; | ||
this.numberOfTrials = numberOfTrials; | ||
} | ||
|
||
public NumberOfCars getNumberOfCars() { | ||
return numberOfCars; | ||
} | ||
|
||
public NumberOfTrials getNumberOfTrials() { | ||
return numberOfTrials; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package racingcar.domain.dto; | ||
|
||
import racingcar.domain.Car; | ||
|
||
import java.util.List; | ||
|
||
public class RacingCarResult { | ||
private final List<Car> cars; | ||
|
||
public RacingCarResult(final List<Car> cars) { | ||
this.cars = cars; | ||
} | ||
|
||
public List<Car> getCars() { | ||
return cars; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package racingcar.domain.vo; | ||
|
||
public class NumberOfCars { | ||
private final int value; | ||
|
||
private NumberOfCars(final int value) { | ||
this.value = value; | ||
} | ||
|
||
public static NumberOfCars from(final int numberOfCar) { | ||
if (numberOfCar < 1) { | ||
throw new RuntimeException("자동차는 1대 이상이어야 합니다"); | ||
} | ||
|
||
return new NumberOfCars(numberOfCar); | ||
} | ||
|
||
public int getValue() { | ||
return value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package racingcar.domain.vo; | ||
|
||
public class NumberOfTrials { | ||
private final int value; | ||
|
||
private NumberOfTrials(final int value) { | ||
this.value = value; | ||
} | ||
|
||
public static NumberOfTrials from(final int numberOfTrial) { | ||
if (numberOfTrial < 1) { | ||
throw new RuntimeException("시도 횟수는 1회 이상이어야 합니다"); | ||
} | ||
|
||
return new NumberOfTrials(numberOfTrial); | ||
} | ||
|
||
public int getValue() { | ||
return value; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package racingcar.presentation; | ||
|
||
import racingcar.domain.Car; | ||
import racingcar.domain.dto.RacingCarRequest; | ||
import racingcar.domain.dto.RacingCarResult; | ||
import racingcar.domain.vo.NumberOfCars; | ||
import racingcar.domain.vo.NumberOfTrials; | ||
|
||
import java.util.List; | ||
import java.util.Scanner; | ||
|
||
public class ConsoleRacingCarClient implements RacingCarClient { | ||
private static final String LINE_SEPARATOR = System.lineSeparator(); | ||
private static final String PROGRESS_CHARACTER = "-"; | ||
private static final String MESSAGE_FOR_CAR_INPUT_REQUEST = "자동차 대수는 몇 대 인가요?"; | ||
private static final String MESSAGE_FOR_TRIAL_INPUT_REQUEST = "시도할 회수는 몇 회 인가요?"; | ||
private static final String MESSAGE_FOR_INVALID_CAR_INPUT = "자동차 대수를 양의 숫자로 입력해주세요 : %s"; | ||
private static final String MESSAGE_FOR_INVALID_TRIAL_INPUT = "시도 횟수를 양의 숫자로 입력해주세요 : %s"; | ||
private static final String RESULT_HEADER = "%s실행 결과%s"; | ||
private final Scanner scanner = new Scanner(System.in); | ||
|
||
@Override | ||
public RacingCarRequest getRacingCarInput() { | ||
final NumberOfCars numberOfCars = getNumberOfCars(); | ||
final NumberOfTrials numberOfTrials = getNumberOfTrials(); | ||
scanner.close(); | ||
|
||
return new RacingCarRequest(numberOfCars, numberOfTrials); | ||
} | ||
|
||
private NumberOfCars getNumberOfCars() { | ||
System.out.println(MESSAGE_FOR_CAR_INPUT_REQUEST); | ||
final String input = scanner.nextLine(); | ||
try { | ||
final int parsed = Integer.parseInt(input); | ||
return NumberOfCars.from(parsed); | ||
} catch (NumberFormatException e) { | ||
throw new RuntimeException(String.format(MESSAGE_FOR_INVALID_CAR_INPUT, input), e); | ||
} | ||
} | ||
|
||
private NumberOfTrials getNumberOfTrials() { | ||
System.out.println(MESSAGE_FOR_TRIAL_INPUT_REQUEST); | ||
final String input = scanner.nextLine(); | ||
try { | ||
final int parsed = Integer.parseInt(input); | ||
return NumberOfTrials.from(parsed); | ||
} catch (NumberFormatException e) { | ||
throw new RuntimeException(String.format(MESSAGE_FOR_INVALID_TRIAL_INPUT, input), e); | ||
} | ||
} | ||
|
||
@Override | ||
public void showResultHeader() { | ||
System.out.printf(RESULT_HEADER, LINE_SEPARATOR, LINE_SEPARATOR); | ||
} | ||
|
||
@Override | ||
public void showRacingCarResult(final RacingCarResult racingCarResult) { | ||
final List<Car> cars = racingCarResult.getCars(); | ||
cars.forEach(car -> System.out.println(PROGRESS_CHARACTER.repeat(car.getPosition()))); | ||
|
||
System.out.println(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package racingcar.presentation; | ||
|
||
import racingcar.domain.dto.RacingCarRequest; | ||
import racingcar.domain.dto.RacingCarResult; | ||
|
||
public interface RacingCarClient { | ||
RacingCarRequest getRacingCarInput(); | ||
|
||
void showResultHeader(); | ||
|
||
void showRacingCarResult(RacingCarResult result); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍