diff --git a/README.md b/README.md index 1969313..b9021ce 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,87 @@ 자동차 경주 미션 저장소 +## 설정 사항 + +- (중요) JDK 17 버전으로 진행한다. + +## **기능 요구사항** + +- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다. +- 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다. +- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다. +- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다. +- 전진하는 조건은 0에서 9 사이에서 random 값을 구한 후 random 값이 4 이상일 경우 전진하고, 3 이하의 값이면 멈춘다. +- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다. + +## **실행 결과** + +- 위 요구사항에 따라 3대의 자동차가 5번 움직였을 경우 프로그램을 실행한 결과는 다음과 같다. + +``` +경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분). +kokodak,kuku,cucu +시도할 회수는 몇회인가요? +5 + +실행 결과 +kokodak : - +kuku : - +cucu : - + +kokodak : -- +kuku : - +cucu : -- + +kokodak : --- +kuku : -- +cucu : --- + +kokodak : ---- +kuku : --- +cucu : ---- + +kokodak : ----- +kuku : ---- +cucu : ----- + +kokodak : ----- +kuku : ---- +cucu : ----- + +kokodak, cucu가 최종 우승했습니다. +``` + +## **프로그래밍 요구사항** + +- **모든 로직에 단위 테스트를 구현한다. 단, UI(System.out, System.in) 로직은 제외** +- **자바 코드 컨벤션을 지키면서 프로그래밍한다.** + - 참고문서: https://google.github.io/styleguide/javaguide.html 또는 https://myeonguni.tistory.com/1596 +- **`규칙 1: 한 메서드에 오직 한 단계의 들여쓰기(indent)만 한다.`**를 지키며 구현한다. + - 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다. + - 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다. +- **`규칙 2: else 예약어를 쓰지 않는다.`**를 지키며 구현한다. + - 힌트: if 조건절에서 값을 return하는 방식으로 구현하면 else를 사용하지 않아도 된다. + - else를 쓰지 말라고 하니 switch/case로 구현하는 경우가 있는데 switch/case도 허용하지 않는다. +- **함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.** + - 함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다. + +**MVC 패턴으로 리팩터링 후의 main 메소드 예시** + +```java +import view.InputView; +import view.ResultView; +import domain.RacingGame; + +public class RacingMain { + public static void main(final String... args) { + final var carNames = InputView.getCarNames(); + final var tryCount = InputView.getTryCount(); + + final var racingGame = new RacingGame(carNames, tryCount); + racingGame.race(); + + ResultView.printWinners(racingGame.getWinners()); + } +} +``` diff --git a/src/main/java/Controller/RacingCarController.java b/src/main/java/Controller/RacingCarController.java new file mode 100644 index 0000000..3268aef --- /dev/null +++ b/src/main/java/Controller/RacingCarController.java @@ -0,0 +1,25 @@ +package Controller; + +import Domain.RacingCarGenetator; +import Domain.RacingCars; +import Service.MoveCar; +import View.Input; +import View.Output; + +import java.util.List; + +public class RacingCarController { + public void racingStart(){ + RacingCarGenetator racingCarGenetator = new RacingCarGenetator(); + RacingCars racingCars = new RacingCars(racingCarGenetator.generateRacingCars()); + MoveCar moveCar = new MoveCar(); + int gameNumbers = Input.inputGameNumber(); + for(int i = 0 ; i < gameNumbers ; i++){ + Output.printResults(racingCars); + moveCar.moveCars(racingCars); + } + Output.printResults(racingCars); + Output.printFinalResult(racingCars); + } + +} diff --git a/src/main/java/Domain/RacingCar.java b/src/main/java/Domain/RacingCar.java new file mode 100644 index 0000000..b98dae8 --- /dev/null +++ b/src/main/java/Domain/RacingCar.java @@ -0,0 +1,26 @@ +package Domain; + +import java.util.HashMap; +import java.util.Map; + +public class RacingCar { + private String carName; + private int carPosition; + + RacingCar(String carName){ + this.carName = carName; + this.carPosition = 1; + } + + public void moveCarPosition(){ + carPosition += 1; + } + + public int getCarPosition(){ + return carPosition; + } + + public String getCarName(){ + return carName; + } +} diff --git a/src/main/java/Domain/RacingCarGenetator.java b/src/main/java/Domain/RacingCarGenetator.java new file mode 100644 index 0000000..d2e952f --- /dev/null +++ b/src/main/java/Domain/RacingCarGenetator.java @@ -0,0 +1,26 @@ +package Domain; + +import View.Input; + +import java.util.ArrayList; +import java.util.List; + +public class RacingCarGenetator { + private final List racingCars = new ArrayList<>(); + + public RacingCarGenetator(){ + } + + public RacingCar generateRacingCar(String carName){ + return new RacingCar(carName); + } + + public List generateRacingCars(){ + List carNames = Input.inputCarName(); + List racingCars = new ArrayList<>(); + for(int i = 0 ; i < carNames.size() ; i++){ + racingCars.add(generateRacingCar(carNames.get(i))); + } + return racingCars; + } +} diff --git a/src/main/java/Domain/RacingCars.java b/src/main/java/Domain/RacingCars.java new file mode 100644 index 0000000..c73a381 --- /dev/null +++ b/src/main/java/Domain/RacingCars.java @@ -0,0 +1,18 @@ +package Domain; + +import View.Input; + +import java.util.List; +import java.util.Map; + +public class RacingCars { + private List racingCars; + + public RacingCars (List racingCars){ + this.racingCars = racingCars; + } + + public List getRacingCars(){ + return racingCars; + } +} diff --git a/src/main/java/RacingMain.java b/src/main/java/RacingMain.java index 4394287..e849b0b 100644 --- a/src/main/java/RacingMain.java +++ b/src/main/java/RacingMain.java @@ -1,7 +1,9 @@ -public class RacingMain { +import Controller.RacingCarController; +public class RacingMain { public static void main(String[] args) { // TODO: MVC 패턴을 기반으로 자동차 경주 미션 구현해보기 - System.out.println("Hello, World!"); + RacingCarController racingCarController = new RacingCarController(); + racingCarController.racingStart(); } } diff --git a/src/main/java/Service/MoveCar.java b/src/main/java/Service/MoveCar.java new file mode 100644 index 0000000..86b7cd7 --- /dev/null +++ b/src/main/java/Service/MoveCar.java @@ -0,0 +1,27 @@ +package Service; + +import Domain.RacingCar; +import Domain.RacingCars; + +import java.util.List; +import java.util.Map; + +public class MoveCar { + public int generateRandomNumber(){ + return (int)(Math.random()*10); + } + + public void moveCar(RacingCar racingCar){ + if(generateRandomNumber() >= 4){ + racingCar.moveCarPosition(); + } + } + + public void moveCars(RacingCars racingCars){ + List racingCarList = racingCars.getRacingCars(); + racingCarList.stream() + .forEach(this::moveCar); + + //return racingCarList; + } +} diff --git a/src/main/java/View/Input.java b/src/main/java/View/Input.java new file mode 100644 index 0000000..27425e4 --- /dev/null +++ b/src/main/java/View/Input.java @@ -0,0 +1,29 @@ +package View; + +import Domain.RacingCar; +import Domain.RacingCars; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +public class Input { + private static final String INPUT_CAR_NAME = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분"; + private static final String INPUT_GAME_NUMBER = "시도할 횟수는 몇 회인가요?"; + + public static List inputCarName(){ //리스트로 차 이름 받은 후 controller에서 Racingcars 생성 + System.out.println(INPUT_CAR_NAME); + Scanner sc = new Scanner(System.in); + List carNames = Arrays.stream(sc.next() + .split(",")) + .toList(); + return carNames; + } + + public static int inputGameNumber(){ + System.out.println(INPUT_GAME_NUMBER); + Scanner sc = new Scanner(System.in); + return sc.nextInt(); + } +} diff --git a/src/main/java/View/Output.java b/src/main/java/View/Output.java new file mode 100644 index 0000000..e80447b --- /dev/null +++ b/src/main/java/View/Output.java @@ -0,0 +1,48 @@ +package View; + +import Domain.RacingCar; +import Domain.RacingCars; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +public class Output { + private static final String RESULT = "실행결과\n"; + private static final String FINAL_RESULT = "가 최종 우승했습니다"; + public static void printResults(RacingCars racingCars){ + System.out.print(RESULT); + List racingCarList = racingCars.getRacingCars(); + racingCarList.stream() + .forEach(cars -> System.out.println(cars.getCarName() + " : " + "-".repeat( cars.getCarPosition()))); + System.out.println(); + } + + public static int findWinnersPosition(RacingCars racingCars){ + List racingCarList = racingCars.getRacingCars(); + int maxPosition = 0; + for(int i = 0 ; i < racingCarList.size() ; i++){ + maxPosition = findBigger(racingCarList.get(i).getCarPosition(), maxPosition); + } + return maxPosition; + } + + public static int findBigger(int n, int m){ + if(n > m){ + return n; + } + return m; + } + + public static void printFinalResult(RacingCars racingCars){ + List racingCarList = racingCars.getRacingCars(); + int winnersPosition = findWinnersPosition(racingCars); + for(int i = 0 ; i < racingCarList.size() ; i++){ + if(racingCarList.get(i).getCarPosition() == winnersPosition){ + System.out.print(racingCarList.get(i).getCarName() + ", "); + } + } + System.out.print("\b\b" + FINAL_RESULT); + } +} diff --git "a/\352\265\254\355\230\204\352\265\254\354\241\260" "b/\352\265\254\355\230\204\352\265\254\354\241\260" new file mode 100644 index 0000000..03dab2a --- /dev/null +++ "b/\352\265\254\355\230\204\352\265\254\354\241\260" @@ -0,0 +1,18 @@ +1. 입력 + 경주할 자동차 이름 입력(쉼표로 구분) + 시도 횟수 입력(양수인지 확인) + +2. 출력 + 각 자동차 현재 상태 출력 + 최종 우승한 차량 이름 출력 + +3. 서비스 + 3-1. 랜덤 변수 생성 + 3-2 변수값 확인하여 전진 여부 결정 + +4. 도메인 + 4-1 자동차 이름, 현재 위치 저장 + 4-2 Map<자동차 이름, 현재위치> 로 자동차 목록 저장 + +5.컨트롤러 + 전체적인 동작 실행