diff --git a/src/main/java/ladder/Direction.java b/src/main/java/ladder/Direction.java new file mode 100644 index 0000000..900d997 --- /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..2ac4101 --- /dev/null +++ b/src/main/java/ladder/ExceptionMessage.java @@ -0,0 +1,20 @@ +package ladder; + +public enum ExceptionMessage { + + INVALID_NUMBER_OF_PERSON("게임의 참여자 수는 1명 이상이어야 합니다."), + INVALID_LINE_POSITION("라인 생성이 불가능한 위치입니다."), + INVALID_POSITION("유효하지 않은 위치입니다."), + INVALID_NATURAL_NUMBER("유효하지 않은 자연수입니다."); + + private final String message; + + ExceptionMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/ladder/Ladder.java b/src/main/java/ladder/Ladder.java deleted file mode 100644 index 503ae00..0000000 --- a/src/main/java/ladder/Ladder.java +++ /dev/null @@ -1,27 +0,0 @@ -package ladder; - -public class Ladder { - - private Row[] rows; - - public Ladder(int numberOfRows, int numberOfPerson) { - rows = new Row[numberOfPerson]; - - for(int i = 0; i < numberOfRows; 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/LadderCreator.java b/src/main/java/ladder/LadderCreator.java new file mode 100644 index 0000000..5cb2fab --- /dev/null +++ b/src/main/java/ladder/LadderCreator.java @@ -0,0 +1,21 @@ +package ladder; + +public class LadderCreator { + private Row[] rows; + + public LadderCreator(NaturalNumber numberOfRows, NaturalNumber numberOfPerson) { + rows = new Row[numberOfPerson.getValue()]; + + for (int i = 0; i < numberOfRows.getValue(); i++) { + rows[i] = new Row(numberOfPerson); + } + } + + public void drawLine(int row, int col) { + rows[row].drawLine(Position.of(col)); + } + + public Row[] getRows() { + return rows; + } +} diff --git a/src/main/java/ladder/LadderGame.java b/src/main/java/ladder/LadderGame.java new file mode 100644 index 0000000..17d65c5 --- /dev/null +++ b/src/main/java/ladder/LadderGame.java @@ -0,0 +1,14 @@ +package ladder; + +public class LadderGame { + private final LadderCreator ladderCreator; + + public LadderGame(LadderCreator ladderCreator){ + this.ladderCreator = ladderCreator; + } + + public Position run(Position position){ + LadderRunner ladderRunner =new LadderRunner(ladderCreator.getRows()); + return ladderRunner.run((position)); + } +} diff --git a/src/main/java/ladder/LadderRunner.java b/src/main/java/ladder/LadderRunner.java new file mode 100644 index 0000000..f971e76 --- /dev/null +++ b/src/main/java/ladder/LadderRunner.java @@ -0,0 +1,17 @@ +package ladder; + +public class LadderRunner { + private Row[] rows; + + public LadderRunner(Row[] rows) { + this.rows = rows; + } + + public Position run(Position position) { + + for (int i = 0; i < rows.length; i++) { + position = rows[i].nextPosition(position); + } + return position; + } +} diff --git a/src/main/java/ladder/NaturalNumber.java b/src/main/java/ladder/NaturalNumber.java new file mode 100644 index 0000000..b424f7e --- /dev/null +++ b/src/main/java/ladder/NaturalNumber.java @@ -0,0 +1,33 @@ +package ladder; + +public class NaturalNumber { + + private final int value; + + private NaturalNumber(int value) { + validate(value); + this.value = value; + } + + + public static NaturalNumber of(int value){ + return new NaturalNumber(value); + } + + public int getValue() { + return value; + } + + private void validate(int value){ + if(!isNaturalNumber(value)){ + throw new IllegalArgumentException(ExceptionMessage.INVALID_NATURAL_NUMBER.getMessage()); + } + } + + private static boolean isNaturalNumber(int value){ + return value >=1; + } +} + + + diff --git a/src/main/java/ladder/Node.java b/src/main/java/ladder/Node.java new file mode 100644 index 0000000..99267a4 --- /dev/null +++ b/src/main/java/ladder/Node.java @@ -0,0 +1,33 @@ +package ladder; + +public class Node { + + private Direction direction; + + private Node(Direction direction){ + this.direction = direction; + } + + public static Node of(Direction direction){ + return new Node(direction); + } + + public Position move(Position position){ + if(isRight()){ + return position.next(); + } + else if(isLeft()){ + return position.prev(); + } + return position; + } + + public boolean isRight(){ + return direction == Direction.RIGHT; + } + public boolean isLeft(){ + return direction == Direction.LEFT; + } + + +} diff --git a/src/main/java/ladder/Position.java b/src/main/java/ladder/Position.java new file mode 100644 index 0000000..4873d8f --- /dev/null +++ b/src/main/java/ladder/Position.java @@ -0,0 +1,37 @@ +package ladder; + +public class Position { + private int position; + + private Position(int position) { + this.position = position; + } + + public static Position of(int position) { + validatePosition(position); + return new Position(position); + } + + public int getValue() { + return position; + } + + public Position prev() { + return Position.of(position - 1); + } + + public Position next() { + return Position.of(position + 1); + } + + // 유효성 검증 + private static void validatePosition(int position) { + if (!isPosition(position)) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_POSITION.getMessage()); + } + } + + private static boolean isPosition(int position) { + return position >= 0; + } +} diff --git a/src/main/java/ladder/Row.java b/src/main/java/ladder/Row.java index 722a9a6..8a82e72 100644 --- a/src/main/java/ladder/Row.java +++ b/src/main/java/ladder/Row.java @@ -1,56 +1,51 @@ package ladder; +import static ladder.ExceptionMessage.*; + public class Row { - private int[] row; + private Node[] nodes; - public Row(int numberOfPerson) { - validateNumberOfPerson(numberOfPerson); - row = new int[numberOfPerson]; - } + public static final int MINIMUM_NUMBER_OF_PERSON = 1; + public static final int MAXIMUM_INVALID_POSITION_NUMBER = 0; - public void drawLine(int lineStartPosition) { - validateDrawLinePosition(lineStartPosition); - row[lineStartPosition] = 1; - row[lineStartPosition + 1] = -1; + public Row(NaturalNumber numberOfPerson) { + validateNumberOfPerson(numberOfPerson.getValue()); + nodes = new Node[numberOfPerson.getValue()]; } - public int nextPosition(int position) { - - validatePosition(position); - - if (isLeft(position)) { - return position - 1; - } - if (isRight(position)) { - return position + 1; - } - - return position; + // 사다리 행에 가로선을 그리는 역할 + public void drawLine(Position lineStartPosition) { + validateDrawLinePosition(lineStartPosition); + nodes[lineStartPosition.getValue()] = Node.of(Direction.RIGHT); + nodes[lineStartPosition.getValue() + 1] = Node.of(Direction.LEFT); } - private boolean isLeft(int position) { - return row[position] == -1; - } + //현재위치 position에서 다음 위치를 계산해서 변환 + public Position nextPosition(Position currentPosition) { - private boolean isRight(int position) { - return row[position] == 1; + validatePosition(currentPosition); + Position nextPosition = nodes[currentPosition.getValue()].move(currentPosition); + return nextPosition; } private void validateNumberOfPerson(int numberOfPerson) { - if(numberOfPerson < 1) { - throw new IllegalArgumentException("게임의 참여자 수는 1명 이상이어야 합니다."); + if(numberOfPerson < MINIMUM_NUMBER_OF_PERSON) { + throw new IllegalArgumentException(INVALID_NUMBER_OF_PERSON.getMessage()); } } - private void validateDrawLinePosition(int lineStartPosition) { - if(lineStartPosition < 0 || lineStartPosition >= row.length - 1 || row[lineStartPosition] == -1 || row[lineStartPosition + 1] == 1) { - throw new IllegalArgumentException("라인 생성이 불가능한 위치 입니다."); + private void validateDrawLinePosition(Position lineStartPosition) { + if(lineStartPosition.getValue() < MAXIMUM_INVALID_POSITION_NUMBER || + lineStartPosition.getValue() >= nodes.length - 1 || + nodes[lineStartPosition.getValue()].isLeft() || + nodes[lineStartPosition.getValue() + 1].isRight() ) { + throw new IllegalArgumentException(INVALID_LINE_POSITION.getMessage()); } } - private void validatePosition(int position) { - if(position >= row.length || position < 0 ) { - throw new IllegalArgumentException("유효하지 않은 위치 입니다."); + private void validatePosition(Position position) { + if(position.getValue() >= nodes.length || position.getValue() < MAXIMUM_INVALID_POSITION_NUMBER ) { + throw new IllegalArgumentException(INVALID_POSITION.getMessage()); } } diff --git a/src/test/java/ladder/LadderTest.java b/src/test/java/ladder/LadderTest.java index db63615..aaf2da6 100644 --- a/src/test/java/ladder/LadderTest.java +++ b/src/test/java/ladder/LadderTest.java @@ -3,17 +3,17 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; - +import ladder.NaturalNumber; class LadderTest { @Test void 사다리_생성_확인() { //given - int numberOfRows = 3; - int numberOfPerson = 5; + NaturalNumber numberOfRows = NaturalNumber.of(3); + NaturalNumber numberOfPerson = NaturalNumber.of(5) ; //when - Ladder ladder = new Ladder(numberOfRows, numberOfPerson); + LadderCreator ladder = new LadderCreator(numberOfRows, numberOfPerson); //then assertNotNull(ladder); @@ -22,48 +22,50 @@ class LadderTest { @Test void 사다리_시작위치_예외_처리() { //given - int numberOfPerson = 3; - int numberOfRows = 1; - Ladder ladder = new Ladder(numberOfRows, numberOfPerson); + NaturalNumber numberOfPerson = NaturalNumber.of(3); + NaturalNumber numberOfRows = NaturalNumber.of(1); + LadderCreator ladder = new LadderCreator(numberOfRows, numberOfPerson); //when - int position = 3; + Position position = Position.of(3); //then - assertThrows(IllegalArgumentException.class, () -> ladder.run(3)); + assertThrows(IllegalArgumentException.class, () -> ladder.run(Position.of(3))); } @Test void 사다리_결과_확인() { //given - int numberOfPerson = 4; - int numberOfRows = 4; - Ladder ladder = new Ladder(numberOfRows, numberOfPerson); + NaturalNumber numberOfPerson = NaturalNumber.of(4); + NaturalNumber numberOfRows =NaturalNumber.of(4) ; + LadderCreator ladder = new LadderCreator(numberOfRows, numberOfPerson); ladder.drawLine(1,0); ladder.drawLine(1,2); ladder.drawLine(2,1); //when - int position = 0; - int resultPosition = ladder.run(position); + Position position = Position.of(0); + LadderRunner ladderRunner = new LadderRunner(ladder.getRows()); + Position resultPosition = ladderRunner.run(position); + //then assertEquals(2, resultPosition); //when - position = 1; + position = Position.of(1); resultPosition = ladder.run(position); //then assertEquals(0, resultPosition); //when - position = 2; + position = Position.of(2); resultPosition = ladder.run(position); //then assertEquals(3, resultPosition); //when - position = 3; + position = Position.of(3); resultPosition = ladder.run(position); //then assertEquals(1, resultPosition); diff --git a/src/test/java/ladder/RowTest.java b/src/test/java/ladder/RowTest.java index c5eeed9..64ba48e 100644 --- a/src/test/java/ladder/RowTest.java +++ b/src/test/java/ladder/RowTest.java @@ -9,32 +9,32 @@ class RowTest { @Test void 참여자_한_명_사다리_이동() { //given - int numberOfPerson = 1; + NaturalNumber numberOfPerson = NaturalNumber.of(1); Row row = new Row(numberOfPerson); //when - int position = 0; + Position position = Position.of(0) ; //then - assertEquals(0,row.nextPosition(position)); + assertEquals(0, row.nextPosition(position)); } @Test void 참여자_두_명_사다리_열간_이동() { //given - int numberOfPerson = 2; + NaturalNumber numberOfPerson = NaturalNumber.of(2); Row row = new Row(numberOfPerson); - row.drawLine(0); + row.drawLine(Position.of(0)); //when - int position = 0; - int resultPosition = row.nextPosition(position); + Position position = Position.of(0); + Position resultPosition = row.nextPosition(position); //then - assertEquals(1,resultPosition); + assertEquals(1, resultPosition); //when - position = 1; + position = Position.of(1); resultPosition = row.nextPosition(position); //then assertEquals(0, resultPosition); @@ -43,25 +43,25 @@ class RowTest { @Test void 참여자_세_명_사다리_열간_이동() { //given - int numberOfPerson = 3; + NaturalNumber numberOfPerson = NaturalNumber.of(3); Row row = new Row(numberOfPerson); - row.drawLine(0); + row.drawLine(Position.of(0)); //when - int position = 0; - int resultPosition = row.nextPosition(position); + Position position = Position.of(0); + Position resultPosition = row.nextPosition(position); //then - assertEquals(1,resultPosition); + assertEquals(1, resultPosition); //when - position = 1; + position = Position.of(1); resultPosition = row.nextPosition(position); //then assertEquals(0, resultPosition); //when - position = 2; + position = Position.of(2); resultPosition = row.nextPosition(position); //then assertEquals(2, resultPosition); @@ -69,17 +69,17 @@ class RowTest { @Test void 사다리_사람수_예외_처리() { - assertThrows(IllegalArgumentException.class, () -> new Row(0)); + assertThrows(IllegalArgumentException.class, () -> new Row(NaturalNumber.of(0))); } @Test void 사다리_위치_최대값_초과_예외_처리() { //given - int numberOfPerson = 3; + NaturalNumber numberOfPerson = NaturalNumber.of(3); Row row = new Row(numberOfPerson); //when - int position = 3; + Position position = Position.of(3); //then assertThrows(IllegalArgumentException.class, () -> row.nextPosition(position)); @@ -88,11 +88,11 @@ class RowTest { @Test void 사다리_위치_최소값_미만_예외_처리() { //given - int numberOfPerson = 3; + NaturalNumber numberOfPerson = NaturalNumber.of(3); Row row = new Row(numberOfPerson); //when - int position = -1; + Position position = Position.of(-1); //then assertThrows(IllegalArgumentException.class, () -> row.nextPosition(position)); @@ -101,11 +101,11 @@ class RowTest { @Test void 사다리_라인_그리기_위치_초과_예외() { //given - int numberOfPerson = 3; + NaturalNumber numberOfPerson = NaturalNumber.of(3); Row row = new Row(numberOfPerson); //when - int lineStartPosition = 2; + Position lineStartPosition = Position.of(2); //then assertThrows(IllegalArgumentException.class, () -> row.drawLine(lineStartPosition)); @@ -114,11 +114,11 @@ class RowTest { @Test void 사다리_라인_그리기_위치_미만_예외() { //given - int numberOfPerson = 3; + NaturalNumber numberOfPerson = NaturalNumber.of(3); Row row = new Row(numberOfPerson); //when - int lineStartPosition = -1; + Position lineStartPosition = Position.of(-1); //then assertThrows(IllegalArgumentException.class, () -> row.drawLine(lineStartPosition)); @@ -127,12 +127,12 @@ class RowTest { @Test void 라인_그리기_좌측_라인_중복_예외() { //given - int numberOfPerson = 3; + NaturalNumber numberOfPerson = NaturalNumber.of(3); Row row = new Row(numberOfPerson); - row.drawLine(0); + row.drawLine(Position.of(0)); //when - int lineStartPosition = 1; + Position lineStartPosition = Position.of(1); //then assertThrows(IllegalArgumentException.class, () -> row.drawLine(lineStartPosition)); @@ -142,12 +142,12 @@ class RowTest { @Test void 라인_그리기_우측_라인_중복_예외() { //given - int numberOfPerson = 3; + NaturalNumber numberOfPerson = NaturalNumber.of(3); Row row = new Row(numberOfPerson); - row.drawLine(1); + row.drawLine(Position.of(1)); //when - int lineStartPosition = 0; + Position lineStartPosition = Position.of(0); //then assertThrows(IllegalArgumentException.class, () -> row.drawLine(lineStartPosition));