-
Notifications
You must be signed in to change notification settings - Fork 8
[자동차 경주] 김연서 미션 제출합니다. #10
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
base: main
Are you sure you want to change the base?
Changes from all commits
2fbaee4
e536ea5
ddbd59e
2a736e5
16d9b39
91973da
32061e0
b5e5c14
5f1616e
d983f9b
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 |
|---|---|---|
| @@ -1 +1,22 @@ | ||
| # java-racingcar-precourse | ||
|
|
||
| # 기능 목록 | ||
|
|
||
| 1. 자동차경주 뷰 | ||
| - input, output(차수별, 우승자) | ||
|
|
||
| 2. 자동차 움직임 뷰 | ||
| - 자동차가 움직이면 그걸 출력하는 뷰 | ||
|
|
||
| 3. 자동차경주 컨트롤러 | ||
| - 입력값 처리 및 자동차 모델에게 전달 및 생성 | ||
| - 자동차 경주 게임 진행 | ||
|
|
||
| 4. 자동차경주 서비스 | ||
| - 예외처리 후 모델에게 전달 | ||
| - 우승자 판별 | ||
| - 1회차 경기 기능 | ||
|
|
||
| 5. 자동차 모델(클래스) | ||
| - 이름, 좌표 관련 입출력 | ||
| - 좌표 이동 후 뷰에 통보하는 observer |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| org.gradle.jvmargs=-Dfile.encoding=UTF-8 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,24 @@ | ||
| package racingcar; | ||
|
|
||
| import racingcar.controller.RacingGameController; | ||
| import racingcar.service.RacingGameService; | ||
| import racingcar.view.RacingGameView; | ||
|
|
||
| import java.io.PrintStream; | ||
| import java.io.UnsupportedEncodingException; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| // TODO: 프로그램 구현 | ||
| new Application().run(); | ||
| } | ||
|
|
||
| public void run(){ | ||
| RacingGameService racingGameService = new RacingGameService(); | ||
| RacingGameView racingGameView = new RacingGameView(); | ||
| RacingGameController racingGameController = new RacingGameController(racingGameView, racingGameService); | ||
|
|
||
| racingGameController.makeCar(); | ||
| racingGameController.runGame(); | ||
| racingGameController.result(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package racingcar.controller; | ||
|
|
||
| import racingcar.service.RacingGameService; | ||
| import racingcar.util.ErrorMessage; | ||
| import racingcar.util.Validator; | ||
| import racingcar.view.RacingGameView; | ||
|
|
||
| public class RacingGameController { | ||
|
|
||
| private RacingGameView racingGameView; | ||
| private RacingGameService racingGameService; | ||
|
|
||
| public RacingGameController(RacingGameView racingGameView, RacingGameService racingGameService){ | ||
| this.racingGameService = racingGameService; | ||
| this.racingGameView = racingGameView; | ||
| } | ||
|
|
||
| public void makeCar(){ | ||
| String[] carNames = racingGameView.readName().split(","); | ||
| for(String name : carNames) racingGameService.addCar(name); | ||
| racingGameService.addObserver(racingGameView); | ||
| } | ||
|
|
||
| public void runGame(){ | ||
| String input = racingGameView.readRepeat(); | ||
| if(!Validator.isNumber(input)) throw new IllegalArgumentException(ErrorMessage.WRONG_REPEAT_INPUT.getMessage()); | ||
|
|
||
| int repetitionNumber = Integer.parseInt(input); | ||
| if(repetitionNumber<1) | ||
| racingGameView.printEndGuide(); | ||
|
Contributor
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. 코드 포멧이 미션에서 제시된 거랑 다른 것 같아요! 전반적으로 코드 포멧을 맞추면 가독성이 높아질 것 같아요
Author
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. 오 그런가요 넴~~~ |
||
| for (int i=0;i<repetitionNumber;i++) { | ||
| racingGameService.playOneGame(); | ||
| racingGameView.lineBreak(); | ||
| } | ||
| } | ||
|
|
||
| public void result(){ | ||
| String winners = racingGameService.checkWinner(); | ||
| racingGameView.printFinalWinner(winners); | ||
|
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package racingcar.model; | ||
|
|
||
| import racingcar.util.ErrorMessage; | ||
|
|
||
| public class Car { | ||
| private String name; | ||
| private int position; | ||
| private CarObserver observer; | ||
|
|
||
| public Car(String name){ | ||
| setName(name); | ||
| this.position = 0; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public void setName(String name) { | ||
| if(name.length()>5) throw new IllegalArgumentException(ErrorMessage.TOO_LONG.getMessage()); | ||
| this.name = name; | ||
| } | ||
|
|
||
| public int getPosition() { | ||
| return position; | ||
| } | ||
|
|
||
| public void addPosition(int dice) { | ||
| if(dice>3) this.position++; | ||
| observer.onCarMove(name, position); | ||
| } | ||
|
Contributor
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.
Author
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. 저걸 일종의 validation이라구 봐서 자동차 모델 안에 집어넣어두 되지 않을까 생각했습니다~~ 저 메세드는 내부에서 검사를 하지만 받은 파라미터가 뭘 뜻하는진 모르니까용 흠 먼가 사용이 부적절한가?? |
||
|
|
||
| public void setObserver(CarObserver observer) { | ||
| this.observer = observer; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package racingcar.model; | ||
|
|
||
| public interface CarObserver { | ||
| void onCarMove(String carName, int position); | ||
| } | ||
|
Contributor
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. 모델을 확장해서 뷰로 구현하는 구조라고 이해했는데(CarObserver가 model 패키지 내 인터페이스이고, 인터페이스를 구현한 것이 view 이기에), 모델이 뷰와 강한 의존관계를 갖게 되기 때문에 이러한 구조가 MVC 패턴에 적절한지에 대해서는 다시 생각해볼 부분이 있을 것 같아요! 옵저버를 컨트롤러와 연결시켜 컨트롤러가 다시 뷰에게 전달하는 방향이 더 좋지 않을까요?
Author
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,41 @@ | ||
| package racingcar.service; | ||
|
|
||
| import racingcar.model.Car; | ||
| import racingcar.model.CarObserver; | ||
|
|
||
| import java.net.CacheRequest; | ||
| import java.util.ArrayList; | ||
| import java.util.Comparator; | ||
| import java.util.List; | ||
| import java.util.Optional; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import static camp.nextstep.edu.missionutils.Randoms.pickNumberInRange; | ||
|
|
||
| public class RacingGameService { | ||
| private List<Car> cars = new ArrayList<>(); | ||
|
|
||
| public void addCar(String carName){ | ||
| Car car = new Car(carName); | ||
| cars.add(car); | ||
| } | ||
|
|
||
| public void addObserver(CarObserver carObserver){ | ||
| cars.forEach(car->car.setObserver(carObserver)); | ||
| } | ||
|
|
||
| public void playOneGame(){ | ||
| for(Car car : cars) car.addPosition(pickNumberInRange(0,9)); | ||
| } | ||
|
|
||
| public String checkWinner(){ | ||
| Optional<Integer> maxValue = cars.stream().map(Car::getPosition).max(Integer::compareTo); | ||
|
|
||
| String maxPositionCars = cars.stream() | ||
| .filter(n -> maxValue.isPresent() && n.getPosition()==maxValue.get()) | ||
|
Contributor
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.
Author
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. 저도 점찍고 스크롤하다가 보여서 알게 되었읍니다.. |
||
| .map(Car::getName) | ||
| .collect(Collectors.joining(", ")); | ||
|
|
||
| return maxPositionCars; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package racingcar.util; | ||
|
|
||
| public enum ErrorMessage { | ||
| TOO_LONG("이름 5자 초과"), | ||
| WRONG_REPEAT_INPUT("입력 반복 횟수는 1 이상의 숫자여야합니다."); | ||
|
|
||
|
|
||
| private String message; | ||
|
|
||
| ErrorMessage(String message){this.message = message;} | ||
|
|
||
| public String getMessage() { | ||
| return "Error: "+message; | ||
| } | ||
| } | ||
|
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. 각 에러 메시지에 "Error: "를 미리 붙이지 않고, 왜 getMessage()에서 추가하도록 짠건지 궁금해요ㅕ!!
Author
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. 에러는 메세지 출력 때 공통으로 나오는거니 enum에 넣기보단 view로 떠넘기는게 더 낫지 않을까 큰 생각없이 만들었습니다만 좀 더 효율적이려면 enum을 조작해서 에러부분을 스태틱으로 하던지 하면 될 것 같습니다! 크게 고민 안하고 한거라 거창한 이유는 없었습니다..ㅋㅋㅋ |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package racingcar.util; | ||
|
|
||
| public enum SystemMessage { | ||
| START_NAME_GUIDE("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), | ||
| START_REPEAT_GUIDE("시도할 회수는 몇 회인가요?"), | ||
| RESULT_GUIDE("실행 결과"), | ||
| RESULT_WINNER("최종 우승자 : "); | ||
|
|
||
|
|
||
| private String message; | ||
|
|
||
| SystemMessage(String message){this.message = message;} | ||
|
|
||
| public String getMessage() { | ||
| return this.message; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package racingcar.util; | ||
|
|
||
| import java.util.regex.Pattern; | ||
|
|
||
| public class Validator { | ||
| public static boolean isNumber(String arg){ | ||
| if(arg == null || !arg.matches("\\d+")) return false; | ||
| return true; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package racingcar.view; | ||
|
|
||
| import camp.nextstep.edu.missionutils.Console; | ||
| import racingcar.model.CarObserver; | ||
| import racingcar.util.SystemMessage; | ||
|
|
||
| public class RacingGameView implements CarObserver { | ||
|
|
||
| public String readName(){ | ||
| System.out.println(SystemMessage.START_NAME_GUIDE.getMessage()); | ||
| return Console.readLine(); | ||
| } | ||
|
|
||
| public String readRepeat(){ | ||
| System.out.println(SystemMessage.START_REPEAT_GUIDE.getMessage()); | ||
| return Console.readLine(); | ||
| } | ||
|
|
||
| public void lineBreak(){ | ||
| System.out.println(""); | ||
| } | ||
|
|
||
| public void printEndGuide(){ | ||
| System.out.println(SystemMessage.RESULT_GUIDE.getMessage()); | ||
| } | ||
|
|
||
| public void printFinalWinner(String winner){ | ||
| System.out.println(SystemMessage.RESULT_WINNER.getMessage() + winner); | ||
| } | ||
|
|
||
| @Override | ||
| public void onCarMove(String carName, int position){ | ||
| //뷰가 모델과 분리되어야해서 인스턴스 말고 각각 보내는게 좋다 함. | ||
| String message = carName + " : " + "-".repeat(position); | ||
| System.out.println(message); | ||
| } | ||
| } |
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.
for도 좋지만 forEach로 써도 가독성이 높을 것 같아요
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.
오 그러게요 왜 그렇게 안했지 수정하겠습니다~~