diff --git a/README.md b/README.md index 8fe711203..e4b9b05b2 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,20 @@ -## [NEXTSTEP 플레이그라운드의 미션 진행 과정](https://github.com/next-step/nextstep-docs/blob/master/playground/README.md) +자동차 클래스, +---- +## 1. 자동차 이름 유효성 ---- -## 학습 효과를 높이기 위해 추천하는 미션 진행 방법 +## 2. 자동차 1개 클래스 ---- -1. 피드백 강의 전까지 미션 진행 -> 피드백 강의 전까지 혼자 힘으로 미션 진행. 미션을 진행하면서 하나의 작업이 끝날 때 마다 add, commit -> 예를 들어 다음 숫자 야구 게임의 경우 0, 1, 2단계까지 구현을 완료한 후 push +## 3. 자동차 클래스에 race 메소드 or Race 메소드 +작과 데이터를 완전 분리 + 일급 컬렉션 List -> Cars +후자로 해보자. +3-1. race 메소드 할 때 Race 클래스의 멤버 변수인 Car에 접근해야하는데, +해당 메소드가 public 이면 setter써서 하는게 좋나 ? -![mission baseball](https://raw.githubusercontent.com/next-step/nextstep-docs/master/playground/images/mission_baseball.png) +## 4. 자동차 여러대 클래스 ---- -2. 피드백 앞 단계까지 미션 구현을 완료한 후 피드백 강의를 학습한다. +## 5. 사용자 input 문자열 포장 ---- -3. Git 브랜치를 master 또는 main으로 변경한 후 피드백을 반영하기 위한 새로운 브랜치를 생성한 후 처음부터 다시 미션 구현을 도전한다. - -``` -git branch -a // 모든 로컬 브랜치 확인 -git checkout master // 기본 브랜치가 master인 경우 -git checkout main // 기본 브랜치가 main인 경우 - -git checkout -b 브랜치이름 -ex) git checkout -b apply-feedback -``` +------------------ +우승자들을 cars에 넣는게 맞을까? +그냥 racing 내부에서 우승자만 반환 해주는게 맞나 ? +고민.. \ No newline at end of file diff --git a/src/main/java/racingcarGame/Application.java b/src/main/java/racingcarGame/Application.java new file mode 100644 index 000000000..6c08e7f4c --- /dev/null +++ b/src/main/java/racingcarGame/Application.java @@ -0,0 +1,46 @@ +package racingcarGame; + +import racingcarGame.domain.Car; +import racingcarGame.domain.Cars; +import racingcarGame.domain.Race; +import racingcarGame.views.InputView; +import racingcarGame.views.ResultView; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import static racingcarGame.utils.SplitNames.splitName; + +public class Application { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + String input = InputView.name(scanner); + int times = InputView.number(scanner); + + UserInput userInput = new UserInput(input, times); + + String[] carNames = splitName(input); + List carList = new ArrayList<>(); + + for (String carName : carNames) { + Car car = new Car(carName); + carList.add(car); + } + + Cars cars = new Cars(carList); + Race race = new Race(cars); + + ResultView.result(); + + for (int i = 0; i < userInput.getTimes(); i++) { + race.race(); + ResultView.racingResult(cars); + System.out.println(); + } + + int farLocation = race.farLocation(); + Cars winner = race.winner(farLocation); + ResultView.winner(winner); + } +} diff --git a/src/main/java/racingcarGame/UserInput.java b/src/main/java/racingcarGame/UserInput.java new file mode 100644 index 000000000..0acfa8b59 --- /dev/null +++ b/src/main/java/racingcarGame/UserInput.java @@ -0,0 +1,18 @@ +package racingcarGame; + +public class UserInput { + private final String inputName; + private final int times; + + UserInput(String inputName,int times) { + this.inputName = inputName; + this.times = times; + } + + public String getInput() { + return inputName; + } + public int getTimes() { + return times; + } +} diff --git a/src/main/java/racingcarGame/domain/Car.java b/src/main/java/racingcarGame/domain/Car.java new file mode 100644 index 000000000..d490b54d8 --- /dev/null +++ b/src/main/java/racingcarGame/domain/Car.java @@ -0,0 +1,42 @@ +package racingcarGame.domain; + +public class Car { + private final String name; + private int location; + private Position position; + + public String getName() { + return name; + } + + public int getLocation() { + return location; + } + + Car(String name) { + if (name.length() > 5) { + throw new IllegalArgumentException(); + } + this.name = name; + this.location = 0; + this.position = new Position(); + } + + public void move(int rand) { + if (rand >= 4 ) + this.location += 1; + } + + + // move 전력이 바뀌는 것을 대비한 추상화 + public void move(MovingStrategy movingStrategy) { + //여기만 보면 구현체 뭔지 모르는데 + //애플리케이션 코드에 이 메서드 사용할 때 구현체를 넣어주지 + if (movingStrategy.movable()){ + this.location += 1; + position.move(); + + } + } + +} diff --git a/src/main/java/racingcarGame/domain/Cars.java b/src/main/java/racingcarGame/domain/Cars.java new file mode 100644 index 000000000..9dc9b46f8 --- /dev/null +++ b/src/main/java/racingcarGame/domain/Cars.java @@ -0,0 +1,24 @@ +package racingcarGame.domain; + +import java.util.ArrayList; +import java.util.List; + +public class Cars { + + private final List cars; + + public List getCars() { + return cars; + } + public Cars(List carList) { + this.cars = carList; + } + public List getLocations() { + List carList = getCars(); + List locations = new ArrayList<>(); + for (Car car : carList) { + locations.add(car.getLocation()); + } + return locations; + } +} diff --git a/src/main/java/racingcarGame/domain/MovingStrategy.java b/src/main/java/racingcarGame/domain/MovingStrategy.java new file mode 100644 index 000000000..9db9d6286 --- /dev/null +++ b/src/main/java/racingcarGame/domain/MovingStrategy.java @@ -0,0 +1,6 @@ +package racingcarGame.domain; + +public interface MovingStrategy { + + boolean movable(); +} diff --git a/src/main/java/racingcarGame/domain/Position.java b/src/main/java/racingcarGame/domain/Position.java new file mode 100644 index 000000000..cb4a96877 --- /dev/null +++ b/src/main/java/racingcarGame/domain/Position.java @@ -0,0 +1,22 @@ +package racingcarGame.domain; + +public class Position { + private int position; + public Position(int i) { + if (i < 0) { + throw new IllegalArgumentException("Position cannot be less than 0"); + } + this.position = i; + } + + public Position() { + this.position = 0; + } + public int getPosition() { + return this.position; + } + + public void move() { + this.position += 1; + } +} diff --git a/src/main/java/racingcarGame/domain/Race.java b/src/main/java/racingcarGame/domain/Race.java new file mode 100644 index 000000000..671cd44b5 --- /dev/null +++ b/src/main/java/racingcarGame/domain/Race.java @@ -0,0 +1,52 @@ +package racingcarGame.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static racingcarGame.utils.GenerateNumber.generateNumber; + +public class Race { + + private final Cars cars; + + public Race(Cars car) { + this.cars = car; + } + public void race() { + Cars cars = getCars(); + for(Car car: cars.getCars()){ + int rand = generateNumber(); + car.move(rand); + } + } + public Cars winner(int farLocation) { + Cars cars = getCars(); + List carsList = new ArrayList<>(); + for(Car car: cars.getCars()){ + Optional result = Optional.ofNullable(compareFarLocation(farLocation, car)); + result.ifPresent(carsList::add); + } + return new Cars(carsList); + } + public int farLocation() { + int far = 0; + for(Car car: cars.getCars()){ + far = compareLocation(far, car); + } + return far; + } + private static int compareLocation(int location,Car car){ + return Math.max(car.getLocation(), location); + } + private static Car compareFarLocation(int farLocation,Car car){ + if(car.getLocation() == farLocation){ + return car; + } + return null; + } + public Cars getCars() { + return cars; + } +} + diff --git a/src/main/java/racingcarGame/domain/RandomMovingImpl.java b/src/main/java/racingcarGame/domain/RandomMovingImpl.java new file mode 100644 index 000000000..3814aea5b --- /dev/null +++ b/src/main/java/racingcarGame/domain/RandomMovingImpl.java @@ -0,0 +1,18 @@ +package racingcarGame.domain; + +import java.util.Random; + +public class RandomMovingImpl implements MovingStrategy{ + private static final int MAX_BOUND = 10; + private static final int FORWARD_NUM = 4; + @Override + public boolean movable() { + return getRandomNo() >= FORWARD_NUM; + } + + + private int getRandomNo() { + Random rand = new Random(); + return rand.nextInt(MAX_BOUND); + } +} diff --git a/src/main/java/racingcarGame/utils/GenerateNumber.java b/src/main/java/racingcarGame/utils/GenerateNumber.java new file mode 100644 index 000000000..7b8aea1ee --- /dev/null +++ b/src/main/java/racingcarGame/utils/GenerateNumber.java @@ -0,0 +1,10 @@ +package racingcarGame.utils; + +import java.util.Random; + +public class GenerateNumber { + public static int generateNumber() { + Random rand = new Random(); + return rand.nextInt(10); + } +} diff --git a/src/main/java/racingcarGame/utils/SplitNames.java b/src/main/java/racingcarGame/utils/SplitNames.java new file mode 100644 index 000000000..15f9b5c4c --- /dev/null +++ b/src/main/java/racingcarGame/utils/SplitNames.java @@ -0,0 +1,7 @@ +package racingcarGame.utils; + +public class SplitNames { + public static String[] splitName(String input) { + return input.split(","); + } +} diff --git a/src/main/java/racingcarGame/utils/Validation.java b/src/main/java/racingcarGame/utils/Validation.java new file mode 100644 index 000000000..02bf9941b --- /dev/null +++ b/src/main/java/racingcarGame/utils/Validation.java @@ -0,0 +1,9 @@ +package racingcarGame.utils; + + +// Car 객체 생성자 만들면서 필요 없어짐 +public class Validation { + public static boolean carNameValidator(String carName) { + return carName.length() <= 5; + } +} diff --git a/src/main/java/racingcarGame/views/InputView.java b/src/main/java/racingcarGame/views/InputView.java new file mode 100644 index 000000000..4a6e5c6f0 --- /dev/null +++ b/src/main/java/racingcarGame/views/InputView.java @@ -0,0 +1,18 @@ +package racingcarGame.views; + +import java.util.Scanner; + +public class InputView { + static String nameInput = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)"; + static String timesInput = "시도할 회수는 몇회인가요?"; + + public static String name(Scanner scanner) { + System.out.println(nameInput); + return scanner.nextLine(); + } + + public static int number(Scanner scanner) { + System.out.println(timesInput); + return scanner.nextInt(); + } +} diff --git a/src/main/java/racingcarGame/views/ResultView.java b/src/main/java/racingcarGame/views/ResultView.java new file mode 100644 index 000000000..726751c13 --- /dev/null +++ b/src/main/java/racingcarGame/views/ResultView.java @@ -0,0 +1,40 @@ +package racingcarGame.views; + +import racingcarGame.domain.Car; +import racingcarGame.domain.Cars; + +import java.util.List; + +public class ResultView { + static String resultView = "실행결과"; + static String winningMention = "가 최종 우승했습니다."; + + public static void result() { + System.out.println(resultView); + } + + public static void racingResult(Cars cars){ + for (Car car : cars.getCars()) { + System.out.print(car.getName()+" : "); + locationResult(car); + System.out.println(); + } + } + + private static void locationResult(Car car) { + int location = car.getLocation(); + for (int i = 0 ; i < location ; i++){ + System.out.print("-"); + } + } + + public static void winner(Cars cars) { + List carList = cars.getCars(); + System.out.print(carList.get(0).getName()); + int size = carList.size(); + for (int i = 1; i < size; i++){ + System.out.print(", "+carList.get(i).getName()); + } + System.out.println(winningMention); + } +} diff --git a/src/test/java/racingcarGame/CarTest.java b/src/test/java/racingcarGame/CarTest.java new file mode 100644 index 000000000..0e2e67ca5 --- /dev/null +++ b/src/test/java/racingcarGame/CarTest.java @@ -0,0 +1,32 @@ +package racingcarGame; + +import org.junit.jupiter.api.Test; +import racingcarGame.domain.Car; + +import static org.assertj.core.api.Assertions.*; + +public class CarTest { + + @Test + void 차_1개_생성_테스트() throws Exception { + Car car1 = new Car("hhj12"); + assertThat(car1).isNotEqualTo(null); + assertThat(car1.getLocation()).isEqualTo(0); + assertThat(car1.getName()).isEqualTo("hhj12"); + } + + @Test + void 차_1개_생성_이름_유효성_테스트() throws Exception { + assertThatThrownBy(()->{ + Car car2 = new Car("heehun"); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 차_1대_이동(){ + Car car1 = new Car("hhj12"); + car1.move(5); + assertThat(car1.getLocation()).isEqualTo(1); + } + +} diff --git a/src/test/java/racingcarGame/CarsTest.java b/src/test/java/racingcarGame/CarsTest.java new file mode 100644 index 000000000..b7f5e5c30 --- /dev/null +++ b/src/test/java/racingcarGame/CarsTest.java @@ -0,0 +1,26 @@ +package racingcarGame; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import racingcarGame.domain.Car; +import racingcarGame.domain.Cars; + +import java.util.Arrays; +import java.util.List; + +public class CarsTest { + + @Test + void 차_여러대_생성(){ + Car car1 = new Car("hhj"); + Car car2 = new Car("hhj2"); + Car car3 = new Car("hhj3"); + Car car4 = new Car("hhj4"); + + List car_list = Arrays.asList(car1,car2,car3,car4); + + Cars cars = new Cars(car_list); + + Assertions.assertThat(cars).isNotEqualTo(null); + } +} diff --git a/src/test/java/racingcarGame/LocationTest.java b/src/test/java/racingcarGame/LocationTest.java new file mode 100644 index 000000000..51b19db87 --- /dev/null +++ b/src/test/java/racingcarGame/LocationTest.java @@ -0,0 +1,22 @@ +package racingcarGame; + +import org.junit.jupiter.api.Test; +import racingcarGame.domain.Position; + +import static org.assertj.core.api.Assertions.*; + +public class LocationTest { + @Test + void create() { + Position position = new Position(3); + assertThat(position).isNotNull(); + assertThat(position.getPosition()).isEqualTo(3); + + } + @Test + void valid() { + assertThatThrownBy(() -> new Position(-1)) + .isInstanceOf(IllegalArgumentException.class); + + } +} diff --git a/src/test/java/racingcarGame/RaceTest.java b/src/test/java/racingcarGame/RaceTest.java new file mode 100644 index 000000000..f3521c59d --- /dev/null +++ b/src/test/java/racingcarGame/RaceTest.java @@ -0,0 +1,38 @@ +package racingcarGame; + +import org.junit.jupiter.api.Test; +import racingcarGame.domain.Car; +import racingcarGame.domain.Cars; +import racingcarGame.domain.Race; + +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RaceTest { + +// @Test +// void 차_1대_move_테스트() { +// Car car1 = new Car("hhj"); +// Race race = new Race(car1); +// race.race(); +// assertThat(car1.getLocation()).isEqualTo(1); +// } + + + @Test + void 차_여러대_move_테스트() { + Car car1 = new Car("hhj"); + Car car2 = new Car("hhj2"); + Car car3 = new Car("hhj3"); + Car car4 = new Car("hhj4"); + + List car_list = Arrays.asList(car1,car2,car3,car4); + + Cars cars = new Cars(car_list); + Race race = new Race(cars); + race.race(); + assertThat(cars.getLocations()).isNotEqualTo(Arrays.asList(1,1,1,1)); + } +} diff --git a/src/test/java/racingcarGame/ValidationUtilsTest.java b/src/test/java/racingcarGame/ValidationUtilsTest.java new file mode 100644 index 000000000..f6b50df67 --- /dev/null +++ b/src/test/java/racingcarGame/ValidationUtilsTest.java @@ -0,0 +1,18 @@ +package racingcarGame; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import racingcarGame.utils.Validation; + +public class ValidationUtilsTest { + + @Test + void 자동차_이름_유효성() { + String name = "carname"; + Assertions.assertThat(Validation.carNameValidator(name)) + .isEqualTo(false); + } + + + +} diff --git a/src/test/java/racingcarGame/splitUtilsTest.java b/src/test/java/racingcarGame/splitUtilsTest.java new file mode 100644 index 000000000..ca185f20d --- /dev/null +++ b/src/test/java/racingcarGame/splitUtilsTest.java @@ -0,0 +1,18 @@ +package racingcarGame; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import racingcarGame.utils.SplitNames; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; + +public class splitUtilsTest { + + @Test + void 입력_쉼표_구분자() { + UserInput input = new UserInput("hhj,hhj2,hhj3",5); + assertThat(SplitNames.splitName(input.getInput())).isEqualTo(new String[] { "hhj", "hhj2", "hhj3" }); + } +}