From 147abc785bacde2f3f4b29a89ff3dab32a09835f Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 00:09:10 +0900 Subject: [PATCH 01/10] =?UTF-8?q?feat:=20=EB=AC=B8=EC=9E=90=EC=97=B4=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/study/StringAddCalculator.java | 45 ++++++++++ .../java/study/StringAddCalculatorTest.java | 86 +++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 src/main/java/study/StringAddCalculator.java create mode 100644 src/test/java/study/StringAddCalculatorTest.java diff --git a/src/main/java/study/StringAddCalculator.java b/src/main/java/study/StringAddCalculator.java new file mode 100644 index 000000000..4ce3a2b84 --- /dev/null +++ b/src/main/java/study/StringAddCalculator.java @@ -0,0 +1,45 @@ +package study; + +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import jdk.nashorn.internal.runtime.regexp.joni.Regex; + +public class StringAddCalculator { + private final static String BASIC_DELIMITER = ",|:"; + + public int splitAndSum(String str) { + if(isNullOrEmpty(str)) { + return 0; + } + + String delimiter = getDelimiter(str); + if(!delimiter.equals(BASIC_DELIMITER)) { + str = str.substring(4); + } + + return Arrays.stream(str.split(delimiter)) + .mapToInt((num) -> { + if(num.matches("\\d*")){ + return Integer.parseInt(num); + } + throw new RuntimeException(); + }).sum(); + } + + public boolean isNullOrEmpty(String str) { + return str == null || str.isEmpty(); + } + + public String getDelimiter(String str) { + Matcher m = Pattern.compile("//(.)\n(.*)").matcher(str); + + if (m.find()) { + return m.group(1) + "|" + BASIC_DELIMITER; + } + + return BASIC_DELIMITER; + } + +} diff --git a/src/test/java/study/StringAddCalculatorTest.java b/src/test/java/study/StringAddCalculatorTest.java new file mode 100644 index 000000000..13065d8c7 --- /dev/null +++ b/src/test/java/study/StringAddCalculatorTest.java @@ -0,0 +1,86 @@ +package study; + +import static org.assertj.core.api.AssertionsForClassTypes.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class StringAddCalculatorTest { + StringAddCalculator stringAddCalculator; + + @BeforeEach + void setUp() { + stringAddCalculator = new StringAddCalculator(); + } + + @Test + void null_또는_빈문자() { + assertThat(stringAddCalculator.splitAndSum("")).isEqualTo(0); + assertThat(stringAddCalculator.splitAndSum(null)).isEqualTo(0); + } + + @Test + void 숫자_1개() { + assertThat(stringAddCalculator.splitAndSum("5")).isEqualTo(5); + assertThat(stringAddCalculator.splitAndSum("10")).isEqualTo(10); + } + + @Test + void 쉼표_구분자() { + assertThat(stringAddCalculator.splitAndSum("1,2")).isEqualTo(3); + assertThat(stringAddCalculator.splitAndSum("12,3")).isEqualTo(15); + } + + @Test + void 콜론_구분자() { + assertThat(stringAddCalculator.splitAndSum("1:2")).isEqualTo(3); + assertThat(stringAddCalculator.splitAndSum("12:3")).isEqualTo(15); + } + + @Test + void 쉼표_AND_콜론() { + assertThat(stringAddCalculator.splitAndSum("1:2:3,4")).isEqualTo(10); + assertThat(stringAddCalculator.splitAndSum("1,2:3")).isEqualTo(6); + } + + @Test + void 커스텀_구분자() { + assertThat(stringAddCalculator.splitAndSum("//!\n1!2!3")).isEqualTo(6); + assertThat(stringAddCalculator.splitAndSum("//#\n1#2#3")).isEqualTo(6); + assertThat(stringAddCalculator.splitAndSum("//;\n1;2;3")).isEqualTo(6); + } + + @Test + void 커스텀_구분자_AND_쉼표() { + assertThat(stringAddCalculator.splitAndSum("//#\n1#2,3")).isEqualTo(6); + assertThat(stringAddCalculator.splitAndSum("//;\n1;2,3")).isEqualTo(6); + } + + @Test + void 커스텀_구분자_AND_콜롬() { + assertThat(stringAddCalculator.splitAndSum("//#\n1#2:3")).isEqualTo(6); + assertThat(stringAddCalculator.splitAndSum("//;\n1;2:3")).isEqualTo(6); + } + + @Test + void 커스텀_구분자_AND_콜롬_AND_쉼표() { + assertThat(stringAddCalculator.splitAndSum("//#\n1#2:3,4")).isEqualTo(10); + assertThat(stringAddCalculator.splitAndSum("//;\n1;2:3,0")).isEqualTo(6); + } + + @Test + void 음수_포함() { + assertThatThrownBy(() -> stringAddCalculator.splitAndSum("//#\n-1:2:3")) + .isInstanceOf(RuntimeException.class); + } + + @Test + void 정수가_아닌_입력값() { + assertThatThrownBy(() -> stringAddCalculator.splitAndSum("//#\na:32b:3")) + .isInstanceOf(RuntimeException.class); + + assertThatThrownBy(() -> stringAddCalculator.splitAndSum("//#\n1a:b:3")) + .isInstanceOf(RuntimeException.class); + } + +} From e02666da70dcb492c689a0fe59d116e91591b3ad Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 01:30:14 +0900 Subject: [PATCH 02/10] =?UTF-8?q?feat:=20Car=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Car.java | 32 +++++++++++++++ src/main/java/racingcar/MoveStrategy.java | 6 +++ src/test/java/racingcar/CarTest.java | 34 +++++++++++++++ src/test/java/racingcar/CarsTest.java | 50 +++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 src/main/java/racingcar/Car.java create mode 100644 src/main/java/racingcar/MoveStrategy.java create mode 100644 src/test/java/racingcar/CarTest.java create mode 100644 src/test/java/racingcar/CarsTest.java diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/Car.java new file mode 100644 index 000000000..4e50efd7a --- /dev/null +++ b/src/main/java/racingcar/Car.java @@ -0,0 +1,32 @@ + package racingcar; + + public class Car { + private final String name; + private final Position position; + public Car(String name) { + this(name, 0); + } + + public Car(String name, int position) { + if(name.length() == 0 || name.isEmpty()) { + throw new IllegalArgumentException("차 이름은 빈값을 넣을 수 없습니다."); + } + + if(name.length() > 5) { + throw new IllegalArgumentException("차 이름의 길이를 5자를 초과할 수 없습니다."); + } + + this.name = name; + this.position = new Position(position); + } + + public void move(MoveStrategy moveStrategy) { + if(moveStrategy.movable()) { + position.add(); + } + } + + public Position getPosition() { + return this.position; + } + } diff --git a/src/main/java/racingcar/MoveStrategy.java b/src/main/java/racingcar/MoveStrategy.java new file mode 100644 index 000000000..3e94c889c --- /dev/null +++ b/src/main/java/racingcar/MoveStrategy.java @@ -0,0 +1,6 @@ +package racingcar; + +@FunctionalInterface +public interface MoveStrategy { + boolean movable(); +} diff --git a/src/test/java/racingcar/CarTest.java b/src/test/java/racingcar/CarTest.java new file mode 100644 index 000000000..ed237b574 --- /dev/null +++ b/src/test/java/racingcar/CarTest.java @@ -0,0 +1,34 @@ +package racingcar; + +import static org.assertj.core.api.AssertionsForClassTypes.*; + +import org.junit.jupiter.api.Test; + +public class CarTest { + @Test + void create() { + assertThatThrownBy(() -> { + new Car("abcdef"); + }).isInstanceOf(IllegalArgumentException.class); + + assertThatThrownBy(() -> { + new Car(""); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void move() { + Car car = new Car("ws"); + car.move(() -> true); + + assertThat(car.getPosition()).isEqualTo(new Position(1)); + } + + @Test + void notMove() { + Car car = new Car("ws"); + car.move(() -> false); + + assertThat(car.getPosition()).isEqualTo(new Position(0)); + } +} diff --git a/src/test/java/racingcar/CarsTest.java b/src/test/java/racingcar/CarsTest.java new file mode 100644 index 000000000..f32692652 --- /dev/null +++ b/src/test/java/racingcar/CarsTest.java @@ -0,0 +1,50 @@ +package racingcar; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Test; + +public class CarsTest { + @Test + void findWinners() { + Car ws = new Car("ws", 5); + Car mh = new Car("mh", 5); + Car dh = new Car("dh", 3); + Cars cars = new Cars(Arrays.asList(ws, mh, dh)); + + assertThat(cars.findWinners()).containsExactly(ws, mh); + } + + @Test + void getMaxPosition() { + Car ws = new Car("ws", 5); + Car mh = new Car("mh", 4); + Car dh = new Car("dh", 3); + Cars cars = new Cars(Arrays.asList(ws, mh, dh)); + + assertThat(cars.getMaxPosition()).isEqualTo(new Position(5)); + } + + @Test + void moveAll() { + Car ws = new Car("ws", 5); + Car mh = new Car("mh", 4); + Car dh = new Car("dh", 3); + Cars cars = new Cars(Arrays.asList(ws, mh, dh)); + + cars.moveAll(() -> true); + List carList = cars.getCars(); + + assertAll( + () -> assertThat(carList.get(0).getPosition()).isEqualTo(new Position(6)), + () -> assertThat(carList.get(1).getPosition()).isEqualTo(new Position(5)), + () -> assertThat(carList.get(2).getPosition()).isEqualTo(new Position(4)) + ); + + } + +} From c7ed87faae51a8575358d1b8b9b9872787c811ca Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 01:30:28 +0900 Subject: [PATCH 03/10] =?UTF-8?q?feat:=20Position=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Position.java | 40 +++++++++++++++++++++++ src/test/java/racingcar/PositionTest.java | 22 +++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/main/java/racingcar/Position.java create mode 100644 src/test/java/racingcar/PositionTest.java diff --git a/src/main/java/racingcar/Position.java b/src/main/java/racingcar/Position.java new file mode 100644 index 000000000..c3badff5c --- /dev/null +++ b/src/main/java/racingcar/Position.java @@ -0,0 +1,40 @@ +package racingcar; + +import java.util.Comparator; +import java.util.Objects; + +public class Position { + private int position; + + public Position(int position) { + if(position < 0) { + throw new IllegalArgumentException("position은 0보다 적을 수 없습니다."); + } + this.position = position; + } + + public void add() { + position++; + } + + public int getPosition() { + return position; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Position position1 = (Position)o; + return position == position1.position; + } + + @Override + public int hashCode() { + return Objects.hash(position); + } + + +} diff --git a/src/test/java/racingcar/PositionTest.java b/src/test/java/racingcar/PositionTest.java new file mode 100644 index 000000000..a42e427d1 --- /dev/null +++ b/src/test/java/racingcar/PositionTest.java @@ -0,0 +1,22 @@ +package racingcar; + +import static org.assertj.core.api.AssertionsForClassTypes.*; + +import org.junit.jupiter.api.Test; + +public class PositionTest { + @Test + void create() { + assertThatThrownBy( () -> { + new Position(-1); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void add() { + Position position = new Position(1); + position.add(); + + assertThat(position).isEqualTo(new Position(2)); + } +} From 5b7b550dd7cf8168301a7a762140a78a167f5293 Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 01:30:46 +0900 Subject: [PATCH 04/10] =?UTF-8?q?feat:=20Cars,=20RandomMoveStrategy=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Cars.java | 36 +++++++++++++++++++ .../java/racingcar/RandomMoveStrategy.java | 18 ++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/main/java/racingcar/Cars.java create mode 100644 src/main/java/racingcar/RandomMoveStrategy.java diff --git a/src/main/java/racingcar/Cars.java b/src/main/java/racingcar/Cars.java new file mode 100644 index 000000000..802389349 --- /dev/null +++ b/src/main/java/racingcar/Cars.java @@ -0,0 +1,36 @@ +package racingcar; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +public class Cars { + private final List cars; + + public Cars(List cars) { + this.cars = cars; + } + + public List findWinners() { + Position maxPosition = getMaxPosition(); + + return cars.stream() + .filter(car -> car.getPosition().equals(maxPosition)) + .collect(Collectors.toList()); + } + + public Position getMaxPosition() { + + return cars.stream().map(Car::getPosition).max( + Comparator.comparingInt(Position::getPosition) + ).orElse(new Position(0)); + } + + public List getCars() { + return cars; + } + + public void moveAll(MoveStrategy moveStrategy) { + cars.forEach(car -> car.move(moveStrategy)); + } +} diff --git a/src/main/java/racingcar/RandomMoveStrategy.java b/src/main/java/racingcar/RandomMoveStrategy.java new file mode 100644 index 000000000..d0171b9b0 --- /dev/null +++ b/src/main/java/racingcar/RandomMoveStrategy.java @@ -0,0 +1,18 @@ +package racingcar; + +import java.util.Random; + +public class RandomMoveStrategy implements MoveStrategy{ + private static final int FORWARD_NUM = 4; + private static final int MAX_BOUND = 10; + private static final Random RANDOM = new Random(); + + @Override + public boolean movable() { + return getRandomNo() >= FORWARD_NUM; + } + + private int getRandomNo() { + return RANDOM.nextInt(MAX_BOUND); + } +} From bde046a29af83d3e7f81a5a524847466dd126c9a Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 12:55:36 +0900 Subject: [PATCH 05/10] =?UTF-8?q?feat:=20Car=20=ED=94=BC=EB=93=9C=EB=B0=B1?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/{ => domain}/Car.java | 10 +++++++++- src/main/java/racingcar/{ => domain}/MoveStrategy.java | 2 +- src/test/java/racingcar/{ => domain}/CarTest.java | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) rename src/main/java/racingcar/{ => domain}/Car.java (82%) rename src/main/java/racingcar/{ => domain}/MoveStrategy.java (74%) rename src/test/java/racingcar/{ => domain}/CarTest.java (96%) diff --git a/src/main/java/racingcar/Car.java b/src/main/java/racingcar/domain/Car.java similarity index 82% rename from src/main/java/racingcar/Car.java rename to src/main/java/racingcar/domain/Car.java index 4e50efd7a..fdadba97e 100644 --- a/src/main/java/racingcar/Car.java +++ b/src/main/java/racingcar/domain/Car.java @@ -1,4 +1,4 @@ - package racingcar; + package racingcar.domain; public class Car { private final String name; @@ -26,7 +26,15 @@ public void move(MoveStrategy moveStrategy) { } } + public String getName() { + return name; + } + public Position getPosition() { return this.position; } + + public int getDistance() { + return position.getPosition(); + } } diff --git a/src/main/java/racingcar/MoveStrategy.java b/src/main/java/racingcar/domain/MoveStrategy.java similarity index 74% rename from src/main/java/racingcar/MoveStrategy.java rename to src/main/java/racingcar/domain/MoveStrategy.java index 3e94c889c..aaabddc18 100644 --- a/src/main/java/racingcar/MoveStrategy.java +++ b/src/main/java/racingcar/domain/MoveStrategy.java @@ -1,4 +1,4 @@ -package racingcar; +package racingcar.domain; @FunctionalInterface public interface MoveStrategy { diff --git a/src/test/java/racingcar/CarTest.java b/src/test/java/racingcar/domain/CarTest.java similarity index 96% rename from src/test/java/racingcar/CarTest.java rename to src/test/java/racingcar/domain/CarTest.java index ed237b574..0508d9f46 100644 --- a/src/test/java/racingcar/CarTest.java +++ b/src/test/java/racingcar/domain/CarTest.java @@ -1,4 +1,4 @@ -package racingcar; +package racingcar.domain; import static org.assertj.core.api.AssertionsForClassTypes.*; From f455fc17f359e29db044c962cf11f3cf7ed8db2d Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 12:55:51 +0900 Subject: [PATCH 06/10] =?UTF-8?q?feat:=20Position=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/{ => domain}/Position.java | 3 +-- src/test/java/racingcar/{ => domain}/PositionTest.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) rename src/main/java/racingcar/{ => domain}/Position.java (93%) rename src/test/java/racingcar/{ => domain}/PositionTest.java (93%) diff --git a/src/main/java/racingcar/Position.java b/src/main/java/racingcar/domain/Position.java similarity index 93% rename from src/main/java/racingcar/Position.java rename to src/main/java/racingcar/domain/Position.java index c3badff5c..428eb5a54 100644 --- a/src/main/java/racingcar/Position.java +++ b/src/main/java/racingcar/domain/Position.java @@ -1,6 +1,5 @@ -package racingcar; +package racingcar.domain; -import java.util.Comparator; import java.util.Objects; public class Position { diff --git a/src/test/java/racingcar/PositionTest.java b/src/test/java/racingcar/domain/PositionTest.java similarity index 93% rename from src/test/java/racingcar/PositionTest.java rename to src/test/java/racingcar/domain/PositionTest.java index a42e427d1..064c8e3a1 100644 --- a/src/test/java/racingcar/PositionTest.java +++ b/src/test/java/racingcar/domain/PositionTest.java @@ -1,4 +1,4 @@ -package racingcar; +package racingcar.domain; import static org.assertj.core.api.AssertionsForClassTypes.*; From 45ac106475bbc962c556d2d4333fd6b5607ee383 Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 12:56:07 +0900 Subject: [PATCH 07/10] =?UTF-8?q?feat:=20Cars=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/{ => domain}/Cars.java | 17 +++++++++++++---- .../java/racingcar/{ => domain}/CarsTest.java | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) rename src/main/java/racingcar/{ => domain}/Cars.java (73%) rename src/test/java/racingcar/{ => domain}/CarsTest.java (72%) diff --git a/src/main/java/racingcar/Cars.java b/src/main/java/racingcar/domain/Cars.java similarity index 73% rename from src/main/java/racingcar/Cars.java rename to src/main/java/racingcar/domain/Cars.java index 802389349..4a06a7c1b 100644 --- a/src/main/java/racingcar/Cars.java +++ b/src/main/java/racingcar/domain/Cars.java @@ -1,5 +1,6 @@ -package racingcar; +package racingcar.domain; +import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -11,12 +12,20 @@ public Cars(List cars) { this.cars = cars; } - public List findWinners() { + public Cars(String[] names) { + cars = Arrays.stream(names) + .map(Car::new) + .collect(Collectors.toList()); + } + + public Cars findWinners() { Position maxPosition = getMaxPosition(); - return cars.stream() + return new Cars( + cars.stream() .filter(car -> car.getPosition().equals(maxPosition)) - .collect(Collectors.toList()); + .collect(Collectors.toList()) + ); } public Position getMaxPosition() { diff --git a/src/test/java/racingcar/CarsTest.java b/src/test/java/racingcar/domain/CarsTest.java similarity index 72% rename from src/test/java/racingcar/CarsTest.java rename to src/test/java/racingcar/domain/CarsTest.java index f32692652..23e48cbbd 100644 --- a/src/test/java/racingcar/CarsTest.java +++ b/src/test/java/racingcar/domain/CarsTest.java @@ -1,4 +1,4 @@ -package racingcar; +package racingcar.domain; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -9,6 +9,18 @@ import org.junit.jupiter.api.Test; public class CarsTest { + @Test + void create() { + Cars cars = new Cars(new String[]{"ws", "mh", "dh"}); + List carList = cars.getCars(); + + assertAll( + () -> assertThat(carList.get(0).getName()).isEqualTo("ws"), + () -> assertThat(carList.get(1).getName()).isEqualTo("mh"), + () -> assertThat(carList.get(2).getName()).isEqualTo("dh") + ); + } + @Test void findWinners() { Car ws = new Car("ws", 5); @@ -16,7 +28,7 @@ void findWinners() { Car dh = new Car("dh", 3); Cars cars = new Cars(Arrays.asList(ws, mh, dh)); - assertThat(cars.findWinners()).containsExactly(ws, mh); + assertThat(cars.findWinners().getCars()).containsExactly(ws, mh); } @Test From befa3ffc4f8b21c7bbdfc3351d3b549e59810b3d Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 12:56:23 +0900 Subject: [PATCH 08/10] =?UTF-8?q?feat:=20RacingView=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/view/RacingView.java | 44 +++++++++++++ .../java/racingcar/view/RacingViewTest.java | 63 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 src/main/java/racingcar/view/RacingView.java create mode 100644 src/test/java/racingcar/view/RacingViewTest.java diff --git a/src/main/java/racingcar/view/RacingView.java b/src/main/java/racingcar/view/RacingView.java new file mode 100644 index 000000000..7db024943 --- /dev/null +++ b/src/main/java/racingcar/view/RacingView.java @@ -0,0 +1,44 @@ +package racingcar.view; + +import java.util.Scanner; +import java.util.stream.Collectors; + +import racingcar.domain.Car; +import racingcar.domain.Cars; + +public class RacingView { + + public String printRace(Cars cars) { + + return cars.getCars() + .stream() + .map(RacingView::renderCarPosition) + .collect(Collectors.joining("\n")) + + "\n"; + } + + private static String renderCarPosition(Car car) { + return car.getName() + " : " + "-".repeat(car.getDistance() + 1); + } + + public String[] inputNames(Scanner scanner) { + System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분)."); + + return scanner.nextLine().trim().split(","); + } + + public int inputTrialCount(Scanner scanner) { + System.out.println("시도할 회수는 몇회인가요?"); + + return Integer.parseInt(scanner.nextLine()); + } + + public String printWinners(Cars cars) { + Cars winners = cars.findWinners(); + String winnerNames = winners.getCars().stream().map(Car::getName).collect(Collectors.joining(", ")); + + return winnerNames + "가 최종 우승했습니다."; + } + + +} diff --git a/src/test/java/racingcar/view/RacingViewTest.java b/src/test/java/racingcar/view/RacingViewTest.java new file mode 100644 index 000000000..73b50724c --- /dev/null +++ b/src/test/java/racingcar/view/RacingViewTest.java @@ -0,0 +1,63 @@ +package racingcar.view; + +import static org.assertj.core.api.AssertionsForClassTypes.*; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Scanner; + +import org.junit.jupiter.api.Test; + +import racingcar.domain.Car; +import racingcar.domain.Cars; + +public class RacingViewTest { + @Test + void printRace() { + Car ws = new Car("ws", 2); + Car mh = new Car("mh"); + Car dh = new Car("dh", 1); + Cars cars = new Cars(Arrays.asList(ws, mh, dh)); + + RacingView racingView = new RacingView(); + + assertThat(racingView.printRace(cars)).isEqualTo("ws : ---\nmh : -\ndh : --\n"); + } + + @Test + void printWinners() { + Car ws = new Car("ws", 2); + Car mh = new Car("mh"); + Car dh = new Car("dh", 2); + Cars cars = new Cars(Arrays.asList(ws, mh, dh)); + + RacingView racingView = new RacingView(); + + assertThat(racingView.printWinners(cars)).isEqualTo("ws, dh가 최종 우승했습니다."); + } + + @Test + void inputName() { + String input = "ws,mh,dh"; + InputStream in = new ByteArrayInputStream(input.getBytes()); + System.setIn(in); + Scanner scanner = new Scanner(System.in); + + RacingView racingView = new RacingView(); + + assertThat(racingView.inputNames(scanner)).containsExactly("ws", "mh", "dh"); + } + + @Test + void inputTrialCount() { + String input = "5"; + InputStream in = new ByteArrayInputStream(input.getBytes()); + System.setIn(in); + Scanner scanner = new Scanner(System.in); + + RacingView racingView = new RacingView(); + + assertThat(racingView.inputTrialCount(scanner)).isEqualTo(5); + } +} From 7ae9e0ca388881e8b09b460cb90014d71847686a Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 12:56:41 +0900 Subject: [PATCH 09/10] =?UTF-8?q?feat:=20RacingGame,=20RandomMoveStrategy?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racingcar/domain/RacingGame.java | 39 +++++++++++++++++++ .../{ => domain}/RandomMoveStrategy.java | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/main/java/racingcar/domain/RacingGame.java rename src/main/java/racingcar/{ => domain}/RandomMoveStrategy.java (93%) diff --git a/src/main/java/racingcar/domain/RacingGame.java b/src/main/java/racingcar/domain/RacingGame.java new file mode 100644 index 000000000..8b971d8c9 --- /dev/null +++ b/src/main/java/racingcar/domain/RacingGame.java @@ -0,0 +1,39 @@ +package racingcar.domain; + +import racingcar.domain.Cars; +import racingcar.domain.MoveStrategy; + +public class RacingGame { + private final Cars cars; + private final MoveStrategy moveStrategy; + private int trialCount; + + public RacingGame(Cars cars, int trialCount, MoveStrategy moveStrategy) { + if(trialCount < 1) { + throw new IllegalArgumentException("시도할 횟수는 1이상이어야 합니다."); + } + + this.cars = cars; + this.trialCount = trialCount; + this.moveStrategy = moveStrategy; + } + + public boolean isEnd() { + return trialCount == 0; + } + + public Cars race() { + if(trialCount == 0) { + return cars; + } + + trialCount--; + cars.moveAll(moveStrategy); + return cars; + } + + public Cars getWinners() { + return cars.findWinners(); + } + +} diff --git a/src/main/java/racingcar/RandomMoveStrategy.java b/src/main/java/racingcar/domain/RandomMoveStrategy.java similarity index 93% rename from src/main/java/racingcar/RandomMoveStrategy.java rename to src/main/java/racingcar/domain/RandomMoveStrategy.java index d0171b9b0..842242b6a 100644 --- a/src/main/java/racingcar/RandomMoveStrategy.java +++ b/src/main/java/racingcar/domain/RandomMoveStrategy.java @@ -1,4 +1,4 @@ -package racingcar; +package racingcar.domain; import java.util.Random; From aefc6e69f1b1fbc8a95c737496d6a3ca6a480baf Mon Sep 17 00:00:00 2001 From: Songwonseok Date: Mon, 14 Mar 2022 12:56:57 +0900 Subject: [PATCH 10/10] =?UTF-8?q?feat:=20=EB=A0=88=EC=9D=B4=EC=8B=B1?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EB=A9=94=EC=9D=B8=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/racingcar/Application.java | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/racingcar/Application.java diff --git a/src/main/java/racingcar/Application.java b/src/main/java/racingcar/Application.java new file mode 100644 index 000000000..9e5c50d63 --- /dev/null +++ b/src/main/java/racingcar/Application.java @@ -0,0 +1,32 @@ +package racingcar; + +import java.util.Scanner; + +import racingcar.domain.Cars; +import racingcar.domain.RacingGame; +import racingcar.domain.RandomMoveStrategy; +import racingcar.view.RacingView; + +public class Application { + public static void main(String[] args) { + RacingView racingView = new RacingView(); + + Scanner scanner = new Scanner(System.in); + + try { + String[] names = racingView.inputNames(scanner); + Cars cars = new Cars(names); + int trialCount = racingView.inputTrialCount(scanner); + + RacingGame racingGame = new RacingGame(cars, trialCount, new RandomMoveStrategy()); + + while(!racingGame.isEnd()) { + System.out.println(racingView.printRace(racingGame.race())); + } + + System.out.println(racingView.printWinners(racingGame.getWinners())); + }catch(Exception e) { + System.out.println(e.getMessage()); + } + } +}