From f851cb79792efb856604be81615cebeb49e21397 Mon Sep 17 00:00:00 2001 From: sang5c Date: Wed, 3 Apr 2024 00:18:34 +0900 Subject: [PATCH 01/36] build: java 11 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index db8d2fdbd8..b7e31be58a 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'java' apply plugin: 'eclipse' version = '1.0.0' -sourceCompatibility = 1.8 +sourceCompatibility = 11 repositories { mavenCentral() From f887f8a479159011893efbd94f1d5207df2166cb Mon Sep 17 00:00:00 2001 From: sang5c Date: Wed, 3 Apr 2024 00:21:43 +0900 Subject: [PATCH 02/36] =?UTF-8?q?docs:=20step2=20=EC=9A=94=EA=B5=AC?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b853592f59..038d9e4495 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,44 @@ # 사다리 게임 + ## 진행 방법 + * 사다리 게임 게임 요구사항을 파악한다. * 요구사항에 대한 구현을 완료한 후 자신의 github 아이디에 해당하는 브랜치에 Pull Request(이하 PR)를 통해 코드 리뷰 요청을 한다. * 코드 리뷰 피드백에 대한 개선 작업을 하고 다시 PUSH한다. * 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다. ## 온라인 코드 리뷰 과정 -* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/nextstep-step/nextstep-docs/tree/master/codereview) \ No newline at end of file + +* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/nextstep-step/nextstep-docs/tree/master/codereview) + +--- + +## Step 2. 사다리(생성) + +### 기능 요구사항 + +- 사다리 게임에 참여하는 사람에 이름을 최대5글자까지 부여할 수 있다. 사다리를 출력할 때 사람 이름도 같이 출력한다. +- 사람 이름은 쉼표(,)를 기준으로 구분한다. +- 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다. +- 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다. +- |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다. + +### 프로그래밍 요구사항 +- 자바 8의 스트림과 람다를 적용해 프로그래밍한다. +- 규칙 6: 모든 엔티티를 작게 유지한다. + +### 요구사항 분석 + +- [ ] 사용자는 이름을 갖는다. + - [ ] 이름은 최대 5자이다. + - [ ] 이름이 비어있거나 6자 이상이면 예외가 발생한다. +- [ ] 사람 수 만큼 사다리가 생성된다. + - [ ] 사다리의 각 라인에는 사람 수 만큼 포인트(점)이 생성된다. + - 라인은 가로 라인을 의미한다. + - [ ] 가장 왼쪽 사다리에서는 좌로 이동 불가하다. + - [ ] 가장 오른쪽 사다리에서는 우로 이동 불가하다. +- [ ] 포인트에서는 좌, 우로 이동할 수 있다. + - 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. + - [ ] 좌 이동 불가, 우 이동 불가 + - [ ] 좌 이동 가능, 우 이동 불가 + - [ ] 좌 이동 불가, 우 이동 가능 From 0c09d1eb1fc4ed5ba3d4852b9189045604bb35c1 Mon Sep 17 00:00:00 2001 From: sang5c Date: Thu, 4 Apr 2024 03:14:58 +0900 Subject: [PATCH 03/36] =?UTF-8?q?feat:=20=EC=82=AC=EB=8B=A4=EB=A6=AC=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EA=B8=B0=EB=B3=B8=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=ED=98=95=ED=83=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/LadderGame.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/main/java/nextstep/ladder/LadderGame.java diff --git a/src/main/java/nextstep/ladder/LadderGame.java b/src/main/java/nextstep/ladder/LadderGame.java new file mode 100644 index 0000000000..e4f4435097 --- /dev/null +++ b/src/main/java/nextstep/ladder/LadderGame.java @@ -0,0 +1,31 @@ +package nextstep.ladder; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class LadderGame { + + private static final int MAX_NAME_LENGTH = 5; + + public static void main(String[] args) { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + String input = "pobi,honux,crong,jk"; + List users = Arrays.stream(input.split(",")) + .collect(Collectors.toList()); + int countOfPerson = users.size(); + + System.out.println("최대 사다리 높이는 몇 개인가요?"); + int height = 5; + + System.out.println("실행결과"); + String collect = users.stream() + .map(name -> String.format("%5s", name)) + .collect(Collectors.joining(" ")); + + System.out.println(collect); + for (int i = 0; i < height; i++) { + System.out.println(" ".repeat(MAX_NAME_LENGTH) + "|" + "-".repeat(MAX_NAME_LENGTH) + "|" + "-".repeat(MAX_NAME_LENGTH) + "|" + "-".repeat(MAX_NAME_LENGTH) + "|"); + } + } +} From f6311a6de5840eeac8207e4926bf80f44da1e545 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 15:54:49 +0900 Subject: [PATCH 04/36] =?UTF-8?q?docs:=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EB=B6=84=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 038d9e4495..306dcf7c40 100644 --- a/README.md +++ b/README.md @@ -32,12 +32,14 @@ - [ ] 사용자는 이름을 갖는다. - [ ] 이름은 최대 5자이다. - [ ] 이름이 비어있거나 6자 이상이면 예외가 발생한다. -- [ ] 사람 수 만큼 사다리가 생성된다. - - [ ] 사다리의 각 라인에는 사람 수 만큼 포인트(점)이 생성된다. - - 라인은 가로 라인을 의미한다. - - [ ] 가장 왼쪽 사다리에서는 좌로 이동 불가하다. - - [ ] 가장 오른쪽 사다리에서는 우로 이동 불가하다. -- [ ] 포인트에서는 좌, 우로 이동할 수 있다. +- [ ] 사다리 + - [ ] 사다리의 높이를 설정할 수 있다. + - [ ] 사다리의 세로 라인은 사람 수 만큼 생성된다. (너비) + - [ ] 사다리의 각 가로 라인에는 포인트(점)가 생성된다. +- [ ] 포인트 + - [ ] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. + - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. + - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. - 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. - [ ] 좌 이동 불가, 우 이동 불가 - [ ] 좌 이동 가능, 우 이동 불가 From 066ce9d7370569560f3f346e5a91730cb0b62810 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 16:04:56 +0900 Subject: [PATCH 05/36] build: gradle 5.0 --- gradle/wrapper/gradle-wrapper.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 290541c738..8c41e30626 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Sat Apr 06 16:04:18 KST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 1adfd820fb6a5a392e588854ca5fc0b6d5050830 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 16:06:08 +0900 Subject: [PATCH 06/36] =?UTF-8?q?feat:=20=EC=A2=8C,=20=EC=9A=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=91=90=20=EC=9D=B4=EB=8F=99=20=EA=B0=80=EB=8A=A5?= =?UTF-8?q?=ED=95=9C=20Point=EB=8A=94=20=EC=83=9D=EC=84=B1=ED=95=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=97=86=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/nextstep/ladder/Point.java | 14 ++++++++++++++ src/test/java/nextstep/ladder/PointTest.java | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/main/java/nextstep/ladder/Point.java create mode 100644 src/test/java/nextstep/ladder/PointTest.java diff --git a/README.md b/README.md index 306dcf7c40..915b8d534f 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ - [ ] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. - - 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. + - [X] 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. - [ ] 좌 이동 불가, 우 이동 불가 - [ ] 좌 이동 가능, 우 이동 불가 - [ ] 좌 이동 불가, 우 이동 가능 diff --git a/src/main/java/nextstep/ladder/Point.java b/src/main/java/nextstep/ladder/Point.java new file mode 100644 index 0000000000..44753480d0 --- /dev/null +++ b/src/main/java/nextstep/ladder/Point.java @@ -0,0 +1,14 @@ +package nextstep.ladder; + +public class Point { + private final boolean left; + private final boolean right; + + public Point(boolean left, boolean right) { + if (left && right) { + throw new IllegalArgumentException("좌 우 모두 이동 가능한 Point 생성 불가"); + } + this.left = left; + this.right = right; + } +} diff --git a/src/test/java/nextstep/ladder/PointTest.java b/src/test/java/nextstep/ladder/PointTest.java new file mode 100644 index 0000000000..35a129df90 --- /dev/null +++ b/src/test/java/nextstep/ladder/PointTest.java @@ -0,0 +1,17 @@ +package nextstep.ladder; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PointTest { + + @DisplayName("좌 우 모두 이동 가능한 Point는 생성할 수 없다") + @Test + void create() { + assertThatThrownBy(() -> new Point(true, true)) + .isInstanceOf(IllegalArgumentException.class); + } + +} From dff107231e05b1d2da2028543a379584c0acaf79 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 16:11:59 +0900 Subject: [PATCH 07/36] =?UTF-8?q?test:=20Point=EB=8A=94=20=EC=A2=8C,=20?= =?UTF-8?q?=EC=9A=B0=20=EC=9D=B4=EB=8F=99=20=EA=B0=80=EB=8A=A5=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=EB=A5=BC=20=EA=B0=80=EC=A7=84=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++------- src/main/java/nextstep/ladder/Point.java | 8 ++++++++ src/test/java/nextstep/ladder/PointTest.java | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 915b8d534f..3a0619dc36 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,12 @@ - [ ] 사다리 - [ ] 사다리의 높이를 설정할 수 있다. - [ ] 사다리의 세로 라인은 사람 수 만큼 생성된다. (너비) - - [ ] 사다리의 각 가로 라인에는 포인트(점)가 생성된다. -- [ ] 포인트 - [ ] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. - - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. - - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. + - [ ] 사다리의 각 가로 라인에는 포인트(점)가 생성된다. + - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. + - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. +- [ ] 포인트 - [X] 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. - - [ ] 좌 이동 불가, 우 이동 불가 - - [ ] 좌 이동 가능, 우 이동 불가 - - [ ] 좌 이동 불가, 우 이동 가능 + - [X] 좌 이동 불가, 우 이동 불가 + - [X] 좌 이동 가능, 우 이동 불가 + - [X] 좌 이동 불가, 우 이동 가능 diff --git a/src/main/java/nextstep/ladder/Point.java b/src/main/java/nextstep/ladder/Point.java index 44753480d0..23050cad0d 100644 --- a/src/main/java/nextstep/ladder/Point.java +++ b/src/main/java/nextstep/ladder/Point.java @@ -11,4 +11,12 @@ public Point(boolean left, boolean right) { this.left = left; this.right = right; } + + public boolean canMoveLeft() { + return left; + } + + public boolean canMoveRight() { + return right; + } } diff --git a/src/test/java/nextstep/ladder/PointTest.java b/src/test/java/nextstep/ladder/PointTest.java index 35a129df90..c8df85c7ad 100644 --- a/src/test/java/nextstep/ladder/PointTest.java +++ b/src/test/java/nextstep/ladder/PointTest.java @@ -2,16 +2,29 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; class PointTest { @DisplayName("좌 우 모두 이동 가능한 Point는 생성할 수 없다") @Test - void create() { + void invalidPoint() { assertThatThrownBy(() -> new Point(true, true)) .isInstanceOf(IllegalArgumentException.class); } + @DisplayName("Point는 좌 우 이동 가능 여부를 가진다") + @ParameterizedTest(name = "좌 이동: {0}, 우 이동: {1})") + @CsvSource(value = {"true,false", "false,true", "false,false"}) + void create(boolean left, boolean right) { + Point point = new Point(left, right); + + assertThat(point.canMoveLeft()).isEqualTo(left); + assertThat(point.canMoveRight()).isEqualTo(right); + } + } From 85f0fccd8fa51543a526c5389bd392ea23905d7e Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 16:52:43 +0900 Subject: [PATCH 08/36] =?UTF-8?q?feat:=20=EC=82=AC=EB=9E=8C=20=EC=88=98?= =?UTF-8?q?=EB=A5=BC=20=EB=B0=9B=EC=95=84=20=EA=B0=80=EB=A1=9C=20=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=EC=9D=84=20=EC=83=9D=EC=84=B1=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 26 ++++++----- src/main/java/nextstep/ladder/Line.java | 51 +++++++++++++++++++++ src/test/java/nextstep/ladder/LineTest.java | 15 ++++++ 3 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 src/main/java/nextstep/ladder/Line.java create mode 100644 src/test/java/nextstep/ladder/LineTest.java diff --git a/README.md b/README.md index 3a0619dc36..320e08f5ec 100644 --- a/README.md +++ b/README.md @@ -24,23 +24,25 @@ - |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다. ### 프로그래밍 요구사항 + - 자바 8의 스트림과 람다를 적용해 프로그래밍한다. - 규칙 6: 모든 엔티티를 작게 유지한다. ### 요구사항 분석 - [ ] 사용자는 이름을 갖는다. - - [ ] 이름은 최대 5자이다. - - [ ] 이름이 비어있거나 6자 이상이면 예외가 발생한다. + - [ ] 이름은 최대 5자이다. + - [ ] 이름이 비어있거나 6자 이상이면 예외가 발생한다. - [ ] 사다리 - - [ ] 사다리의 높이를 설정할 수 있다. - - [ ] 사다리의 세로 라인은 사람 수 만큼 생성된다. (너비) - - [ ] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. - - [ ] 사다리의 각 가로 라인에는 포인트(점)가 생성된다. - - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. - - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. + - [ ] 사다리의 가로 라인을 수를 설정할 수 있다. (높이) + - [ ] 사다리의 세로 라인은 사람 수 만큼 생성된다. (너비) + - [X] 사다리의 각 가로 라인에는 사람 수 만큼 포인트(점)가 생성된다. + - [ ] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. + - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. + - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. + - [ ] 연속으로 이동 가능한 포인트는 존재할 수 없다. - [ ] 포인트 - - [X] 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. - - [X] 좌 이동 불가, 우 이동 불가 - - [X] 좌 이동 가능, 우 이동 불가 - - [X] 좌 이동 불가, 우 이동 가능 + - [X] 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. + - [X] 좌 이동 불가, 우 이동 불가 + - [X] 좌 이동 가능, 우 이동 불가 + - [X] 좌 이동 불가, 우 이동 가능 diff --git a/src/main/java/nextstep/ladder/Line.java b/src/main/java/nextstep/ladder/Line.java new file mode 100644 index 0000000000..c685560450 --- /dev/null +++ b/src/main/java/nextstep/ladder/Line.java @@ -0,0 +1,51 @@ +package nextstep.ladder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class Line { + private static final Random RANDOM = new Random(); + + private List points; + + private Line(List points) { + if (points == null || points.isEmpty()) { + throw new IllegalArgumentException("점이 없습니다."); + } + this.points = points; + } + + public static Line createLine(int countOfPerson) { + return new Line(createPoints(countOfPerson)); + } + + private static List createPoints(int count) { + List points = new ArrayList<>(); + + boolean moveable = RANDOM.nextBoolean(); + points.add(createFirstPoint(moveable)); + + boolean leftMoveable = moveable; + for (int i = 1; i < count - 2; i++) { + boolean rightMoveable = RANDOM.nextBoolean(); + if (leftMoveable) { + rightMoveable = false; + } + points.add(new Point(moveable, rightMoveable)); + leftMoveable = rightMoveable; + } + + points.add(createLastPoint(leftMoveable)); + + return points; + } + + private static Point createLastPoint(boolean leftMoveable) { + return new Point(leftMoveable, false); + } + + private static Point createFirstPoint(boolean rightMoveable) { + return new Point(false, rightMoveable); + } +} diff --git a/src/test/java/nextstep/ladder/LineTest.java b/src/test/java/nextstep/ladder/LineTest.java new file mode 100644 index 0000000000..2ec07462a8 --- /dev/null +++ b/src/test/java/nextstep/ladder/LineTest.java @@ -0,0 +1,15 @@ +package nextstep.ladder; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatCode; + +class LineTest { + + @DisplayName("사람 수를 받아 가로 라인을 생성한다") + @Test + void createLine() { + assertThatCode(() -> Line.createLine(5)).doesNotThrowAnyException(); + } +} From ad63923ee731d8cdd76815e48ca49666580eb094 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 17:10:11 +0900 Subject: [PATCH 09/36] =?UTF-8?q?refactor:=20=ED=8F=AC=EC=9D=B8=ED=8A=B8?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/Line.java | 12 ++---------- src/main/java/nextstep/ladder/Point.java | 8 ++++++++ src/test/java/nextstep/ladder/PointTest.java | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/nextstep/ladder/Line.java b/src/main/java/nextstep/ladder/Line.java index c685560450..0ed423969f 100644 --- a/src/main/java/nextstep/ladder/Line.java +++ b/src/main/java/nextstep/ladder/Line.java @@ -24,7 +24,7 @@ private static List createPoints(int count) { List points = new ArrayList<>(); boolean moveable = RANDOM.nextBoolean(); - points.add(createFirstPoint(moveable)); + points.add(Point.leftmostPoint(moveable)); boolean leftMoveable = moveable; for (int i = 1; i < count - 2; i++) { @@ -36,16 +36,8 @@ private static List createPoints(int count) { leftMoveable = rightMoveable; } - points.add(createLastPoint(leftMoveable)); + points.add(Point.rightmostPoint(leftMoveable)); return points; } - - private static Point createLastPoint(boolean leftMoveable) { - return new Point(leftMoveable, false); - } - - private static Point createFirstPoint(boolean rightMoveable) { - return new Point(false, rightMoveable); - } } diff --git a/src/main/java/nextstep/ladder/Point.java b/src/main/java/nextstep/ladder/Point.java index 23050cad0d..f62e553091 100644 --- a/src/main/java/nextstep/ladder/Point.java +++ b/src/main/java/nextstep/ladder/Point.java @@ -12,6 +12,14 @@ public Point(boolean left, boolean right) { this.right = right; } + public static Point leftmostPoint(boolean rightMoveable) { + return new Point(false, rightMoveable); + } + + public static Point rightmostPoint(boolean leftMoveable) { + return new Point(leftMoveable, false); + } + public boolean canMoveLeft() { return left; } diff --git a/src/test/java/nextstep/ladder/PointTest.java b/src/test/java/nextstep/ladder/PointTest.java index c8df85c7ad..d58bd05b63 100644 --- a/src/test/java/nextstep/ladder/PointTest.java +++ b/src/test/java/nextstep/ladder/PointTest.java @@ -27,4 +27,19 @@ void create(boolean left, boolean right) { assertThat(point.canMoveRight()).isEqualTo(right); } + @DisplayName("가장 왼쪽 포인트는 왼쪽으로 이동할 수 없다") + @Test + void leftmostPoint() { + Point point = Point.leftmostPoint(true); + + assertThat(point.canMoveLeft()).isFalse(); + } + + @DisplayName("가장 오른쪽 포인트는 오른쪽으로 이동할 수 없다") + @Test + void rightmostPoint() { + Point point = Point.rightmostPoint(true); + + assertThat(point.canMoveRight()).isFalse(); + } } From 2368cef396871c97c987a7ef80ac3c489c77f3f7 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 17:18:13 +0900 Subject: [PATCH 10/36] =?UTF-8?q?refactor:=20=EB=9E=9C=EB=8D=A4=20?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=83=9D=EC=84=B1=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=AA=85=ED=99=95=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/Line.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/nextstep/ladder/Line.java b/src/main/java/nextstep/ladder/Line.java index 0ed423969f..528028cbf9 100644 --- a/src/main/java/nextstep/ladder/Line.java +++ b/src/main/java/nextstep/ladder/Line.java @@ -17,10 +17,10 @@ private Line(List points) { } public static Line createLine(int countOfPerson) { - return new Line(createPoints(countOfPerson)); + return new Line(generateRandomPoints(countOfPerson)); } - private static List createPoints(int count) { + private static List generateRandomPoints(int count) { List points = new ArrayList<>(); boolean moveable = RANDOM.nextBoolean(); From 7f26af3aad10b82282c5e1e423155f3b5ed4f2d4 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 17:39:59 +0900 Subject: [PATCH 11/36] =?UTF-8?q?docs:=20=EC=99=84=EB=A3=8C=EB=90=9C=20?= =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20=EC=99=84=EB=A3=8C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 320e08f5ec..740b9eb098 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ - [ ] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. - - [ ] 연속으로 이동 가능한 포인트는 존재할 수 없다. + - [X] 연속으로 이동 가능한 포인트는 존재할 수 없다. -> 좌 우 모두 이동 가능한 포인트는 존재할 수 없다 - [ ] 포인트 - [X] 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. - [X] 좌 이동 불가, 우 이동 불가 From 7b8e81de3ddfdf4e663b48f341fc04c895c96c49 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 18:56:01 +0900 Subject: [PATCH 12/36] =?UTF-8?q?feat:=20=EB=9E=98=EB=8D=94=EA=B2=8C?= =?UTF-8?q?=EC=9E=84=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++-- src/main/java/nextstep/ladder/LadderGame.java | 71 ++++++++++++++++--- src/main/java/nextstep/ladder/Line.java | 12 +++- src/test/java/nextstep/ladder/LineTest.java | 5 +- 4 files changed, 79 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 740b9eb098..5cbb9d4cd6 100644 --- a/README.md +++ b/README.md @@ -30,16 +30,16 @@ ### 요구사항 분석 -- [ ] 사용자는 이름을 갖는다. +- [ ] 참가자는 이름을 갖는다. - [ ] 이름은 최대 5자이다. - [ ] 이름이 비어있거나 6자 이상이면 예외가 발생한다. - [ ] 사다리 - - [ ] 사다리의 가로 라인을 수를 설정할 수 있다. (높이) - - [ ] 사다리의 세로 라인은 사람 수 만큼 생성된다. (너비) + - [X] 사다리의 가로 라인을 수를 설정할 수 있다. (높이) + - [X] 사다리의 세로 라인은 사람 수 만큼 생성된다. (너비) - [X] 사다리의 각 가로 라인에는 사람 수 만큼 포인트(점)가 생성된다. - - [ ] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. - - [ ] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. - - [ ] 가장 오른쪽 포인트에서는 우로 이동 불가하다. + - [X] 좌, 우에 포인트가 존재하는 경우 이동할 수 있다. + - [X] 가장 왼쪽 포인트에서는 좌로 이동 불가하다. + - [X] 가장 오른쪽 포인트에서는 우로 이동 불가하다. - [X] 연속으로 이동 가능한 포인트는 존재할 수 없다. -> 좌 우 모두 이동 가능한 포인트는 존재할 수 없다 - [ ] 포인트 - [X] 좌, 우 모두 이동 가능한 포인트는 존재할 수 없다. 세 가지 경우만 존재한다. diff --git a/src/main/java/nextstep/ladder/LadderGame.java b/src/main/java/nextstep/ladder/LadderGame.java index e4f4435097..f591eaaee7 100644 --- a/src/main/java/nextstep/ladder/LadderGame.java +++ b/src/main/java/nextstep/ladder/LadderGame.java @@ -3,29 +3,78 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.IntStream; public class LadderGame { - private static final int MAX_NAME_LENGTH = 5; + private static final String MOVEABLE_FORMAT = "-----|"; + private static final String IMMOVABLE_FORMAT = " |"; public static void main(String[] args) { - System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); - String input = "pobi,honux,crong,jk"; - List users = Arrays.stream(input.split(",")) - .collect(Collectors.toList()); - int countOfPerson = users.size(); + List playerNames = inputPlayerNames(); + int countOfPerson = playerNames.size(); + int height = inputHeight(); + List lines = createLines(countOfPerson, height); - System.out.println("최대 사다리 높이는 몇 개인가요?"); - int height = 5; + printGameResults(playerNames, lines); + } + private static void printGameResults(List players, List lines) { System.out.println("실행결과"); - String collect = users.stream() + printPlayers(players); + printLines(lines); + } + + private static void printPlayers(List players) { + String collect = players.stream() .map(name -> String.format("%5s", name)) .collect(Collectors.joining(" ")); System.out.println(collect); - for (int i = 0; i < height; i++) { - System.out.println(" ".repeat(MAX_NAME_LENGTH) + "|" + "-".repeat(MAX_NAME_LENGTH) + "|" + "-".repeat(MAX_NAME_LENGTH) + "|" + "-".repeat(MAX_NAME_LENGTH) + "|"); + } + + private static void printLines(List lines) { + String str = lines.stream() + .map(LadderGame::lineToString) + .collect(Collectors.joining("\n")); + + System.out.println(str); + } + + private static String lineToString(Line line) { + StringBuilder lineBuilder = new StringBuilder(); + + for (int i = 0; i < line.size(); i++) { + lineBuilder.append(lineToString(line.getPoint(i))); + } + + return lineBuilder.toString(); + } + + private static String lineToString(Point point) { + if (point.canMoveLeft()) { + return MOVEABLE_FORMAT; } + + return IMMOVABLE_FORMAT; + } + + private static int inputHeight() { + System.out.println("최대 사다리 높이는 몇 개인가요?"); + return 5; // TODO: input + } + + private static List inputPlayerNames() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + + String input = "pobi,honux,crong,jk"; // TODO: input + return Arrays.stream(input.split(",")) + .collect(Collectors.toList()); + } + + private static List createLines(int countOfPerson, int height) { + return IntStream.range(0, height) + .mapToObj(i -> Line.createLine(countOfPerson)) + .collect(Collectors.toList()); } } diff --git a/src/main/java/nextstep/ladder/Line.java b/src/main/java/nextstep/ladder/Line.java index 528028cbf9..e00f465855 100644 --- a/src/main/java/nextstep/ladder/Line.java +++ b/src/main/java/nextstep/ladder/Line.java @@ -27,12 +27,12 @@ private static List generateRandomPoints(int count) { points.add(Point.leftmostPoint(moveable)); boolean leftMoveable = moveable; - for (int i = 1; i < count - 2; i++) { + for (int i = 0; i < count - 2; i++) { boolean rightMoveable = RANDOM.nextBoolean(); if (leftMoveable) { rightMoveable = false; } - points.add(new Point(moveable, rightMoveable)); + points.add(new Point(leftMoveable, rightMoveable)); leftMoveable = rightMoveable; } @@ -40,4 +40,12 @@ private static List generateRandomPoints(int count) { return points; } + + public int size() { + return points.size(); + } + + public Point getPoint(int index) { + return points.get(index); + } } diff --git a/src/test/java/nextstep/ladder/LineTest.java b/src/test/java/nextstep/ladder/LineTest.java index 2ec07462a8..3734d168a4 100644 --- a/src/test/java/nextstep/ladder/LineTest.java +++ b/src/test/java/nextstep/ladder/LineTest.java @@ -3,13 +3,14 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThat; class LineTest { @DisplayName("사람 수를 받아 가로 라인을 생성한다") @Test void createLine() { - assertThatCode(() -> Line.createLine(5)).doesNotThrowAnyException(); + Line line = Line.createLine(5); + assertThat(line.size()).isEqualTo(5); } } From fab1fe551695c9830af9c59c09f4e75577ea753d Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 19:07:27 +0900 Subject: [PATCH 13/36] =?UTF-8?q?refactor:=20=EB=A7=A4=EC=A7=81=20?= =?UTF-8?q?=EB=A6=AC=ED=84=B0=EB=9F=B4=20=EC=83=81=EC=88=98=EB=A1=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/LadderGame.java | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/main/java/nextstep/ladder/LadderGame.java b/src/main/java/nextstep/ladder/LadderGame.java index f591eaaee7..fb6a28dc58 100644 --- a/src/main/java/nextstep/ladder/LadderGame.java +++ b/src/main/java/nextstep/ladder/LadderGame.java @@ -7,8 +7,11 @@ public class LadderGame { - private static final String MOVEABLE_FORMAT = "-----|"; - private static final String IMMOVABLE_FORMAT = " |"; + private static final String VERTICAL_LINE = "|"; + private static final String MOVEABLE_FORMAT = "-----"; + private static final String LINE_BREAK = "\n"; + private static final String PRINT_FORMAT = "%6s"; + private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; public static void main(String[] args) { List playerNames = inputPlayerNames(); @@ -27,8 +30,8 @@ private static void printGameResults(List players, List lines) { private static void printPlayers(List players) { String collect = players.stream() - .map(name -> String.format("%5s", name)) - .collect(Collectors.joining(" ")); + .map(name -> String.format(PRINT_FORMAT, name)) + .collect(Collectors.joining()); System.out.println(collect); } @@ -36,27 +39,23 @@ private static void printPlayers(List players) { private static void printLines(List lines) { String str = lines.stream() .map(LadderGame::lineToString) - .collect(Collectors.joining("\n")); + .collect(Collectors.joining(LINE_BREAK)); System.out.println(str); } private static String lineToString(Line line) { - StringBuilder lineBuilder = new StringBuilder(); - - for (int i = 0; i < line.size(); i++) { - lineBuilder.append(lineToString(line.getPoint(i))); - } - - return lineBuilder.toString(); + return IntStream.range(0, line.size()) + .mapToObj(index -> pointToString(line.getPoint(index))) + .collect(Collectors.joining()); } - private static String lineToString(Point point) { + private static String pointToString(Point point) { if (point.canMoveLeft()) { - return MOVEABLE_FORMAT; + return String.format(PRINT_FORMAT, MOVEABLE_FORMAT + VERTICAL_LINE); } - return IMMOVABLE_FORMAT; + return String.format(PRINT_FORMAT, VERTICAL_LINE); } private static int inputHeight() { @@ -68,7 +67,7 @@ private static List inputPlayerNames() { System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); String input = "pobi,honux,crong,jk"; // TODO: input - return Arrays.stream(input.split(",")) + return Arrays.stream(input.split(PLAYER_NAME_SPLIT_DELIMITER)) .collect(Collectors.toList()); } From 9427f15b3a6fbc127ab41193c29b034a016a26af Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 19:28:33 +0900 Subject: [PATCH 14/36] =?UTF-8?q?feat:=20=EC=9D=BC=EA=B8=89=20=EC=BB=AC?= =?UTF-8?q?=EB=A0=89=EC=85=98=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/nextstep/ladder/LadderGame.java | 45 +++++++++---------- src/main/java/nextstep/ladder/Lines.java | 29 ++++++++++++ src/main/java/nextstep/ladder/Player.java | 13 ++++++ src/main/java/nextstep/ladder/Players.java | 28 ++++++++++++ 4 files changed, 92 insertions(+), 23 deletions(-) create mode 100644 src/main/java/nextstep/ladder/Lines.java create mode 100644 src/main/java/nextstep/ladder/Player.java create mode 100644 src/main/java/nextstep/ladder/Players.java diff --git a/src/main/java/nextstep/ladder/LadderGame.java b/src/main/java/nextstep/ladder/LadderGame.java index fb6a28dc58..b5c3fe7c79 100644 --- a/src/main/java/nextstep/ladder/LadderGame.java +++ b/src/main/java/nextstep/ladder/LadderGame.java @@ -14,34 +14,41 @@ public class LadderGame { private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; public static void main(String[] args) { - List playerNames = inputPlayerNames(); - int countOfPerson = playerNames.size(); + String playerNames = inputPlayerNames(); + Players players = Players.of(splitNames(playerNames)); + int height = inputHeight(); - List lines = createLines(countOfPerson, height); + Lines lines = Lines.of(players.countOfPerson(), height); + + printGameResults(players, lines); + } - printGameResults(playerNames, lines); + private static List splitNames(String playerNames) { + return Arrays.stream(playerNames.split(PLAYER_NAME_SPLIT_DELIMITER)) + .collect(Collectors.toList()); } - private static void printGameResults(List players, List lines) { + private static void printGameResults(Players players, Lines lines) { System.out.println("실행결과"); printPlayers(players); printLines(lines); } - private static void printPlayers(List players) { - String collect = players.stream() - .map(name -> String.format(PRINT_FORMAT, name)) + private static void printPlayers(Players players) { + String playerNames = IntStream.range(0, players.countOfPerson()) + .mapToObj(players::getPlayer) + .map(player -> String.format(PRINT_FORMAT, player.getName())) .collect(Collectors.joining()); - System.out.println(collect); + System.out.println(playerNames); } - private static void printLines(List lines) { - String str = lines.stream() - .map(LadderGame::lineToString) + private static void printLines(Lines lines) { + String linesString = IntStream.range(0, lines.getHeight()) + .mapToObj(targetHeight -> lineToString(lines.getLine(targetHeight))) .collect(Collectors.joining(LINE_BREAK)); - System.out.println(str); + System.out.println(linesString); } private static String lineToString(Line line) { @@ -63,17 +70,9 @@ private static int inputHeight() { return 5; // TODO: input } - private static List inputPlayerNames() { + private static String inputPlayerNames() { System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); - String input = "pobi,honux,crong,jk"; // TODO: input - return Arrays.stream(input.split(PLAYER_NAME_SPLIT_DELIMITER)) - .collect(Collectors.toList()); - } - - private static List createLines(int countOfPerson, int height) { - return IntStream.range(0, height) - .mapToObj(i -> Line.createLine(countOfPerson)) - .collect(Collectors.toList()); + return "pobi,honux,crong,jk"; // TODO: input } } diff --git a/src/main/java/nextstep/ladder/Lines.java b/src/main/java/nextstep/ladder/Lines.java new file mode 100644 index 0000000000..bd0b0c8fdd --- /dev/null +++ b/src/main/java/nextstep/ladder/Lines.java @@ -0,0 +1,29 @@ +package nextstep.ladder; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Lines { + + private final List lines; + + private Lines(List lines) { + this.lines = lines; + } + + public static Lines of(int countOfPerson, int height) { + List lines = IntStream.range(0, height) + .mapToObj(i -> Line.createLine(countOfPerson)) + .collect(Collectors.toList()); + return new Lines(lines); + } + + public int getHeight() { + return lines.size(); + } + + public Line getLine(int targetHeight) { + return lines.get(targetHeight); + } +} diff --git a/src/main/java/nextstep/ladder/Player.java b/src/main/java/nextstep/ladder/Player.java new file mode 100644 index 0000000000..eb1b1990dc --- /dev/null +++ b/src/main/java/nextstep/ladder/Player.java @@ -0,0 +1,13 @@ +package nextstep.ladder; + +public class Player { + private final String name; + + public Player(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/nextstep/ladder/Players.java b/src/main/java/nextstep/ladder/Players.java new file mode 100644 index 0000000000..7169710844 --- /dev/null +++ b/src/main/java/nextstep/ladder/Players.java @@ -0,0 +1,28 @@ +package nextstep.ladder; + +import java.util.List; +import java.util.stream.Collectors; + +public class Players { + private List players; + + public Players(List players) { + this.players = players; + } + + public static Players of(List playerNames) { + List players = playerNames.stream() + .map(Player::new) + .collect(Collectors.toList()); + + return new Players(players); + } + + public int countOfPerson() { + return players.size(); + } + + public Player getPlayer(int index) { + return players.get(index); + } +} From 6929a1fe72d641e7ef6d71b0fc236a0547eb8f46 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 19:32:20 +0900 Subject: [PATCH 15/36] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90?= =?UTF-8?q?=EB=8A=94=20=EC=9D=B4=EB=A6=84=EC=9D=84=20=EA=B0=96=EB=8A=94?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++--- src/main/java/nextstep/ladder/Player.java | 11 ++++++++ src/test/java/nextstep/ladder/PlayerTest.java | 25 +++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 src/test/java/nextstep/ladder/PlayerTest.java diff --git a/README.md b/README.md index 5cbb9d4cd6..31786f79f2 100644 --- a/README.md +++ b/README.md @@ -30,9 +30,9 @@ ### 요구사항 분석 -- [ ] 참가자는 이름을 갖는다. - - [ ] 이름은 최대 5자이다. - - [ ] 이름이 비어있거나 6자 이상이면 예외가 발생한다. +- [X] 참가자는 이름을 갖는다. + - [X] 이름은 최대 5자이다. + - [X] 이름이 비어있거나 6자 이상이면 예외가 발생한다. - [ ] 사다리 - [X] 사다리의 가로 라인을 수를 설정할 수 있다. (높이) - [X] 사다리의 세로 라인은 사람 수 만큼 생성된다. (너비) diff --git a/src/main/java/nextstep/ladder/Player.java b/src/main/java/nextstep/ladder/Player.java index eb1b1990dc..2055940172 100644 --- a/src/main/java/nextstep/ladder/Player.java +++ b/src/main/java/nextstep/ladder/Player.java @@ -4,9 +4,20 @@ public class Player { private final String name; public Player(String name) { + validate(name); this.name = name; } + private static void validate(String name) { + if (name == null || name.isEmpty()) { + throw new IllegalArgumentException("이름은 비어있을 수 없습니다."); + } + + if (name.length() > 5) { + throw new IllegalArgumentException("이름은 5자 이하여야 합니다."); + } + } + public String getName() { return name; } diff --git a/src/test/java/nextstep/ladder/PlayerTest.java b/src/test/java/nextstep/ladder/PlayerTest.java new file mode 100644 index 0000000000..3d900d5c32 --- /dev/null +++ b/src/test/java/nextstep/ladder/PlayerTest.java @@ -0,0 +1,25 @@ +package nextstep.ladder; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class PlayerTest { + + @DisplayName("이름은 5글자 이하만 가능하다") + @Test + void tooLongName() { + assertThatThrownBy(() -> new Player("123456")).isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("이름은 비어있을 수 없다") + @ParameterizedTest(name = "name = {0}") + @NullAndEmptySource + void emptyName(String name) { + assertThatThrownBy(() -> new Player(name)).isInstanceOf(IllegalArgumentException.class); + } + +} From 53309edfe383ddd318601f5669bc69165e629aa4 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 19:38:56 +0900 Subject: [PATCH 16/36] =?UTF-8?q?refactor:=20LadderGame=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/LadderGame.java | 73 ++++--------------- .../ladder/LadderGameApplication.java | 69 ++++++++++++++++++ src/main/java/nextstep/ladder/Players.java | 6 +- 3 files changed, 87 insertions(+), 61 deletions(-) create mode 100644 src/main/java/nextstep/ladder/LadderGameApplication.java diff --git a/src/main/java/nextstep/ladder/LadderGame.java b/src/main/java/nextstep/ladder/LadderGame.java index b5c3fe7c79..f78035953d 100644 --- a/src/main/java/nextstep/ladder/LadderGame.java +++ b/src/main/java/nextstep/ladder/LadderGame.java @@ -3,76 +3,35 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import java.util.stream.IntStream; public class LadderGame { - - private static final String VERTICAL_LINE = "|"; - private static final String MOVEABLE_FORMAT = "-----"; - private static final String LINE_BREAK = "\n"; - private static final String PRINT_FORMAT = "%6s"; private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; - public static void main(String[] args) { - String playerNames = inputPlayerNames(); - Players players = Players.of(splitNames(playerNames)); - - int height = inputHeight(); - Lines lines = Lines.of(players.countOfPerson(), height); - - printGameResults(players, lines); - } - - private static List splitNames(String playerNames) { - return Arrays.stream(playerNames.split(PLAYER_NAME_SPLIT_DELIMITER)) - .collect(Collectors.toList()); - } + private final Players players; + private final Lines lines; - private static void printGameResults(Players players, Lines lines) { - System.out.println("실행결과"); - printPlayers(players); - printLines(lines); + private LadderGame(final Players players, final Lines lines) { + this.players = players; + this.lines = lines; } - private static void printPlayers(Players players) { - String playerNames = IntStream.range(0, players.countOfPerson()) - .mapToObj(players::getPlayer) - .map(player -> String.format(PRINT_FORMAT, player.getName())) - .collect(Collectors.joining()); - - System.out.println(playerNames); - } - - private static void printLines(Lines lines) { - String linesString = IntStream.range(0, lines.getHeight()) - .mapToObj(targetHeight -> lineToString(lines.getLine(targetHeight))) - .collect(Collectors.joining(LINE_BREAK)); + public static LadderGame of(String playerNames, int height) { + Players players = Players.of(splitNames(playerNames)); + Lines lines = Lines.of(players.countOfPerson(), height); - System.out.println(linesString); + return new LadderGame(players, lines); } - private static String lineToString(Line line) { - return IntStream.range(0, line.size()) - .mapToObj(index -> pointToString(line.getPoint(index))) - .collect(Collectors.joining()); + public Players getPlayers() { + return players; } - private static String pointToString(Point point) { - if (point.canMoveLeft()) { - return String.format(PRINT_FORMAT, MOVEABLE_FORMAT + VERTICAL_LINE); - } - - return String.format(PRINT_FORMAT, VERTICAL_LINE); + public Lines getLines() { + return lines; } - private static int inputHeight() { - System.out.println("최대 사다리 높이는 몇 개인가요?"); - return 5; // TODO: input - } - - private static String inputPlayerNames() { - System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); - - return "pobi,honux,crong,jk"; // TODO: input + private static List splitNames(String playerNames) { + return Arrays.stream(playerNames.split(PLAYER_NAME_SPLIT_DELIMITER)) + .collect(Collectors.toList()); } } diff --git a/src/main/java/nextstep/ladder/LadderGameApplication.java b/src/main/java/nextstep/ladder/LadderGameApplication.java new file mode 100644 index 0000000000..7cfaadb9f2 --- /dev/null +++ b/src/main/java/nextstep/ladder/LadderGameApplication.java @@ -0,0 +1,69 @@ +package nextstep.ladder; + +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class LadderGameApplication { + + private static final String VERTICAL_LINE = "|"; + private static final String MOVEABLE_FORMAT = "-----"; + private static final String LINE_BREAK = "\n"; + private static final String PRINT_FORMAT = "%6s"; + + public static void main(String[] args) { + String playerNames = inputPlayerNames(); + int height = inputHeight(); + + LadderGame ladderGame = LadderGame.of(playerNames, height); + + printGameResults(ladderGame); + } + + private static void printGameResults(LadderGame ladderGame) { + System.out.println("실행결과"); + printPlayers(ladderGame.getPlayers()); + printLines(ladderGame.getLines()); + } + + private static void printPlayers(Players players) { + String playerNames = IntStream.range(0, players.countOfPerson()) + .mapToObj(players::getPlayer) + .map(player -> String.format(PRINT_FORMAT, player.getName())) + .collect(Collectors.joining()); + + System.out.println(playerNames); + } + + private static void printLines(Lines lines) { + String linesString = IntStream.range(0, lines.getHeight()) + .mapToObj(targetHeight -> lineToString(lines.getLine(targetHeight))) + .collect(Collectors.joining(LINE_BREAK)); + + System.out.println(linesString); + } + + private static String lineToString(Line line) { + return IntStream.range(0, line.size()) + .mapToObj(index -> pointToString(line.getPoint(index))) + .collect(Collectors.joining()); + } + + private static String pointToString(Point point) { + if (point.canMoveLeft()) { + return String.format(PRINT_FORMAT, MOVEABLE_FORMAT + VERTICAL_LINE); + } + + return String.format(PRINT_FORMAT, VERTICAL_LINE); + } + + private static int inputHeight() { + System.out.println("최대 사다리 높이는 몇 개인가요?"); + return 5; // TODO: input + } + + private static String inputPlayerNames() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + + return "pobi,honux,crong,jk"; // TODO: input + } +} diff --git a/src/main/java/nextstep/ladder/Players.java b/src/main/java/nextstep/ladder/Players.java index 7169710844..4a16176487 100644 --- a/src/main/java/nextstep/ladder/Players.java +++ b/src/main/java/nextstep/ladder/Players.java @@ -6,14 +6,12 @@ public class Players { private List players; - public Players(List players) { + private Players(List players) { this.players = players; } public static Players of(List playerNames) { - List players = playerNames.stream() - .map(Player::new) - .collect(Collectors.toList()); + List players = playerNames.stream().map(Player::new).collect(Collectors.toList()); return new Players(players); } From e3bdceb8679742ec5c909962b93697952e3634aa Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 19:40:06 +0900 Subject: [PATCH 17/36] =?UTF-8?q?refactor:=20domain=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/LadderGameApplication.java | 2 ++ src/main/java/nextstep/ladder/{ => domain}/LadderGame.java | 2 +- src/main/java/nextstep/ladder/{ => domain}/Line.java | 2 +- src/main/java/nextstep/ladder/{ => domain}/Lines.java | 2 +- src/main/java/nextstep/ladder/{ => domain}/Player.java | 2 +- src/main/java/nextstep/ladder/{ => domain}/Players.java | 2 +- src/main/java/nextstep/ladder/{ => domain}/Point.java | 2 +- src/test/java/nextstep/ladder/{ => domain}/LineTest.java | 2 +- src/test/java/nextstep/ladder/{ => domain}/PlayerTest.java | 2 +- src/test/java/nextstep/ladder/{ => domain}/PointTest.java | 2 +- 10 files changed, 11 insertions(+), 9 deletions(-) rename src/main/java/nextstep/ladder/{ => domain}/LadderGame.java (96%) rename src/main/java/nextstep/ladder/{ => domain}/Line.java (97%) rename src/main/java/nextstep/ladder/{ => domain}/Lines.java (95%) rename src/main/java/nextstep/ladder/{ => domain}/Player.java (94%) rename src/main/java/nextstep/ladder/{ => domain}/Players.java (94%) rename src/main/java/nextstep/ladder/{ => domain}/Point.java (95%) rename src/test/java/nextstep/ladder/{ => domain}/LineTest.java (91%) rename src/test/java/nextstep/ladder/{ => domain}/PlayerTest.java (95%) rename src/test/java/nextstep/ladder/{ => domain}/PointTest.java (97%) diff --git a/src/main/java/nextstep/ladder/LadderGameApplication.java b/src/main/java/nextstep/ladder/LadderGameApplication.java index 7cfaadb9f2..034b9d5d8a 100644 --- a/src/main/java/nextstep/ladder/LadderGameApplication.java +++ b/src/main/java/nextstep/ladder/LadderGameApplication.java @@ -1,5 +1,7 @@ package nextstep.ladder; +import nextstep.ladder.domain.*; + import java.util.stream.Collectors; import java.util.stream.IntStream; diff --git a/src/main/java/nextstep/ladder/LadderGame.java b/src/main/java/nextstep/ladder/domain/LadderGame.java similarity index 96% rename from src/main/java/nextstep/ladder/LadderGame.java rename to src/main/java/nextstep/ladder/domain/LadderGame.java index f78035953d..a79a8ab877 100644 --- a/src/main/java/nextstep/ladder/LadderGame.java +++ b/src/main/java/nextstep/ladder/domain/LadderGame.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/nextstep/ladder/Line.java b/src/main/java/nextstep/ladder/domain/Line.java similarity index 97% rename from src/main/java/nextstep/ladder/Line.java rename to src/main/java/nextstep/ladder/domain/Line.java index e00f465855..7d253cd00b 100644 --- a/src/main/java/nextstep/ladder/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nextstep/ladder/Lines.java b/src/main/java/nextstep/ladder/domain/Lines.java similarity index 95% rename from src/main/java/nextstep/ladder/Lines.java rename to src/main/java/nextstep/ladder/domain/Lines.java index bd0b0c8fdd..02fc17eb05 100644 --- a/src/main/java/nextstep/ladder/Lines.java +++ b/src/main/java/nextstep/ladder/domain/Lines.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/nextstep/ladder/Player.java b/src/main/java/nextstep/ladder/domain/Player.java similarity index 94% rename from src/main/java/nextstep/ladder/Player.java rename to src/main/java/nextstep/ladder/domain/Player.java index 2055940172..75a3632fd7 100644 --- a/src/main/java/nextstep/ladder/Player.java +++ b/src/main/java/nextstep/ladder/domain/Player.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; public class Player { private final String name; diff --git a/src/main/java/nextstep/ladder/Players.java b/src/main/java/nextstep/ladder/domain/Players.java similarity index 94% rename from src/main/java/nextstep/ladder/Players.java rename to src/main/java/nextstep/ladder/domain/Players.java index 4a16176487..2cb96e2055 100644 --- a/src/main/java/nextstep/ladder/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/nextstep/ladder/Point.java b/src/main/java/nextstep/ladder/domain/Point.java similarity index 95% rename from src/main/java/nextstep/ladder/Point.java rename to src/main/java/nextstep/ladder/domain/Point.java index f62e553091..5f4b5d4b65 100644 --- a/src/main/java/nextstep/ladder/Point.java +++ b/src/main/java/nextstep/ladder/domain/Point.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; public class Point { private final boolean left; diff --git a/src/test/java/nextstep/ladder/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java similarity index 91% rename from src/test/java/nextstep/ladder/LineTest.java rename to src/test/java/nextstep/ladder/domain/LineTest.java index 3734d168a4..0369be8fec 100644 --- a/src/test/java/nextstep/ladder/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/nextstep/ladder/PlayerTest.java b/src/test/java/nextstep/ladder/domain/PlayerTest.java similarity index 95% rename from src/test/java/nextstep/ladder/PlayerTest.java rename to src/test/java/nextstep/ladder/domain/PlayerTest.java index 3d900d5c32..090a2a5c7b 100644 --- a/src/test/java/nextstep/ladder/PlayerTest.java +++ b/src/test/java/nextstep/ladder/domain/PlayerTest.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/nextstep/ladder/PointTest.java b/src/test/java/nextstep/ladder/domain/PointTest.java similarity index 97% rename from src/test/java/nextstep/ladder/PointTest.java rename to src/test/java/nextstep/ladder/domain/PointTest.java index d58bd05b63..14a20db496 100644 --- a/src/test/java/nextstep/ladder/PointTest.java +++ b/src/test/java/nextstep/ladder/domain/PointTest.java @@ -1,4 +1,4 @@ -package nextstep.ladder; +package nextstep.ladder.domain; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 5f53b788e012edf1021d15cc1fa6f6073b3b3a9c Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 20:02:51 +0900 Subject: [PATCH 18/36] =?UTF-8?q?test:=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ladder/LadderGameApplication.java | 11 +++++++- .../nextstep/ladder/domain/LadderGame.java | 12 ++------- .../java/nextstep/ladder/domain/Lines.java | 7 +++++ .../java/nextstep/ladder/domain/Players.java | 4 ++- .../ladder/domain/LadderGameTest.java | 20 ++++++++++++++ .../nextstep/ladder/domain/LinesTest.java | 26 +++++++++++++++++++ .../nextstep/ladder/domain/PlayersTest.java | 21 +++++++++++++++ 7 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 src/test/java/nextstep/ladder/domain/LadderGameTest.java create mode 100644 src/test/java/nextstep/ladder/domain/LinesTest.java create mode 100644 src/test/java/nextstep/ladder/domain/PlayersTest.java diff --git a/src/main/java/nextstep/ladder/LadderGameApplication.java b/src/main/java/nextstep/ladder/LadderGameApplication.java index 034b9d5d8a..7086954c7f 100644 --- a/src/main/java/nextstep/ladder/LadderGameApplication.java +++ b/src/main/java/nextstep/ladder/LadderGameApplication.java @@ -2,11 +2,14 @@ import nextstep.ladder.domain.*; +import java.util.Arrays; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; public class LadderGameApplication { + private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; private static final String VERTICAL_LINE = "|"; private static final String MOVEABLE_FORMAT = "-----"; private static final String LINE_BREAK = "\n"; @@ -16,11 +19,17 @@ public static void main(String[] args) { String playerNames = inputPlayerNames(); int height = inputHeight(); - LadderGame ladderGame = LadderGame.of(playerNames, height); + LadderGame ladderGame = LadderGame.of(splitNames(playerNames), height); printGameResults(ladderGame); } + + private static List splitNames(String playerNames) { + return Arrays.stream(playerNames.split(PLAYER_NAME_SPLIT_DELIMITER)) + .collect(Collectors.toList()); + } + private static void printGameResults(LadderGame ladderGame) { System.out.println("실행결과"); printPlayers(ladderGame.getPlayers()); diff --git a/src/main/java/nextstep/ladder/domain/LadderGame.java b/src/main/java/nextstep/ladder/domain/LadderGame.java index a79a8ab877..502993821d 100644 --- a/src/main/java/nextstep/ladder/domain/LadderGame.java +++ b/src/main/java/nextstep/ladder/domain/LadderGame.java @@ -1,11 +1,8 @@ package nextstep.ladder.domain; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; public class LadderGame { - private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; private final Players players; private final Lines lines; @@ -15,8 +12,8 @@ private LadderGame(final Players players, final Lines lines) { this.lines = lines; } - public static LadderGame of(String playerNames, int height) { - Players players = Players.of(splitNames(playerNames)); + public static LadderGame of(List playerNames, int height) { + Players players = Players.of(playerNames); Lines lines = Lines.of(players.countOfPerson(), height); return new LadderGame(players, lines); @@ -29,9 +26,4 @@ public Players getPlayers() { public Lines getLines() { return lines; } - - private static List splitNames(String playerNames) { - return Arrays.stream(playerNames.split(PLAYER_NAME_SPLIT_DELIMITER)) - .collect(Collectors.toList()); - } } diff --git a/src/main/java/nextstep/ladder/domain/Lines.java b/src/main/java/nextstep/ladder/domain/Lines.java index 02fc17eb05..52a5b5481b 100644 --- a/src/main/java/nextstep/ladder/domain/Lines.java +++ b/src/main/java/nextstep/ladder/domain/Lines.java @@ -9,9 +9,16 @@ public class Lines { private final List lines; private Lines(List lines) { + validate(lines); this.lines = lines; } + private void validate(List lines) { + if (lines == null || lines.isEmpty()) { + throw new IllegalArgumentException("사다리 높이는 1 이상이어야 합니다."); + } + } + public static Lines of(int countOfPerson, int height) { List lines = IntStream.range(0, height) .mapToObj(i -> Line.createLine(countOfPerson)) diff --git a/src/main/java/nextstep/ladder/domain/Players.java b/src/main/java/nextstep/ladder/domain/Players.java index 2cb96e2055..86b0844eda 100644 --- a/src/main/java/nextstep/ladder/domain/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -11,7 +11,9 @@ private Players(List players) { } public static Players of(List playerNames) { - List players = playerNames.stream().map(Player::new).collect(Collectors.toList()); + List players = playerNames.stream() + .map(Player::new) + .collect(Collectors.toList()); return new Players(players); } diff --git a/src/test/java/nextstep/ladder/domain/LadderGameTest.java b/src/test/java/nextstep/ladder/domain/LadderGameTest.java new file mode 100644 index 0000000000..2da44ffaba --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/LadderGameTest.java @@ -0,0 +1,20 @@ +package nextstep.ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThatCode; + +class LadderGameTest { + + @DisplayName("참여할 사람 이름과 사다리 높이를 받아 사다리 게임을 생성한다") + @Test + void create() { + List playerNames = List.of("pobi", "honux", "crong", "jk"); + int height = 5; + + assertThatCode(() -> LadderGame.of(playerNames, height)).doesNotThrowAnyException(); + } +} diff --git a/src/test/java/nextstep/ladder/domain/LinesTest.java b/src/test/java/nextstep/ladder/domain/LinesTest.java new file mode 100644 index 0000000000..e64180ce75 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/LinesTest.java @@ -0,0 +1,26 @@ +package nextstep.ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class LinesTest { + + @DisplayName("사다리 높이는 1 이상이어야 한다.") + @Test + void invalidHeight() { + assertThatThrownBy(() -> Lines.of(3, 0)).isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("참여자 수와 사다리 높이를 받아 사다리를 생성한다.") + @Test + void create() { + int height = 5; + int countOfPerson = 3; + Lines lines = Lines.of(countOfPerson, height); + + assertThat(lines.getHeight()).isEqualTo(height); + } +} diff --git a/src/test/java/nextstep/ladder/domain/PlayersTest.java b/src/test/java/nextstep/ladder/domain/PlayersTest.java new file mode 100644 index 0000000000..89a249ca74 --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/PlayersTest.java @@ -0,0 +1,21 @@ +package nextstep.ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class PlayersTest { + + @DisplayName("참여자 이름을 받아 참여자를 생성한다") + @Test + void create() { + List playerNames = List.of("pobi", "crong", "honux"); + Players players = Players.of(playerNames); + + assertThat(players.countOfPerson()).isEqualTo(playerNames.size()); + } + +} From 73d2e593ee4e89c612cf9418210110234e34e9d4 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 22:21:49 +0900 Subject: [PATCH 19/36] =?UTF-8?q?refactor:=20=EC=A4=91=EA=B0=84=20?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=83=9D=EC=84=B1=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/ladder/domain/Line.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index 7d253cd00b..d76ca578dd 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -17,28 +17,30 @@ private Line(List points) { } public static Line createLine(int countOfPerson) { - return new Line(generateRandomPoints(countOfPerson)); + return new Line(generateRandomMoveablePoints(countOfPerson)); } - private static List generateRandomPoints(int count) { + private static List generateRandomMoveablePoints(int count) { List points = new ArrayList<>(); boolean moveable = RANDOM.nextBoolean(); points.add(Point.leftmostPoint(moveable)); + points.addAll(generateMiddlePoints(count, points.get(points.size() - 1).canMoveRight())); + points.add(Point.rightmostPoint(points.get(points.size() - 1).canMoveLeft())); - boolean leftMoveable = moveable; + return points; + } + + private static List generateMiddlePoints(int count, boolean startPointMoveable) { + List middlePoints = new ArrayList<>(); + + boolean leftMoveable = startPointMoveable; for (int i = 0; i < count - 2; i++) { - boolean rightMoveable = RANDOM.nextBoolean(); - if (leftMoveable) { - rightMoveable = false; - } - points.add(new Point(leftMoveable, rightMoveable)); + boolean rightMoveable = !leftMoveable && RANDOM.nextBoolean(); + middlePoints.add(new Point(leftMoveable, rightMoveable)); leftMoveable = rightMoveable; } - - points.add(Point.rightmostPoint(leftMoveable)); - - return points; + return middlePoints; } public int size() { From 99c8db77144e134ecb4ef89f26eb267dc60276cf Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 22:29:49 +0900 Subject: [PATCH 20/36] =?UTF-8?q?refactor:=20Line=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/ladder/domain/Line.java | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index d76ca578dd..b150c4c9e4 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class Line { private static final Random RANDOM = new Random(); @@ -10,10 +12,14 @@ public class Line { private List points; private Line(List points) { + validate(points); + this.points = points; + } + + private static void validate(List points) { if (points == null || points.isEmpty()) { throw new IllegalArgumentException("점이 없습니다."); } - this.points = points; } public static Line createLine(int countOfPerson) { @@ -23,24 +29,27 @@ public static Line createLine(int countOfPerson) { private static List generateRandomMoveablePoints(int count) { List points = new ArrayList<>(); - boolean moveable = RANDOM.nextBoolean(); - points.add(Point.leftmostPoint(moveable)); - points.addAll(generateMiddlePoints(count, points.get(points.size() - 1).canMoveRight())); - points.add(Point.rightmostPoint(points.get(points.size() - 1).canMoveLeft())); + points.add(Point.leftmostPoint(RANDOM.nextBoolean())); + points.addAll(generateMiddlePoints(count, points)); + points.add(Point.rightmostPoint(getLastPoint(points).canMoveLeft())); return points; } - private static List generateMiddlePoints(int count, boolean startPointMoveable) { - List middlePoints = new ArrayList<>(); + private static List generateMiddlePoints(int count, List points) { + return IntStream.range(0, count - 2) + .mapToObj(i -> generateMiddlePoint(points)) + .collect(Collectors.toList()); + } - boolean leftMoveable = startPointMoveable; - for (int i = 0; i < count - 2; i++) { - boolean rightMoveable = !leftMoveable && RANDOM.nextBoolean(); - middlePoints.add(new Point(leftMoveable, rightMoveable)); - leftMoveable = rightMoveable; - } - return middlePoints; + private static Point generateMiddlePoint(List points) { + boolean leftMoveable = getLastPoint(points).canMoveRight(); + boolean rightMoveable = !leftMoveable && RANDOM.nextBoolean(); + return new Point(leftMoveable, rightMoveable); + } + + private static Point getLastPoint(List points) { + return points.get(points.size() - 1); } public int size() { From d10073db2be2c2748ee3f4b4ded2aff2a32c718f Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 22:39:01 +0900 Subject: [PATCH 21/36] =?UTF-8?q?feat:=20=EC=B0=B8=EA=B0=80=EC=9E=90?= =?UTF-8?q?=EB=8A=94=201=EB=AA=85=20=EC=9D=B4=EC=83=81=EC=9D=B4=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/domain/Players.java | 7 +++++++ src/test/java/nextstep/ladder/domain/PlayersTest.java | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/nextstep/ladder/domain/Players.java b/src/main/java/nextstep/ladder/domain/Players.java index 86b0844eda..13cfe35553 100644 --- a/src/main/java/nextstep/ladder/domain/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -7,9 +7,16 @@ public class Players { private List players; private Players(List players) { + validate(players); this.players = players; } + private void validate(List players) { + if (players == null || players.isEmpty()) { + throw new IllegalArgumentException("참가자가 없습니다."); + } + } + public static Players of(List playerNames) { List players = playerNames.stream() .map(Player::new) diff --git a/src/test/java/nextstep/ladder/domain/PlayersTest.java b/src/test/java/nextstep/ladder/domain/PlayersTest.java index 89a249ca74..adfd5050b8 100644 --- a/src/test/java/nextstep/ladder/domain/PlayersTest.java +++ b/src/test/java/nextstep/ladder/domain/PlayersTest.java @@ -6,6 +6,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class PlayersTest { @@ -18,4 +19,10 @@ void create() { assertThat(players.countOfPerson()).isEqualTo(playerNames.size()); } + @DisplayName("참가자는 1명 이상이다") + @Test + void invalidPlayerCount() { + assertThatThrownBy(() -> Players.of(List.of())) + .isInstanceOf(IllegalArgumentException.class); + } } From e4da8495b6ae49e1df71f2cb3bfa5fa77cb13668 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sat, 6 Apr 2024 23:31:56 +0900 Subject: [PATCH 22/36] =?UTF-8?q?refactor:=20Line=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20LineBuilder=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ladder/LadderGameApplication.java | 2 +- .../java/nextstep/ladder/domain/Line.java | 40 +++----------- .../nextstep/ladder/domain/LineBuilder.java | 55 +++++++++++++++++++ .../java/nextstep/ladder/domain/Lines.java | 2 +- .../ladder/domain/LineBuilderTest.java | 16 ++++++ .../java/nextstep/ladder/domain/LineTest.java | 55 +++++++++++++++++-- 6 files changed, 132 insertions(+), 38 deletions(-) create mode 100644 src/main/java/nextstep/ladder/domain/LineBuilder.java create mode 100644 src/test/java/nextstep/ladder/domain/LineBuilderTest.java diff --git a/src/main/java/nextstep/ladder/LadderGameApplication.java b/src/main/java/nextstep/ladder/LadderGameApplication.java index 7086954c7f..e6362cf256 100644 --- a/src/main/java/nextstep/ladder/LadderGameApplication.java +++ b/src/main/java/nextstep/ladder/LadderGameApplication.java @@ -54,7 +54,7 @@ private static void printLines(Lines lines) { } private static String lineToString(Line line) { - return IntStream.range(0, line.size()) + return IntStream.range(0, line.width()) .mapToObj(index -> pointToString(line.getPoint(index))) .collect(Collectors.joining()); } diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index b150c4c9e4..b66419967e 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -1,17 +1,11 @@ package nextstep.ladder.domain; -import java.util.ArrayList; import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; -import java.util.stream.IntStream; public class Line { - private static final Random RANDOM = new Random(); - private List points; - private Line(List points) { + Line(List points) { validate(points); this.points = points; } @@ -20,39 +14,21 @@ private static void validate(List points) { if (points == null || points.isEmpty()) { throw new IllegalArgumentException("점이 없습니다."); } - } - - public static Line createLine(int countOfPerson) { - return new Line(generateRandomMoveablePoints(countOfPerson)); - } - - private static List generateRandomMoveablePoints(int count) { - List points = new ArrayList<>(); - points.add(Point.leftmostPoint(RANDOM.nextBoolean())); - points.addAll(generateMiddlePoints(count, points)); - points.add(Point.rightmostPoint(getLastPoint(points).canMoveLeft())); - - return points; - } - - private static List generateMiddlePoints(int count, List points) { - return IntStream.range(0, count - 2) - .mapToObj(i -> generateMiddlePoint(points)) - .collect(Collectors.toList()); + if (firstPoint(points).canMoveLeft() || lastPoint(points).canMoveRight()) { + throw new IllegalArgumentException("첫 점에서는 왼쪽으로 이동할 수 없고, 마지막 점에서는 오른쪽으로 이동할 수 없습니다."); + } } - private static Point generateMiddlePoint(List points) { - boolean leftMoveable = getLastPoint(points).canMoveRight(); - boolean rightMoveable = !leftMoveable && RANDOM.nextBoolean(); - return new Point(leftMoveable, rightMoveable); + private static Point firstPoint(List points) { + return points.get(0); } - private static Point getLastPoint(List points) { + private static Point lastPoint(List points) { return points.get(points.size() - 1); } - public int size() { + public int width() { return points.size(); } diff --git a/src/main/java/nextstep/ladder/domain/LineBuilder.java b/src/main/java/nextstep/ladder/domain/LineBuilder.java new file mode 100644 index 0000000000..f29123fec1 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/LineBuilder.java @@ -0,0 +1,55 @@ +package nextstep.ladder.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class LineBuilder { + + private static final Random RANDOM = new Random(); + + private final List points = new ArrayList<>(); + + public static Line buildWithRandomPoints(int count) { + return new LineBuilder().initRandomMoveablePoint() + .addRandomMoveablePoints(count - 2) + .build(); + } + + private LineBuilder addPoint(Point point) { + points.add(point); + return this; + } + + private Line build() { + points.add(Point.rightmostPoint(lastPoint().canMoveLeft())); + return new Line(points); + } + + private LineBuilder addRandomMoveablePoints(int countOfMiddlePoint) { + points.addAll(generateMiddlePoints(countOfMiddlePoint)); + return this; + } + + private LineBuilder initRandomMoveablePoint() { + return addPoint(Point.leftmostPoint(RANDOM.nextBoolean())); + } + + private List generateMiddlePoints(int count) { + return IntStream.range(0, count) + .mapToObj(i -> generateMiddlePoint()) + .collect(Collectors.toList()); + } + + private Point generateMiddlePoint() { + boolean leftMoveable = lastPoint().canMoveRight(); + boolean rightMoveable = !leftMoveable && RANDOM.nextBoolean(); + return new Point(leftMoveable, rightMoveable); + } + + private Point lastPoint() { + return points.get(points.size() - 1); + } +} diff --git a/src/main/java/nextstep/ladder/domain/Lines.java b/src/main/java/nextstep/ladder/domain/Lines.java index 52a5b5481b..3544bde600 100644 --- a/src/main/java/nextstep/ladder/domain/Lines.java +++ b/src/main/java/nextstep/ladder/domain/Lines.java @@ -21,7 +21,7 @@ private void validate(List lines) { public static Lines of(int countOfPerson, int height) { List lines = IntStream.range(0, height) - .mapToObj(i -> Line.createLine(countOfPerson)) + .mapToObj(i -> LineBuilder.buildWithRandomPoints(countOfPerson)) .collect(Collectors.toList()); return new Lines(lines); } diff --git a/src/test/java/nextstep/ladder/domain/LineBuilderTest.java b/src/test/java/nextstep/ladder/domain/LineBuilderTest.java new file mode 100644 index 0000000000..4a10b868ec --- /dev/null +++ b/src/test/java/nextstep/ladder/domain/LineBuilderTest.java @@ -0,0 +1,16 @@ +package nextstep.ladder.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class LineBuilderTest { + + @DisplayName("사람 수를 받아 가로 라인을 생성한다") + @Test + void createLine() { + Line line = LineBuilder.buildWithRandomPoints(5); + assertThat(line.width()).isEqualTo(5); + } +} diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index 0369be8fec..34c494d008 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -3,14 +3,61 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class LineTest { - @DisplayName("사람 수를 받아 가로 라인을 생성한다") + @DisplayName("포인트를 받아 라인을 생성한다") + @Test + void create() { + List points = List.of( + Point.leftmostPoint(false), + Point.rightmostPoint(false) + ); + Line line = new Line(points); + + assertThat(line.width()).isEqualTo(2); + } + + @DisplayName("포인트가 null이면 예외가 발생한다") @Test - void createLine() { - Line line = Line.createLine(5); - assertThat(line.size()).isEqualTo(5); + void nullPoints() { + assertThatThrownBy(() -> new Line(null)) + .isInstanceOf(IllegalArgumentException.class); } + + @DisplayName("포인트가 비어있으면 예외가 발생한다") + @Test + void emptyPoints() { + assertThatThrownBy(() -> new Line(List.of())) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("시작 포인트가 왼쪽으로 이동 가능하면 예외가 발생한다") + @Test + void firstPointCannotMoveLeft() { + List points = List.of( + new Point(true, false), + new Point(false, false) + ); + + assertThatThrownBy(() -> new Line(points)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("마지막 포인트가 오른쪽으로 이동 가능하면 예외가 발생한다") + @Test + void lastPointCannotMoveRight() { + List points = List.of( + new Point(false, false), + new Point(false, true) + ); + + assertThatThrownBy(() -> new Line(points)) + .isInstanceOf(IllegalArgumentException.class); + } + } From a241c10a0ffc731468050718fb45509d0a769bb4 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sun, 7 Apr 2024 00:22:44 +0900 Subject: [PATCH 23/36] =?UTF-8?q?feat:=20=EC=9D=B4=EB=8F=99=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=9C=20=ED=8F=AC=EC=9D=B8=ED=8A=B8=EA=B0=84?= =?UTF-8?q?=EC=97=90=20=EC=84=9C=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9C=BC=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EA=B0=80=20=EB=B0=9C=EC=83=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/ladder/domain/Line.java | 25 +++++++++++++++++++ .../java/nextstep/ladder/domain/LineTest.java | 16 ++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index b66419967e..291583ca0a 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -11,13 +11,38 @@ public class Line { } private static void validate(List points) { + validatePointsListSize(points); + validatePointMovements(points); + } + + private static void validatePointsListSize(List points) { if (points == null || points.isEmpty()) { throw new IllegalArgumentException("점이 없습니다."); } + if (points.size() < 2) { + throw new IllegalArgumentException("점이 두 개 이상 있어야 합니다."); + } + } + + private static void validatePointMovements(List points) { if (firstPoint(points).canMoveLeft() || lastPoint(points).canMoveRight()) { throw new IllegalArgumentException("첫 점에서는 왼쪽으로 이동할 수 없고, 마지막 점에서는 오른쪽으로 이동할 수 없습니다."); } + + for (int i = 0; i < points.size() - 1; i++) { + assertConsecutivePointsAreMovable(points, i); + } + } + + private static void assertConsecutivePointsAreMovable(List points, int i) { + if (!hasMovableConnectionToNext(points, i)) { + throw new IllegalArgumentException("연속된 점에서는 서로 이동 가능해야 합니다."); + } + } + + private static boolean hasMovableConnectionToNext(List points, int i) { + return points.get(i).canMoveRight() && points.get(i + 1).canMoveLeft(); } private static Point firstPoint(List points) { diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index 34c494d008..d97f33f073 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -14,8 +14,8 @@ class LineTest { @Test void create() { List points = List.of( - Point.leftmostPoint(false), - Point.rightmostPoint(false) + Point.leftmostPoint(true), + Point.rightmostPoint(true) ); Line line = new Line(points); @@ -60,4 +60,16 @@ void lastPointCannotMoveRight() { .isInstanceOf(IllegalArgumentException.class); } + @DisplayName("이동 가능한 포인트간에 서로 이동 가능하지 않으면 예외가 발생한다") + @Test + void hasMovableConnectionToNext() { + List points = List.of( + new Point(false, true), + new Point(false, false) + ); + + assertThatThrownBy(() -> new Line(points)) + .isInstanceOf(IllegalArgumentException.class); + } + } From 9d2ef6cb8e9d9bf0a94e589ad8149463853647df Mon Sep 17 00:00:00 2001 From: sang5c Date: Sun, 7 Apr 2024 01:03:21 +0900 Subject: [PATCH 24/36] =?UTF-8?q?feat:=20=EB=A7=88=EC=A7=80=EB=A7=89=20?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=EB=A5=BC=20=EC=9D=B4=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EB=8B=A4=EC=9D=8C=20=ED=8F=AC=EC=9D=B8?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=83=9D=EC=84=B1=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/ladder/domain/Line.java | 6 +--- .../nextstep/ladder/domain/LineBuilder.java | 29 +++++-------------- .../java/nextstep/ladder/domain/Point.java | 8 +++-- .../java/nextstep/ladder/domain/LineTest.java | 5 ++-- .../nextstep/ladder/domain/PointTest.java | 2 +- 5 files changed, 18 insertions(+), 32 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index 291583ca0a..3ea118b789 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -36,15 +36,11 @@ private static void validatePointMovements(List points) { } private static void assertConsecutivePointsAreMovable(List points, int i) { - if (!hasMovableConnectionToNext(points, i)) { + if (points.get(i).canMoveRight() && !points.get(i + 1).canMoveLeft()) { throw new IllegalArgumentException("연속된 점에서는 서로 이동 가능해야 합니다."); } } - private static boolean hasMovableConnectionToNext(List points, int i) { - return points.get(i).canMoveRight() && points.get(i + 1).canMoveLeft(); - } - private static Point firstPoint(List points) { return points.get(0); } diff --git a/src/main/java/nextstep/ladder/domain/LineBuilder.java b/src/main/java/nextstep/ladder/domain/LineBuilder.java index f29123fec1..7114216f28 100644 --- a/src/main/java/nextstep/ladder/domain/LineBuilder.java +++ b/src/main/java/nextstep/ladder/domain/LineBuilder.java @@ -3,8 +3,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -import java.util.stream.Collectors; -import java.util.stream.IntStream; public class LineBuilder { @@ -18,35 +16,22 @@ public static Line buildWithRandomPoints(int count) { .build(); } - private LineBuilder addPoint(Point point) { - points.add(point); - return this; - } - private Line build() { - points.add(Point.rightmostPoint(lastPoint().canMoveLeft())); + points.add(lastPoint().rightmostPoint()); return new Line(points); } private LineBuilder addRandomMoveablePoints(int countOfMiddlePoint) { - points.addAll(generateMiddlePoints(countOfMiddlePoint)); + for (int i = 0; i < countOfMiddlePoint; i++) { + Point point = lastPoint().nextPoint(RANDOM.nextBoolean()); + points.add(point); + } return this; } private LineBuilder initRandomMoveablePoint() { - return addPoint(Point.leftmostPoint(RANDOM.nextBoolean())); - } - - private List generateMiddlePoints(int count) { - return IntStream.range(0, count) - .mapToObj(i -> generateMiddlePoint()) - .collect(Collectors.toList()); - } - - private Point generateMiddlePoint() { - boolean leftMoveable = lastPoint().canMoveRight(); - boolean rightMoveable = !leftMoveable && RANDOM.nextBoolean(); - return new Point(leftMoveable, rightMoveable); + points.add(Point.leftmostPoint(RANDOM.nextBoolean())); + return this; } private Point lastPoint() { diff --git a/src/main/java/nextstep/ladder/domain/Point.java b/src/main/java/nextstep/ladder/domain/Point.java index 5f4b5d4b65..1181bcab11 100644 --- a/src/main/java/nextstep/ladder/domain/Point.java +++ b/src/main/java/nextstep/ladder/domain/Point.java @@ -16,8 +16,12 @@ public static Point leftmostPoint(boolean rightMoveable) { return new Point(false, rightMoveable); } - public static Point rightmostPoint(boolean leftMoveable) { - return new Point(leftMoveable, false); + public Point rightmostPoint() { + return new Point(this.right, false); + } + + public Point nextPoint(boolean rightMoveable) { + return new Point(this.right, !this.right && rightMoveable); } public boolean canMoveLeft() { diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index d97f33f073..f516bca856 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -13,9 +13,10 @@ class LineTest { @DisplayName("포인트를 받아 라인을 생성한다") @Test void create() { + Point leftmostPoint = Point.leftmostPoint(true); List points = List.of( - Point.leftmostPoint(true), - Point.rightmostPoint(true) + leftmostPoint, + leftmostPoint.rightmostPoint() ); Line line = new Line(points); diff --git a/src/test/java/nextstep/ladder/domain/PointTest.java b/src/test/java/nextstep/ladder/domain/PointTest.java index 14a20db496..b1c0f5d9e1 100644 --- a/src/test/java/nextstep/ladder/domain/PointTest.java +++ b/src/test/java/nextstep/ladder/domain/PointTest.java @@ -38,7 +38,7 @@ void leftmostPoint() { @DisplayName("가장 오른쪽 포인트는 오른쪽으로 이동할 수 없다") @Test void rightmostPoint() { - Point point = Point.rightmostPoint(true); + Point point = new Point(false, true).rightmostPoint(); assertThat(point.canMoveRight()).isFalse(); } From 82cb33561538039bb3e538ce44ffb37f72a59dfe Mon Sep 17 00:00:00 2001 From: sang5c Date: Sun, 7 Apr 2024 01:19:02 +0900 Subject: [PATCH 25/36] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=EB=AA=85,?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EC=9D=BC=EA=B4=80?= =?UTF-8?q?=EC=84=B1=EC=9E=88=EA=B3=A0=20=EB=AA=85=ED=99=95=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nextstep/ladder/LadderGameApplication.java | 2 +- .../nextstep/ladder/domain/LadderGame.java | 2 +- .../nextstep/ladder/domain/LineBuilder.java | 10 +++++----- .../java/nextstep/ladder/domain/Lines.java | 4 ++-- .../java/nextstep/ladder/domain/Players.java | 2 +- .../java/nextstep/ladder/domain/Point.java | 18 +++++++++++------- .../java/nextstep/ladder/domain/LineTest.java | 4 ++-- .../java/nextstep/ladder/domain/LinesTest.java | 4 ++-- .../nextstep/ladder/domain/PlayersTest.java | 2 +- .../java/nextstep/ladder/domain/PointTest.java | 8 ++++---- 10 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/main/java/nextstep/ladder/LadderGameApplication.java b/src/main/java/nextstep/ladder/LadderGameApplication.java index e6362cf256..003219de4a 100644 --- a/src/main/java/nextstep/ladder/LadderGameApplication.java +++ b/src/main/java/nextstep/ladder/LadderGameApplication.java @@ -37,7 +37,7 @@ private static void printGameResults(LadderGame ladderGame) { } private static void printPlayers(Players players) { - String playerNames = IntStream.range(0, players.countOfPerson()) + String playerNames = IntStream.range(0, players.count()) .mapToObj(players::getPlayer) .map(player -> String.format(PRINT_FORMAT, player.getName())) .collect(Collectors.joining()); diff --git a/src/main/java/nextstep/ladder/domain/LadderGame.java b/src/main/java/nextstep/ladder/domain/LadderGame.java index 502993821d..bac087fc55 100644 --- a/src/main/java/nextstep/ladder/domain/LadderGame.java +++ b/src/main/java/nextstep/ladder/domain/LadderGame.java @@ -14,7 +14,7 @@ private LadderGame(final Players players, final Lines lines) { public static LadderGame of(List playerNames, int height) { Players players = Players.of(playerNames); - Lines lines = Lines.of(players.countOfPerson(), height); + Lines lines = Lines.of(players.count(), height); return new LadderGame(players, lines); } diff --git a/src/main/java/nextstep/ladder/domain/LineBuilder.java b/src/main/java/nextstep/ladder/domain/LineBuilder.java index 7114216f28..5b5dca21d8 100644 --- a/src/main/java/nextstep/ladder/domain/LineBuilder.java +++ b/src/main/java/nextstep/ladder/domain/LineBuilder.java @@ -17,20 +17,20 @@ public static Line buildWithRandomPoints(int count) { } private Line build() { - points.add(lastPoint().rightmostPoint()); + points.add(lastPoint().createRightmost()); return new Line(points); } - private LineBuilder addRandomMoveablePoints(int countOfMiddlePoint) { - for (int i = 0; i < countOfMiddlePoint; i++) { - Point point = lastPoint().nextPoint(RANDOM.nextBoolean()); + private LineBuilder addRandomMoveablePoints(int numberOfMiddlePoints) { + for (int i = 0; i < numberOfMiddlePoints; i++) { + Point point = lastPoint().createNext(RANDOM.nextBoolean()); points.add(point); } return this; } private LineBuilder initRandomMoveablePoint() { - points.add(Point.leftmostPoint(RANDOM.nextBoolean())); + points.add(Point.createLeftmost(RANDOM.nextBoolean())); return this; } diff --git a/src/main/java/nextstep/ladder/domain/Lines.java b/src/main/java/nextstep/ladder/domain/Lines.java index 3544bde600..8ca9b2714c 100644 --- a/src/main/java/nextstep/ladder/domain/Lines.java +++ b/src/main/java/nextstep/ladder/domain/Lines.java @@ -19,9 +19,9 @@ private void validate(List lines) { } } - public static Lines of(int countOfPerson, int height) { + public static Lines of(int numberOfPlayers, int height) { List lines = IntStream.range(0, height) - .mapToObj(i -> LineBuilder.buildWithRandomPoints(countOfPerson)) + .mapToObj(i -> LineBuilder.buildWithRandomPoints(numberOfPlayers)) .collect(Collectors.toList()); return new Lines(lines); } diff --git a/src/main/java/nextstep/ladder/domain/Players.java b/src/main/java/nextstep/ladder/domain/Players.java index 13cfe35553..e5b9d82e64 100644 --- a/src/main/java/nextstep/ladder/domain/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -25,7 +25,7 @@ public static Players of(List playerNames) { return new Players(players); } - public int countOfPerson() { + public int count() { return players.size(); } diff --git a/src/main/java/nextstep/ladder/domain/Point.java b/src/main/java/nextstep/ladder/domain/Point.java index 1181bcab11..2b9a3519fa 100644 --- a/src/main/java/nextstep/ladder/domain/Point.java +++ b/src/main/java/nextstep/ladder/domain/Point.java @@ -5,23 +5,27 @@ public class Point { private final boolean right; public Point(boolean left, boolean right) { + validate(left, right); + this.left = left; + this.right = right; + } + + private static void validate(boolean left, boolean right) { if (left && right) { throw new IllegalArgumentException("좌 우 모두 이동 가능한 Point 생성 불가"); } - this.left = left; - this.right = right; } - public static Point leftmostPoint(boolean rightMoveable) { - return new Point(false, rightMoveable); + public static Point createLeftmost(boolean canMoveRight) { + return new Point(false, canMoveRight); } - public Point rightmostPoint() { + public Point createRightmost() { return new Point(this.right, false); } - public Point nextPoint(boolean rightMoveable) { - return new Point(this.right, !this.right && rightMoveable); + public Point createNext(boolean canMoveRight) { + return new Point(this.right, !this.right && canMoveRight); } public boolean canMoveLeft() { diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index f516bca856..c874970f1b 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -13,10 +13,10 @@ class LineTest { @DisplayName("포인트를 받아 라인을 생성한다") @Test void create() { - Point leftmostPoint = Point.leftmostPoint(true); + Point leftmostPoint = Point.createLeftmost(true); List points = List.of( leftmostPoint, - leftmostPoint.rightmostPoint() + leftmostPoint.createRightmost() ); Line line = new Line(points); diff --git a/src/test/java/nextstep/ladder/domain/LinesTest.java b/src/test/java/nextstep/ladder/domain/LinesTest.java index e64180ce75..affdad6038 100644 --- a/src/test/java/nextstep/ladder/domain/LinesTest.java +++ b/src/test/java/nextstep/ladder/domain/LinesTest.java @@ -18,8 +18,8 @@ void invalidHeight() { @Test void create() { int height = 5; - int countOfPerson = 3; - Lines lines = Lines.of(countOfPerson, height); + int numberOfPlayers = 3; + Lines lines = Lines.of(numberOfPlayers, height); assertThat(lines.getHeight()).isEqualTo(height); } diff --git a/src/test/java/nextstep/ladder/domain/PlayersTest.java b/src/test/java/nextstep/ladder/domain/PlayersTest.java index adfd5050b8..6365b65214 100644 --- a/src/test/java/nextstep/ladder/domain/PlayersTest.java +++ b/src/test/java/nextstep/ladder/domain/PlayersTest.java @@ -16,7 +16,7 @@ void create() { List playerNames = List.of("pobi", "crong", "honux"); Players players = Players.of(playerNames); - assertThat(players.countOfPerson()).isEqualTo(playerNames.size()); + assertThat(players.count()).isEqualTo(playerNames.size()); } @DisplayName("참가자는 1명 이상이다") diff --git a/src/test/java/nextstep/ladder/domain/PointTest.java b/src/test/java/nextstep/ladder/domain/PointTest.java index b1c0f5d9e1..80be5d53df 100644 --- a/src/test/java/nextstep/ladder/domain/PointTest.java +++ b/src/test/java/nextstep/ladder/domain/PointTest.java @@ -29,16 +29,16 @@ void create(boolean left, boolean right) { @DisplayName("가장 왼쪽 포인트는 왼쪽으로 이동할 수 없다") @Test - void leftmostPoint() { - Point point = Point.leftmostPoint(true); + void createLeftmost() { + Point point = Point.createLeftmost(true); assertThat(point.canMoveLeft()).isFalse(); } @DisplayName("가장 오른쪽 포인트는 오른쪽으로 이동할 수 없다") @Test - void rightmostPoint() { - Point point = new Point(false, true).rightmostPoint(); + void createRightmost() { + Point point = new Point(false, true).createRightmost(); assertThat(point.canMoveRight()).isFalse(); } From 82abe22ed8e84b17443e8514adc0024ef3e01733 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sun, 7 Apr 2024 16:07:57 +0900 Subject: [PATCH 26/36] =?UTF-8?q?refactor:=20ConsoleUtil=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ladder/LadderGameApplication.java | 74 ++----------------- .../nextstep/ladder/util/ConsoleUtil.java | 71 ++++++++++++++++++ 2 files changed, 77 insertions(+), 68 deletions(-) create mode 100644 src/main/java/nextstep/ladder/util/ConsoleUtil.java diff --git a/src/main/java/nextstep/ladder/LadderGameApplication.java b/src/main/java/nextstep/ladder/LadderGameApplication.java index 003219de4a..cd92c89c40 100644 --- a/src/main/java/nextstep/ladder/LadderGameApplication.java +++ b/src/main/java/nextstep/ladder/LadderGameApplication.java @@ -1,80 +1,18 @@ package nextstep.ladder; -import nextstep.ladder.domain.*; +import nextstep.ladder.domain.LadderGame; +import nextstep.ladder.util.ConsoleUtil; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; public class LadderGameApplication { - private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; - private static final String VERTICAL_LINE = "|"; - private static final String MOVEABLE_FORMAT = "-----"; - private static final String LINE_BREAK = "\n"; - private static final String PRINT_FORMAT = "%6s"; - public static void main(String[] args) { - String playerNames = inputPlayerNames(); - int height = inputHeight(); - - LadderGame ladderGame = LadderGame.of(splitNames(playerNames), height); - - printGameResults(ladderGame); - } - - - private static List splitNames(String playerNames) { - return Arrays.stream(playerNames.split(PLAYER_NAME_SPLIT_DELIMITER)) - .collect(Collectors.toList()); - } - - private static void printGameResults(LadderGame ladderGame) { - System.out.println("실행결과"); - printPlayers(ladderGame.getPlayers()); - printLines(ladderGame.getLines()); - } - - private static void printPlayers(Players players) { - String playerNames = IntStream.range(0, players.count()) - .mapToObj(players::getPlayer) - .map(player -> String.format(PRINT_FORMAT, player.getName())) - .collect(Collectors.joining()); - - System.out.println(playerNames); - } - - private static void printLines(Lines lines) { - String linesString = IntStream.range(0, lines.getHeight()) - .mapToObj(targetHeight -> lineToString(lines.getLine(targetHeight))) - .collect(Collectors.joining(LINE_BREAK)); - - System.out.println(linesString); - } - - private static String lineToString(Line line) { - return IntStream.range(0, line.width()) - .mapToObj(index -> pointToString(line.getPoint(index))) - .collect(Collectors.joining()); - } - - private static String pointToString(Point point) { - if (point.canMoveLeft()) { - return String.format(PRINT_FORMAT, MOVEABLE_FORMAT + VERTICAL_LINE); - } - - return String.format(PRINT_FORMAT, VERTICAL_LINE); - } - - private static int inputHeight() { - System.out.println("최대 사다리 높이는 몇 개인가요?"); - return 5; // TODO: input - } + List playerNames = ConsoleUtil.inputPlayerNames(); + int height = ConsoleUtil.inputHeight(); - private static String inputPlayerNames() { - System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + LadderGame ladderGame = LadderGame.of(playerNames, height); - return "pobi,honux,crong,jk"; // TODO: input + ConsoleUtil.printGameResults(ladderGame); } } diff --git a/src/main/java/nextstep/ladder/util/ConsoleUtil.java b/src/main/java/nextstep/ladder/util/ConsoleUtil.java new file mode 100644 index 0000000000..79a7233346 --- /dev/null +++ b/src/main/java/nextstep/ladder/util/ConsoleUtil.java @@ -0,0 +1,71 @@ +package nextstep.ladder.util; + +import nextstep.ladder.domain.*; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class ConsoleUtil { + private static final String VERTICAL_LINE = "|"; + private static final String MOVEABLE_FORMAT = "-----"; + private static final String LINE_BREAK = "\n"; + private static final String PRINT_FORMAT = "%6s"; + private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; + + public static List inputPlayerNames() { + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + + String input = "pobi,honux,crong,jk"; // TODO: input + return splitNames(input); + + } + + private static List splitNames(String playerNames) { + return Arrays.stream(playerNames.split(PLAYER_NAME_SPLIT_DELIMITER)) + .collect(Collectors.toList()); + } + + public static int inputHeight() { + System.out.println("최대 사다리 높이는 몇 개인가요?"); + return 5; // TODO: input + } + + public static void printGameResults(LadderGame ladderGame) { + System.out.println("실행결과"); + printPlayers(ladderGame.getPlayers()); + printLines(ladderGame.getLines()); + } + + private static void printPlayers(Players players) { + String playerNames = IntStream.range(0, players.count()) + .mapToObj(players::getPlayer) + .map(player -> String.format(PRINT_FORMAT, player.getName())) + .collect(Collectors.joining()); + + System.out.println(playerNames); + } + + private static void printLines(Lines lines) { + String linesString = IntStream.range(0, lines.getHeight()) + .mapToObj(targetHeight -> lineToString(lines.getLine(targetHeight))) + .collect(Collectors.joining(LINE_BREAK)); + + System.out.println(linesString); + } + + private static String lineToString(Line line) { + return IntStream.range(0, line.width()) + .mapToObj(index -> pointToString(line.getPoint(index))) + .collect(Collectors.joining()); + } + + private static String pointToString(Point point) { + if (point.canMoveLeft()) { + return String.format(PRINT_FORMAT, MOVEABLE_FORMAT + VERTICAL_LINE); + } + + return String.format(PRINT_FORMAT, VERTICAL_LINE); + } +} From 6aaabc178af14dec6d77a75d96aa8d61078d133f Mon Sep 17 00:00:00 2001 From: sang5c Date: Sun, 7 Apr 2024 16:08:56 +0900 Subject: [PATCH 27/36] =?UTF-8?q?refactor:=20=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=20final?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/domain/Line.java | 2 +- src/main/java/nextstep/ladder/domain/Players.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index 3ea118b789..675c47e750 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -3,7 +3,7 @@ import java.util.List; public class Line { - private List points; + private final List points; Line(List points) { validate(points); diff --git a/src/main/java/nextstep/ladder/domain/Players.java b/src/main/java/nextstep/ladder/domain/Players.java index e5b9d82e64..b8d43d4212 100644 --- a/src/main/java/nextstep/ladder/domain/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -4,7 +4,7 @@ import java.util.stream.Collectors; public class Players { - private List players; + private final List players; private Players(List players) { validate(players); From 7e1e4ecda9bb864c6542dcc6c4ae9eb66d283050 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sun, 7 Apr 2024 16:10:52 +0900 Subject: [PATCH 28/36] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=AA=85=ED=99=95=ED=95=98=EA=B2=8C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/LadderGameApplication.java | 2 +- src/main/java/nextstep/ladder/domain/LadderGame.java | 2 +- src/test/java/nextstep/ladder/domain/LadderGameTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/nextstep/ladder/LadderGameApplication.java b/src/main/java/nextstep/ladder/LadderGameApplication.java index cd92c89c40..aebe120cdd 100644 --- a/src/main/java/nextstep/ladder/LadderGameApplication.java +++ b/src/main/java/nextstep/ladder/LadderGameApplication.java @@ -11,7 +11,7 @@ public static void main(String[] args) { List playerNames = ConsoleUtil.inputPlayerNames(); int height = ConsoleUtil.inputHeight(); - LadderGame ladderGame = LadderGame.of(playerNames, height); + LadderGame ladderGame = LadderGame.start(playerNames, height); ConsoleUtil.printGameResults(ladderGame); } diff --git a/src/main/java/nextstep/ladder/domain/LadderGame.java b/src/main/java/nextstep/ladder/domain/LadderGame.java index bac087fc55..1a1fb20459 100644 --- a/src/main/java/nextstep/ladder/domain/LadderGame.java +++ b/src/main/java/nextstep/ladder/domain/LadderGame.java @@ -12,7 +12,7 @@ private LadderGame(final Players players, final Lines lines) { this.lines = lines; } - public static LadderGame of(List playerNames, int height) { + public static LadderGame start(List playerNames, int height) { Players players = Players.of(playerNames); Lines lines = Lines.of(players.count(), height); diff --git a/src/test/java/nextstep/ladder/domain/LadderGameTest.java b/src/test/java/nextstep/ladder/domain/LadderGameTest.java index 2da44ffaba..6b6d72d643 100644 --- a/src/test/java/nextstep/ladder/domain/LadderGameTest.java +++ b/src/test/java/nextstep/ladder/domain/LadderGameTest.java @@ -15,6 +15,6 @@ void create() { List playerNames = List.of("pobi", "honux", "crong", "jk"); int height = 5; - assertThatCode(() -> LadderGame.of(playerNames, height)).doesNotThrowAnyException(); + assertThatCode(() -> LadderGame.start(playerNames, height)).doesNotThrowAnyException(); } } From 1b2b225ee8412f2a6186c58389f07acabe86eb49 Mon Sep 17 00:00:00 2001 From: sang5c Date: Sun, 7 Apr 2024 16:13:03 +0900 Subject: [PATCH 29/36] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20inp?= =?UTF-8?q?ut=20=EB=B0=9B=EC=95=84=20=EA=B2=8C=EC=9E=84=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/util/ConsoleUtil.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/nextstep/ladder/util/ConsoleUtil.java b/src/main/java/nextstep/ladder/util/ConsoleUtil.java index 79a7233346..a62ffb5b23 100644 --- a/src/main/java/nextstep/ladder/util/ConsoleUtil.java +++ b/src/main/java/nextstep/ladder/util/ConsoleUtil.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Scanner; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -14,10 +15,12 @@ public class ConsoleUtil { private static final String PRINT_FORMAT = "%6s"; private static final String PLAYER_NAME_SPLIT_DELIMITER = ","; + private static final Scanner SCANNER = new Scanner(System.in); + public static List inputPlayerNames() { System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); - String input = "pobi,honux,crong,jk"; // TODO: input + String input = SCANNER.nextLine(); // ex) pobi,honux,crong,jk return splitNames(input); } @@ -29,7 +32,7 @@ private static List splitNames(String playerNames) { public static int inputHeight() { System.out.println("최대 사다리 높이는 몇 개인가요?"); - return 5; // TODO: input + return SCANNER.nextInt(); } public static void printGameResults(LadderGame ladderGame) { From 30de8612b819b2357259746855c77bd2d4667ddc Mon Sep 17 00:00:00 2001 From: sang5c Date: Thu, 11 Apr 2024 23:13:21 +0900 Subject: [PATCH 30/36] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20static=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/domain/Line.java | 12 ++++++------ src/main/java/nextstep/ladder/domain/Player.java | 2 +- src/main/java/nextstep/ladder/domain/Point.java | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index 675c47e750..ae4fb8ef36 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -10,12 +10,12 @@ public class Line { this.points = points; } - private static void validate(List points) { + private void validate(List points) { validatePointsListSize(points); validatePointMovements(points); } - private static void validatePointsListSize(List points) { + private void validatePointsListSize(List points) { if (points == null || points.isEmpty()) { throw new IllegalArgumentException("점이 없습니다."); } @@ -25,7 +25,7 @@ private static void validatePointsListSize(List points) { } } - private static void validatePointMovements(List points) { + private void validatePointMovements(List points) { if (firstPoint(points).canMoveLeft() || lastPoint(points).canMoveRight()) { throw new IllegalArgumentException("첫 점에서는 왼쪽으로 이동할 수 없고, 마지막 점에서는 오른쪽으로 이동할 수 없습니다."); } @@ -35,17 +35,17 @@ private static void validatePointMovements(List points) { } } - private static void assertConsecutivePointsAreMovable(List points, int i) { + private void assertConsecutivePointsAreMovable(List points, int i) { if (points.get(i).canMoveRight() && !points.get(i + 1).canMoveLeft()) { throw new IllegalArgumentException("연속된 점에서는 서로 이동 가능해야 합니다."); } } - private static Point firstPoint(List points) { + private Point firstPoint(List points) { return points.get(0); } - private static Point lastPoint(List points) { + private Point lastPoint(List points) { return points.get(points.size() - 1); } diff --git a/src/main/java/nextstep/ladder/domain/Player.java b/src/main/java/nextstep/ladder/domain/Player.java index 75a3632fd7..7bdc88890a 100644 --- a/src/main/java/nextstep/ladder/domain/Player.java +++ b/src/main/java/nextstep/ladder/domain/Player.java @@ -8,7 +8,7 @@ public Player(String name) { this.name = name; } - private static void validate(String name) { + private void validate(String name) { if (name == null || name.isEmpty()) { throw new IllegalArgumentException("이름은 비어있을 수 없습니다."); } diff --git a/src/main/java/nextstep/ladder/domain/Point.java b/src/main/java/nextstep/ladder/domain/Point.java index 2b9a3519fa..ef99a1f2c5 100644 --- a/src/main/java/nextstep/ladder/domain/Point.java +++ b/src/main/java/nextstep/ladder/domain/Point.java @@ -10,7 +10,7 @@ public Point(boolean left, boolean right) { this.right = right; } - private static void validate(boolean left, boolean right) { + private void validate(boolean left, boolean right) { if (left && right) { throw new IllegalArgumentException("좌 우 모두 이동 가능한 Point 생성 불가"); } From 439d1cc2be73be1e4509d0f3492188f6c921324f Mon Sep 17 00:00:00 2001 From: sang5c Date: Fri, 19 Apr 2024 03:18:03 +0900 Subject: [PATCH 31/36] =?UTF-8?q?refactor:=20=EB=A7=A4=EC=A7=81=20?= =?UTF-8?q?=EB=84=98=EB=B2=84=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/domain/Line.java | 6 ++++-- src/main/java/nextstep/ladder/domain/Player.java | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index ae4fb8ef36..3442ae6711 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -3,6 +3,8 @@ import java.util.List; public class Line { + private static final int MIN_POINT_SIZE = 2; + private final List points; Line(List points) { @@ -20,8 +22,8 @@ private void validatePointsListSize(List points) { throw new IllegalArgumentException("점이 없습니다."); } - if (points.size() < 2) { - throw new IllegalArgumentException("점이 두 개 이상 있어야 합니다."); + if (points.size() < MIN_POINT_SIZE) { + throw new IllegalArgumentException("점이 " + MIN_POINT_SIZE + "개 이상 있어야 합니다."); } } diff --git a/src/main/java/nextstep/ladder/domain/Player.java b/src/main/java/nextstep/ladder/domain/Player.java index 7bdc88890a..1fec2dcbc6 100644 --- a/src/main/java/nextstep/ladder/domain/Player.java +++ b/src/main/java/nextstep/ladder/domain/Player.java @@ -1,6 +1,8 @@ package nextstep.ladder.domain; public class Player { + private static final int MAX_NAME_LENGTH = 5; + private final String name; public Player(String name) { @@ -13,8 +15,8 @@ private void validate(String name) { throw new IllegalArgumentException("이름은 비어있을 수 없습니다."); } - if (name.length() > 5) { - throw new IllegalArgumentException("이름은 5자 이하여야 합니다."); + if (name.length() > MAX_NAME_LENGTH) { + throw new IllegalArgumentException("이름은 " + MAX_NAME_LENGTH + "자 이하여야 합니다."); } } From 6498f498531cda8075e88f9858ddcf76485c1773 Mon Sep 17 00:00:00 2001 From: sang5c Date: Fri, 19 Apr 2024 03:35:30 +0900 Subject: [PATCH 32/36] =?UTF-8?q?feat:=20player=EB=8A=94=20=EB=AA=87=20?= =?UTF-8?q?=EB=B2=88=EC=A7=B8=20=EC=9E=90=EB=A6=AC=EC=9D=B8=EC=A7=80=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?index=EB=A5=BC=20=EA=B0=96=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/ladder/domain/Player.java | 18 ++++++++++++++-- .../java/nextstep/ladder/domain/Players.java | 10 ++++++--- .../nextstep/ladder/domain/PlayerTest.java | 21 +++++++++++++++++-- .../nextstep/ladder/domain/PlayersTest.java | 14 +++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Player.java b/src/main/java/nextstep/ladder/domain/Player.java index 1fec2dcbc6..1fc79b1316 100644 --- a/src/main/java/nextstep/ladder/domain/Player.java +++ b/src/main/java/nextstep/ladder/domain/Player.java @@ -2,14 +2,24 @@ public class Player { private static final int MAX_NAME_LENGTH = 5; - + private static final int MIN_INDEX = 0; + + private final int index; private final String name; - public Player(String name) { + public Player(int index, String name) { + validate(index); validate(name); + this.index = index; this.name = name; } + private static void validate(int index) { + if (index < MIN_INDEX) { + throw new IllegalArgumentException("인덱스는 " + MIN_INDEX + "보다 작을 수 없습니다."); + } + } + private void validate(String name) { if (name == null || name.isEmpty()) { throw new IllegalArgumentException("이름은 비어있을 수 없습니다."); @@ -23,4 +33,8 @@ private void validate(String name) { public String getName() { return name; } + + public boolean sameIndex(int index) { + return this.index == index; + } } diff --git a/src/main/java/nextstep/ladder/domain/Players.java b/src/main/java/nextstep/ladder/domain/Players.java index b8d43d4212..579375520c 100644 --- a/src/main/java/nextstep/ladder/domain/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.stream.Collectors; +import java.util.stream.IntStream; public class Players { private final List players; @@ -18,8 +19,8 @@ private void validate(List players) { } public static Players of(List playerNames) { - List players = playerNames.stream() - .map(Player::new) + List players = IntStream.range(0, playerNames.size()) + .mapToObj(index -> new Player(index, playerNames.get(index))) .collect(Collectors.toList()); return new Players(players); @@ -30,6 +31,9 @@ public int count() { } public Player getPlayer(int index) { - return players.get(index); + return players.stream() + .filter(player -> player.sameIndex(index)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("참가자가 없습니다. index: " + index)); } } diff --git a/src/test/java/nextstep/ladder/domain/PlayerTest.java b/src/test/java/nextstep/ladder/domain/PlayerTest.java index 090a2a5c7b..b682f90d98 100644 --- a/src/test/java/nextstep/ladder/domain/PlayerTest.java +++ b/src/test/java/nextstep/ladder/domain/PlayerTest.java @@ -3,8 +3,10 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.NullAndEmptySource; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; class PlayerTest { @@ -12,14 +14,29 @@ class PlayerTest { @DisplayName("이름은 5글자 이하만 가능하다") @Test void tooLongName() { - assertThatThrownBy(() -> new Player("123456")).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> new Player(0, "123456")).isInstanceOf(IllegalArgumentException.class); } @DisplayName("이름은 비어있을 수 없다") @ParameterizedTest(name = "name = {0}") @NullAndEmptySource void emptyName(String name) { - assertThatThrownBy(() -> new Player(name)).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> new Player(0, name)).isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("인덱스는 0보다 작을 수 없다") + @Test + void negativeIndex() { + assertThatThrownBy(() -> new Player(-1, "hello")).isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("인덱스가 같은지 비교") + @ParameterizedTest(name = "index = {0}, targetIndex = {1}, expected = {2}") + @CsvSource(value = {"0,0,true", "1,0,false"}) + void sameIndex(int index, int targetIndex, boolean expected) { + Player player = new Player(index, "hello"); + + assertThat(player.sameIndex(targetIndex)).isEqualTo(expected); } } diff --git a/src/test/java/nextstep/ladder/domain/PlayersTest.java b/src/test/java/nextstep/ladder/domain/PlayersTest.java index 6365b65214..20e8ce1b99 100644 --- a/src/test/java/nextstep/ladder/domain/PlayersTest.java +++ b/src/test/java/nextstep/ladder/domain/PlayersTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.SoftAssertions.assertSoftly; class PlayersTest { @@ -25,4 +26,17 @@ void invalidPlayerCount() { assertThatThrownBy(() -> Players.of(List.of())) .isInstanceOf(IllegalArgumentException.class); } + + @DisplayName("인덱스를 받아 참가자를 반환한다") + @Test + void getPlayer() { + List playerNames = List.of("pobi", "crong", "honux"); + Players players = Players.of(playerNames); + + assertSoftly(softAssertions -> { + softAssertions.assertThat(players.getPlayer(0).getName()).isEqualTo("pobi"); + softAssertions.assertThat(players.getPlayer(1).getName()).isEqualTo("crong"); + softAssertions.assertThat(players.getPlayer(2).getName()).isEqualTo("honux"); + }); + } } From a8a84a8c5ed1d94b8c8fe899ec54511d5b909fe2 Mon Sep 17 00:00:00 2001 From: sang5c Date: Fri, 19 Apr 2024 03:40:58 +0900 Subject: [PATCH 33/36] =?UTF-8?q?feat:=20Point=EB=8A=94=20=EB=AA=87=20?= =?UTF-8?q?=EB=B2=88=EC=A7=B8=20=EC=9E=90=EB=A6=AC=EC=9D=B8=EC=A7=80=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?index=EB=A5=BC=20=EA=B0=96=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/ladder/domain/Line.java | 7 ++++-- .../java/nextstep/ladder/domain/Point.java | 23 ++++++++++++++--- .../java/nextstep/ladder/domain/LineTest.java | 25 ++++++++++++++----- .../nextstep/ladder/domain/PointTest.java | 22 +++++++++++++--- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index 3442ae6711..b44c931045 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -4,7 +4,7 @@ public class Line { private static final int MIN_POINT_SIZE = 2; - + private final List points; Line(List points) { @@ -56,6 +56,9 @@ public int width() { } public Point getPoint(int index) { - return points.get(index); + return points.stream() + .filter(point -> point.sameIndex(index)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("포인트가 없습니다. index: " + index)); } } diff --git a/src/main/java/nextstep/ladder/domain/Point.java b/src/main/java/nextstep/ladder/domain/Point.java index ef99a1f2c5..83bd8568c7 100644 --- a/src/main/java/nextstep/ladder/domain/Point.java +++ b/src/main/java/nextstep/ladder/domain/Point.java @@ -1,15 +1,26 @@ package nextstep.ladder.domain; public class Point { + private static final int MIN_INDEX = 0; + + private final int index; private final boolean left; private final boolean right; - public Point(boolean left, boolean right) { + public Point(int index, boolean left, boolean right) { + validate(index); validate(left, right); + this.index = index; this.left = left; this.right = right; } + private void validate(int index) { + if (index < MIN_INDEX) { + throw new IllegalArgumentException("인덱스는 " + MIN_INDEX + "보다 작을 수 없습니다."); + } + } + private void validate(boolean left, boolean right) { if (left && right) { throw new IllegalArgumentException("좌 우 모두 이동 가능한 Point 생성 불가"); @@ -17,15 +28,15 @@ private void validate(boolean left, boolean right) { } public static Point createLeftmost(boolean canMoveRight) { - return new Point(false, canMoveRight); + return new Point(MIN_INDEX, false, canMoveRight); } public Point createRightmost() { - return new Point(this.right, false); + return new Point(this.index + 1, this.right, false); } public Point createNext(boolean canMoveRight) { - return new Point(this.right, !this.right && canMoveRight); + return new Point(this.index + 1, this.right, !this.right && canMoveRight); } public boolean canMoveLeft() { @@ -35,4 +46,8 @@ public boolean canMoveLeft() { public boolean canMoveRight() { return right; } + + public boolean sameIndex(int index) { + return this.index == index; + } } diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index c874970f1b..b77ed95fde 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -41,8 +41,8 @@ void emptyPoints() { @Test void firstPointCannotMoveLeft() { List points = List.of( - new Point(true, false), - new Point(false, false) + new Point(0, true, false), + new Point(1, false, false) ); assertThatThrownBy(() -> new Line(points)) @@ -53,8 +53,8 @@ void firstPointCannotMoveLeft() { @Test void lastPointCannotMoveRight() { List points = List.of( - new Point(false, false), - new Point(false, true) + new Point(0, false, false), + new Point(1, false, true) ); assertThatThrownBy(() -> new Line(points)) @@ -65,12 +65,25 @@ void lastPointCannotMoveRight() { @Test void hasMovableConnectionToNext() { List points = List.of( - new Point(false, true), - new Point(false, false) + new Point(0, false, true), + new Point(1, false, false) ); assertThatThrownBy(() -> new Line(points)) .isInstanceOf(IllegalArgumentException.class); } + @DisplayName("인덱스를 받아 포인트를 반환한다") + @Test + void getPoint() { + Point leftmostPoint = Point.createLeftmost(true); + List points = List.of( + leftmostPoint, + leftmostPoint.createRightmost() + ); + Line line = new Line(points); + + assertThat(line.getPoint(0)).isEqualTo(leftmostPoint); + } + } diff --git a/src/test/java/nextstep/ladder/domain/PointTest.java b/src/test/java/nextstep/ladder/domain/PointTest.java index 80be5d53df..585108014a 100644 --- a/src/test/java/nextstep/ladder/domain/PointTest.java +++ b/src/test/java/nextstep/ladder/domain/PointTest.java @@ -10,10 +10,17 @@ class PointTest { + @DisplayName("인덱스는 0보다 작을 수 없다") + @Test + void negativeIndex() { + assertThatThrownBy(() -> new Point(-1, false, false)) + .isInstanceOf(IllegalArgumentException.class); + } + @DisplayName("좌 우 모두 이동 가능한 Point는 생성할 수 없다") @Test void invalidPoint() { - assertThatThrownBy(() -> new Point(true, true)) + assertThatThrownBy(() -> new Point(1, true, true)) .isInstanceOf(IllegalArgumentException.class); } @@ -21,7 +28,7 @@ void invalidPoint() { @ParameterizedTest(name = "좌 이동: {0}, 우 이동: {1})") @CsvSource(value = {"true,false", "false,true", "false,false"}) void create(boolean left, boolean right) { - Point point = new Point(left, right); + Point point = new Point(1, left, right); assertThat(point.canMoveLeft()).isEqualTo(left); assertThat(point.canMoveRight()).isEqualTo(right); @@ -38,8 +45,17 @@ void createLeftmost() { @DisplayName("가장 오른쪽 포인트는 오른쪽으로 이동할 수 없다") @Test void createRightmost() { - Point point = new Point(false, true).createRightmost(); + Point point = new Point(1, false, true).createRightmost(); assertThat(point.canMoveRight()).isFalse(); } + + @DisplayName("인덱스가 같은지 비교") + @ParameterizedTest(name = "index = {0}, targetIndex = {1}, expected = {2}") + @CsvSource(value = {"0,0,true", "1,0,false"}) + void sameIndex(int index, int targetIndex, boolean expected) { + Point point = new Point(index, false, false); + + assertThat(point.sameIndex(targetIndex)).isEqualTo(expected); + } } From 9ad91e831ba1a31c79e57b9550a0981ed28cfbe7 Mon Sep 17 00:00:00 2001 From: sang5c Date: Fri, 19 Apr 2024 03:48:16 +0900 Subject: [PATCH 34/36] =?UTF-8?q?refactor:=20collectingAndThen=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=97=AC=20=EB=B0=94=EB=A1=9C=20=EB=B0=98?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/ladder/domain/Lines.java | 9 +++++---- src/main/java/nextstep/ladder/domain/Players.java | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/nextstep/ladder/domain/Lines.java b/src/main/java/nextstep/ladder/domain/Lines.java index 8ca9b2714c..393211852e 100644 --- a/src/main/java/nextstep/ladder/domain/Lines.java +++ b/src/main/java/nextstep/ladder/domain/Lines.java @@ -1,9 +1,11 @@ package nextstep.ladder.domain; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.IntStream; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + public class Lines { private final List lines; @@ -20,10 +22,9 @@ private void validate(List lines) { } public static Lines of(int numberOfPlayers, int height) { - List lines = IntStream.range(0, height) + return IntStream.range(0, height) .mapToObj(i -> LineBuilder.buildWithRandomPoints(numberOfPlayers)) - .collect(Collectors.toList()); - return new Lines(lines); + .collect(collectingAndThen(toList(), Lines::new)); } public int getHeight() { diff --git a/src/main/java/nextstep/ladder/domain/Players.java b/src/main/java/nextstep/ladder/domain/Players.java index 579375520c..2c8b49dad3 100644 --- a/src/main/java/nextstep/ladder/domain/Players.java +++ b/src/main/java/nextstep/ladder/domain/Players.java @@ -1,9 +1,11 @@ package nextstep.ladder.domain; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.IntStream; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + public class Players { private final List players; @@ -19,11 +21,9 @@ private void validate(List players) { } public static Players of(List playerNames) { - List players = IntStream.range(0, playerNames.size()) + return IntStream.range(0, playerNames.size()) .mapToObj(index -> new Player(index, playerNames.get(index))) - .collect(Collectors.toList()); - - return new Players(players); + .collect(collectingAndThen(toList(), Players::new)); } public int count() { From 9a91a2fe32476d6ea99ad51c8cfd30bc7d111819 Mon Sep 17 00:00:00 2001 From: sang5c Date: Mon, 22 Apr 2024 01:12:16 +0900 Subject: [PATCH 35/36] =?UTF-8?q?refactor:=20LineBuilder=EB=A5=BC=20Line?= =?UTF-8?q?=20=EB=82=B4=EB=B6=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/ladder/domain/Line.java | 34 ++++++++- .../nextstep/ladder/domain/LineBuilder.java | 40 ----------- .../java/nextstep/ladder/domain/Lines.java | 13 +++- .../java/nextstep/ladder/domain/Point.java | 15 ++++ .../ladder/domain/LineBuilderTest.java | 16 ----- .../java/nextstep/ladder/domain/LineTest.java | 70 +++---------------- 6 files changed, 69 insertions(+), 119 deletions(-) delete mode 100644 src/main/java/nextstep/ladder/domain/LineBuilder.java delete mode 100644 src/test/java/nextstep/ladder/domain/LineBuilderTest.java diff --git a/src/main/java/nextstep/ladder/domain/Line.java b/src/main/java/nextstep/ladder/domain/Line.java index b44c931045..8035f269e1 100644 --- a/src/main/java/nextstep/ladder/domain/Line.java +++ b/src/main/java/nextstep/ladder/domain/Line.java @@ -1,5 +1,6 @@ package nextstep.ladder.domain; +import java.util.ArrayList; import java.util.List; public class Line { @@ -7,7 +8,7 @@ public class Line { private final List points; - Line(List points) { + private Line(List points) { validate(points); this.points = points; } @@ -61,4 +62,35 @@ public Point getPoint(int index) { .findFirst() .orElseThrow(() -> new IllegalArgumentException("포인트가 없습니다. index: " + index)); } + + static class LineBuilder { + private final List points; + + public LineBuilder() { + this.points = new ArrayList<>(); + } + + public LineBuilder point(boolean canMoveRight) { + if (points.isEmpty()) { + points.add(Point.createLeftmost(canMoveRight)); + return this; + } + points.add(lastPoint().createNext(canMoveRight)); + return this; + } + + public Line build() { + if (points.isEmpty()) { + throw new IllegalStateException("점이 없습니다."); + } + + points.add(lastPoint().createRightmost()); + + return new Line(points); + } + + private Point lastPoint() { + return points.get(points.size() - 1); + } + } } diff --git a/src/main/java/nextstep/ladder/domain/LineBuilder.java b/src/main/java/nextstep/ladder/domain/LineBuilder.java deleted file mode 100644 index 5b5dca21d8..0000000000 --- a/src/main/java/nextstep/ladder/domain/LineBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -package nextstep.ladder.domain; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -public class LineBuilder { - - private static final Random RANDOM = new Random(); - - private final List points = new ArrayList<>(); - - public static Line buildWithRandomPoints(int count) { - return new LineBuilder().initRandomMoveablePoint() - .addRandomMoveablePoints(count - 2) - .build(); - } - - private Line build() { - points.add(lastPoint().createRightmost()); - return new Line(points); - } - - private LineBuilder addRandomMoveablePoints(int numberOfMiddlePoints) { - for (int i = 0; i < numberOfMiddlePoints; i++) { - Point point = lastPoint().createNext(RANDOM.nextBoolean()); - points.add(point); - } - return this; - } - - private LineBuilder initRandomMoveablePoint() { - points.add(Point.createLeftmost(RANDOM.nextBoolean())); - return this; - } - - private Point lastPoint() { - return points.get(points.size() - 1); - } -} diff --git a/src/main/java/nextstep/ladder/domain/Lines.java b/src/main/java/nextstep/ladder/domain/Lines.java index 393211852e..5632a15074 100644 --- a/src/main/java/nextstep/ladder/domain/Lines.java +++ b/src/main/java/nextstep/ladder/domain/Lines.java @@ -1,12 +1,14 @@ package nextstep.ladder.domain; import java.util.List; +import java.util.Random; import java.util.stream.IntStream; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toList; public class Lines { + private static final Random RANDOM = new Random(); private final List lines; @@ -23,10 +25,19 @@ private void validate(List lines) { public static Lines of(int numberOfPlayers, int height) { return IntStream.range(0, height) - .mapToObj(i -> LineBuilder.buildWithRandomPoints(numberOfPlayers)) + .mapToObj(i -> getBuildWithRandomPoints(numberOfPlayers)) .collect(collectingAndThen(toList(), Lines::new)); } + private static Line getBuildWithRandomPoints(int numberOfPlayers) { + Line.LineBuilder builder = new Line.LineBuilder(); + builder.point(RANDOM.nextBoolean()); + for (int i = 0; i < numberOfPlayers - 2; i++) { + builder.point(RANDOM.nextBoolean()); + } + return builder.build(); + } + public int getHeight() { return lines.size(); } diff --git a/src/main/java/nextstep/ladder/domain/Point.java b/src/main/java/nextstep/ladder/domain/Point.java index 83bd8568c7..7a6f0c2d6d 100644 --- a/src/main/java/nextstep/ladder/domain/Point.java +++ b/src/main/java/nextstep/ladder/domain/Point.java @@ -1,5 +1,7 @@ package nextstep.ladder.domain; +import java.util.Objects; + public class Point { private static final int MIN_INDEX = 0; @@ -50,4 +52,17 @@ public boolean canMoveRight() { public boolean sameIndex(int index) { return this.index == index; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Point point = (Point) o; + return index == point.index && left == point.left && right == point.right; + } + + @Override + public int hashCode() { + return Objects.hash(index, left, right); + } } diff --git a/src/test/java/nextstep/ladder/domain/LineBuilderTest.java b/src/test/java/nextstep/ladder/domain/LineBuilderTest.java deleted file mode 100644 index 4a10b868ec..0000000000 --- a/src/test/java/nextstep/ladder/domain/LineBuilderTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package nextstep.ladder.domain; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class LineBuilderTest { - - @DisplayName("사람 수를 받아 가로 라인을 생성한다") - @Test - void createLine() { - Line line = LineBuilder.buildWithRandomPoints(5); - assertThat(line.width()).isEqualTo(5); - } -} diff --git a/src/test/java/nextstep/ladder/domain/LineTest.java b/src/test/java/nextstep/ladder/domain/LineTest.java index b77ed95fde..66f09e3203 100644 --- a/src/test/java/nextstep/ladder/domain/LineTest.java +++ b/src/test/java/nextstep/ladder/domain/LineTest.java @@ -3,8 +3,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -13,77 +11,27 @@ class LineTest { @DisplayName("포인트를 받아 라인을 생성한다") @Test void create() { - Point leftmostPoint = Point.createLeftmost(true); - List points = List.of( - leftmostPoint, - leftmostPoint.createRightmost() - ); - Line line = new Line(points); + Line line = new Line.LineBuilder() + .point(true) + .build(); assertThat(line.width()).isEqualTo(2); } - @DisplayName("포인트가 null이면 예외가 발생한다") - @Test - void nullPoints() { - assertThatThrownBy(() -> new Line(null)) - .isInstanceOf(IllegalArgumentException.class); - } - @DisplayName("포인트가 비어있으면 예외가 발생한다") @Test void emptyPoints() { - assertThatThrownBy(() -> new Line(List.of())) - .isInstanceOf(IllegalArgumentException.class); - } - - @DisplayName("시작 포인트가 왼쪽으로 이동 가능하면 예외가 발생한다") - @Test - void firstPointCannotMoveLeft() { - List points = List.of( - new Point(0, true, false), - new Point(1, false, false) - ); - - assertThatThrownBy(() -> new Line(points)) - .isInstanceOf(IllegalArgumentException.class); - } - - @DisplayName("마지막 포인트가 오른쪽으로 이동 가능하면 예외가 발생한다") - @Test - void lastPointCannotMoveRight() { - List points = List.of( - new Point(0, false, false), - new Point(1, false, true) - ); - - assertThatThrownBy(() -> new Line(points)) - .isInstanceOf(IllegalArgumentException.class); - } - - @DisplayName("이동 가능한 포인트간에 서로 이동 가능하지 않으면 예외가 발생한다") - @Test - void hasMovableConnectionToNext() { - List points = List.of( - new Point(0, false, true), - new Point(1, false, false) - ); - - assertThatThrownBy(() -> new Line(points)) - .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> new Line.LineBuilder().build()) + .isInstanceOf(IllegalStateException.class); } @DisplayName("인덱스를 받아 포인트를 반환한다") @Test void getPoint() { - Point leftmostPoint = Point.createLeftmost(true); - List points = List.of( - leftmostPoint, - leftmostPoint.createRightmost() - ); - Line line = new Line(points); + Line line = new Line.LineBuilder() + .point(true) + .build(); - assertThat(line.getPoint(0)).isEqualTo(leftmostPoint); + assertThat(line.getPoint(0)).isEqualTo(Point.createLeftmost(true)); } - } From 4a9ad3083b3a1de1cdab9a496e720dce5f4a614a Mon Sep 17 00:00:00 2001 From: sang5c Date: Mon, 22 Apr 2024 01:48:32 +0900 Subject: [PATCH 36/36] =?UTF-8?q?refactor:=20Lines=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=EC=9D=84=20LinesGenerator=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nextstep/ladder/domain/LadderGame.java | 4 +- .../java/nextstep/ladder/domain/Lines.java | 24 +------ .../ladder/domain/LinesGenerator.java | 5 ++ .../ladder/domain/RandomLinesGenerator.java | 36 ++++++++++ .../nextstep/ladder/domain/LinesTest.java | 65 ++++++++++++++++--- 5 files changed, 99 insertions(+), 35 deletions(-) create mode 100644 src/main/java/nextstep/ladder/domain/LinesGenerator.java create mode 100644 src/main/java/nextstep/ladder/domain/RandomLinesGenerator.java diff --git a/src/main/java/nextstep/ladder/domain/LadderGame.java b/src/main/java/nextstep/ladder/domain/LadderGame.java index 1a1fb20459..ce80ea5d17 100644 --- a/src/main/java/nextstep/ladder/domain/LadderGame.java +++ b/src/main/java/nextstep/ladder/domain/LadderGame.java @@ -14,9 +14,9 @@ private LadderGame(final Players players, final Lines lines) { public static LadderGame start(List playerNames, int height) { Players players = Players.of(playerNames); - Lines lines = Lines.of(players.count(), height); + LinesGenerator linesGenerator = new RandomLinesGenerator(players.count(), height); - return new LadderGame(players, lines); + return new LadderGame(players, linesGenerator.generate()); } public Players getPlayers() { diff --git a/src/main/java/nextstep/ladder/domain/Lines.java b/src/main/java/nextstep/ladder/domain/Lines.java index 5632a15074..112732c8e2 100644 --- a/src/main/java/nextstep/ladder/domain/Lines.java +++ b/src/main/java/nextstep/ladder/domain/Lines.java @@ -1,18 +1,11 @@ package nextstep.ladder.domain; import java.util.List; -import java.util.Random; -import java.util.stream.IntStream; - -import static java.util.stream.Collectors.collectingAndThen; -import static java.util.stream.Collectors.toList; public class Lines { - private static final Random RANDOM = new Random(); - private final List lines; - private Lines(List lines) { + public Lines(List lines) { validate(lines); this.lines = lines; } @@ -23,21 +16,6 @@ private void validate(List lines) { } } - public static Lines of(int numberOfPlayers, int height) { - return IntStream.range(0, height) - .mapToObj(i -> getBuildWithRandomPoints(numberOfPlayers)) - .collect(collectingAndThen(toList(), Lines::new)); - } - - private static Line getBuildWithRandomPoints(int numberOfPlayers) { - Line.LineBuilder builder = new Line.LineBuilder(); - builder.point(RANDOM.nextBoolean()); - for (int i = 0; i < numberOfPlayers - 2; i++) { - builder.point(RANDOM.nextBoolean()); - } - return builder.build(); - } - public int getHeight() { return lines.size(); } diff --git a/src/main/java/nextstep/ladder/domain/LinesGenerator.java b/src/main/java/nextstep/ladder/domain/LinesGenerator.java new file mode 100644 index 0000000000..4a1a8a1b1d --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/LinesGenerator.java @@ -0,0 +1,5 @@ +package nextstep.ladder.domain; + +public interface LinesGenerator { + Lines generate(); +} diff --git a/src/main/java/nextstep/ladder/domain/RandomLinesGenerator.java b/src/main/java/nextstep/ladder/domain/RandomLinesGenerator.java new file mode 100644 index 0000000000..068e3f0244 --- /dev/null +++ b/src/main/java/nextstep/ladder/domain/RandomLinesGenerator.java @@ -0,0 +1,36 @@ +package nextstep.ladder.domain; + +import java.util.Random; +import java.util.stream.IntStream; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toList; + +public class RandomLinesGenerator implements LinesGenerator { + private static final Random RANDOM = new Random(); + private static final int SYSTEM_CREATE_FINAL_POINT_COUNT = 1; + + private final int numberOfPlayers; + private final int height; + + public RandomLinesGenerator(int numberOfPlayers, int height) { + this.numberOfPlayers = numberOfPlayers; + this.height = height; + } + + @Override + public Lines generate() { + return IntStream.range(0, height) + .mapToObj(i -> generateLineWithRandomPoints(numberOfPlayers)) + .collect(collectingAndThen(toList(), Lines::new)); + } + + private Line generateLineWithRandomPoints(int numberOfPlayers) { + Line.LineBuilder builder = new Line.LineBuilder(); + for (int i = 0; i < numberOfPlayers - SYSTEM_CREATE_FINAL_POINT_COUNT; i++) { + builder.point(RANDOM.nextBoolean()); + } + + return builder.build(); + } +} diff --git a/src/test/java/nextstep/ladder/domain/LinesTest.java b/src/test/java/nextstep/ladder/domain/LinesTest.java index affdad6038..335e9b6297 100644 --- a/src/test/java/nextstep/ladder/domain/LinesTest.java +++ b/src/test/java/nextstep/ladder/domain/LinesTest.java @@ -3,24 +3,69 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; class LinesTest { - @DisplayName("사다리 높이는 1 이상이어야 한다.") + @DisplayName("라인의 높이를 반환한다") @Test - void invalidHeight() { - assertThatThrownBy(() -> Lines.of(3, 0)).isInstanceOf(IllegalArgumentException.class); + void getHeight() { + Lines lines = new RandomLinesGenerator(5, 5).generate(); + assertThat(lines.getHeight()).isEqualTo(5); } - @DisplayName("참여자 수와 사다리 높이를 받아 사다리를 생성한다.") + @DisplayName("지정한 특정 높이의 라인을 반환한다") @Test - void create() { - int height = 5; - int numberOfPlayers = 3; - Lines lines = Lines.of(numberOfPlayers, height); + void getLine() { + Line firstLine = new Line.LineBuilder() + .point(false) + .point(true) + .point(false) + .build(); + + Line secondLine = new Line.LineBuilder() + .point(true) + .point(false) + .point(true) + .build(); + + Lines lines = new ManualLinesGenerator(4, 2, List.of(firstLine, secondLine)) + .generate(); + + assertThat(lines.getLine(0)).isEqualTo(firstLine); + } + + static class ManualLinesGenerator implements LinesGenerator { + private final int numberOfPlayers; + private final int height; + private final List lines; + + public ManualLinesGenerator(int numberOfPlayers, int height, List lines) { + validate(numberOfPlayers, height, lines); + + this.numberOfPlayers = numberOfPlayers; + this.height = height; + this.lines = lines; + } + + private static void validate(int numberOfPlayers, int height, List lines) { + if (lines.size() != height) { + throw new IllegalArgumentException("사다리 높이와 라인의 개수가 일치하지 않습니다."); + } + if (containsInvalidLineWidth(numberOfPlayers, lines)) { + throw new IllegalArgumentException("사다리의 너비와 라인의 너비가 일치하지 않습니다."); + } + } + + private static boolean containsInvalidLineWidth(int numberOfPlayers, List lines) { + return lines.stream().anyMatch(line -> line.width() != numberOfPlayers); + } - assertThat(lines.getHeight()).isEqualTo(height); + @Override + public Lines generate() { + return new Lines(lines); + } } }