diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..51f9fd7
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+kuit-ladder
\ No newline at end of file
diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml
new file mode 100644
index 0000000..6dafaf6
--- /dev/null
+++ b/.idea/dbnavigator.xml
@@ -0,0 +1,403 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 8f86b33..690f4c6 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/ExceptionMessage.java b/src/main/java/ExceptionMessage.java
new file mode 100644
index 0000000..c237610
--- /dev/null
+++ b/src/main/java/ExceptionMessage.java
@@ -0,0 +1,16 @@
+public enum ExceptionMessage {
+
+ INVALID_LADDER_SIZE("사다리의 열과 행은 2이상의 자연수입니다."),
+ INVALID_LINE_POSITION("선의 위치가 사다리를 벗어납니다."),
+ INVALID_START_POSITION("출발 위치는 1이상의 자연수입니다.");
+
+ private final String message;
+
+ ExceptionMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/src/main/java/Ladder.java b/src/main/java/Ladder.java
index 0d2b070..a90c0ea 100644
--- a/src/main/java/Ladder.java
+++ b/src/main/java/Ladder.java
@@ -1,8 +1,56 @@
-public class Ladder {
+import java.util.ArrayList;
+import java.util.List;
- private final int[][] rows;
+class Ladder {
+private final int[][] rows;
+private final List lines;
- public Ladder(int row, int numberOfPerson) {
- rows = new int[row][numberOfPerson];
+public Ladder(int row, int column) {
+ validateLadderDimensions(row, column);
+ this.rows = new int[row][column];
+ lines = new ArrayList<>();
+}
+
+private void validateLadderDimensions(int row, int column) {
+ if(row < 2 || column < 2) {
+ throw new IllegalArgumentException(ExceptionMessage.INVALID_LADDER_SIZE.getMessage());
+ }
+}
+
+public void addLine(int fromLine, int toLine, int currentRow) {
+ Line line = new Line(fromLine, toLine, currentRow, this.rows);
+ lines.add(line);
+}
+
+public boolean isLine(int row, int col) {
+ return rows[row][col] == 1 || rows[row][col] == -1;
+}
+
+public boolean isLineAtLeft(int row, int col) {
+ return col > 0 && rows[row][col - 1] == - 1;
+}
+
+public boolean isLineAtRight(int row, int col) {
+ return col + 1 < rows[row].length && rows[row][col + 1] == 1;
+}
+
+public int getHeight() {
+ return rows.length;
+}
+
+public int getWidth() {
+ return rows[0].length;
+}
+
+public int getRows(int row, int col) {
+ return rows[row][col];
+}
+
+ public boolean isLeftLine(int currentRow, int currentCol) {
+ return rows[currentRow][currentCol] == 1;
+ }
+
+ public boolean isRightLine(int currentRow, int currentCol) {
+ return rows[currentRow][currentCol] == - 1;
}
}
diff --git a/src/main/java/LadderCreator.java b/src/main/java/LadderCreator.java
new file mode 100644
index 0000000..ca0d035
--- /dev/null
+++ b/src/main/java/LadderCreator.java
@@ -0,0 +1,3 @@
+public interface LadderCreator {
+ Ladder createLine(int rows, int columns);
+}
diff --git a/src/main/java/LadderGame.java b/src/main/java/LadderGame.java
new file mode 100644
index 0000000..eafd256
--- /dev/null
+++ b/src/main/java/LadderGame.java
@@ -0,0 +1,28 @@
+import java.util.Scanner;
+
+public class LadderGame {
+ private Ladder ladder;
+ private static Scanner scanner;
+ private int startPosition;
+ private LadderRunner ladderRunner;
+
+ public LadderGame(Ladder ladder) {
+ this.ladder = ladder;
+ }
+
+ public void play() {
+ System.out.print("Enter the start position: ");
+ startPosition = scanner.nextInt();
+
+ ladderRunner = new LadderRunner(ladder, startPosition);
+ int result = ladderRunner.run()+1;
+ System.out.println("Final position: " + result);
+ }
+
+ public static void main(String[] args) {
+ scanner = new Scanner(System.in);
+ LadderGame game = LadderGameFactory.createRandomLadderGame(5, 5);
+ game.play();
+ scanner.close();
+ }
+}
diff --git a/src/main/java/LadderGameFactory.java b/src/main/java/LadderGameFactory.java
new file mode 100644
index 0000000..63f1268
--- /dev/null
+++ b/src/main/java/LadderGameFactory.java
@@ -0,0 +1,7 @@
+public class LadderGameFactory {
+ public static LadderGame createRandomLadderGame(int rows, int columns) {
+ LadderCreator creator = new RandomLadderCreator();
+ Ladder ladder = creator.createLine(rows, columns);
+ return new LadderGame(ladder);
+ }
+}
diff --git a/src/main/java/LadderPrinter.java b/src/main/java/LadderPrinter.java
new file mode 100644
index 0000000..63adb15
--- /dev/null
+++ b/src/main/java/LadderPrinter.java
@@ -0,0 +1,16 @@
+public class LadderPrinter {
+
+ // 정적메소드 적용
+ public static void print(Ladder ladder, Player player) {
+ for (int i = 0; i < ladder.getHeight(); i++) {
+ for (int j = 0; j < ladder.getWidth(); j++) {
+ System.out.print(ladder.getRows(i, j));
+ if (player.getxPosition() == j && player.getyPosition() == i) {
+ System.out.print("*");
+ }
+ System.out.print(" ");
+ }
+ System.out.println();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/LadderRunner.java b/src/main/java/LadderRunner.java
new file mode 100644
index 0000000..b5e23df
--- /dev/null
+++ b/src/main/java/LadderRunner.java
@@ -0,0 +1,54 @@
+public class LadderRunner {
+
+ private final Ladder ladder;
+ private Player player;
+
+ public LadderRunner(Ladder ladder, int startPosition) {
+ this.ladder = ladder;
+ this.player = new Player(startPosition);
+ }
+
+ int run() {
+ while (true) {
+ printLadderState("Before");
+
+ // 오른쪽으로 가기
+ if (ladder.isLeftLine(player.getyPosition(), player.getxPosition())) {
+ player.right();
+ printLadderState("After");
+ player.down();
+ }
+ // 왼쪽으로 가기
+ else if (ladder.isRightLine(player.getyPosition(), player.getxPosition())) {
+ player.left();
+ printLadderState("After");
+ player.down();
+ }
+ // 그냥 아래로 가기
+ else {
+ player.down();
+ if (isGameOver()) {
+ printLadderState("Final");
+ break;
+ }
+ printLadderState("After");
+ }
+
+ if (isGameOver()) {
+ printLadderState("Final");
+ break;
+ }
+ }
+ return player.getxPosition();
+ }
+
+ private boolean isGameOver() {
+ return player.getyPosition() == ladder.getHeight() - 1;
+ }
+
+ private void printLadderState(String state) {
+ System.out.println(state);
+ LadderPrinter.print(ladder, player);
+ }
+}
+
diff --git a/src/main/java/Line.java b/src/main/java/Line.java
new file mode 100644
index 0000000..588e942
--- /dev/null
+++ b/src/main/java/Line.java
@@ -0,0 +1,57 @@
+public class Line {
+ private int fromLine;
+ private int toLine;
+ private int t;
+ private int[][] rows;
+
+ public Line(int fromLine, int toLine, int currentRow, int[][] rows) {
+ sort(fromLine, toLine);
+ this.rows = rows;
+
+ if (validateFromLine(rows) && currentRow >= 0 && validateCurrentRow(currentRow, rows)) {
+ this.rows[currentRow][this.fromLine] = 1;
+ }
+ if (validateToLine(rows) && currentRow >= 0 && validateCurrentRow(currentRow, rows)) {
+ this.rows[currentRow][this.toLine] = - 1;
+ }
+ }
+
+ private static boolean validateCurrentRow(int currentRow, int[][] rows) {
+ if(currentRow < rows.length){
+ return true;
+ }
+ else{
+ throw new IllegalArgumentException(ExceptionMessage.INVALID_LINE_POSITION.getMessage());
+ }
+ }
+
+ private boolean validateToLine(int[][] rows) {
+ if(this.toLine >= 0 && this.toLine <= rows[0].length){
+ return true;
+ }
+ else{
+ throw new IllegalArgumentException(ExceptionMessage.INVALID_LINE_POSITION.getMessage());
+ }
+ }
+
+ private boolean validateFromLine(int[][] rows) {
+ if(this.fromLine >= 0 && this.fromLine <= rows[0].length){
+ return true;
+ }
+ else{
+ throw new IllegalArgumentException(ExceptionMessage.INVALID_LINE_POSITION.getMessage());
+ }
+ }
+
+ public void sort(int x, int y) {
+ this.fromLine = x;
+ this.toLine = y;
+
+ if (this.fromLine > this.toLine) {
+ this.t = y;
+ this.toLine = x;
+ this.fromLine = t;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/Player.java b/src/main/java/Player.java
new file mode 100644
index 0000000..2880539
--- /dev/null
+++ b/src/main/java/Player.java
@@ -0,0 +1,41 @@
+public class Player {
+ private int xPosition;
+ private int yPosition;
+
+ public Player(int startPosition) {
+ // 사다리는 0부터 시작하기 때문에
+ this.xPosition = startPosition-1;
+ this.yPosition = 0;
+ validatePosition();
+ }
+
+ private void validatePosition(){
+ if(this.xPosition<0){
+ throw new IllegalArgumentException(ExceptionMessage.INVALID_START_POSITION.getMessage());
+ }
+ }
+
+ public void right(){
+ this.xPosition += 1;
+ }
+
+ public void left(){
+ this.xPosition -= 1;
+ }
+
+ public void down(){
+ this.yPosition += 1;
+ }
+
+ public int getStartPosition() {
+ return xPosition;
+ }
+
+ public int getxPosition(){
+ return xPosition;
+ }
+
+ public int getyPosition(){
+ return yPosition;
+ }
+}
diff --git a/src/main/java/RandomLadderCreator.java b/src/main/java/RandomLadderCreator.java
new file mode 100644
index 0000000..0632982
--- /dev/null
+++ b/src/main/java/RandomLadderCreator.java
@@ -0,0 +1,46 @@
+import java.util.Random;
+
+public class RandomLadderCreator implements LadderCreator {
+ private Random random = new Random();
+
+ @Override
+ public Ladder createLine(int rows, int columns) {
+ Ladder ladder = new Ladder(rows, columns);
+ int totalLines = (int) (rows * (columns - 1) * 0.3);
+ int createdLines = 0;
+
+ while (createdLines < totalLines) {
+ int row = random.nextInt(rows);
+ int col = random.nextInt(columns - 1);
+
+ if (canAddLine(ladder, row, col)) {
+ ladder.addLine(col, col + 1, row);
+ createdLines++;
+ }
+ }
+
+ return ladder;
+ }
+
+ boolean canAddLine(Ladder ladder, int row, int col) {
+ // 현재 선택된 위치에 이미 가로선이 있는지 확인
+ if (ladder.isLine(row, col)) {
+ return false;
+ }
+ // 현재 위치의 왼쪽에 가로선이 있는지를 확인
+ if (col > 0 && ladder.isLineAtLeft(row, col)) {
+ return false;
+ }
+ // 현재 위치의 오른쪽에 가로선이 있는지를 확인
+ if (col < ladder.getWidth() - 1 && ladder.isLineAtRight(row, col)) {
+ return false;
+ }
+ // 마지막 열에는 선이 생성되지 않습니다
+ if (row >= ladder.getHeight() - 1){
+ return false;
+ }
+ return true;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/test/java/LadderRunnerTest.java b/src/test/java/LadderRunnerTest.java
new file mode 100644
index 0000000..cefdb7e
--- /dev/null
+++ b/src/test/java/LadderRunnerTest.java
@@ -0,0 +1,57 @@
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+class LadderRunnerTest {
+
+ @Test
+ @DisplayName("오른쪽 이동")
+ void testMoveRight() {
+
+ // Given
+ Ladder ladder = new Ladder(5, 3);
+ ladder.addLine(0, 1, 0);
+ ladder.addLine(1, 2, 1);
+
+ // When
+ LadderRunner runner = new LadderRunner(ladder, 1);
+ int finalPosition = runner.run()+1;
+
+ //Then
+ Assertions.assertEquals(3, finalPosition);
+ }
+
+ @Test
+ @DisplayName("왼쪽 이동")
+ void testMoveLeft() {
+ // Given
+ Ladder ladder = new Ladder(5, 3);
+ ladder.addLine(1, 2, 0);
+ ladder.addLine(0, 1, 1);
+ LadderRunner runner = new LadderRunner(ladder, 3);
+
+ // When
+ int finalPosition = runner.run()+1;
+
+ // Then
+ Assertions.assertEquals(1, finalPosition);
+ }
+
+ @Test
+ @DisplayName("사다리가 연달아 있는 경우")
+ void testMoveBetween() {
+ // Given
+ Ladder ladder = new Ladder(5, 4);
+ ladder.addLine(0, 1, 1);
+ ladder.addLine(2, 3, 1);
+ LadderRunner runner = new LadderRunner(ladder, 3);
+
+ // When
+ int finalPosition = runner.run() + 1;
+
+ // Then
+ Assertions.assertEquals(4, finalPosition);
+ }
+
+
+}
\ No newline at end of file
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/RandomLadderCreatorTest.java b/src/test/java/RandomLadderCreatorTest.java
new file mode 100644
index 0000000..4fe3c2f
--- /dev/null
+++ b/src/test/java/RandomLadderCreatorTest.java
@@ -0,0 +1,98 @@
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public class RandomLadderCreatorTest {
+
+ @Test
+ @DisplayName("사다리의 크기가 올바르게 생성되는지 확인")
+ void testCreateLineWithCorrectSize() {
+ RandomLadderCreator creator = new RandomLadderCreator();
+ Ladder ladder = creator.createLine(5, 3);
+
+ Assertions.assertEquals(5, ladder.getHeight());
+ Assertions.assertEquals(3, ladder.getWidth());
+ }
+
+ @Test
+ @DisplayName("라인이 위치에 추가되는지 확인")
+ void testCanAddLineAtValidPosition() {
+
+ // Given
+ RandomLadderCreator creator = new RandomLadderCreator();
+ Ladder ladder = new Ladder(5, 3);
+
+ // When
+ boolean canAddLineAt00 = creator.canAddLine(ladder, 0, 0);
+ boolean canAddLineAt21 = creator.canAddLine(ladder, 2, 1);
+
+ // Then
+ Assertions.assertTrue(canAddLineAt00);
+ Assertions.assertTrue(canAddLineAt21);
+
+ }
+
+ @Test
+ @DisplayName("이미 라인이 있는 위치에는 라인을 추가할 수 없는지 확인")
+ void testCannotAddLineAtOccupiedPosition() {
+
+ // Given
+ RandomLadderCreator creator = new RandomLadderCreator();
+ Ladder ladder = new Ladder(5, 3);
+ ladder.addLine(0, 1, 0);
+
+ // When
+ boolean canAddLineAt00 = creator.canAddLine(ladder, 0, 0);
+
+ // Then
+ Assertions.assertFalse(canAddLineAt00);
+ }
+
+ @Test
+ @DisplayName("마지막 행에는 라인을 추가할 수 없는지 확인")
+ void testCannotAddLineAtLastRow() {
+
+ // Given
+ RandomLadderCreator creator = new RandomLadderCreator();
+ Ladder ladder = new Ladder(5, 3);
+
+ // When
+ boolean canAddLineAt41 = creator.canAddLine(ladder, 4, 1);
+
+ // Then
+ Assertions.assertFalse(canAddLineAt41);
+ }
+
+ @Test
+ @DisplayName("이미 오른쪽에 라인이 있는 위치에는 라인을 추가할 수 없는지 확인")
+ void testCannotAddLineAtAlreadyRight() {
+
+ //Given
+ RandomLadderCreator creator = new RandomLadderCreator();
+ Ladder ladder = new Ladder(5, 3);
+ ladder.addLine(1, 2, 0);
+
+ // When
+ boolean canAddLineAt00 = creator.canAddLine(ladder, 0, 0);
+
+ // Then
+ Assertions.assertFalse(canAddLineAt00);
+ }
+
+ @Test
+ @DisplayName("이미 왼쪽에 라인이 있는 위치에는 라인을 추가할 수 없는지 확인")
+ void testCannotAddLineAtAlreadyLeft() {
+
+ //Given
+ RandomLadderCreator creator = new RandomLadderCreator();
+ Ladder ladder = new Ladder(5, 3);
+ ladder.addLine(0, 1, 0);
+
+ // When
+ boolean canAddLineAt00 = creator.canAddLine(ladder, 0, 1);
+
+ // Then
+ Assertions.assertFalse(canAddLineAt00);
+ }
+
+}
\ No newline at end of file