diff --git a/README.md b/README.md index d0286c859f..5372048054 100644 --- a/README.md +++ b/README.md @@ -1 +1,118 @@ # java-racingcar-precourse +# 구현할 기능 목록 + +- 클라이언트 요청(RacingView), RacingRequest 기능 정의 +- Car 클래스 데이터 정의 및 기능 구현 +- RacingController 기능 정의 구현 RacingService 기능 정의 +- 클라이언트 요청 출력(racingView) 기능 정의 + +## 기능 요구 사항 +초간단 자동차 경주 게임 구현 + +- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출수 있다. +- 각 자동차에 이름을 부여 할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. +- 사용자는 몇번의 이동을 할 것인지를 입력할 수 있어야한다. +- 전진하는 조건은 0에서 9사이에서 무작위 값을 구한 후 무작위 값이 4이상일 경우이다. +- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. +- 우승자가 여러명일 경우 쉼표(,)를 이용하여 구분한다. +- 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생 시킨 후 애플리케이션 종료 + + +### 입출력 요구 사항 +- 경주할 자동차 이름(이름은 쉼표(,) 기준으로 구분) pobi,woni,jun +- 시도할 횟수 5 + + +### 출력 +- 차수별 실행 결과 + > pobi : -- + > + > woni : ---- + > + > jun : --- + +- 단독 우승자 +> 최종 우승자 : pobi +- 공동 우승자 +> 최종 우승자 : pobi, jun + + +> 경주할 자동차 이름을 입력하세요.(이름은 쉽표(,) 기준으로 구분) + +> >pobi,woni,jun + +> 시도 할 횟수는 몇회인가요? + +> >5 + +> 실행 결과 + + +## 학습 목표 +- ### 단일 책임 함수로 구현 +- ### 구현한 함수 및 프로그램을 테스트 도구를 활용하여 제대로 작동하는지 확인하고 테스트도구 사용하는 방법 숙달 +- ### 1차 공통 피드백 반영 + 1. 과제 진행 요구사항, 기능 요구 사항, 프로그래밍 요구사항 정확하게 준수 + 2. git 사용 명령어 및 방법 숙지 + 3. 커밋 메세지를 수행한 작업을 이해할 수 있게 작성. + 4. IDE에서 어플리케이션 디버깅 방법 학습 및 활용하기 + 5. 클래스, 메서드, 변수의 이름을 통해 의도를 정확히 표현한다. 축약하지 않는다. 문맥상 중복 이름은 자제한다. + 6. Java에서 제공하는 API를 적극 활용 <- 함수 직접 구현 전 Java에서 제공되는 기능이 있는지 확인 + 7. 배열 대신 컬렉션 사용 및 활용. + +## 회고 +아래 질문 항모게 대한 중간 회고를 진행하고 소감에 구체적인 결과를 작성. +- 지원서에 작성한 목표 달성율과 그 이유 +- 지원서에 작성한 목표 변경을 해야한다면 이유와 어떤 목표로 변경 할건지 +- 프리코스 진행 중 눈에 띄는 변화나 깨달은 점 + +## 과제 진행 요구 사항 +- 구현 전 READ.md 에 구현할 기능 목록을 만들고, 기능 단위로 커밋하는 방식으로 진행 +## 기능 요구 사항 +초간단 자동차 경주 게임 구현 + +- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출수 있다. +- 각 자동차에 이름을 부여 할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. +- 사용자는 몇번의 이동을 할 것인지를 입력할 수 있어야한다. +- 전진하는 조건은 0에서 9사이에서 무작위 값을 구한 후 무작위 값이 4이상일 경우이다. +- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. +- 우승자가 여러명일 경우 쉼표(,)를 이용하여 구분한다. +- 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생 시킨 후 애플리케이션 종료 +### 입출력 요구 사항 +- 경주할 자동차 이름(이름은 쉼표(,) 기준으로 구분) pobi,woni,jun +- 시도할 횟수 5 +### 출력 +- 차수별 실행 결과 + > pobi : -- + > + > woni : ---- + > + > jun : --- + +- 단독 우승자 +> 최종 우승자 : pobi +- 공동 우승자 +> 최종 우승자 : pobi, jun + +- 실행결과 예시 + +> 경주할 자동차 이름을 입력하세요.(이름은 쉽표(,) 기준으로 구분) + +> >pobi,woni,jun + +> 시도 할 횟수는 몇회인가요? + +> >5 + +> 실행 결과 + + +## 프로그래밍 요구사항 +- indent depth를 3이 넘지 않도록 구현, 2까지만 허용 +- 3항 연산자 쓰지 않는다. +- 함수가 한 가지 일만 하도록 최대한 작게 만들어라 +- Junit5 와 AssertJ를 이요하여 정리한 기능 목록이 정상 작동하는지 테스트 코드로 확인 + + diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e724..ca4ea1f668 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -3,5 +3,8 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + RacingController carRacing = new RacingController(new RacingView(), new RacingService()); + carRacing.applicationRun(); + } } diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java new file mode 100644 index 0000000000..9e18d2451c --- /dev/null +++ b/src/main/java/racingcar/Car.java @@ -0,0 +1,27 @@ +package racingcar; + +public class Car { + private String carName; + private int movement = 0; + + public Car(String carName) { + this.carName = carName; + } + + public String getDistance() { + return "-".repeat(movement); + } + + public String getCarName() { + return carName; + } + + public int getMovement() { + return movement; + } + + public void move() { + ++movement; + } + +} diff --git a/src/main/java/racingcar/RacingController.java b/src/main/java/racingcar/RacingController.java new file mode 100644 index 0000000000..429e3ba567 --- /dev/null +++ b/src/main/java/racingcar/RacingController.java @@ -0,0 +1,17 @@ +package racingcar; + +public class RacingController { + private final RacingView view; + private final RacingService racingService; + + public RacingController(RacingView view, RacingService racingService) { + this.view = view; + this.racingService = racingService; + } + + public void applicationRun() { + racingService.ready(view); + racingService.go(view); + racingService.winner(view); + } +} diff --git a/src/main/java/racingcar/RacingDto.java b/src/main/java/racingcar/RacingDto.java new file mode 100644 index 0000000000..615625d6b2 --- /dev/null +++ b/src/main/java/racingcar/RacingDto.java @@ -0,0 +1,57 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Randoms; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class RacingDto { + private final List playerList = new ArrayList<>(); + private int raceMovement; + + public void setRace(String players, String raceMovement) { + setPlayer(players); + this.raceMovement = Integer.parseInt(raceMovement); + } + + public List goRace() { + for (Car player : playerList) { + if(Randoms.pickNumberInRange(0, 9) > 3) player.move(); + } + return playerList; + } + + public String getWinner() { + + int maxDistance = getMaxDistance(); + List winnerList = getWinnerList(maxDistance); + + return String.join(",", winnerList); + } + + public int getRaceMovement() { + return raceMovement; + } + + private void setPlayer(String nameList) { + for (String name : nameList.split(",")) { + checkPlayer(name); + playerList.add(new Car(name)); + } + } + + private List getWinnerList(int maxDistance) { + return playerList.stream().filter(player -> player.getMovement() == maxDistance).map(Car::getCarName).collect(Collectors.toList()); + } + + private int getMaxDistance() { + return playerList.stream().mapToInt(Car::getMovement).max().orElse(0); + } + + private void checkPlayer(String name) { + if (name.length() > 5) { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/racingcar/RacingService.java b/src/main/java/racingcar/RacingService.java new file mode 100644 index 0000000000..720c4cc296 --- /dev/null +++ b/src/main/java/racingcar/RacingService.java @@ -0,0 +1,19 @@ +package racingcar; + +public class RacingService { + + private final RacingDto dto = new RacingDto(); + + public void ready(RacingView view) { + view.raceReadyView(dto); + } + + public void go(RacingView view) { + view.raceGoView(dto); + } + + public void winner(RacingView view) { + view.winnerView(dto); + } + +} diff --git a/src/main/java/racingcar/RacingView.java b/src/main/java/racingcar/RacingView.java new file mode 100644 index 0000000000..5f5baae5e8 --- /dev/null +++ b/src/main/java/racingcar/RacingView.java @@ -0,0 +1,34 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Console; + +public class RacingView { + + public void raceReadyView(RacingDto dto) { + + System.out.println("경주할 자동차 이름(이름은 쉼표(,) 기준으로 구분)"); + String carNameList = Console.readLine(); + System.out.println(carNameList); + + System.out.println("시도할 횟수"); + String raceMovement = Console.readLine(); + System.out.println(raceMovement); + + dto.setRace(carNameList, raceMovement); + } + + public void raceGoView(RacingDto dto) { + System.out.println("실행 결과"); + for (int i = 0; i < dto.getRaceMovement(); i++) { + for (Car player : dto.goRace()) { + System.out.println(player.getCarName() + " : " + player.getDistance()); + } + System.out.println(); + } + + } + + public void winnerView(RacingDto dto) { + System.out.println("최종 우승자 : " + dto.getWinner()); + } +}