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/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.java b/src/main/java/Ladder.java index 0d2b070..3975cac 100644 --- a/src/main/java/Ladder.java +++ b/src/main/java/Ladder.java @@ -1,8 +1,116 @@ public class Ladder { + // Ladder + private final Matrix matrix; // should get Matrix's row and numberOfPerson + // private LadderLine LadderLine = new LadderLine(); - private final int[][] rows; + public Ladder(Matrix matrix) { + // 사다리 생성하고 크기 지정해야 함 + this.matrix = new Matrix(matrix.getRow(),matrix.getNumberOfPerson()); + } + + public static Ladder createLadder(NaturalNum row, NaturalNum numberOfPerson) { + Ladder ladder = new Ladder(new Matrix(row, numberOfPerson)); + return new Ladder(new Matrix(row, numberOfPerson)); + } + + // Line is always drawn from left to right. (1을 먼저 대입하고 오른쪽에 -1 대입, 1 : 오른쪽이동 / -1 : 왼쪽이동) + // 연속된 라인은 허용하지 않는다 + + public void drawLine(LadderLine ladderLine) { // make LadderLine of ladder + // checkList + // If coordinate out of range(row / col(numberOfPerson) + // If that point is last col Line (only can draw to right) + // If that point has been drawn + + int direction = 1; + // 이미 -1되이, 2차원 배열의 좌표 단위에 맞춰짐 (0부터 시작) + int x = ladderLine.getX(); + int y = ladderLine.getY(); + + if (! checkCoordinateRange(x,y)) { // if coordinate out of range + throw new IllegalArgumentException("Out of coordinate range"); + } + + if (! checkColRange(x)) { // if that point is last col Line + throw new IllegalArgumentException("At the end of X coordinate can't draw to right"); + } + + if (! checkDrawn(x,y)) { // If that point has been drawn + throw new IllegalArgumentException("Point (x,y) has already been drawn"); + } + + // drawingLine + matrix.setDirection(x,y, direction); + matrix.printLadder(); + + } + + // implement a movement along the line + public int run(NaturalNum line) { // choose num of ladder then can know where line to arrive + // check x coordinate is out of range + + if (!checkCoordinateRange(line.getNaturalNum())) + throw new IllegalArgumentException("Out of starter line range"); + + return matrix.runLadder(line); + } + + // ----------------------------------------------------------------------------------------------------- + public int getRowsLength() { + return matrix.getRowsLength(); + } - public Ladder(int row, int numberOfPerson) { - rows = new int[row][numberOfPerson]; + public int getIntRow() { + return matrix.getIntRow(); } + + public int getIntNumberOfPerson() { + return matrix.getIntNumberOfPerson(); + } + + public boolean checkCoordinateRange(int x, int y) { + if ((y > matrix.getIntRow()-1) && (x > matrix.getIntNumberOfPerson()-1)) + return false; + + return true; + } + + public boolean checkColRange(int x) { + if (x > matrix.getIntNumberOfPerson() - 2) + return false; + + return true; + } + + public boolean checkDrawn(int x, int y) { + if (matrix.returnMatrixValue(x,y) == 1 || matrix.returnMatrixValue(x,y) == -1) { + return false; + } + return true; + } + +// public int getMatrixValue(int x, int y) { +// return matrix.returnMatrixValue(x,y); +// } + + + // run메소드 starter line 검사 + public boolean checkCoordinateRange(int x) { + if ((x > matrix.getIntNumberOfPerson()-1)) + return false; + + return true; + } + } + +// 객체지향 생활 체조 원칙 9단계 +// 1. 메소드 하나에는 하나의 들여쓰기만 +// 2. else 지양 (if문 안에서 early return) +// 3. 원시값과 문자열을 wrapper 객체로 +// 4. method 체이닝 X +// 5. 축약X +// 6. Entity 적게 유지 (짧게하기) +// 7. 인스턴스는 1개만 +// 8. 일급 컬렉션 +// 9. getter / setter / property를 쓰지 않는다 \ No newline at end of file diff --git a/src/main/java/LadderLine.java b/src/main/java/LadderLine.java new file mode 100644 index 0000000..8cb6af1 --- /dev/null +++ b/src/main/java/LadderLine.java @@ -0,0 +1,30 @@ +// Used when we drawLine, to control coordinate +// 일단 만들어야 할 거같아서 만듦 + +// Q : 좌표를 받아서 범위 유효성 검사를 이 클래스에서 진행하면 좋을 것 같은데 Ladder클래스의 멤버에 접근을... +public class LadderLine { + private int x, y; + + private LadderLine(NaturalNum x) { + this.x = x.getNaturalNum() - 1; + } + + private LadderLine(NaturalNum x, NaturalNum y) { + this.x = x.getNaturalNum() - 1; + this.y = y.getNaturalNum() - 1; + // x, y의 유효성 검사를 이 클래스에서 해야 할 거 같은데 row와 numberofPerson에 접근을 못해서 여기에 만듦 + + } + + public static LadderLine from(NaturalNum x,NaturalNum y) { + return new LadderLine(x,y); + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } +} diff --git a/src/main/java/Matrix.java b/src/main/java/Matrix.java new file mode 100644 index 0000000..dd9a5ef --- /dev/null +++ b/src/main/java/Matrix.java @@ -0,0 +1,104 @@ +import java.io.IOException; + +public class Matrix { + private final int[][] rows; + private final NaturalNum row, numberOfPerson; // y, x + + // make ladder (row : height of ladder, col : numberOfPerson) (while checking parameter being naturalNum) + public Matrix(NaturalNum row, NaturalNum numberOfPerson) { + this.row = row; + this.numberOfPerson = numberOfPerson; + rows = new int[row.getNaturalNum()][numberOfPerson.getNaturalNum()]; + } + + public NaturalNum getRow() { + return row; + } + + public NaturalNum getNumberOfPerson() { + return numberOfPerson; + } + + public int getRowsLength() { + return rows.length * rows[0].length; + } + + public int getIntRow() { + return row.getNaturalNum(); + } + + public int getIntNumberOfPerson() { + return numberOfPerson.getNaturalNum(); + } + + public void setDirection(int x, int y, int direction) { + rows[y][x] = direction; + rows[y][x + 1] = -direction; + } + + public int returnMatrixValue(int x, int y) { + return rows[y][x]; // 이미 -1 되었음 + } + + public int runLadder(NaturalNum x) { + int starter = x.getNaturalNum() - 1; + int currentRow = 0; + int finalLine = 0; + + + while (currentRow < row.getNaturalNum()) { // 높이 만큼 반복 + // 양쪽 끝일 때는? + switch (rows[currentRow][starter]) { + case 0: + currentRow = moveDown(currentRow); // move to down + break; + + case 1: // 일단 오른쪽으로 가면 다음은 무조건 내려가야 함 + starter = moveRight(starter); + currentRow = moveDown(currentRow); + break; + + case -1: // 일단 왼쪽으로 가면 다음은 무조건 내려가야 함 + starter = moveLeft(starter); + currentRow = moveDown(currentRow); + break; + + default: + throw new IllegalArgumentException("There is unacceptable value in ladder"); + } + } + + finalLine = starter + 1; + return finalLine; // 1부터 시작하므로 + } + + public int moveDown(int currentRow) { + return ++currentRow; + } + + public int moveRight(int starter) { + if (starter >= numberOfPerson.getNaturalNum()-1) { + return starter; + } + return ++starter; + } + + public int moveLeft(int starter) { + if (starter <= 0) { + return starter; + } + return --starter; + } + + public void printLadder() { + for(int i = 0; i < row.getNaturalNum(); i++) { + for (int j = 0; j < numberOfPerson.getNaturalNum(); j++) { + System.out.print(rows[i][j] + " "); + } + System.out.println(); + } + System.out.println("-".repeat(10)); + } + + +} diff --git a/src/main/java/NaturalNum.java b/src/main/java/NaturalNum.java new file mode 100644 index 0000000..e002590 --- /dev/null +++ b/src/main/java/NaturalNum.java @@ -0,0 +1,33 @@ +public class NaturalNum { + private int naturalNum; + + // static 메소드로 객체 생성하기 때문에, 생성자는 private으로 변경하였음 + // Factory method와 private 생성자 (by study) + private NaturalNum() { + } + + private NaturalNum(int naturalNum) { + + if(checkNaturalNum(naturalNum)) { + this.naturalNum = naturalNum; + } + + } + + // Without making instance, can get naturalNum from int parameter + public static NaturalNum from(int i) { + return new NaturalNum(i); + } + + public int getNaturalNum() { + return naturalNum; + } + + public boolean checkNaturalNum(int naturalNum) { + if(naturalNum < 1) { + throw new IllegalArgumentException("Natural number must be positive"); + } + return true; + } + +} diff --git a/src/test/java/LadderTest.java b/src/test/java/LadderTest.java index 741a915..2c3d4f3 100644 --- a/src/test/java/LadderTest.java +++ b/src/test/java/LadderTest.java @@ -1,5 +1,45 @@ +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; +// All test should be done with Junit test code + +// check Ladder class work normally +// check method of run return right value in various situation. class LadderTest { + // 모든 테스트의 인수는 수학적 좌표 형식으로 주어야 함 ! + + @Test + @DisplayName("사다리 생성검사") + void createLadder() { + Ladder ladder = Ladder.createLadder(NaturalNum.from(3), NaturalNum.from(4)); + // compare size of ladder with row * numberOfPerson + assertThat(ladder.getRowsLength()).isEqualTo(ladder.getIntRow() * ladder.getIntNumberOfPerson()); + } + + // Test if drawingLine acts normally and especially check how drawingLine acts at the right end. + @Test + void testDrawLine() { + Ladder ladder = Ladder.createLadder(NaturalNum.from(3), NaturalNum.from(4)); + ladder.drawLine(LadderLine.from(NaturalNum.from(2), NaturalNum.from(2))); + ladder.drawLine(LadderLine.from(NaturalNum.from(3), NaturalNum.from(3))); +// assertThat(ladder.getMatrixValue(2,2)).isEqualTo(1); +// assertThat(ladder.getMatrixValue(3,2)).isEqualTo(-1); + } +// + // Test if it arrives right destination, when row is given + @Test + void testRunLadder() { + Ladder ladder = Ladder.createLadder(NaturalNum.from(3), NaturalNum.from(4)); + ladder.drawLine(LadderLine.from(NaturalNum.from(2), NaturalNum.from(2))); + ladder.drawLine(LadderLine.from(NaturalNum.from(3), NaturalNum.from(3))); + assertThat(ladder.run(NaturalNum.from(2))).isEqualTo(4); + // assertThat(ladder.run(NaturalNum.from(1))).isEqualTo(4); + } + + } \ No newline at end of file