diff --git a/README.md b/README.md index d0286c859f..74e640a2c6 100644 --- a/README.md +++ b/README.md @@ -1 +1,25 @@ # java-racingcar-precourse +--- + +## 기능 요구 사항 +### 자동차 +- [ ] 자동차 이름(플레이어 이름) +- [ ] 전진 + - 랜덤값 4 이상시 +- [ ] 정지 +### 플레이어 +- [ ] 플레이어 이름 +- [ ] 승리 횟수 +### 우승자 +- [ ] 우승자 이름 + +### 예외처리 + +- 자동차 입력 + - [ ] 공백이 들어올경우 + - [ ] 이름에 정규표현식? +- 횟수 입력 + - [ ] 문자입력시 + - [ ] 공백 입력시 + - [ ] 0이나 0보다 작은수 입력 + - [ ] 인트범위를 넘는 수 \ No newline at end of file diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java index a17a52e724..93e3e1469b 100644 --- a/src/main/java/racingcar/Application.java +++ b/src/main/java/racingcar/Application.java @@ -3,5 +3,7 @@ public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + Game game = new Game(); + game.start(); } } diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java new file mode 100644 index 0000000000..b84845d17c --- /dev/null +++ b/src/main/java/racingcar/Car.java @@ -0,0 +1,29 @@ +package racingcar; +import camp.nextstep.edu.missionutils.Randoms; +// + +public class Car { + private final String name; + private int position; + Car(String name){ + this.name = name; + position = 0; + } + Car(String name,int position){ + this.name = name; + this.position = position; + } + public void move(){ + // TODO: 랜덤으로 전진 position +1 + if (Randoms.pickNumberInRange(0,9)>3){ + position++; + } + } + public int getPosition(){ + return position; + } + + public String getName(){ + return name; + } +} diff --git a/src/main/java/racingcar/Game.java b/src/main/java/racingcar/Game.java new file mode 100644 index 0000000000..e37f081baa --- /dev/null +++ b/src/main/java/racingcar/Game.java @@ -0,0 +1,74 @@ +package racingcar; + +import java.util.ArrayList; +import java.util.List; + +public class Game { + List cars = new ArrayList<>(); + + public void start() { + View view = new View(); + + List carNames; + String input; + int count; + + + input = view.inputCars(); + carNames = view.inputCarNames(input); //이름 리스트 생성 + count = view.inputCount(); + cars = addCars(carNames); + playResult(count, cars); + printWinners(winners(cars)); + } + + public List addCars(List carNames) { + for (String carName : carNames) { + Car car = new Car(carName); + cars.add(car); + } + return cars; + } + + public void playResult(int count, List cars) { + System.out.println("실행 결과"); + for (int i = 0; i < count; i++) { + + for (Car car : cars) { + printGame(car); + } + System.out.println(); + + } + } + + public List winners(List cars) { + int max = 0; + List winners = new ArrayList<>(); + + for (Car car : cars) { + if (car.getPosition() > max) + max = car.getPosition(); + } + for (Car car : cars) { + if (car.getPosition() == max) { + winners.add(car.getName()); + } + } + return winners; + } + + public void printWinners(List winners) { + System.out.println("최종 우승자 : " + String.join(", ", winners)); + } + + private void printGame(Car car) { //start + car.move(); + car.getPosition(); + System.out.print(car.getName() + " : "); + for (int i = 0; i < car.getPosition(); i++) { + System.out.print("-"); + } + System.out.println(); + } +} diff --git a/src/main/java/racingcar/View.java b/src/main/java/racingcar/View.java new file mode 100644 index 0000000000..d3ec8b1879 --- /dev/null +++ b/src/main/java/racingcar/View.java @@ -0,0 +1,129 @@ +package racingcar; + +import camp.nextstep.edu.missionutils.Console; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class View { + /* + 클래스 변수, 상수 + + 인스턴스 변수 + + 생성자 + */ + static final int MAX_NAME = 5; + List carNames = new ArrayList(); + List cars = new ArrayList(); + + Game game = new Game(); + + + public void game(){ + int count; + String input; + + input = inputCars(); + carNames =inputCarNames(input); //이름 리스트 생성 + count = inputCount(); + cars = addCars(carNames); + play(count,cars); + System.out.println( game.winners(cars)); + } + /* + 실행 결과 + wo: - + po: + 메소드 구분 + */ + public void play(int count,List cars){ + System.out.println("실행결과"); + for(int i =0; i inputCarNames(String input) { + String[] names = input.split(","); + + for (int i = 0; i < names.length; i++) { + names[i] = names[i].trim(); + isVaildName(names[i]); + } + return Arrays.asList(names); + } + public List addCars(List carNames){ + for(String carName : carNames){ + Car car = new Car(carName); + cars.add(car); + } + return cars; + } + private void isVaildNameMax(String name) { + if (name.length() > MAX_NAME || name.isEmpty()) { + throw new IllegalArgumentException("이름은 1글자 이상 5글자 이하로 입력해주세요."); + } + } + + private void isVaildInputEmpty(String input) { + if (input.isEmpty()) { + throw new IllegalArgumentException("입력이 비었습니다."); + } + } + public void isVaildName(String name) { + if (name.length() > MAX_NAME || name.isEmpty()) { + throw new IllegalArgumentException("이름은 1글자 이상 5글자 이하로 입력해주세요."); + } + if (!name.matches("[0-9|a-z|A-Z|ㄱ-ㅎ|ㅏ-ㅣ|가-힝]*")) { + throw new IllegalArgumentException("이름에 특수문자가 있습니다."); + } + } + public int isVaildNum(String input) { + try { + isVaildInputEmpty(input); + int count = Integer.parseInt(input); + isVaildPositive(count); + return count; + } catch (NumberFormatException e) { + throw new IllegalArgumentException("숫자가 아닙니다."); + } + } + + private void isVaildPositive(int count) { + if (count < 0) { + throw new IllegalArgumentException("0보다 큰 수를 입력해야합니다."); + } + } + +} \ No newline at end of file diff --git a/src/test/java/racingcar/CarTest.java b/src/test/java/racingcar/CarTest.java new file mode 100644 index 0000000000..d17920e7e1 --- /dev/null +++ b/src/test/java/racingcar/CarTest.java @@ -0,0 +1,25 @@ +package racingcar; + + +import org.junit.jupiter.api.*; + +import camp.nextstep.edu.missionutils.test.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; + + +public class CarTest { + + @DisplayName("차 전진 랜덤 테스트") + @Test + void move() { + Car car = new Car("전진"); + Assertions.assertRandomNumberInRangeTest( + () -> { + car.move(); + assertEquals(1,car.getPosition()); + }, + 4 + ); + + } +} diff --git a/src/test/java/racingcar/GameTest.java b/src/test/java/racingcar/GameTest.java new file mode 100644 index 0000000000..cb51e34d7d --- /dev/null +++ b/src/test/java/racingcar/GameTest.java @@ -0,0 +1,66 @@ +package racingcar; + + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +public class GameTest { + @DisplayName("Car 객체 리스트 생성 테스트") + @Test + void addCars() { + Game game = new Game(); + List carNames = Arrays.asList("pobi", "woni", "crong"); + + List result = game.addCars(carNames); + + assertEquals("pobi", result.get(0).getName()); + assertEquals("woni", result.get(1).getName()); + assertEquals("crong", result.get(2).getName()); + } + @DisplayName("우승자 테스트") + @Test + void winnersTest(){ + Game game = new Game(); + + List cars = new ArrayList<>(); + List expected = new ArrayList<>(); + List result = new ArrayList<>(); + + cars.add(new Car("win1", 4)); + cars.add(new Car("win2", 4)); + cars.add(new Car("lose", 2)); + + expected = List.of("win1", "win2"); + result = game.winners(cars); + + assertEquals(expected,result); + + } + @DisplayName("우승자 출력 테스트") + @Test + void printWinners() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(outputStream); + System.setOut(printStream); + + Game game = new Game(); + + List winners = new ArrayList<>(); + + winners = List.of("win1", "win2"); + + game.printWinners(winners); + + assertEquals("최종 우승자 : win1, win2\n", outputStream.toString()); + } +} diff --git a/src/test/java/racingcar/ViewTest.java b/src/test/java/racingcar/ViewTest.java new file mode 100644 index 0000000000..965209f481 --- /dev/null +++ b/src/test/java/racingcar/ViewTest.java @@ -0,0 +1,59 @@ +package racingcar; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +public class ViewTest { + + @DisplayName("이름 분할 테스트") + @ParameterizedTest + @MethodSource("expectedAndResult") + void inputCarNames(String input, List expected) { + + + View view = new View(); + + List result = view.inputCarNames(input); + + + + // 결과 검증 + assertEquals(expected, result); + } + + static Stream expectedAndResult() { + return Stream.of( + Arguments.arguments("woni,pobi", Arrays.asList("woni", "pobi")), + arguments("car1", List.of("car1")), + arguments("pobi ,woni ", Arrays.asList("pobi", "woni")) + ); + } + @DisplayName("숫자 예외처리 테스트") + @Test + void vaildNum() { + View view = new View(); + assertThrows(IllegalArgumentException.class, () -> { + view.isVaildNum("asd"); + }); + } + + @DisplayName("차이름 예외처리 테스트") + @Test + void vaildName() { + View view = new View(); + assertThrows(IllegalArgumentException.class, () -> { + view.isVaildName("wqerrr"); + }); + } +}