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/.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.java b/src/main/java/Ladder.java
deleted file mode 100644
index 0d2b070..0000000
--- a/src/main/java/Ladder.java
+++ /dev/null
@@ -1,8 +0,0 @@
-public class Ladder {
-
- private final int[][] rows;
-
- public Ladder(int row, int numberOfPerson) {
- rows = new int[row][numberOfPerson];
- }
-}
diff --git a/src/main/java/ladder/Direction.java b/src/main/java/ladder/Direction.java
new file mode 100644
index 0000000..1d1d1f2
--- /dev/null
+++ b/src/main/java/ladder/Direction.java
@@ -0,0 +1,20 @@
+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;
+ }
+
+ public String getStringValue() {
+ return Integer.toString(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..940c76e
--- /dev/null
+++ b/src/main/java/ladder/GreaterThanOne.java
@@ -0,0 +1,27 @@
+package ladder;
+
+// 1보다 큰지 검증하는 클래스
+public class GreaterThanOne {
+
+ private final int number;
+
+ private GreaterThanOne(int number) {
+ this.number = number;
+ }
+
+ public static GreaterThanOne from(int number) {
+ if (! isGreaterThanOne(number)) { // 팩토리 메소드로 검증 (1보다 큰지)
+ 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/LadderGame.java b/src/main/java/ladder/LadderGame.java
new file mode 100644
index 0000000..754d7b2
--- /dev/null
+++ b/src/main/java/ladder/LadderGame.java
@@ -0,0 +1,31 @@
+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를 통해 돌리자 (사다리를 타는것을 관리하는 클래스)
+ public int run(Position position) {
+ LadderRunner ladderRunner = new LadderRunner(ladderCreator.getRows()); // 이미 만들어 둔 ladderCreator의 사다리를 인수로 넘긴다..
+ ladderRunner.run(position);
+
+ 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..c2fe9b7
--- /dev/null
+++ b/src/main/java/ladder/LadderPosition.java
@@ -0,0 +1,30 @@
+package ladder;
+
+// 사다리 출력을 위해, (x,y)좌표를 동시에 다루는 클래스
+// 어디에 점을 찍을 지 알 수 있다...?
+public class LadderPosition {
+ Position x, y;
+
+ public LadderPosition(Position x, Position y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public Position getX() {
+ return x;
+ }
+
+ public Position getY() {
+ return y;
+ }
+
+ public int getIntX() {
+ return x.getPosition();
+ }
+
+ public int getIntY() {
+ return y.getPosition();
+ }
+
+
+}
diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java
new file mode 100644
index 0000000..933e2cf
--- /dev/null
+++ b/src/main/java/ladder/LadderRunner.java
@@ -0,0 +1,62 @@
+package ladder;
+
+public class LadderRunner {
+
+ private final Row[] rows; // 사다리의 한 행을 빼놓았다.
+ private StringBuilder ladder = new StringBuilder();
+
+ public LadderRunner(Row[] rows) {
+ this.rows = rows;
+ }
+
+ // todo 포지션 wrapper 클래스 필요
+ // 매개변수 : 시작 x좌표 / 반복문 : y좌표
+ public int run(Position position) {
+ // position (x)좌표는 마지막 위치에 있고
+ // for문의 반복으로 y좌표가 움직이면 좌표 다룰 수 있음
+
+ for (int i = 0; i < rows.length; i++) {
+ // 사다리 (*포함) 세팅
+ // todo 매개변수로 넘기는 값이 x,y인지 구별될 수 있도록
+ setStringLadder(new LadderPosition(position, Position.from(i)));
+ printLadder();
+ rows[i].nextPosition(position);
+ setStringLadder(new LadderPosition(position, Position.from(i)));
+ printLadder();
+ }
+
+ System.out.println("-".repeat(10));
+
+ return position.getPosition();
+ }
+
+ public void setStringLadder(LadderPosition xy) {
+ // 점을 한번 찍으면 특정 변수에 변화를 주어서, 다음 줄에서는 *을 찍지 않도록 조치..?
+
+ for (int i = 0; i < rows.length; i++) { // 높이만큼 순환
+ // todo 여기서 xy의 y좌표랑 반복문 인자 i랑 같은지 확인하고
+ // 같을 때 만 *을 찍을 수 있도록 인자를 넘긴다.
+ if (xy.getIntY() == i) {
+ ladder.append(rows[i].setStringStarLadder(xy)); // *을 붙이는 라인
+ ladder.append(System.lineSeparator());
+ continue;
+ }
+ ladder.append(rows[i].setStringLadder(xy)); // 일반 사다리 붙이는 라인
+ ladder.append(System.lineSeparator());
+ }
+ }
+
+ public void printLadder() {
+ System.out.println(ladder);
+ // System.out.println();
+ 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/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/Node.java b/src/main/java/ladder/Node.java
new file mode 100644
index 0000000..2de93fe
--- /dev/null
+++ b/src/main/java/ladder/Node.java
@@ -0,0 +1,58 @@
+package ladder;
+import static ladder.Direction.*;
+
+// 사다리의 세로줄 (열), numberOFPerson
+// 사다리의 실제 값 (방향)을 지정하는 클래스
+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(); // position (인덱스값 ++)
+ return;
+ }
+ if (isLeft()) {
+ position.prev();
+ return;
+ }
+ }
+
+ public String getDirection() {
+ return direction.getStringValue();
+ }
+
+}
diff --git a/src/main/java/ladder/Position.java b/src/main/java/ladder/Position.java
new file mode 100644
index 0000000..9951904
--- /dev/null
+++ b/src/main/java/ladder/Position.java
@@ -0,0 +1,52 @@
+package ladder;
+
+// 사다리의 인덱스(위치)를 나타내는 클래스
+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
new file mode 100644
index 0000000..0b94ccf
--- /dev/null
+++ b/src/main/java/ladder/Row.java
@@ -0,0 +1,104 @@
+package ladder;
+// 문제점
+// drawLine, nextPosition 등의 하드코딩 (+1 or -1)
+
+import static ladder.Direction.*;
+
+// 사다리의 하나의 가로줄 (행)
+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++) {
+ nodes[i] = Node.from(NONE);
+ }
+ }
+
+ public StringBuilder setStringLadder(LadderPosition xy) {
+ StringBuilder rowLadder = new StringBuilder(); // 호출 될 때 마다 새로운 StringBuilder
+
+ 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.getIntX()) { // x좌표에 무조건 점을 찍게된다
+ rowLadder.append("*");
+ }
+ rowLadder.append(" ");
+ }
+ return rowLadder;
+
+ }
+
+ // todo : 상수 리팩토링 (1,-1, 0)
+ public void drawLine(Position startPosition) {
+ validateDrawLinePosition(startPosition); // 선 그리기 유효성 검사 통합
+
+ setDirectionBetweenNextPosition(startPosition);
+ }
+
+ private void setDirectionBetweenNextPosition(Position position) {
+ nodes[position.getPosition()].setRightNode(position); // 현재 노드에 1대입 (오른쪽 이동)
+ position.next();
+ nodes[position.getPosition()].setLeftNode(position); // 그 다음 노드에 -1대입 (왼쪽 이동)
+ }
+
+ // run 메소드의 다음 상태
+ // 시작점이 될 수 있는지 판단하고
+ // Node 클래스의 move메소드로 넘겨서 실제 움직임을 동작한다
+ public void nextPosition(Position position) {
+ // Position클래스 자체에서는 사다리의 크기를 모르므로 Row클래스에서 검증해야 함
+ validatePosition(position); // 1-2. next, prev 이전에 다시 position 검증
+
+ nodes[position.getPosition()].move(position); // 검증이 완료된 position을 넘긴다.
+ }
+
+ // Todo 상수 하드코딩도 enum으로 클래스단위로 관리하자
+
+ private void validatePosition(Position position) {
+ if (position.isBiggerThan(nodes.length - 1)) { // 위치값과 실제 인덱스값 동일시
+ throw new IllegalArgumentException(ExceptionMessage.INVALID_POSITION.getMessage());
+ }
+ }
+
+ // 선그리기 유효성 검사 통합
+ private void validateDrawLinePosition(Position startPosition) {
+ if (isInvalidPosition(startPosition) || isLineAtPosition(startPosition) || isLineAtNextPosition(startPosition)) {
+ throw new IllegalArgumentException(ExceptionMessage.INVALID_DRAW_POSITION.getMessage());
+ }
+ }
+
+ // 선그리기 유효성 검사
+ // 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();
+ startPosition.prev();
+ return IsLineAtPosition;
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..6d88d1a
--- /dev/null
+++ b/src/main/java/ladder/creator/LadderCreator.java
@@ -0,0 +1,31 @@
+package ladder.creator;
+
+import ladder.GreaterThanOne;
+import ladder.Position;
+import ladder.Row;
+
+public class LadderCreator implements LadderCreation{
+
+ private final Row[] rows; // 사다리의 한 행을 빼놓았다.
+
+ // todo 생성자 wrapper 클래스 필요 ㅇㅋ (-> GreaterThanOne)
+ // Greaterthanone 클래스 필요 : 사다리 게임을 1명이서 하지는 않으니 (사다리 높이 및 인원수는 최소 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부터 입력가능한)
+ // Position으로 인덱스 접근하여 rows에 실제 사다리 방향(선)을 그린다
+ public void drawLine(Position row, Position col) {
+ rows[row.getPosition()].drawLine(col);
+ }
+
+ public Row[] getRows() {
+ return 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/LadderTest.java b/src/test/java/LadderTest.java
deleted file mode 100644
index 741a915..0000000
--- a/src/test/java/LadderTest.java
+++ /dev/null
@@ -1,5 +0,0 @@
-import static org.junit.jupiter.api.Assertions.*;
-
-class LadderTest {
-
-}
\ No newline at end of file
diff --git a/src/test/java/ladder/LadderGameTest.java b/src/test/java/ladder/LadderGameTest.java
new file mode 100644
index 0000000..1a9ae38
--- /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(0);
+
+ //given
+ nthOfPerson = Position.from(2);
+
+ //then
+ assertThat(ladderRunner.run(nthOfPerson)).isEqualTo(1);
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..319fc9b
--- /dev/null
+++ b/src/test/java/ladder/NodesTest.java
@@ -0,0 +1,42 @@
+package ladder;
+
+
+import org.junit.jupiter.api.Test;
+import static org.assertj.core.api.Assertions.*;
+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
new file mode 100644
index 0000000..b0745f6
--- /dev/null
+++ b/src/test/java/ladder/RowTest.java
@@ -0,0 +1,162 @@
+package ladder;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.*;
+
+class RowTest {
+
+ // 유효성 처리 및 핵심 로직을 분리해두었다.
+
+ @Test
+ void 한_칸_사다리_이동() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(2);
+ Row row = new Row(numberOfPerson);
+
+ //given
+ Position position = Position.from(0);
+ row.nextPosition(position);
+
+ //then
+ assertThat(position.getPosition()).isEqualTo(0);
+ }
+
+ @Test
+ void 두_칸_사다리_선_이동() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(2);
+ Row row = new Row(numberOfPerson);
+ row.drawLine(Position.from(0));
+
+ //given
+ Position position = Position.from(0);
+ row.nextPosition(position);
+
+ //then
+ assertThat(position.getPosition()).isEqualTo(1);
+
+ //given
+ position = Position.from(1);
+ row.nextPosition(position);
+
+ //then
+ assertThat(position.getPosition()).isEqualTo(0);
+ }
+
+ @Test
+ void 세_칸_사다리_선_이동() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(3);
+ Row row = new Row(numberOfPerson);
+ row.drawLine(Position.from(0));
+
+ //given
+ Position position = Position.from(0);
+ row.nextPosition(position);
+
+ //then
+ assertThat(position.getPosition()).isEqualTo(1);
+
+ //given
+ position = Position.from(1);
+ row.nextPosition(position);
+
+ //then
+ assertThat(position.getPosition()).isEqualTo(0);
+
+ //given
+ position = Position.from(2);
+ row.nextPosition(position);
+
+ //then
+ assertThat(position.getPosition()).isEqualTo(2);
+ }
+
+ @Test
+ void 사다리_사람수_예외_처리() {
+ assertThatThrownBy(() -> new Row(GreaterThanOne.from(0)))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void 사다리_최대_사람수_초과_예외() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(3);
+ Row row = new Row(numberOfPerson);
+
+ //given
+ Position position = Position.from(3);
+
+ //then
+ assertThatThrownBy(() -> row.nextPosition(Position.from(3)))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void 사다리_최소_사람수_미만_예외() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(3);
+ Row row = new Row(numberOfPerson);
+
+ //given
+ //Position position = Position.from(-1);
+
+ //then
+ assertThatThrownBy(() -> row.nextPosition(Position.from(-1)))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void 사다리_그리기_위치_초과_예외() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(3);
+ Row row = new Row(numberOfPerson);
+
+ //given
+ Position position = Position.from(3);
+
+ //then
+ assertThatThrownBy(() -> row.drawLine(position))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void 사다리_그리기_위치_미만_예외() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(3);
+ Row row = new Row(numberOfPerson);
+
+ //given
+ //Position position = Position.from(-1);
+
+ //then
+ assertThatThrownBy(() -> row.drawLine(Position.from(-1)))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void 사다리_그리기_좌측_선_중복_예외() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(3);
+ Row row = new Row(numberOfPerson);
+ row.drawLine(Position.from(0));
+
+ //then
+ assertThatThrownBy(() -> row.drawLine(Position.from(1)))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+
+ @Test
+ void 사다리_그리기_우측_선_중복_예외() {
+ //when
+ GreaterThanOne numberOfPerson = GreaterThanOne.from(3);
+ Row row = new Row(numberOfPerson);
+ row.drawLine(Position.from(1));
+
+ //then
+ assertThatThrownBy(() -> row.drawLine(Position.from(0)))
+ .isInstanceOf(IllegalArgumentException.class);
+
+ }
+}
\ No newline at end of file
diff --git a/week02.md b/week02.md
new file mode 100644
index 0000000..e69de29