-
Notifications
You must be signed in to change notification settings - Fork 442
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
[자동차경주] 유재건 미션 제출합니다. #523
base: main
Are you sure you want to change the base?
Changes from all commits
2582cec
8ab640b
3533fae
b2cd25d
2140df2
60daeed
89f1d4e
341f881
985255e
3379a80
96466cc
a46a553
8be9572
a625905
230b18f
71754a9
5eac4e9
4e5db3e
6c8e714
588c1b4
11b36eb
3ccb9fd
7d6eaad
4daf01b
92357f1
597c564
ac4002b
3f6a7ae
37e9f89
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,75 @@ | ||
## 🚀 기능목록 | ||
|
||
<<<<<<< HEAD | ||
## CAR | ||
|
||
- [x] 이름, 포지션 관리 | ||
- [x] 0 ~ 9 사이의 값을 입력받고 4 이상이면 포지션 이동 | ||
- [x] 이름과 포지션을 toString | ||
- [x] 포지션과 우승 포지션 비교 | ||
|
||
## CARS | ||
- [x] Car의 일급 컬렉션 | ||
- [x] 차의 이동, 턴당 출력문, 우승 출력문 관리 | ||
|
||
## CAR VENUE SERVICE | ||
|
||
- [x] 참가하는 자동차, 시도 횟수 관리 | ||
- [ ] .. | ||
|
||
## CAR POSITION OPERATOR | ||
|
||
- [x] 대회에 참가하는 차들의 한 턴당 포지션 값들 관리 | ||
|
||
## ROUND | ||
|
||
- [x] 우승 라운드와 현재 라운드 관리 | ||
|
||
## RANDOM NUMBER GENERATE(interface + class) | ||
|
||
- [x] 0~9 사이의 값을 생성 | ||
|
||
## NUMBER | ||
|
||
- [x] 대회의 무작위 값 범위 관리 | ||
- [x] 기준 값(4) 관리 | ||
|
||
## Message | ||
|
||
- [x] 출력문에 필요한 문자열 관리 | ||
|
||
## ErrorMessage | ||
|
||
- [x] 에러 출력문에 필요한 문자열 관리 | ||
|
||
## View | ||
|
||
- [x] 자동차 이름 입력 | ||
- [x] 시도할 횟수 입력 | ||
- [x] 한턴당 결과 출력 | ||
- [x] 우승자 출력 | ||
|
||
## Controller | ||
|
||
- [ ] 이름, 횟수, 결과출력, 우승자 출력의 흐름 제어 | ||
|
||
## Exception | ||
|
||
- [ ] Car의 이름이 1보다 작거나 5보다 크면 예외처리 | ||
- [ ] 시도할 횟수가 숫자가 아니면 예외처리 | ||
- | ||
======= | ||
|
||
## CAR | ||
- [ ] 이름, 포지션 관리 | ||
- [ ] 0 ~ 9 사이의 값을 입력받고 4 이상이면 포지션 이동 | ||
- [ ] 이름과 포지션을 toString으로 던져줌 | ||
- [ ] 포지션과 우승 포지션 비교, | ||
|
||
## CAR VENUE | ||
- [ ] 참가하는 자동차, 시도 횟수 관리 | ||
- [ ] 최종 우승자 관리, 다수이면 ","로 관리 | ||
|
||
## RANDOM NUMBER GENERATE | ||
- [ ] 0~9 사이의 값을 생성 | ||
>>>>>>> 2582cec307554d1cd318e15d23e6ad11db432f44 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
package racingcar; | ||
|
||
import racingcar.controller.RacingCarController; | ||
|
||
public class Application { | ||
public static void main(String[] args) { | ||
// TODO 구현 진행 | ||
new RacingCarController().play(); | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package racingcar.controller; | ||
|
||
import racingcar.domain.Car; | ||
import racingcar.domain.Cars; | ||
import racingcar.service.CarVenueService; | ||
import racingcar.view.View; | ||
|
||
import java.util.List; | ||
|
||
import static racingcar.message.Message.ESCAPE_SEQUENCE; | ||
|
||
public class RacingCarController { | ||
private final View view = new View(); | ||
|
||
public void play() { | ||
List<Car> cars = view.inputCar(); | ||
int round = view.inputRound(); | ||
CarVenueService carVenueService = new CarVenueService(cars, round); | ||
moveAndPrint(carVenueService); | ||
} | ||
|
||
private void moveAndPrint(CarVenueService carVenueService) { | ||
StringBuilder print = new StringBuilder(); | ||
while (!carVenueService.isEnd()) { | ||
carVenueService.moveTurn(); | ||
print.append(carVenueService.printTurn() + ESCAPE_SEQUENCE.getMessage()); | ||
} | ||
view.printResult(print.toString()); | ||
whoIsWinner(carVenueService); | ||
} | ||
private void whoIsWinner(CarVenueService carVenueService){ | ||
view.printWinner(carVenueService.printWinner()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package racingcar.domain; | ||
|
||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
import static racingcar.message.ErrorMessage.CAR_NAME_TOO_LONG; | ||
import static racingcar.message.Message.*; | ||
import static racingcar.util.NumberManager.NAME_MIN_LENGTH; | ||
import static racingcar.util.NumberManager.STANDARD_NUMBER; | ||
|
||
public class Car { | ||
private final int maxNameSize = 5; | ||
private final String name; | ||
private int position = 0; | ||
|
||
|
||
public Car(String name) { | ||
validate(name); | ||
this.name = name; | ||
} | ||
|
||
private void validate(String name) { | ||
if (name.length() > maxNameSize || name.length() < NAME_MIN_LENGTH.getNumber()) { | ||
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. MIN_LENGTH 보다는 null check 혹은 StringUtils.isEmpty(); 를 사용하는건 어떨까요 |
||
throw new IllegalArgumentException(CAR_NAME_TOO_LONG.getMessage()); | ||
} | ||
} | ||
|
||
// 추가 기능 구현 | ||
public void move(int moveInput) { | ||
if (moveInput >= STANDARD_NUMBER.getNumber()) position++; | ||
} | ||
|
||
public int getPosition() { | ||
return position; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
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. 관련해서 비슷한 내용의 리뷰가 있어 공유드립니다 |
||
StringBuilder print = new StringBuilder(name); | ||
appendPosition(print); | ||
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. StringJoiner를 사용하면 더 간결하게 표현할 수 있습니다 // ex
StringJoiner joiner = new StringJoiner(INFIX.getMessage());
String positionToMessage = doSomething();
joiner.add(name, positionToMessage); |
||
return print.toString(); | ||
} | ||
|
||
private void appendPosition(StringBuilder print) { | ||
print.append(INFIX.getMessage()); | ||
print.append(IntStream.range(0, position).mapToObj(i -> POSITION.getMessage()).collect(Collectors.joining())); | ||
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. 저도 이번에 처음알았는데 Java 11에서 String.repeat()라는 함수가 있더라고요 String positionToMessage = "-".repeat(position); 이렇게 하면 해당 문자열을 position번 반복할수있습니다! |
||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package racingcar.domain; | ||
|
||
import racingcar.message.Message; | ||
import racingcar.util.CarOperator; | ||
|
||
import java.util.List; | ||
import java.util.StringJoiner; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
import static racingcar.message.Message.*; | ||
|
||
public class Cars { | ||
private final List<Car> cars; | ||
|
||
public Cars(List<Car> cars) { | ||
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. 클래스를 분할해서 List 만을 가지는 일급컬렉션으로 구현하신게 너무 좋은것 같습니다. Car가 Cars에만 참조된다면 더 좋을꺼같아요 |
||
this.cars = cars; | ||
} | ||
|
||
public void moveCars(CarOperator operator) { | ||
List<Integer> nowMove = operator.tempPosition(); | ||
IntStream.range(0, cars.size()).forEach(index -> { | ||
cars.get(index).move((nowMove.get(index))); | ||
}); | ||
} | ||
|
||
public String printCars() { | ||
return cars.stream().map(car -> car.toString() + ESCAPE_SEQUENCE.getMessage()) | ||
.collect(Collectors.joining()); | ||
} | ||
|
||
public int getMaxPosition() { | ||
return cars.stream().mapToInt(Car::getPosition).max() | ||
.orElseThrow(IllegalArgumentException::new); | ||
} | ||
|
||
public String getWinCar() { | ||
int max = getMaxPosition(); | ||
StringJoiner joiner = new StringJoiner(DELIMITER.getMessage() + " "); | ||
IntStream.range(0, cars.size()) | ||
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. stream을 이렇게 사용할 수도 있을것같아요 cars.stream()
.filter(car -> car.getPosition() == max)
.forEach(car -> joiner.add(car.getName()); |
||
.filter(i -> cars.get(i).getPosition() == max) | ||
.mapToObj(i -> cars.get(i).getName()) | ||
.forEach(joiner::add); | ||
return joiner.toString(); | ||
} | ||
|
||
public int getSize(){ | ||
return cars.size(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package racingcar.domain; | ||
|
||
public class Round { | ||
private final int finalRound; | ||
private int tempRound = 0; | ||
|
||
public Round(int finalRound) { | ||
this.finalRound = finalRound; | ||
} | ||
|
||
public void next() { | ||
tempRound++; | ||
} | ||
|
||
public boolean isFinish() { | ||
if (tempRound == finalRound) return true; | ||
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.
|
||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package racingcar.message; | ||
|
||
public enum ErrorMessage { | ||
CAR_NAME_TOO_LONG("차 이름은 공백이 아니고, 5글자 이내여야합니다."), | ||
ROUND_IS_DIGIT("시도 횟수는 숫자여야 합니다."), | ||
DUPLICATE_PARTICIPANT("중복된 참가자가 존재합니다."); | ||
private final String prefix = "[ERROR]"; | ||
private String message; | ||
|
||
private ErrorMessage(String message) { | ||
this.message = message; | ||
} | ||
|
||
public String getMessage(){ | ||
return prefix + message; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package racingcar.message; | ||
|
||
public enum Message { | ||
DELIMITER(","), | ||
INFIX(" : "), | ||
POSITION("-"), | ||
ESCAPE_SEQUENCE("\n"), | ||
WINNER("최종 우승자 : "), | ||
LOSER(""), | ||
PRINT_INPUT_NAMES("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), | ||
PRINT_INPUT_FINAL_ROUND("시도할 회수는 몇회인가요?"), | ||
PRINT_OUTPUT("실행 결과"); | ||
|
||
private String message; | ||
|
||
Message(String message) { | ||
this.message = message; | ||
} | ||
public String getMessage(){ | ||
return message; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package racingcar.service; | ||
|
||
import racingcar.domain.Car; | ||
import racingcar.domain.Cars; | ||
import racingcar.domain.Round; | ||
import racingcar.util.CarOperator; | ||
import racingcar.util.RandomNumberGenerate; | ||
|
||
import java.util.List; | ||
|
||
import static racingcar.message.Message.WINNER; | ||
|
||
public class CarVenueService { | ||
private final Cars cars; | ||
private final CarOperator carOperator; | ||
private final Round round; | ||
|
||
|
||
public CarVenueService(List<Car> cars, int finalRound) { | ||
this.cars = new Cars(cars); | ||
this.carOperator = new CarOperator(new RandomNumberGenerate(), cars.size()); | ||
this.round = new Round(finalRound); | ||
} | ||
|
||
public void moveTurn() { | ||
round.next(); | ||
cars.moveCars(carOperator); | ||
} | ||
|
||
public String printTurn() { | ||
return cars.printCars(); | ||
} | ||
|
||
public boolean isEnd() { | ||
if (round.isFinish()) return true; | ||
return false; | ||
} | ||
|
||
public String printWinner() { | ||
StringBuilder print = new StringBuilder(WINNER.getMessage()); | ||
print.append(cars.getWinCar()); | ||
return print.toString(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package racingcar.util; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
public class CarOperator { | ||
private final NumberGenerate numberGenerate; | ||
private final int carAmount; | ||
|
||
public CarOperator(NumberGenerate numberGenerate, int carAmount) { | ||
this.numberGenerate = numberGenerate; | ||
this.carAmount = carAmount; | ||
} | ||
|
||
public List<Integer> tempPosition() { | ||
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. 만약에 해당 행위를 묶어서 관리한다면 이건 개인적인 의견이지만 List로 움직임의 여부를 한꺼번에 반환하기보다는 하나씩 반환해주는 것도 괜찮은 방법인것 같아요.
이렇게하면 위에서 선언하셨던 // 변경전
public void moveCars(CarOperator operator) {
List<Integer> nowMove = operator.tempPosition();
IntStream.range(0, cars.size()).forEach(index -> {
cars.get(index).move((nowMove.get(index)));
});
}
// 변경후
public void moveCars(CarOperator operator) {
IntStream.range(0, cars.size()).forEach(index -> {
cars.get(index).move(operator.getMoveFlag()));
});
} |
||
return IntStream.range(0, carAmount).mapToObj(index -> numberGenerate.generate()).collect(Collectors.toList()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package racingcar.util; | ||
|
||
@FunctionalInterface | ||
public interface NumberGenerate { | ||
int generate(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package racingcar.util; | ||
|
||
public enum NumberManager { | ||
NAME_MIN_LENGTH(1), | ||
START_NUMBER(0), | ||
LAST_NUMBER(9), | ||
STANDARD_NUMBER(4); | ||
private int number; | ||
|
||
NumberManager(int number) { | ||
this.number = number; | ||
} | ||
|
||
public int getNumber() { | ||
return number; | ||
} | ||
} |
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.
결과에는 항상 최종우승자 목록도 따라오니 하나로 합치는 방법도 있을거같아요.
view.printResult나 carVenueService.printWinner에서. '실행결과\n최종 우승자 : ' 로 출력했으면
조금은 더 깔끔해졌을꺼 같아요