From adb3d07a52bf4769049c9415e0b2f4b97a2763ed Mon Sep 17 00:00:00 2001 From: hamhyeongju Date: Tue, 17 Sep 2024 11:10:49 +0900 Subject: [PATCH 01/10] feat : add basic code and test --- src/main/java/Ladder.java | 20 ++++- src/main/java/Row.java | 52 ++++++++++++ src/test/java/LadderTest.java | 60 +++++++++++++- src/test/java/RowTest.java | 152 ++++++++++++++++++++++++++++++++++ 4 files changed, 280 insertions(+), 4 deletions(-) create mode 100644 src/main/java/Row.java create mode 100644 src/test/java/RowTest.java diff --git a/src/main/java/Ladder.java b/src/main/java/Ladder.java index 0d2b070..f3c57ee 100644 --- a/src/main/java/Ladder.java +++ b/src/main/java/Ladder.java @@ -1,8 +1,22 @@ public class Ladder { - private final int[][] rows; + private final Row[] rows; - public Ladder(int row, int numberOfPerson) { - rows = new int[row][numberOfPerson]; + public Ladder(int numberOfRow, int numberOfPerson) { + rows = new Row[numberOfRow]; + for (int i = 0; i < numberOfRow; i++) { + rows[i] = new Row(numberOfPerson); + } + } + + public void drawLine(int row, int col) { + rows[row].drawLine(col); + } + + public int run(int position) { + for (int i = 0; i < rows.length; i++) { + position = rows[i].nextPosition(position); + } + return position; } } diff --git a/src/main/java/Row.java b/src/main/java/Row.java new file mode 100644 index 0000000..f1cf299 --- /dev/null +++ b/src/main/java/Row.java @@ -0,0 +1,52 @@ +public class Row { + int[] row; + + public Row(int numberOfPerson) { + validateNumberOfPerson(numberOfPerson); + row = new int[numberOfPerson]; + } + + public void drawLine(int startPosition) { + validateDrawLinePosition(startPosition); + row[startPosition] = 1; + row[startPosition + 1] = -1; + } + + public int nextPosition(int position) { + validatePosition(position); + + if (isRight(position)) { + return position + 1; + } + if (isLeft(position)) { + return position - 1; + } + return position; + } + + private boolean isLeft(int position) { + return row[position] == -1; + } + + private boolean isRight(int position) { + return row[position] == 1; + } + + private void validateNumberOfPerson(int numberOfPerson) { + if (numberOfPerson < 1) { + throw new IllegalArgumentException("참여 인원은 1명 이상이어야 합니다."); + } + } + + private void validatePosition(int position) { + if (position >= row.length || position < 0) { + throw new IllegalArgumentException("유효하지 않은 위치입니다."); + } + } + + private void validateDrawLinePosition(int startPosition) { + if (startPosition >= row.length - 1 || startPosition < 0 || row[startPosition] == -1 || row[startPosition + 1] == 1) { + throw new IllegalArgumentException("사다리를 그릴 수 없는 위치입니다."); + } + } +} \ No newline at end of file diff --git a/src/test/java/LadderTest.java b/src/test/java/LadderTest.java index 741a915..0279a0e 100644 --- a/src/test/java/LadderTest.java +++ b/src/test/java/LadderTest.java @@ -1,5 +1,63 @@ -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; class LadderTest { + @Test + void 사다리_생성_확인() { + //given + int numberOfRow = 3; + int numberOfPerson = 5; + + //when + Ladder ladder = new Ladder(numberOfRow, numberOfPerson); + + //then + assertThat(ladder).isNotNull(); + } + + @Test + void 사다리_사람_예외_처리_확인() { + //when + int numberOfPerson = 3; + Ladder ladder = new Ladder(1, numberOfPerson); + + //given + int nthOfPerson = 4; + + //then + assertThatThrownBy(() -> ladder.run(nthOfPerson)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_결과_확인() { + //when + int numberOfPerson = 4; + int row = 3; + Ladder ladder = new Ladder(row, numberOfPerson); + + ladder.drawLine(0,0); + ladder.drawLine(1,1); + ladder.drawLine(2,0); + + //given + int nthOfPerson = 0; + + //then + assertThat(ladder.run(nthOfPerson)).isEqualTo(2); + + //given + nthOfPerson = 1; + + //then + assertThat(ladder.run(nthOfPerson)).isEqualTo(1); + + //given + nthOfPerson = 2; + + //then + assertThat(ladder.run(nthOfPerson)).isEqualTo(0); + } } \ No newline at end of file diff --git a/src/test/java/RowTest.java b/src/test/java/RowTest.java new file mode 100644 index 0000000..ffaa72e --- /dev/null +++ b/src/test/java/RowTest.java @@ -0,0 +1,152 @@ +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; + +class RowTest { + + @Test + void 한_칸_사다리_이동() { + //when + int numberOfPerson = 1; + Row row = new Row(numberOfPerson); + + //given + int position = 0; + + //then + assertThat(row.nextPosition(position)).isEqualTo(0); + } + + @Test + void 두_칸_사다리_선_이동() { + //when + int numberOfPerson = 2; + Row row = new Row(numberOfPerson); + row.drawLine(0); + + //given + int position = 0; + + //then + assertThat(row.nextPosition(position)).isEqualTo(1); + + //given + position = 1; + + //then + assertThat(row.nextPosition(position)).isEqualTo(0); + } + + @Test + void 세_칸_사다리_선_이동() { + //when + int numberOfPerson = 3; + Row row = new Row(numberOfPerson); + row.drawLine(0); + + //given + int position = 0; + + //then + assertThat(row.nextPosition(position)).isEqualTo(1); + + //given + position = 1; + + //then + assertThat(row.nextPosition(position)).isEqualTo(0); + + //given + position = 2; + + //then + assertThat(row.nextPosition(position)).isEqualTo(2); + } + + @Test + void 사다리_사람수_예외_처리() { + assertThatThrownBy(() -> new Row(0)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_최대_사람수_초과_예외() { + //when + int numberOfPerson = 3; + Row row = new Row(numberOfPerson); + + //given + int position = 3; + + //then + assertThatThrownBy(() -> row.nextPosition(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_최소_사람수_미만_예외() { + //when + int numberOfPerson = 3; + Row row = new Row(numberOfPerson); + + //given + int position = -1; + + //then + assertThatThrownBy(() -> row.nextPosition(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_그리기_위치_초과_예외() { + //when + int numberOfPerson = 3; + Row row = new Row(numberOfPerson); + + //given + int position = 3; + + //then + assertThatThrownBy(() -> row.drawLine(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_그리기_위치_미만_예외() { + //when + int numberOfPerson = 3; + Row row = new Row(numberOfPerson); + + //given + int position = -1; + + //then + assertThatThrownBy(() -> row.drawLine(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_그리기_좌측_선_중복_예외() { + //when + int numberOfPerson = 3; + Row row = new Row(numberOfPerson); + row.drawLine(0); + + //then + assertThatThrownBy(() -> row.drawLine(1)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_그리기_우측_선_중복_예외() { + //when + int numberOfPerson = 3; + Row row = new Row(numberOfPerson); + row.drawLine(1); + + //then + assertThatThrownBy(() -> row.drawLine(0)) + .isInstanceOf(IllegalArgumentException.class); + + } +} \ No newline at end of file From 7c319083801ad786726bd531895a577c61198dfc Mon Sep 17 00:00:00 2001 From: hamhyeongju Date: Thu, 19 Sep 2024 17:01:21 +0900 Subject: [PATCH 02/10] move : move domain to ladder package --- src/main/java/{ => ladder}/Ladder.java | 2 ++ src/main/java/{ => ladder}/Row.java | 2 ++ src/test/java/{ => ladder}/LadderTest.java | 2 ++ src/test/java/{ => ladder}/RowTest.java | 2 ++ 4 files changed, 8 insertions(+) rename src/main/java/{ => ladder}/Ladder.java (96%) rename src/main/java/{ => ladder}/Row.java (98%) rename src/test/java/{ => ladder}/LadderTest.java (98%) rename src/test/java/{ => ladder}/RowTest.java (99%) diff --git a/src/main/java/Ladder.java b/src/main/java/ladder/Ladder.java similarity index 96% rename from src/main/java/Ladder.java rename to src/main/java/ladder/Ladder.java index f3c57ee..de2b84e 100644 --- a/src/main/java/Ladder.java +++ b/src/main/java/ladder/Ladder.java @@ -1,3 +1,5 @@ +package ladder; + public class Ladder { private final Row[] rows; diff --git a/src/main/java/Row.java b/src/main/java/ladder/Row.java similarity index 98% rename from src/main/java/Row.java rename to src/main/java/ladder/Row.java index f1cf299..00ada79 100644 --- a/src/main/java/Row.java +++ b/src/main/java/ladder/Row.java @@ -1,3 +1,5 @@ +package ladder; + public class Row { int[] row; diff --git a/src/test/java/LadderTest.java b/src/test/java/ladder/LadderTest.java similarity index 98% rename from src/test/java/LadderTest.java rename to src/test/java/ladder/LadderTest.java index 0279a0e..0328fdd 100644 --- a/src/test/java/LadderTest.java +++ b/src/test/java/ladder/LadderTest.java @@ -1,3 +1,5 @@ +package ladder; + import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; diff --git a/src/test/java/RowTest.java b/src/test/java/ladder/RowTest.java similarity index 99% rename from src/test/java/RowTest.java rename to src/test/java/ladder/RowTest.java index ffaa72e..c72ad5e 100644 --- a/src/test/java/RowTest.java +++ b/src/test/java/ladder/RowTest.java @@ -1,3 +1,5 @@ +package ladder; + import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; From 1b840fa788394db9d5344041187191df057d6b33 Mon Sep 17 00:00:00 2001 From: hamhyeongju Date: Fri, 20 Sep 2024 15:26:00 +0900 Subject: [PATCH 03/10] refactor : change access modifier of row to private and add final keyword in Row class --- src/main/java/ladder/Row.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 00ada79..09203ad 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -1,7 +1,7 @@ package ladder; public class Row { - int[] row; + private final int[] row; public Row(int numberOfPerson) { validateNumberOfPerson(numberOfPerson); From 7d264c71a187cf82ebb461f60ad2e5a20253c9b8 Mon Sep 17 00:00:00 2001 From: SangHyun Jung Date: Sun, 22 Sep 2024 23:25:51 +0900 Subject: [PATCH 04/10] 9.22 11:25PM --- .idea/material_theme_project_new.xml | 12 +++ .idea/misc.xml | 2 +- src/main/java/ladder/Direction.java | 16 ++++ src/main/java/ladder/ExceptionMessage.java | 19 ++++ src/main/java/ladder/GreaterThanOne.java | 26 ++++++ src/main/java/ladder/Ladder.java | 24 ----- src/main/java/ladder/LadderGame.java | 25 +++++ src/main/java/ladder/LadderRunner.java | 19 ++++ src/main/java/ladder/Node.java | 55 +++++++++++ src/main/java/ladder/Position.java | 51 ++++++++++ src/main/java/ladder/Row.java | 93 ++++++++++++------- .../java/ladder/creator/LadderCreator.java | 30 ++++++ src/test/java/ladder/LadderGameTest.java | 69 ++++++++++++++ src/test/java/ladder/LadderTest.java | 65 ------------- src/test/java/ladder/NodesTest.java | 42 +++++++++ src/test/java/ladder/RowTest.java | 78 +++++++++------- week02.md | 0 17 files changed, 468 insertions(+), 158 deletions(-) create mode 100644 .idea/material_theme_project_new.xml create mode 100644 src/main/java/ladder/Direction.java create mode 100644 src/main/java/ladder/ExceptionMessage.java create mode 100644 src/main/java/ladder/GreaterThanOne.java delete mode 100644 src/main/java/ladder/Ladder.java create mode 100644 src/main/java/ladder/LadderGame.java create mode 100644 src/main/java/ladder/LadderRunner.java create mode 100644 src/main/java/ladder/Node.java create mode 100644 src/main/java/ladder/Position.java create mode 100644 src/main/java/ladder/creator/LadderCreator.java create mode 100644 src/test/java/ladder/LadderGameTest.java delete mode 100644 src/test/java/ladder/LadderTest.java create mode 100644 src/test/java/ladder/NodesTest.java create mode 100644 week02.md diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..73c9d30 --- /dev/null +++ b/.idea/material_theme_project_new.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 8f86b33..807cb65 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/src/main/java/ladder/Direction.java b/src/main/java/ladder/Direction.java new file mode 100644 index 0000000..da92119 --- /dev/null +++ b/src/main/java/ladder/Direction.java @@ -0,0 +1,16 @@ +package ladder; + +public enum Direction { + + LEFT(-1), RIGHT(1), NONE(0); + + private final int value; + + Direction(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/ladder/ExceptionMessage.java b/src/main/java/ladder/ExceptionMessage.java new file mode 100644 index 0000000..10fea54 --- /dev/null +++ b/src/main/java/ladder/ExceptionMessage.java @@ -0,0 +1,19 @@ +package ladder; + +public enum ExceptionMessage { + + INVALID_LADDER_POSITION("사다리 위치는 1이상 자연수입니다."), + INVALID_LADDER_NUMBER("사다리의 행과 열은 2 이상이여야 합니다."), + INVALID_POSITION("유효하지 않은 위치입니다."), + INVALID_DRAW_POSITION("사다리를 그릴 수 없는 위치입니다."); + + private final String message; + + ExceptionMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/ladder/GreaterThanOne.java b/src/main/java/ladder/GreaterThanOne.java new file mode 100644 index 0000000..c5f4f1b --- /dev/null +++ b/src/main/java/ladder/GreaterThanOne.java @@ -0,0 +1,26 @@ +package ladder; + +public class GreaterThanOne { + + private final int number; + + public GreaterThanOne(int number) { + this.number = number; + } + + public static GreaterThanOne from(int number) { + if (! isGreaterThanOne(number)) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_LADDER_NUMBER.getMessage()); + } + return new GreaterThanOne(number); + } + + // opt + cmd + m : 드래그 한 부분 새로운 method 생성 + private static boolean isGreaterThanOne(int number) { + return number > 1; + } + + public int getNumber() { + return number; + } +} diff --git a/src/main/java/ladder/Ladder.java b/src/main/java/ladder/Ladder.java deleted file mode 100644 index de2b84e..0000000 --- a/src/main/java/ladder/Ladder.java +++ /dev/null @@ -1,24 +0,0 @@ -package ladder; - -public class Ladder { - - private final Row[] rows; - - public Ladder(int numberOfRow, int numberOfPerson) { - rows = new Row[numberOfRow]; - for (int i = 0; i < numberOfRow; i++) { - rows[i] = new Row(numberOfPerson); - } - } - - public void drawLine(int row, int col) { - rows[row].drawLine(col); - } - - public int run(int position) { - for (int i = 0; i < rows.length; i++) { - position = rows[i].nextPosition(position); - } - return position; - } -} diff --git a/src/main/java/ladder/LadderGame.java b/src/main/java/ladder/LadderGame.java new file mode 100644 index 0000000..92a425f --- /dev/null +++ b/src/main/java/ladder/LadderGame.java @@ -0,0 +1,25 @@ +package ladder; + +import ladder.creator.LadderCreator; + +// todo Ladder 클래스가 많은 책임 (사다리 생성 / 사다리 그리기 / 사다리 게임 진행) +// 마지막으로 Ladder는 전체를 관장하는 클래스가 되었으므로 +// LadderGame으로 변경 +public class LadderGame { + + private final LadderCreator ladderCreator; + + public LadderGame(LadderCreator ladderCreator) { + this.ladderCreator = ladderCreator; + } + + // todo 포지션 wrapper 클래스 필요 + // todo LadderRunner로 분리 (Ladder 클래스 책임분산) + // LadderRunner를 통해 돌리자 + public int run(Position position) { + LadderRunner ladderRunner = new LadderRunner(ladderCreator.getRows()); + ladderRunner.run(position); + + return position.getPosition(); + } +} diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java new file mode 100644 index 0000000..ab5de6a --- /dev/null +++ b/src/main/java/ladder/LadderRunner.java @@ -0,0 +1,19 @@ +package ladder; + +public class LadderRunner { + + private final Row[] rows; // 사다리의 한 행을 빼놓았다. + + public LadderRunner(Row[] rows) { + this.rows = rows; + } + + // todo 포지션 wrapper 클래스 필요 + // todo LadderRunner로 분리 (Ladder 클래스 책임분산) + public int run(Position position) { + for (int i = 0; i < rows.length; i++) { + rows[i].nextPosition(position); // position에 대입 삭제 (1) + } + return position.getPosition(); + } +} diff --git a/src/main/java/ladder/Node.java b/src/main/java/ladder/Node.java new file mode 100644 index 0000000..c8dc162 --- /dev/null +++ b/src/main/java/ladder/Node.java @@ -0,0 +1,55 @@ +package ladder; +import static ladder.Direction.*; + +public class Node { + private Direction direction; + + private Node(Direction direction) { + this.direction = direction; + } + + public static Node from(Direction direction) { + return new Node(direction); + } + + public void setRightNode(Position position) { + direction = RIGHT; + } + + public void setLeftNode(Position position) { + direction = LEFT; + } + + // 밖에서 안쓰므로 private으로 만들기 + private boolean isRight() { + return direction == RIGHT; + } + + private boolean isLeft() { + return direction == LEFT; + } + + public boolean isAlreadySetDirection() { + return isNone(); + } + + private boolean isNone() { + return direction == NONE; + } + + // 노드값을 보고 하는 것이므로 node의 책임 (from Row클래스) + public void move(Position position) { + if (isRight()) { + position.next(); // 이 곳에 return 삭제함 (1) + return; + } + if (isLeft()) { + position.prev(); + return; + } + } + + + + +} diff --git a/src/main/java/ladder/Position.java b/src/main/java/ladder/Position.java new file mode 100644 index 0000000..c5c75ba --- /dev/null +++ b/src/main/java/ladder/Position.java @@ -0,0 +1,51 @@ +package ladder; +// 사다리의 값 : 0, 1, -1 +public class Position { + + private int position; + + private Position(int position) { + this.position = position; + } + + public int getPosition() { + return position; + } + + public static Position from(int position) { + validatePosition(position); // 1-1. 검증로직 + return new Position(position); + } + + private static void validatePosition(int position) { + if (!isPosition(position)) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_LADDER_POSITION.getMessage()); + } + + } + + private static boolean isPosition(int position) { + return position >= 0; + } + + public boolean isBiggerThan(int position) { + return this.position > position; + } + + public boolean isSmallerThan(int position) { + return this.position < position; + } + + public void next() { + // return Position.from(position + 1); (1) + position++; + } + // 3번째 강의 11:04 + // 1. Position을 생성해서 넘겨주고 있음 (next, prev) + // 1-3. Position을 생성해서 로직을 돌리는 것 보다, 본인 스스로 관리하도록 + + public void prev() { + // return Position.from(position - 1); + position--; + } +} diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 09203ad..5e327ed 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -1,54 +1,81 @@ package ladder; +// 문제점 +// drawLine, nextPosition 등의 하드코딩 (+1 or -1) -public class Row { - private final int[] row; +import static ladder.Direction.*; - public Row(int numberOfPerson) { - validateNumberOfPerson(numberOfPerson); - row = new int[numberOfPerson]; - } +public class Row { + // todo Node 클래스로 분리(row 배열에서 값을 하나씩 꺼내서 볼 필요가 없다..?) + Node[] nodes; - public void drawLine(int startPosition) { - validateDrawLinePosition(startPosition); - row[startPosition] = 1; - row[startPosition + 1] = -1; + public Row(GreaterThanOne numberOfPerson) { + nodes = new Node[numberOfPerson.getNumber()]; + for (int i = 0; i < numberOfPerson.getNumber(); i++) { + nodes[i] = Node.from(NONE); + } } - public int nextPosition(int position) { - validatePosition(position); + // todo : 상수 리팩토링 (1,-1, 0) + public void drawLine(Position startPosition) { + validateDrawLinePosition(startPosition); // 유효성 처리 - if (isRight(position)) { - return position + 1; - } - if (isLeft(position)) { - return position - 1; - } - return position; + setDirectionBetweenNextPosition(startPosition); } - private boolean isLeft(int position) { - return row[position] == -1; + private void setDirectionBetweenNextPosition(Position position) { + nodes[position.getPosition()].setRightNode(position); + position.next(); + nodes[position.getPosition()].setLeftNode(position); } - private boolean isRight(int position) { - return row[position] == 1; + // run 메소드의 다음 상태 + public void nextPosition(Position position) { + validatePosition(position); // 1-2. next, prev 이전에 다시 position 검증 + // nextPosition method return type : Position -> void (1) + + nodes[position.getPosition()].move(position); } +// Node의 Move 메소드로 이동 +// private boolean isLeft(Position position) { +// +// return nodes[position.getPosition()] == LEFT.getValue(); +// } +// +// private boolean isRight(Position position) { +// +// return nodes[position.getPosition()] == RIGHT.getValue(); +// } - private void validateNumberOfPerson(int numberOfPerson) { - if (numberOfPerson < 1) { - throw new IllegalArgumentException("참여 인원은 1명 이상이어야 합니다."); + // Todo 상수 하드코딩도 enum으로 클래스단위로 관리하자 // + + private void validatePosition(Position position) { + if (position.isBiggerThan(nodes.length - 1)) { // 위치값과 실제 인덱스값 동일시 + throw new IllegalArgumentException(ExceptionMessage.INVALID_POSITION.getMessage()); } } - private void validatePosition(int position) { - if (position >= row.length || position < 0) { - throw new IllegalArgumentException("유효하지 않은 위치입니다."); + private void validateDrawLinePosition(Position startPosition) { + if (isInvalidPosition(startPosition) || isLineAtPosition(startPosition) || isLineAtNextPosition(startPosition)) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_DRAW_POSITION.getMessage()); } } - private void validateDrawLinePosition(int startPosition) { - if (startPosition >= row.length - 1 || startPosition < 0 || row[startPosition] == -1 || row[startPosition + 1] == 1) { - throw new IllegalArgumentException("사다리를 그릴 수 없는 위치입니다."); - } + // 숫자가 사다리 크기보다 커서 실패하는 경우 + private boolean isInvalidPosition(Position startPosition) { + return startPosition.isBiggerThan(nodes.length - 1); // startPosition.getPosition() < 0 -> position 만들때 이미 검증했던 logic + } + + // 이미 그려진 경우 + private boolean isLineAtPosition(Position startPosition) { + return ! nodes[startPosition.getPosition()].isAlreadySetDirection(); // none이 아니면 + // return nodes[startPosition.getPosition()] == RIGHT.getValue() || row[startPosition.getPosition()] == LEFT.getValue(); + } + + // 옆에 이미 그려진 경우 + private boolean isLineAtNextPosition(Position startPosition) { + startPosition.next(); + boolean IsLineAtPosition = !nodes[startPosition.getPosition()].isAlreadySetDirection(); + startPosition.prev(); + return IsLineAtPosition; } } \ No newline at end of file diff --git a/src/main/java/ladder/creator/LadderCreator.java b/src/main/java/ladder/creator/LadderCreator.java new file mode 100644 index 0000000..c6e2cef --- /dev/null +++ b/src/main/java/ladder/creator/LadderCreator.java @@ -0,0 +1,30 @@ +package ladder.creator; + +import ladder.GreaterThanOne; +import ladder.Position; +import ladder.Row; + +public class LadderCreator { + + private final Row[] rows; // 사다리의 한 행을 빼놓았다. + + // todo 생성자 wrapper 클래스 필요 ㅇㅋ (-> GreaterThanOne) + // Greaterthanone 클래스 필요 : 사다리 게임을 1명이서 하지는 않으니 + public LadderCreator(GreaterThanOne numberOfRow, GreaterThanOne numberOfPerson) { + rows = new Row[numberOfRow.getNumber()]; + for (int i = 0; i < numberOfRow.getNumber(); i++) { + rows[i] = new Row(numberOfPerson); + } + } + + // 사다리의 가로 줄 긋기 + // todo LadderCreator로 분리 (Ladder 클래스 책임분산) + // todo 파라미터 Position wrapper 클래스 (0부터 입력가능한) + public void drawLine(Position row, Position col) { + rows[row.getPosition()].drawLine(col); + } + + public Row[] getRows() { + return rows; + } +} diff --git a/src/test/java/ladder/LadderGameTest.java b/src/test/java/ladder/LadderGameTest.java new file mode 100644 index 0000000..2ca5de8 --- /dev/null +++ b/src/test/java/ladder/LadderGameTest.java @@ -0,0 +1,69 @@ +package ladder; + +import ladder.creator.LadderCreator; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; +// Ladder 클래스와 Row 클래스의 테스트를 분리하는게 좋다. +class LadderGameTest { + + @Test + void 사다리_생성_확인() { + //given + GreaterThanOne numberOfRow = GreaterThanOne.from(3); + GreaterThanOne numberOfPerson = GreaterThanOne.from(5); + + //when + LadderCreator ladderCreator = new LadderCreator(numberOfRow, numberOfPerson); + + //then + assertThat(ladderCreator).isNotNull(); + } + + @Test + void 사다리_사람_예외_처리_확인() { + //when + GreaterThanOne row = GreaterThanOne.from(2); + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); + LadderCreator ladderCreator = new LadderCreator(row, numberOfPerson); + LadderRunner ladderRunner = new LadderRunner(ladderCreator.getRows()); + + //given + Position nthOfPerson = Position.from(4); + + //then + assertThatThrownBy(() -> ladderRunner.run(nthOfPerson)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 사다리_결과_확인() { + //when + GreaterThanOne numberOfPerson = GreaterThanOne.from(4); + GreaterThanOne row = GreaterThanOne.from(3); + LadderCreator ladderCreator = new LadderCreator(row, numberOfPerson); + LadderRunner ladderRunner = new LadderRunner(ladderCreator.getRows()); + + ladderCreator.drawLine(Position.from(0),Position.from(0)); + ladderCreator.drawLine(Position.from(1),Position.from(1)); + ladderCreator.drawLine(Position.from(2),Position.from(0)); + + //given + Position nthOfPerson = Position.from(0); + + //then + assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(2); + + //given + nthOfPerson = Position.from(1); + + //then + assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(1); + + //given + nthOfPerson = Position.from(2); + + //then + assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(0); + } +} \ No newline at end of file diff --git a/src/test/java/ladder/LadderTest.java b/src/test/java/ladder/LadderTest.java deleted file mode 100644 index 0328fdd..0000000 --- a/src/test/java/ladder/LadderTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package ladder; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.*; - -class LadderTest { - - @Test - void 사다리_생성_확인() { - //given - int numberOfRow = 3; - int numberOfPerson = 5; - - //when - Ladder ladder = new Ladder(numberOfRow, numberOfPerson); - - //then - assertThat(ladder).isNotNull(); - } - - @Test - void 사다리_사람_예외_처리_확인() { - //when - int numberOfPerson = 3; - Ladder ladder = new Ladder(1, numberOfPerson); - - //given - int nthOfPerson = 4; - - //then - assertThatThrownBy(() -> ladder.run(nthOfPerson)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - void 사다리_결과_확인() { - //when - int numberOfPerson = 4; - int row = 3; - Ladder ladder = new Ladder(row, numberOfPerson); - - ladder.drawLine(0,0); - ladder.drawLine(1,1); - ladder.drawLine(2,0); - - //given - int nthOfPerson = 0; - - //then - assertThat(ladder.run(nthOfPerson)).isEqualTo(2); - - //given - nthOfPerson = 1; - - //then - assertThat(ladder.run(nthOfPerson)).isEqualTo(1); - - //given - nthOfPerson = 2; - - //then - assertThat(ladder.run(nthOfPerson)).isEqualTo(0); - } -} \ No newline at end of file diff --git a/src/test/java/ladder/NodesTest.java b/src/test/java/ladder/NodesTest.java new file mode 100644 index 0000000..98a5e86 --- /dev/null +++ b/src/test/java/ladder/NodesTest.java @@ -0,0 +1,42 @@ +package ladder; + +import static org.assertj.core.api.Assertions.*; +import org.junit.jupiter.api.Test; + +import static ladder.Direction.*; + +public class NodesTest { + + @Test + void 오른쪽_방향_위치_이동_확인() { + Node node = Node.from(RIGHT); + + Position position = Position.from(0); + + node.move(position); + + assertThat(position.getPosition()).isEqualTo(1); + } + + @Test + void NONE_방향_위치_이동_확인() { + Node node = Node.from(NONE); + + Position position = Position.from(0); + + node.move(position); + + assertThat(position.getPosition()).isEqualTo(0); + } + + @Test + void 왼쪽_방향_위치_이동_확인() { + Node node = Node.from(LEFT); + + Position position = Position.from(1); + + node.move(position); + + assertThat(position.getPosition()).isEqualTo(0); + } +} diff --git a/src/test/java/ladder/RowTest.java b/src/test/java/ladder/RowTest.java index c72ad5e..dc85841 100644 --- a/src/test/java/ladder/RowTest.java +++ b/src/test/java/ladder/RowTest.java @@ -6,107 +6,115 @@ class RowTest { + // 유효성 처리 및 핵심 로직을 분리해두었다. + @Test void 한_칸_사다리_이동() { //when - int numberOfPerson = 1; + GreaterThanOne numberOfPerson = GreaterThanOne.from(2); Row row = new Row(numberOfPerson); //given - int position = 0; + Position position = Position.from(0); + row.nextPosition(position); //then - assertThat(row.nextPosition(position)).isEqualTo(0); + assertThat(position.getPosition()).isEqualTo(0); } @Test void 두_칸_사다리_선_이동() { //when - int numberOfPerson = 2; + GreaterThanOne numberOfPerson = GreaterThanOne.from(2); Row row = new Row(numberOfPerson); - row.drawLine(0); + row.drawLine(Position.from(0)); //given - int position = 0; + Position position = Position.from(0); + row.nextPosition(position); //then - assertThat(row.nextPosition(position)).isEqualTo(1); + assertThat(position.getPosition()).isEqualTo(1); //given - position = 1; + position = Position.from(1); + row.nextPosition(position); //then - assertThat(row.nextPosition(position)).isEqualTo(0); + assertThat(position.getPosition()).isEqualTo(0); } @Test void 세_칸_사다리_선_이동() { //when - int numberOfPerson = 3; + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); Row row = new Row(numberOfPerson); - row.drawLine(0); + row.drawLine(Position.from(0)); //given - int position = 0; + Position position = Position.from(0); + row.nextPosition(position); //then - assertThat(row.nextPosition(position)).isEqualTo(1); + assertThat(position.getPosition()).isEqualTo(1); //given - position = 1; + position = Position.from(1); + row.nextPosition(position); //then - assertThat(row.nextPosition(position)).isEqualTo(0); + assertThat(position.getPosition()).isEqualTo(0); //given - position = 2; + position = Position.from(2); + row.nextPosition(position); //then - assertThat(row.nextPosition(position)).isEqualTo(2); + assertThat(position.getPosition()).isEqualTo(2); } @Test void 사다리_사람수_예외_처리() { - assertThatThrownBy(() -> new Row(0)) + assertThatThrownBy(() -> new Row(GreaterThanOne.from(0))) .isInstanceOf(IllegalArgumentException.class); } @Test void 사다리_최대_사람수_초과_예외() { //when - int numberOfPerson = 3; + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); Row row = new Row(numberOfPerson); //given - int position = 3; + Position position = Position.from(3); //then - assertThatThrownBy(() -> row.nextPosition(position)) + assertThatThrownBy(() -> row.nextPosition(Position.from(3))) .isInstanceOf(IllegalArgumentException.class); } @Test void 사다리_최소_사람수_미만_예외() { //when - int numberOfPerson = 3; + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); Row row = new Row(numberOfPerson); //given - int position = -1; + Position position = Position.from(-1); //then - assertThatThrownBy(() -> row.nextPosition(position)) + assertThatThrownBy(() -> row.nextPosition(Position.from(-1))) .isInstanceOf(IllegalArgumentException.class); } @Test void 사다리_그리기_위치_초과_예외() { //when - int numberOfPerson = 3; + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); Row row = new Row(numberOfPerson); //given - int position = 3; + Position position = Position.from(3); //then assertThatThrownBy(() -> row.drawLine(position)) @@ -116,38 +124,38 @@ class RowTest { @Test void 사다리_그리기_위치_미만_예외() { //when - int numberOfPerson = 3; + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); Row row = new Row(numberOfPerson); //given - int position = -1; + Position position = Position.from(-1); //then - assertThatThrownBy(() -> row.drawLine(position)) + assertThatThrownBy(() -> row.drawLine(Position.from(-1))) .isInstanceOf(IllegalArgumentException.class); } @Test void 사다리_그리기_좌측_선_중복_예외() { //when - int numberOfPerson = 3; + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); Row row = new Row(numberOfPerson); - row.drawLine(0); + row.drawLine(Position.from(0)); //then - assertThatThrownBy(() -> row.drawLine(1)) + assertThatThrownBy(() -> row.drawLine(Position.from(1))) .isInstanceOf(IllegalArgumentException.class); } @Test void 사다리_그리기_우측_선_중복_예외() { //when - int numberOfPerson = 3; + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); Row row = new Row(numberOfPerson); - row.drawLine(1); + row.drawLine(Position.from(1)); //then - assertThatThrownBy(() -> row.drawLine(0)) + assertThatThrownBy(() -> row.drawLine(Position.from(0))) .isInstanceOf(IllegalArgumentException.class); } diff --git a/week02.md b/week02.md new file mode 100644 index 0000000..e69de29 From 485c8043c8e0204d2ee59d731532b87b1909f71f Mon Sep 17 00:00:00 2001 From: SangHyun Jung Date: Tue, 24 Sep 2024 00:29:49 +0900 Subject: [PATCH 05/10] =?UTF-8?q?9.24=2000:29AM=20(=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20drawLine)=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/GreaterThanOne.java | 5 +++-- src/main/java/ladder/Node.java | 4 +++- src/main/java/ladder/Position.java | 3 ++- src/main/java/ladder/Row.java | 22 ++++++------------- .../java/ladder/creator/LadderCreator.java | 7 +++--- src/test/java/ladder/RowTest.java | 4 ++-- 6 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/main/java/ladder/GreaterThanOne.java b/src/main/java/ladder/GreaterThanOne.java index c5f4f1b..80e0572 100644 --- a/src/main/java/ladder/GreaterThanOne.java +++ b/src/main/java/ladder/GreaterThanOne.java @@ -1,15 +1,16 @@ package ladder; +// 1보다 큰지 검증하는 클래스 public class GreaterThanOne { private final int number; - public GreaterThanOne(int number) { + private GreaterThanOne(int number) { this.number = number; } public static GreaterThanOne from(int number) { - if (! isGreaterThanOne(number)) { + if (! isGreaterThanOne(number)) { // 팩토리 메소드로 검증 (1보다 큰지) throw new IllegalArgumentException(ExceptionMessage.INVALID_LADDER_NUMBER.getMessage()); } return new GreaterThanOne(number); diff --git a/src/main/java/ladder/Node.java b/src/main/java/ladder/Node.java index c8dc162..b3fcbf5 100644 --- a/src/main/java/ladder/Node.java +++ b/src/main/java/ladder/Node.java @@ -1,8 +1,10 @@ package ladder; import static ladder.Direction.*; +// 사다리의 세로줄 (열), numberOFPerson +// 사다리의 실제 값 (방향)을 담는 클래스 public class Node { - private Direction direction; + private Direction direction; // 사다리의 실제 값 private Node(Direction direction) { this.direction = direction; diff --git a/src/main/java/ladder/Position.java b/src/main/java/ladder/Position.java index c5c75ba..162bd5e 100644 --- a/src/main/java/ladder/Position.java +++ b/src/main/java/ladder/Position.java @@ -1,5 +1,6 @@ package ladder; -// 사다리의 값 : 0, 1, -1 + +// 사다리의 인덱스 값 관리 클래스 public class Position { private int position; diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 5e327ed..500dd92 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -4,12 +4,13 @@ import static ladder.Direction.*; +// 사다리의 하나의 가로줄 (행) public class Row { // todo Node 클래스로 분리(row 배열에서 값을 하나씩 꺼내서 볼 필요가 없다..?) Node[] nodes; public Row(GreaterThanOne numberOfPerson) { - nodes = new Node[numberOfPerson.getNumber()]; + nodes = new Node[numberOfPerson.getNumber()]; // 노드 배열개수할당 for (int i = 0; i < numberOfPerson.getNumber(); i++) { nodes[i] = Node.from(NONE); } @@ -17,15 +18,15 @@ public Row(GreaterThanOne numberOfPerson) { // todo : 상수 리팩토링 (1,-1, 0) public void drawLine(Position startPosition) { - validateDrawLinePosition(startPosition); // 유효성 처리 + validateDrawLinePosition(startPosition); // 선 그리기 유효성 검사 통합 setDirectionBetweenNextPosition(startPosition); } private void setDirectionBetweenNextPosition(Position position) { - nodes[position.getPosition()].setRightNode(position); + nodes[position.getPosition()].setRightNode(position); // 현재 노드에 1대입 (오른쪽 이동) position.next(); - nodes[position.getPosition()].setLeftNode(position); + nodes[position.getPosition()].setLeftNode(position); // 그 다음 노드에 -1대입 (왼쪽 이동) } // run 메소드의 다음 상태 @@ -35,18 +36,8 @@ public void nextPosition(Position position) { nodes[position.getPosition()].move(position); } -// Node의 Move 메소드로 이동 -// private boolean isLeft(Position position) { -// -// return nodes[position.getPosition()] == LEFT.getValue(); -// } -// -// private boolean isRight(Position position) { -// -// return nodes[position.getPosition()] == RIGHT.getValue(); -// } - // Todo 상수 하드코딩도 enum으로 클래스단위로 관리하자 // + // Todo 상수 하드코딩도 enum으로 클래스단위로 관리하자 private void validatePosition(Position position) { if (position.isBiggerThan(nodes.length - 1)) { // 위치값과 실제 인덱스값 동일시 @@ -54,6 +45,7 @@ private void validatePosition(Position position) { } } + // 선그리기 유효성 검사 통합 private void validateDrawLinePosition(Position startPosition) { if (isInvalidPosition(startPosition) || isLineAtPosition(startPosition) || isLineAtNextPosition(startPosition)) { throw new IllegalArgumentException(ExceptionMessage.INVALID_DRAW_POSITION.getMessage()); diff --git a/src/main/java/ladder/creator/LadderCreator.java b/src/main/java/ladder/creator/LadderCreator.java index c6e2cef..5fa1901 100644 --- a/src/main/java/ladder/creator/LadderCreator.java +++ b/src/main/java/ladder/creator/LadderCreator.java @@ -9,17 +9,18 @@ public class LadderCreator { private final Row[] rows; // 사다리의 한 행을 빼놓았다. // todo 생성자 wrapper 클래스 필요 ㅇㅋ (-> GreaterThanOne) - // Greaterthanone 클래스 필요 : 사다리 게임을 1명이서 하지는 않으니 + // Greaterthanone 클래스 필요 : 사다리 게임을 1명이서 하지는 않으니 (사다리 높이 및 인원수는 최소 1이상) public LadderCreator(GreaterThanOne numberOfRow, GreaterThanOne numberOfPerson) { - rows = new Row[numberOfRow.getNumber()]; + rows = new Row[numberOfRow.getNumber()]; // 가로줄 몇개 만들건지 for (int i = 0; i < numberOfRow.getNumber(); i++) { - rows[i] = new Row(numberOfPerson); + rows[i] = new Row(numberOfPerson); // 하나의 가로줄에 실제 세로줄 개수 할당 } } // 사다리의 가로 줄 긋기 // todo LadderCreator로 분리 (Ladder 클래스 책임분산) // todo 파라미터 Position wrapper 클래스 (0부터 입력가능한) + // Position으로 인덱스 접근하여 rows에 실제 사다리 방향(선)을 그린다 public void drawLine(Position row, Position col) { rows[row.getPosition()].drawLine(col); } diff --git a/src/test/java/ladder/RowTest.java b/src/test/java/ladder/RowTest.java index dc85841..b0745f6 100644 --- a/src/test/java/ladder/RowTest.java +++ b/src/test/java/ladder/RowTest.java @@ -100,7 +100,7 @@ class RowTest { Row row = new Row(numberOfPerson); //given - Position position = Position.from(-1); + //Position position = Position.from(-1); //then assertThatThrownBy(() -> row.nextPosition(Position.from(-1))) @@ -128,7 +128,7 @@ class RowTest { Row row = new Row(numberOfPerson); //given - Position position = Position.from(-1); + //Position position = Position.from(-1); //then assertThatThrownBy(() -> row.drawLine(Position.from(-1))) From d4121ab8bf757e0c29de2d5baa6e531c55fa5d70 Mon Sep 17 00:00:00 2001 From: SangHyun Jung Date: Wed, 25 Sep 2024 18:10:47 +0900 Subject: [PATCH 06/10] =?UTF-8?q?9.24=2000:29AM=20(=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20drawLine)=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/Direction.java | 4 +++ src/main/java/ladder/LadderGame.java | 6 ++-- src/main/java/ladder/LadderPosition.java | 22 ++++++++++++++ src/main/java/ladder/LadderRunner.java | 37 +++++++++++++++++++++++- src/main/java/ladder/Node.java | 7 +++-- src/main/java/ladder/Position.java | 2 +- src/main/java/ladder/Row.java | 23 +++++++++++++-- src/test/java/ladder/LadderGameTest.java | 2 ++ 8 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 src/main/java/ladder/LadderPosition.java diff --git a/src/main/java/ladder/Direction.java b/src/main/java/ladder/Direction.java index da92119..1d1d1f2 100644 --- a/src/main/java/ladder/Direction.java +++ b/src/main/java/ladder/Direction.java @@ -13,4 +13,8 @@ public enum Direction { public int getValue() { return value; } + + public String getStringValue() { + return Integer.toString(value); + } } diff --git a/src/main/java/ladder/LadderGame.java b/src/main/java/ladder/LadderGame.java index 92a425f..e6e8534 100644 --- a/src/main/java/ladder/LadderGame.java +++ b/src/main/java/ladder/LadderGame.java @@ -15,11 +15,11 @@ public LadderGame(LadderCreator ladderCreator) { // todo 포지션 wrapper 클래스 필요 // todo LadderRunner로 분리 (Ladder 클래스 책임분산) - // LadderRunner를 통해 돌리자 + // LadderRunner를 통해 돌리자 (사다리를 타는것을 관리하는 클래스) public int run(Position position) { - LadderRunner ladderRunner = new LadderRunner(ladderCreator.getRows()); + LadderRunner ladderRunner = new LadderRunner(ladderCreator.getRows()); // 이미 만들어 둔 ladderCreator의 사다리를 인수로 넘긴다.. ladderRunner.run(position); - return position.getPosition(); + return position.getPosition(); // 최종 인덱스(세로 번 째) 반환 } } diff --git a/src/main/java/ladder/LadderPosition.java b/src/main/java/ladder/LadderPosition.java new file mode 100644 index 0000000..c785033 --- /dev/null +++ b/src/main/java/ladder/LadderPosition.java @@ -0,0 +1,22 @@ +package ladder; + +// 사다리 출력을 위해, (x,y)좌표를 동시에 다루는 클래스 +// 어디에 점을 찍을 지 알 수 있다...? +public class LadderPosition { + Position x, y; + + public LadderPosition(Position x, Position y) { + this.x = x; + this.y = y; + } + + public int getX() { + return x.getPosition(); + } + + public int getY() { + return y.getPosition(); + } + + +} diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java index ab5de6a..35d6101 100644 --- a/src/main/java/ladder/LadderRunner.java +++ b/src/main/java/ladder/LadderRunner.java @@ -3,6 +3,7 @@ public class LadderRunner { private final Row[] rows; // 사다리의 한 행을 빼놓았다. + private StringBuilder ladder = new StringBuilder(); public LadderRunner(Row[] rows) { this.rows = rows; @@ -10,10 +11,44 @@ public LadderRunner(Row[] rows) { // todo 포지션 wrapper 클래스 필요 // todo LadderRunner로 분리 (Ladder 클래스 책임분산) + // 매개변수 : 시작 x좌표 / 반복문 : y좌표 + // todo <미션> 여기서 사다리의 움직임마다 출력해야 함 public int run(Position position) { + // position (x)좌표는 마지막 위치에 있고 + // for문의 반복으로 y좌표가 움직이면 좌표 다룰 수 있음 + + // todo 여기에 (position, 1)로 좌표보내주면 될듯 (setStringLadder()함수) + for (int i = 0; i < rows.length; i++) { - rows[i].nextPosition(position); // position에 대입 삭제 (1) + // todo <미션1> 사다리 진행상황 출력위치 + // 사다리 (*포함) 세팅 + setStringLadder(new LadderPosition(position, Position.from(i))); + printLadder(); + rows[i].nextPosition(position); + setStringLadder(new LadderPosition(position, Position.from(i))); + printLadder(); } + return position.getPosition(); } + + public void setStringLadder(LadderPosition xy) { + for (int i = 0; i < rows.length; i++) { // 높이만큼 순환 + rows[i].setStringLadder(xy); + ladder.append(rows[i].rowLadder); // 한줄 씩 붙이기 + } + } + + public void printLadder() { + System.out.println(ladder); + clearStringLadder(); + } + + public void clearStringLadder() { + ladder.setLength(0); // 전체 사다리 초기화 + + for (int i = 0; i < rows.length; i++) { // 만들었던 사다리 줄 하나씩 초기화 + rows[i].rowLadder.setLength(0); + } + } } diff --git a/src/main/java/ladder/Node.java b/src/main/java/ladder/Node.java index b3fcbf5..6babb09 100644 --- a/src/main/java/ladder/Node.java +++ b/src/main/java/ladder/Node.java @@ -2,7 +2,7 @@ import static ladder.Direction.*; // 사다리의 세로줄 (열), numberOFPerson -// 사다리의 실제 값 (방향)을 담는 클래스 +// 사다리의 실제 값 (방향)을 지정하는 클래스 public class Node { private Direction direction; // 사다리의 실제 값 @@ -42,7 +42,7 @@ private boolean isNone() { // 노드값을 보고 하는 것이므로 node의 책임 (from Row클래스) public void move(Position position) { if (isRight()) { - position.next(); // 이 곳에 return 삭제함 (1) + position.next(); // position (인덱스값 ++) return; } if (isLeft()) { @@ -51,6 +51,9 @@ public void move(Position position) { } } + public String getDirection() { + return direction.getStringValue(); + } diff --git a/src/main/java/ladder/Position.java b/src/main/java/ladder/Position.java index 162bd5e..9951904 100644 --- a/src/main/java/ladder/Position.java +++ b/src/main/java/ladder/Position.java @@ -1,6 +1,6 @@ package ladder; -// 사다리의 인덱스 값 관리 클래스 +// 사다리의 인덱스(위치)를 나타내는 클래스 public class Position { private int position; diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 500dd92..78d3c91 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -8,6 +8,7 @@ public class Row { // todo Node 클래스로 분리(row 배열에서 값을 하나씩 꺼내서 볼 필요가 없다..?) Node[] nodes; + StringBuilder rowLadder = new StringBuilder(); // StringBuilder를 만들어두고 해당 클래스에 출력 public Row(GreaterThanOne numberOfPerson) { nodes = new Node[numberOfPerson.getNumber()]; // 노드 배열개수할당 @@ -16,6 +17,22 @@ public Row(GreaterThanOne numberOfPerson) { } } + public void setStringLadder(LadderPosition xy) { + for (int i = 0; i < nodes.length; i++) { // 사람 수 만큼 순환 + + rowLadder.append(nodes[i].getDirection());// 받는 로직 추가 + if (i == xy.getX()) { + rowLadder.append("*"); + } + rowLadder.append(" "); + } + + } + +// public void printLadder() { +// System.out.println(rowLadder.toString()); +// } + // todo : 상수 리팩토링 (1,-1, 0) public void drawLine(Position startPosition) { validateDrawLinePosition(startPosition); // 선 그리기 유효성 검사 통합 @@ -30,11 +47,13 @@ private void setDirectionBetweenNextPosition(Position position) { } // run 메소드의 다음 상태 + // 시작점이 될 수 있는지 판단하고 + // Node 클래스의 move메소드로 넘겨서 실제 움직임을 동작한다 public void nextPosition(Position position) { + // Position클래스 자체에서는 사다리의 크기를 모르므로 Row클래스에서 검증해야 함 validatePosition(position); // 1-2. next, prev 이전에 다시 position 검증 - // nextPosition method return type : Position -> void (1) - nodes[position.getPosition()].move(position); + nodes[position.getPosition()].move(position); // 검증이 완료된 position을 넘긴다. } // Todo 상수 하드코딩도 enum으로 클래스단위로 관리하자 diff --git a/src/test/java/ladder/LadderGameTest.java b/src/test/java/ladder/LadderGameTest.java index 2ca5de8..c419ead 100644 --- a/src/test/java/ladder/LadderGameTest.java +++ b/src/test/java/ladder/LadderGameTest.java @@ -36,6 +36,8 @@ class LadderGameTest { .isInstanceOf(IllegalArgumentException.class); } + // todo 여기에 사다리 출력결과 메소드 -> 한번 Run으로 이동시마다 출력 (굳이 테스트로 안해도될지도..?) + @Test void 사다리_결과_확인() { //when From 100cd5b6c898882e38ffd7d15c2ba766bded0629 Mon Sep 17 00:00:00 2001 From: SangHyun Jung Date: Thu, 26 Sep 2024 13:14:19 +0900 Subject: [PATCH 07/10] =?UTF-8?q?9.25=206:10pm=20(=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=EC=83=9D=EC=84=B1=20=EC=A4=91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/LadderRunner.java | 9 ++++----- src/main/java/ladder/Node.java | 2 -- src/main/java/ladder/Row.java | 14 +++++++------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java index 35d6101..97bbfed 100644 --- a/src/main/java/ladder/LadderRunner.java +++ b/src/main/java/ladder/LadderRunner.java @@ -34,8 +34,7 @@ public int run(Position position) { public void setStringLadder(LadderPosition xy) { for (int i = 0; i < rows.length; i++) { // 높이만큼 순환 - rows[i].setStringLadder(xy); - ladder.append(rows[i].rowLadder); // 한줄 씩 붙이기 + ladder.append(rows[i].setStringLadder(xy)); // 한줄 씩 붙이기 } } @@ -47,8 +46,8 @@ public void printLadder() { public void clearStringLadder() { ladder.setLength(0); // 전체 사다리 초기화 - for (int i = 0; i < rows.length; i++) { // 만들었던 사다리 줄 하나씩 초기화 - rows[i].rowLadder.setLength(0); - } +// for (int i = 0; i < rows.length; i++) { // 만들었던 사다리 줄 하나씩 초기화 +// rows[i].rowLadder.setLength(0); +// } } } diff --git a/src/main/java/ladder/Node.java b/src/main/java/ladder/Node.java index 6babb09..2de93fe 100644 --- a/src/main/java/ladder/Node.java +++ b/src/main/java/ladder/Node.java @@ -55,6 +55,4 @@ public String getDirection() { return direction.getStringValue(); } - - } diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 78d3c91..0c81ae4 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -8,7 +8,7 @@ public class Row { // todo Node 클래스로 분리(row 배열에서 값을 하나씩 꺼내서 볼 필요가 없다..?) Node[] nodes; - StringBuilder rowLadder = new StringBuilder(); // StringBuilder를 만들어두고 해당 클래스에 출력 + public Row(GreaterThanOne numberOfPerson) { nodes = new Node[numberOfPerson.getNumber()]; // 노드 배열개수할당 @@ -17,21 +17,21 @@ public Row(GreaterThanOne numberOfPerson) { } } - public void setStringLadder(LadderPosition xy) { + public StringBuilder setStringLadder(LadderPosition xy) { + StringBuilder rowLadder = new StringBuilder(); // 호출 될 때 마다 새로운 StringBuilder + for (int i = 0; i < nodes.length; i++) { // 사람 수 만큼 순환 rowLadder.append(nodes[i].getDirection());// 받는 로직 추가 - if (i == xy.getX()) { + if (i == xy.getX()) { // x좌표에 무조건 점을 찍게된다 rowLadder.append("*"); } rowLadder.append(" "); } - } + return rowLadder; -// public void printLadder() { -// System.out.println(rowLadder.toString()); -// } + } // todo : 상수 리팩토링 (1,-1, 0) public void drawLine(Position startPosition) { From 40b7df6e1f114355f938b7cc91df36c26182b882 Mon Sep 17 00:00:00 2001 From: SangHyun Jung Date: Thu, 26 Sep 2024 16:27:30 +0900 Subject: [PATCH 08/10] =?UTF-8?q?9.25=206:10pm=20(=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=EC=83=9D=EC=84=B1=20=EC=A4=91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/LadderRunner.java | 11 ++++++++++- src/main/java/ladder/Row.java | 14 +++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java index 97bbfed..1736a03 100644 --- a/src/main/java/ladder/LadderRunner.java +++ b/src/main/java/ladder/LadderRunner.java @@ -33,13 +33,22 @@ public int run(Position position) { } public void setStringLadder(LadderPosition xy) { + // 점을 한번 찍으면 특정 변수에 변화를 주어서, 다음 줄에서는 *을 찍지 않도록 조치..? + for (int i = 0; i < rows.length; i++) { // 높이만큼 순환 - ladder.append(rows[i].setStringLadder(xy)); // 한줄 씩 붙이기 + // todo 여기서 xy의 y좌표랑 반복문 인자 i랑 같은지 확인하고 + // 같을 때 만 *을 찍을 수 있도록 인자를 넘긴다. + if (xy.getY() == i) { + ladder.append(rows[i].setStringStarLadder(xy)); // *을 붙이는 라인 + } + ladder.append(rows[i].setStringLadder(xy)); // 일반 사다리 붙이는 라인 + ladder.append(System.lineSeparator()); } } public void printLadder() { System.out.println(ladder); + // System.out.println(); clearStringLadder(); } diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 0c81ae4..4c576c5 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -22,13 +22,25 @@ public StringBuilder setStringLadder(LadderPosition xy) { for (int i = 0; i < nodes.length; i++) { // 사람 수 만큼 순환 + rowLadder.append(nodes[i].getDirection());// 받는 로직 추가 + rowLadder.append(" "); + } + return rowLadder; + + } + + public StringBuilder setStringStarLadder(LadderPosition xy) { + StringBuilder rowLadder = new StringBuilder(); // 호출 될 때 마다 새로운 StringBuilder + + for (int i = 0; i < nodes.length; i++) { // 사람 수 만큼 순환 + // y좌표를 고려하여 *을 찍을 수 있는지 없는지 판단한다. + rowLadder.append(nodes[i].getDirection());// 받는 로직 추가 if (i == xy.getX()) { // x좌표에 무조건 점을 찍게된다 rowLadder.append("*"); } rowLadder.append(" "); } - return rowLadder; } From a09628ccfc30d73ae5f6b6eac7b476926d910623 Mon Sep 17 00:00:00 2001 From: SangHyun Jung Date: Thu, 26 Sep 2024 17:53:05 +0900 Subject: [PATCH 09/10] =?UTF-8?q?9.25=206:10pm=20(=EC=82=AC=EB=8B=A4?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=9C=EB=A0=A5=201=EC=B0=A8=EC=99=84=EB=A3=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ladder/LadderRunner.java | 4 ++++ src/test/java/ladder/LadderGameTest.java | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java index 1736a03..7fb25e6 100644 --- a/src/main/java/ladder/LadderRunner.java +++ b/src/main/java/ladder/LadderRunner.java @@ -29,6 +29,8 @@ public int run(Position position) { printLadder(); } + System.out.println("-".repeat(10)); + return position.getPosition(); } @@ -40,6 +42,8 @@ public void setStringLadder(LadderPosition xy) { // 같을 때 만 *을 찍을 수 있도록 인자를 넘긴다. if (xy.getY() == i) { ladder.append(rows[i].setStringStarLadder(xy)); // *을 붙이는 라인 + ladder.append(System.lineSeparator()); + continue; } ladder.append(rows[i].setStringLadder(xy)); // 일반 사다리 붙이는 라인 ladder.append(System.lineSeparator()); diff --git a/src/test/java/ladder/LadderGameTest.java b/src/test/java/ladder/LadderGameTest.java index c419ead..4ef1c31 100644 --- a/src/test/java/ladder/LadderGameTest.java +++ b/src/test/java/ladder/LadderGameTest.java @@ -48,7 +48,7 @@ class LadderGameTest { ladderCreator.drawLine(Position.from(0),Position.from(0)); ladderCreator.drawLine(Position.from(1),Position.from(1)); - ladderCreator.drawLine(Position.from(2),Position.from(0)); + // ladderCreator.drawLine(Position.from(2),Position.from(0)); //given Position nthOfPerson = Position.from(0); @@ -60,12 +60,12 @@ class LadderGameTest { nthOfPerson = Position.from(1); //then - assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(1); + assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(0); //given nthOfPerson = Position.from(2); //then - assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(0); + assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(1); } } \ No newline at end of file From f2765fe8f6c36e5efb687ece12a2b43184529e3d Mon Sep 17 00:00:00 2001 From: SangHyun Jung Date: Fri, 27 Sep 2024 21:35:56 +0900 Subject: [PATCH 10/10] =?UTF-8?q?9.27=20=EA=B8=88=20(9.34pm),=20=EB=AF=B8?= =?UTF-8?q?=EC=85=982=EA=B0=9C=20=EC=9E=84=EC=8B=9C=EC=99=84=EB=A3=8C=20La?= =?UTF-8?q?dderRandomCreator=20=EC=97=90=EC=84=9C=20makeRandomLine=20?= =?UTF-8?q?=ED=95=A0=EB=95=8C=20drawLine=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=AC=B8=EC=A0=9C=20=EC=83=9D=EA=B8=B8=20?= =?UTF-8?q?=EB=95=8C=20=EB=B0=9C=EC=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/uiDesigner.xml | 124 ++++++++++++++++++ src/main/java/ladder/GreaterThanOne.java | 2 +- src/main/java/ladder/LadderGame.java | 6 + src/main/java/ladder/LadderPosition.java | 12 +- src/main/java/ladder/LadderRunner.java | 8 +- src/main/java/ladder/LadderSize.java | 32 +++++ src/main/java/ladder/Row.java | 12 +- .../java/ladder/creator/LadderCreation.java | 10 ++ .../java/ladder/creator/LadderCreator.java | 2 +- .../ladder/creator/LadderRandomCreator.java | 46 +++++++ src/test/java/ladder/LadderGameTest.java | 4 +- src/test/java/ladder/LadderRandomTest.java | 68 ++++++++++ src/test/java/ladder/NodesTest.java | 4 +- 13 files changed, 309 insertions(+), 21 deletions(-) create mode 100644 .idea/uiDesigner.xml create mode 100644 src/main/java/ladder/LadderSize.java create mode 100644 src/main/java/ladder/creator/LadderCreation.java create mode 100644 src/main/java/ladder/creator/LadderRandomCreator.java create mode 100644 src/test/java/ladder/LadderRandomTest.java diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/ladder/GreaterThanOne.java b/src/main/java/ladder/GreaterThanOne.java index 80e0572..940c76e 100644 --- a/src/main/java/ladder/GreaterThanOne.java +++ b/src/main/java/ladder/GreaterThanOne.java @@ -3,7 +3,7 @@ // 1보다 큰지 검증하는 클래스 public class GreaterThanOne { - private final int number; + private final int number; private GreaterThanOne(int number) { this.number = number; diff --git a/src/main/java/ladder/LadderGame.java b/src/main/java/ladder/LadderGame.java index e6e8534..754d7b2 100644 --- a/src/main/java/ladder/LadderGame.java +++ b/src/main/java/ladder/LadderGame.java @@ -1,18 +1,24 @@ package ladder; import ladder.creator.LadderCreator; +import ladder.creator.LadderRandomCreator; // todo Ladder 클래스가 많은 책임 (사다리 생성 / 사다리 그리기 / 사다리 게임 진행) // 마지막으로 Ladder는 전체를 관장하는 클래스가 되었으므로 // LadderGame으로 변경 +// todo LadderGame에 의존성주입을 통해 LadderCreator를 변경해보기 +// todo LadderGame클래스 자체도 정적메소드 패턴을 이용하여 생성 public class LadderGame { private final LadderCreator ladderCreator; + // private final LadderRandomCreator ladderRandomCreator; public LadderGame(LadderCreator ladderCreator) { this.ladderCreator = ladderCreator; } + + // todo 포지션 wrapper 클래스 필요 // todo LadderRunner로 분리 (Ladder 클래스 책임분산) // LadderRunner를 통해 돌리자 (사다리를 타는것을 관리하는 클래스) diff --git a/src/main/java/ladder/LadderPosition.java b/src/main/java/ladder/LadderPosition.java index c785033..c2fe9b7 100644 --- a/src/main/java/ladder/LadderPosition.java +++ b/src/main/java/ladder/LadderPosition.java @@ -10,11 +10,19 @@ public LadderPosition(Position x, Position y) { this.y = y; } - public int getX() { + public Position getX() { + return x; + } + + public Position getY() { + return y; + } + + public int getIntX() { return x.getPosition(); } - public int getY() { + public int getIntY() { return y.getPosition(); } diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java index 7fb25e6..933e2cf 100644 --- a/src/main/java/ladder/LadderRunner.java +++ b/src/main/java/ladder/LadderRunner.java @@ -10,18 +10,14 @@ public LadderRunner(Row[] rows) { } // todo 포지션 wrapper 클래스 필요 - // todo LadderRunner로 분리 (Ladder 클래스 책임분산) // 매개변수 : 시작 x좌표 / 반복문 : y좌표 - // todo <미션> 여기서 사다리의 움직임마다 출력해야 함 public int run(Position position) { // position (x)좌표는 마지막 위치에 있고 // for문의 반복으로 y좌표가 움직이면 좌표 다룰 수 있음 - // todo 여기에 (position, 1)로 좌표보내주면 될듯 (setStringLadder()함수) - for (int i = 0; i < rows.length; i++) { - // todo <미션1> 사다리 진행상황 출력위치 // 사다리 (*포함) 세팅 + // todo 매개변수로 넘기는 값이 x,y인지 구별될 수 있도록 setStringLadder(new LadderPosition(position, Position.from(i))); printLadder(); rows[i].nextPosition(position); @@ -40,7 +36,7 @@ public void setStringLadder(LadderPosition xy) { for (int i = 0; i < rows.length; i++) { // 높이만큼 순환 // todo 여기서 xy의 y좌표랑 반복문 인자 i랑 같은지 확인하고 // 같을 때 만 *을 찍을 수 있도록 인자를 넘긴다. - if (xy.getY() == i) { + if (xy.getIntY() == i) { ladder.append(rows[i].setStringStarLadder(xy)); // *을 붙이는 라인 ladder.append(System.lineSeparator()); continue; diff --git a/src/main/java/ladder/LadderSize.java b/src/main/java/ladder/LadderSize.java new file mode 100644 index 0000000..9f4ef33 --- /dev/null +++ b/src/main/java/ladder/LadderSize.java @@ -0,0 +1,32 @@ +package ladder; + +public class LadderSize { + GreaterThanOne row, numberOfPerson; + + public LadderSize(GreaterThanOne row, GreaterThanOne numberOfPerson) { + this.row = row; + this.numberOfPerson = numberOfPerson; + } + + public GreaterThanOne getRow() { + return row; + } + + public GreaterThanOne getNumberOfPerson() { + return numberOfPerson; + } + + public int getIntRow() { + return row.getNumber(); + } + + public int getIntNumberOfPerson() { + return numberOfPerson.getNumber(); + } + + // 생성해야 할 라인 개수 반환 + public int getLadderLineNum() { + return (int) Math.floor(numberOfPerson.getNumber() * row.getNumber() * 0.3); + } + +} diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 4c576c5..0b94ccf 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -9,7 +9,6 @@ public class Row { // todo Node 클래스로 분리(row 배열에서 값을 하나씩 꺼내서 볼 필요가 없다..?) Node[] nodes; - public Row(GreaterThanOne numberOfPerson) { nodes = new Node[numberOfPerson.getNumber()]; // 노드 배열개수할당 for (int i = 0; i < numberOfPerson.getNumber(); i++) { @@ -28,7 +27,7 @@ public StringBuilder setStringLadder(LadderPosition xy) { return rowLadder; } - + // *이 포함되게 찍히는 메소드 public StringBuilder setStringStarLadder(LadderPosition xy) { StringBuilder rowLadder = new StringBuilder(); // 호출 될 때 마다 새로운 StringBuilder @@ -36,7 +35,7 @@ public StringBuilder setStringStarLadder(LadderPosition xy) { // y좌표를 고려하여 *을 찍을 수 있는지 없는지 판단한다. rowLadder.append(nodes[i].getDirection());// 받는 로직 추가 - if (i == xy.getX()) { // x좌표에 무조건 점을 찍게된다 + if (i == xy.getIntX()) { // x좌표에 무조건 점을 찍게된다 rowLadder.append("*"); } rowLadder.append(" "); @@ -83,18 +82,19 @@ private void validateDrawLinePosition(Position startPosition) { } } - // 숫자가 사다리 크기보다 커서 실패하는 경우 + // 선그리기 유효성 검사 + // 1. 숫자가 사다리 크기보다 커서 실패하는 경우 private boolean isInvalidPosition(Position startPosition) { return startPosition.isBiggerThan(nodes.length - 1); // startPosition.getPosition() < 0 -> position 만들때 이미 검증했던 logic } - // 이미 그려진 경우 + // 2. 이미 그려진 경우 private boolean isLineAtPosition(Position startPosition) { return ! nodes[startPosition.getPosition()].isAlreadySetDirection(); // none이 아니면 // return nodes[startPosition.getPosition()] == RIGHT.getValue() || row[startPosition.getPosition()] == LEFT.getValue(); } - // 옆에 이미 그려진 경우 + // 3. 옆에 이미 그려진 경우 private boolean isLineAtNextPosition(Position startPosition) { startPosition.next(); boolean IsLineAtPosition = !nodes[startPosition.getPosition()].isAlreadySetDirection(); diff --git a/src/main/java/ladder/creator/LadderCreation.java b/src/main/java/ladder/creator/LadderCreation.java new file mode 100644 index 0000000..092ce92 --- /dev/null +++ b/src/main/java/ladder/creator/LadderCreation.java @@ -0,0 +1,10 @@ +package ladder.creator; + +import ladder.Position; +import ladder.Row; + +public interface LadderCreation { + void drawLine(Position row, Position col); + + Row[] getRows(); +} diff --git a/src/main/java/ladder/creator/LadderCreator.java b/src/main/java/ladder/creator/LadderCreator.java index 5fa1901..6d88d1a 100644 --- a/src/main/java/ladder/creator/LadderCreator.java +++ b/src/main/java/ladder/creator/LadderCreator.java @@ -4,7 +4,7 @@ import ladder.Position; import ladder.Row; -public class LadderCreator { +public class LadderCreator implements LadderCreation{ private final Row[] rows; // 사다리의 한 행을 빼놓았다. diff --git a/src/main/java/ladder/creator/LadderRandomCreator.java b/src/main/java/ladder/creator/LadderRandomCreator.java new file mode 100644 index 0000000..962b669 --- /dev/null +++ b/src/main/java/ladder/creator/LadderRandomCreator.java @@ -0,0 +1,46 @@ +package ladder.creator; + +import ladder.*; + +import java.util.HashSet; + +public class LadderRandomCreator implements LadderCreation { + + private final LadderCreator ladderCreator; + private final LadderSize ladderSize; + private final int lineNumber; // 몇개 생성할 건지 개수 + HashSet startPosition; + + // 우선 drawLine으로 x좌표 넘겨주고, 그 다음에 y좌표까지 같은지 반복문으로 판단 + public LadderRandomCreator(LadderSize ladderSize) { + this.ladderSize = ladderSize; + ladderCreator = new LadderCreator(ladderSize.getRow(), ladderSize.getNumberOfPerson()); + this.lineNumber = ladderSize.getLadderLineNum(); + } + + public void makeRandomLine() { + startPosition = new HashSet<>(); // HashSet<>초기화 + + while (startPosition.size() < lineNumber) { // hashset 개수가 lineNumber 안 넘는 동안 + int xValue = (int) (Math.random() * (ladderSize.getIntNumberOfPerson() - 1)); // 제일 오른쪽은 그릴 수 없으므로 + int yValue = (int) (Math.random() * ladderSize.getIntRow()); + Position x = Position.from(xValue); + Position y = Position.from(yValue); + + LadderPosition currentPosition = new LadderPosition(x,y); // 추가하려는 임시 LadderPosition 객체 + + if (!startPosition.contains(currentPosition)) { + startPosition.add(currentPosition); + drawLine(currentPosition.getY(), currentPosition.getX()); + } + } + } + + public void drawLine(Position row, Position col) { + ladderCreator.getRows()[row.getPosition()].drawLine(col); + } + + public Row[] getRows() { + return ladderCreator.getRows(); + } +} diff --git a/src/test/java/ladder/LadderGameTest.java b/src/test/java/ladder/LadderGameTest.java index 4ef1c31..1a9ae38 100644 --- a/src/test/java/ladder/LadderGameTest.java +++ b/src/test/java/ladder/LadderGameTest.java @@ -36,10 +36,8 @@ class LadderGameTest { .isInstanceOf(IllegalArgumentException.class); } - // todo 여기에 사다리 출력결과 메소드 -> 한번 Run으로 이동시마다 출력 (굳이 테스트로 안해도될지도..?) - @Test - void 사다리_결과_확인() { + void 사다리_결과_확인() { // 출력결과 포함 //when GreaterThanOne numberOfPerson = GreaterThanOne.from(4); GreaterThanOne row = GreaterThanOne.from(3); diff --git a/src/test/java/ladder/LadderRandomTest.java b/src/test/java/ladder/LadderRandomTest.java new file mode 100644 index 0000000..ec51584 --- /dev/null +++ b/src/test/java/ladder/LadderRandomTest.java @@ -0,0 +1,68 @@ +package ladder; + +import ladder.creator.LadderRandomCreator; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.*; + +public class LadderRandomTest { + @Test + void 사다리_자동_생성_확인() { + // given + GreaterThanOne numberOfRow = GreaterThanOne.from(3); + GreaterThanOne numberOfPerson = GreaterThanOne.from(4); + + // when + LadderRandomCreator ladderRandomCreator = new LadderRandomCreator(new LadderSize(numberOfRow, numberOfPerson)); + + // then + assertThat(ladderRandomCreator).isNotNull(); + } + + @Test + void 사다리_사람_예외_처리_확인() { + //when + GreaterThanOne numberOfRow = GreaterThanOne.from(2); + GreaterThanOne numberOfPerson = GreaterThanOne.from(3); + LadderRandomCreator ladderRandomCreator = new LadderRandomCreator(new LadderSize(numberOfRow, numberOfPerson)); + LadderRunner ladderRunner = new LadderRunner(ladderRandomCreator.getRows()); + + + //given + Position nthOfPerson = Position.from(4); + + //then + assertThatThrownBy(() -> ladderRunner.run(nthOfPerson)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + // todo test통과할 때가 있고 안될때가 있다... + void 사다리_결과_확인() { // 출력결과 포함 + //when + GreaterThanOne numberOfPerson = GreaterThanOne.from(4); + GreaterThanOne numberOfRow = GreaterThanOne.from(3); + LadderRandomCreator ladderRandomCreator = new LadderRandomCreator(new LadderSize(numberOfRow, numberOfPerson)); + LadderRunner ladderRunner = new LadderRunner(ladderRandomCreator.getRows()); + + ladderRandomCreator.makeRandomLine(); + + //given + Position nthOfPerson = Position.from(0); + + //then + // 눈으로 테스트하는게 제일 직관적이겠지만, numberOfPerson 사이에 결과가 있어야하는 건 자명하니, isBetween 메소드 사용 + assertThat(ladderRunner.run(nthOfPerson)).isBetween(0,3); + + //given + nthOfPerson = Position.from(1); + + //then + assertThat(ladderRunner.run(nthOfPerson)).isBetween(0,3); + + //given + nthOfPerson = Position.from(2); + + //then + assertThat(ladderRunner.run(nthOfPerson)).isBetween(0,3); + } +} diff --git a/src/test/java/ladder/NodesTest.java b/src/test/java/ladder/NodesTest.java index 98a5e86..319fc9b 100644 --- a/src/test/java/ladder/NodesTest.java +++ b/src/test/java/ladder/NodesTest.java @@ -1,8 +1,8 @@ package ladder; -import static org.assertj.core.api.Assertions.*; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.*; import static ladder.Direction.*; public class NodesTest {