diff --git a/src/main/java/car/Car.java b/src/main/java/car/Car.java new file mode 100644 index 000000000..e223fc3b5 --- /dev/null +++ b/src/main/java/car/Car.java @@ -0,0 +1,30 @@ +package car; + +import java.util.Random; + +public class Car { + private static final int MINIMUM_MOVING_STANDARD = 4; + private final String name; + private int location = 1; + public Car(String name) { + if (name.length() > 5) throw new RuntimeException(); + this.name = name; + } + + public int getLocation(){ + return this.location; + } + + public void move(){ + if (MINIMUM_MOVING_STANDARD <= getRandomNum()) this.location++; + } + + protected int getRandomNum(){ + Random random = new Random(); + return random.nextInt(10); + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/car/CarController.java b/src/main/java/car/CarController.java new file mode 100644 index 000000000..987b0086f --- /dev/null +++ b/src/main/java/car/CarController.java @@ -0,0 +1,27 @@ +package car; + +import java.io.IOException; + +public class CarController { + private final InputView inputView; + private final OutputView outputView; + + public CarController(InputView inputView, OutputView outputView) { // 둘은 완전히 책임이 다르므로 의존주입 받기 + this.inputView = inputView; + this.outputView = outputView; + } + + public void game() throws IOException { + outputView.inputName(); + String input = inputView.getInput(); + String[] splitInput = inputView.getCars(input); + Cars cars = new Cars(splitInput); + outputView.getTrial(); + int trial = Integer.parseInt(inputView.getInput()); + for (int i = 0; i < trial; i++) { + cars.move(); + outputView.result(cars); + } + outputView.winner(cars); + } +} diff --git a/src/main/java/car/Cars.java b/src/main/java/car/Cars.java new file mode 100644 index 000000000..a7c94c6ac --- /dev/null +++ b/src/main/java/car/Cars.java @@ -0,0 +1,33 @@ +package car; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class Cars { + private final List cars; + + public Cars(String[] nameArr){ + this.cars = Arrays.stream(nameArr).map(Car::new).collect(Collectors.toList()); + } + + public void move(){ + cars.forEach(Car::move); + } + + public List getCars() { + return cars; + } + + public List winners() { + int maxLocation = cars.stream() + .mapToInt(Car::getLocation) + .max() + .orElse(0); + + return cars.stream() + .filter(car -> car.getLocation() == maxLocation) + .map(Car::getName) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/car/InputView.java b/src/main/java/car/InputView.java new file mode 100644 index 000000000..46ea60462 --- /dev/null +++ b/src/main/java/car/InputView.java @@ -0,0 +1,16 @@ +package car; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class InputView { + public String[] getCars(String s) { + return s.split(","); + } + + public String getInput() throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + return br.readLine(); + } +} diff --git a/src/main/java/car/Main.java b/src/main/java/car/Main.java new file mode 100644 index 000000000..5bff6a8d5 --- /dev/null +++ b/src/main/java/car/Main.java @@ -0,0 +1,16 @@ +package car; + +import car.CarController; +import car.InputView; +import car.OutputView; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) throws IOException { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + CarController carController = new CarController(inputView, outputView); + carController.game(); + } +} diff --git a/src/main/java/car/OutputView.java b/src/main/java/car/OutputView.java new file mode 100644 index 000000000..8c51d505e --- /dev/null +++ b/src/main/java/car/OutputView.java @@ -0,0 +1,45 @@ +package car; + +import java.util.List; + +public class OutputView { + public void inputName(){ + System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); + } + + public void getTrial(){ + System.out.println("시도할 회수는 몇회인가요?"); + } + + public void result(Cars cars){ + List carList = cars.getCars(); + for (Car car : carList) { + System.out.println(carInfo(car)); + } + } + + public void winner(Cars cars){ + List winners = cars.winners(); + if (winners.size() == 1){ + System.out.println(winners.get(0) + "가 최종 우승했습니다."); + } + if (winners.size() > 1){ + StringBuilder sb = new StringBuilder(); + sb.append(String.join(", ", winners)); + sb.append("가 최종 우승했습니다."); + System.out.println(sb.toString()); + } + } + + private String carInfo(Car car) { + return car.getName() + " : " + intToMinus(car.getLocation()); + } + + private String intToMinus(int location){ + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < location; i++) { + sb.append("-"); + } + return sb.toString(); + } +} diff --git a/src/main/java/string_calculator/StringAddCalculator.java b/src/main/java/string_calculator/StringAddCalculator.java new file mode 100644 index 000000000..7c5e25069 --- /dev/null +++ b/src/main/java/string_calculator/StringAddCalculator.java @@ -0,0 +1,46 @@ +package string_calculator; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StringAddCalculator { + + public static int splitAndSum(String s) { + if (noInput(s)) return 0; + if (isJustOneInt(s)) return convertToInt(s); + s = replaceColon(s); + return calculateByRest(s); + } + + private static boolean noInput(String s) { + return s == null || s.isEmpty(); + } + + private static String replaceColon(String s){ + return s.replaceAll(":", ","); + } + private static String splitByPattern(String s){ + Matcher m = Pattern.compile("//(.)\n(.*)").matcher(s); + if (m.find()) { + String customDelimiter = m.group(1); + return m.group(2).replaceAll(customDelimiter, ","); + } + return null; + } + private static int calculateByRest(String s){ + String[] split = s.split(","); + int sum = 0; + for (String s1 : split) { + sum +=convertToInt(s1); + } + return sum; + } + + private static boolean isJustOneInt(String s) { + return s.length() == 1; + } + + private static int convertToInt(String s){ + return Integer.parseInt(s); + } +} diff --git a/src/test/java/CarRacingTest.java b/src/test/java/CarRacingTest.java new file mode 100644 index 000000000..4526389d6 --- /dev/null +++ b/src/test/java/CarRacingTest.java @@ -0,0 +1,54 @@ +import car.Car; +import car.Cars; +import car.InputView; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Random; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +class CarRacingTest { + @Test + void inputByComma(){ + InputView inputView = new InputView(); + String s = "one,two,three"; + String[] cars = inputView.getCars(s); + assertThat(cars.length).isEqualTo(3); + } + + @Test + void carName_failureTest(){ + String name = "more than five words"; + assertThatThrownBy(() -> new Car(name)); + } + @Test + void randomTest(){ + Random random = new Random(); + System.out.println(random.nextInt(10)); + } + @Test + void carMoveTest(){ + Car car = new Car("12"); + while (car.getLocation() != 3){ + car.move(); + } + assertThat(car.getLocation()).isEqualTo(3); + } + + @Test + void carsTest(){ + String[] nameArr = new String[]{"1", "2", "3"}; + Cars cars = new Cars(nameArr); + for (int i = 0; i < 5; i++) { + cars.move(); + } + List cars1 = cars.getCars(); + int count = 0; + for (Car car1 : cars1) { + count += car1.getLocation(); + } + assertThat(count).isGreaterThan(3); // 초기값 3보다는 어쨋든 움직일 확률이 매우 큼 + } +} diff --git a/src/test/java/CarTest.java b/src/test/java/CarTest.java new file mode 100644 index 000000000..efec9dae4 --- /dev/null +++ b/src/test/java/CarTest.java @@ -0,0 +1,30 @@ +import car.Car; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class CarTest { + @Test + void move_SUCCESS(){ + Car car = new Car("소나타"){ + @Override + protected int getRandomNum() { + return 4; + } + }; + car.move(); + assertThat(car.getLocation()).isEqualTo(2); + } + + @Test + void move_FAILURE(){ + Car car = new Car("소나타"){ + @Override + protected int getRandomNum() { + return 3; + } + }; + car.move(); + assertThat(car.getLocation()).isEqualTo(1); + } +} \ No newline at end of file diff --git a/src/test/java/StringAddCalculatorTest.java b/src/test/java/StringAddCalculatorTest.java new file mode 100644 index 000000000..331ae7852 --- /dev/null +++ b/src/test/java/StringAddCalculatorTest.java @@ -0,0 +1,33 @@ +import org.junit.jupiter.api.Test; +import string_calculator.StringAddCalculator; + +import static org.assertj.core.api.Assertions.assertThat; + +class StringAddCalculatorTest { + @Test + public void splitAndSum_null_또는_빈문자() { + int result = StringAddCalculator.splitAndSum(null); + assertThat(result).isEqualTo(0); + + result = StringAddCalculator.splitAndSum(""); + assertThat(result).isEqualTo(0); + } + + @Test + public void splitAndSum_숫자하나() throws Exception { + int result = StringAddCalculator.splitAndSum("1"); + assertThat(result).isEqualTo(1); + } + + @Test + public void splitAndSum_쉼표구분자() throws Exception { + int result = StringAddCalculator.splitAndSum("1,2"); + assertThat(result).isEqualTo(3); + } + + @Test + public void splitAndSum_쉼표_또는_콜론_구분자() throws Exception { + int result = StringAddCalculator.splitAndSum("1,2:3"); + assertThat(result).isEqualTo(6); + } +} diff --git a/src/test/java/StringCalculatorTest.java b/src/test/java/StringCalculatorTest.java new file mode 100644 index 000000000..780fe8e0c --- /dev/null +++ b/src/test/java/StringCalculatorTest.java @@ -0,0 +1,51 @@ +import org.junit.jupiter.api.Test; +import string_calculator.StringAddCalculator; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +class StringCalculatorTest { + @Test + public void splitAndSum_null_또는_빈문자() { + int result = StringAddCalculator.splitAndSum(null); + assertThat(result).isEqualTo(0); + result = StringAddCalculator.splitAndSum(""); + assertThat(result).isEqualTo(0); + } + + @Test + public void splitAndSum_숫자하나() throws Exception { + int result = StringAddCalculator.splitAndSum("1"); + assertThat(result).isEqualTo(1); + } + + @Test + public void splitAndSum_쉼표구분자() throws Exception { + int result = StringAddCalculator.splitAndSum("1,2"); + assertThat(result).isEqualTo(3); + } + + @Test + public void splitAndSum_쉼표_또는_콜론_구분자() throws Exception { + int result = StringAddCalculator.splitAndSum("1,2:3"); + assertThat(result).isEqualTo(6); + } + + @Test + public void splitAndSum_custom_구분자() throws Exception { + int result = StringAddCalculator.splitAndSum("//;\n1;2;3"); + assertThat(result).isEqualTo(6); + } + + @Test + public void splitAndSum_negative() throws Exception { + assertThatThrownBy(() -> StringAddCalculator.splitAndSum("-1,2,3")) + .isInstanceOf(RuntimeException.class); + } + + @Test // 그냥 contains("-") 로 완전히 막을수도 있음. + public void splitAndSum_커스텀마이너스_핸들(){ + int result = StringAddCalculator.splitAndSum("//-\n1-2-3"); + assertThat(result).isEqualTo(6); + } +} \ No newline at end of file