diff --git a/build.gradle b/build.gradle index 3697236c6fb..ce846f70cc6 100644 --- a/build.gradle +++ b/build.gradle @@ -9,15 +9,15 @@ repositories { } dependencies { - testImplementation platform('org.junit:junit-bom:5.9.1') - testImplementation platform('org.assertj:assertj-bom:3.25.1') + testImplementation platform('org.junit:junit-bom:5.11.4') + testImplementation platform('org.assertj:assertj-bom:3.27.3') testImplementation('org.junit.jupiter:junit-jupiter') testImplementation('org.assertj:assertj-core') } java { toolchain { - languageVersion = JavaLanguageVersion.of(17) + languageVersion = JavaLanguageVersion.of(21) } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135c49b..e6441136f3d 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 80187ac3043..b82aa23a4f0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew.bat b/gradlew.bat index 6689b85beec..7101f8e4676 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 00000000000..cb1e2cbc1a9 --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,9 @@ +import chess.ChessGame; + +public class Application { + + public static void main(String[] args) { + ChessGame chessGame = new ChessGame(); + chessGame.run(); + } +} diff --git a/src/main/java/chess/Board.java b/src/main/java/chess/Board.java new file mode 100644 index 00000000000..648f839dd9f --- /dev/null +++ b/src/main/java/chess/Board.java @@ -0,0 +1,61 @@ +package chess; + +import chess.piece.Bishop; +import chess.piece.King; +import chess.piece.Knight; +import chess.piece.Pawn; +import chess.piece.Piece; +import chess.piece.Queen; +import chess.piece.Rook; +import java.util.List; + +public class Board { + + private final List pieces = List.of( + new King(Color.WHITE, new Position(Column.E, Row.ONE)), + new Queen(Color.WHITE, new Position(Column.D, Row.ONE)), + new Knight(Color.WHITE, new Position(Column.B, Row.ONE)), + new Knight(Color.WHITE, new Position(Column.G, Row.ONE)), + new Bishop(Color.WHITE, new Position(Column.C, Row.ONE)), + new Bishop(Color.WHITE, new Position(Column.F, Row.ONE)), + new Rook(Color.WHITE, new Position(Column.A, Row.ONE)), + new Rook(Color.WHITE, new Position(Column.H, Row.ONE)), + new Pawn(Color.WHITE, new Position(Column.A, Row.TWO)), + new Pawn(Color.WHITE, new Position(Column.B, Row.TWO)), + new Pawn(Color.WHITE, new Position(Column.C, Row.TWO)), + new Pawn(Color.WHITE, new Position(Column.D, Row.TWO)), + new Pawn(Color.WHITE, new Position(Column.E, Row.TWO)), + new Pawn(Color.WHITE, new Position(Column.F, Row.TWO)), + new Pawn(Color.WHITE, new Position(Column.G, Row.TWO)), + new Pawn(Color.WHITE, new Position(Column.H, Row.TWO)), + new King(Color.BLACK, new Position(Column.E, Row.EIGHT)), + new Queen(Color.BLACK, new Position(Column.D, Row.EIGHT)), + new Knight(Color.BLACK, new Position(Column.B, Row.EIGHT)), + new Knight(Color.BLACK, new Position(Column.G, Row.EIGHT)), + new Bishop(Color.BLACK, new Position(Column.C, Row.EIGHT)), + new Bishop(Color.BLACK, new Position(Column.F, Row.EIGHT)), + new Rook(Color.BLACK, new Position(Column.A, Row.EIGHT)), + new Rook(Color.BLACK, new Position(Column.H, Row.EIGHT)), + new Pawn(Color.BLACK, new Position(Column.A, Row.SEVEN)), + new Pawn(Color.BLACK, new Position(Column.B, Row.SEVEN)), + new Pawn(Color.BLACK, new Position(Column.C, Row.SEVEN)), + new Pawn(Color.BLACK, new Position(Column.D, Row.SEVEN)), + new Pawn(Color.BLACK, new Position(Column.E, Row.SEVEN)), + new Pawn(Color.BLACK, new Position(Column.F, Row.SEVEN)), + new Pawn(Color.BLACK, new Position(Column.G, Row.SEVEN)), + new Pawn(Color.BLACK, new Position(Column.H, Row.SEVEN)) + ); + + public boolean existPieceIn(Position position) { + return pieces.stream() + .anyMatch(piece -> piece.isSamePosition(position)); + } + + public Piece getPieceIn(Color nowColor, Position start) { + return pieces.stream() + .filter(piece -> piece.isSameTeam(nowColor)) + .filter(piece -> piece.isSamePosition(start)) + .findFirst() + .orElseThrow(IllegalArgumentException::new); + } +} diff --git a/src/main/java/chess/ChessGame.java b/src/main/java/chess/ChessGame.java new file mode 100644 index 00000000000..530e55e2aba --- /dev/null +++ b/src/main/java/chess/ChessGame.java @@ -0,0 +1,49 @@ +package chess; + +import chess.piece.Piece; +import java.util.Scanner; + +public class ChessGame { + + private final Board board = new Board(); + private final Scanner scanner = new Scanner(System.in); + + public void run() { + Color turn = Color.WHITE; + while (true) { + if (turn.isWhite()) { + System.out.print("WHITE "); + } + + if (turn.isBlack()) { + System.out.print("BLACK "); + } + System.out.println("Turn."); + + System.out.println("Select Piece Position And Destination Position (ex. A2 A4)"); + String moveXY = scanner.nextLine(); + + String[] split = moveXY.split(" "); + + Position start = new Position(Row.change(split[0].charAt(1)), Column.change(split[0].charAt(0))); + Position end = new Position(Row.change(split[1].charAt(1)), Column.change(split[1].charAt(0))); + + if (!board.existPieceIn(start)) { + throw new IllegalArgumentException("[ERROR] No Piece"); + } + + Piece piece = board.getPieceIn(turn, start); + piece.move(end); + + if (turn.isWhite()) { + System.out.print("WHITE "); + } + + if (turn.isBlack()) { + System.out.print("BLACK "); + } + System.out.printf("%s move: %s to %s%n", piece.name(), start, end); + turn = turn.opposite(); + } + } +} diff --git a/src/main/java/chess/Color.java b/src/main/java/chess/Color.java new file mode 100644 index 00000000000..55cd020b681 --- /dev/null +++ b/src/main/java/chess/Color.java @@ -0,0 +1,28 @@ +package chess; + +public enum Color { + + BLACK, + WHITE, + EMPTY; + + public boolean isWhite() { + return this == WHITE; + } + + public boolean isBlack() { + return this == BLACK; + } + + public boolean isEmpty() { + return this == EMPTY; + } + + public Color opposite() { + return switch (this) { + case BLACK -> WHITE; + case WHITE -> BLACK; + default -> EMPTY; + }; + } +} diff --git a/src/main/java/chess/Column.java b/src/main/java/chess/Column.java new file mode 100644 index 00000000000..4810c1b8b5f --- /dev/null +++ b/src/main/java/chess/Column.java @@ -0,0 +1,89 @@ +package chess; + +public enum Column { + + A, + B, + C, + D, + E, + F, + G, + H; + + public static Column change(char value) { + if (value == 'A') { + return A; + } + + if (value == 'B') { + return B; + } + + if (value == 'C') { + return C; + } + + if (value == 'D') { + return D; + } + + if (value == 'E') { + return E; + } + + if (value == 'F') { + return F; + } + + if (value == 'G') { + return G; + } + + if (value == 'H') { + return H; + } + + throw new IllegalArgumentException("[ERROR] 그런 열은 없어용"); + } + + public boolean isFarLeft() { + return ordinal() == 0; + } + + public boolean isFarRight() { + return ordinal() + 1 == values().length; + } + + public boolean canMoveLeft(final int step) { + return ordinal() - step >= 0; + } + + public Column moveLeft() { + return moveLeft(1); + } + + public Column moveLeft(final int step) { + if (canMoveLeft(step)) { + return values()[ordinal() - step]; + } + + throw new IllegalStateException("움직일 수 없는 위치입니다."); + } + + public boolean canMoveRight(final int step) { + return ordinal() + step < values().length; + } + + public Column moveRight() { + return moveRight(1); + } + + public Column moveRight(final int step) { + if (canMoveRight(step)) { + return values()[ordinal() + step]; + } + + throw new IllegalStateException("움직일 수 없는 위치입니다."); + } +} diff --git a/src/main/java/chess/Movement.java b/src/main/java/chess/Movement.java new file mode 100644 index 00000000000..e57c6e91bb9 --- /dev/null +++ b/src/main/java/chess/Movement.java @@ -0,0 +1,48 @@ +package chess; + +public enum Movement { + UP(0, 1), + UP_UP(UP.x * 2, UP.y * 2), + DOWN(0, -1), + DOWN_DOWN(DOWN.x * 2, DOWN.y * 2), + LEFT(-1, 0), + RIGHT(1, 0), + LEFT_UP(LEFT.x, UP.y), + RIGHT_UP(RIGHT.x, UP.y), + LEFT_DOWN(LEFT.x, DOWN.y), + RIGHT_DOWN(RIGHT.x, DOWN.y), + UP_UP_LEFT(LEFT_DOWN.x, UP_UP.y), + UP_UP_RIGHT(RIGHT_DOWN.x, UP_UP.y), + LEFT_LEFT_UP(LEFT.x * 2, UP.y), + LEFT_LEFT_DOWN(LEFT.x * 2, DOWN.y), + RIGHT_RIGHT_UP(RIGHT.x * 2, UP.y), + RIGHT_RIGHT_DOWN(RIGHT.x * 2, DOWN.y), + DOWN_DOWN_LEFT(LEFT_DOWN.x, DOWN_DOWN.y), + DOWN_DOWN_RIGHT(RIGHT_DOWN.x, DOWN_DOWN.y), + ; + + private final int x; + + private final int y; + + Movement(final int x, final int y) { + this.x = x; + this.y = y; + } + + public int x() { + return x; + } + + public int y() { + return y; + } + + public boolean isVertical() { + return x == 0 && y != 0; + } + + public boolean isDiagonal() { + return x != 0 && y != 0 && Math.abs(x) == Math.abs(y); + } +} diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/Position.java new file mode 100644 index 00000000000..3ebeb0ea185 --- /dev/null +++ b/src/main/java/chess/Position.java @@ -0,0 +1,170 @@ +package chess; + +public record Position( + Column column, + Row row +) { + public Position(final Row row, final Column column) { + this(column, row); + } + + public boolean canMoveUp() { + return row.canMoveUp(1); + } + + public boolean canMoveUp(final int step) { + return row.canMoveUp(step); + } + + public Position moveUp() { + return moveUp(1); + } + + public Position moveUp(final int step) { + return new Position(row.moveUp(step), column); + } + + public boolean canMoveDown() { + return canMoveDown(1); + } + + public boolean canMoveDown(final int step) { + return row.canMoveDown(step); + } + + public Position moveDown() { + return moveDown(1); + } + + public Position moveDown(final int step) { + return new Position(row.moveDown(step), column); + } + + public boolean canMoveLeft() { + return canMoveLeft(1); + } + + public boolean canMoveLeft(final int step) { + return column.canMoveLeft(step); + } + + public Position moveLeft() { + return moveLeft(1); + } + + public Position moveLeft(final int step) { + return new Position(row, column.moveLeft(step)); + } + + public boolean canMoveRight() { + return canMoveRight(1); + } + + public boolean canMoveRight(final int step) { + return column.canMoveRight(step); + } + + public Position moveRight() { + return moveRight(1); + } + + public Position moveRight(final int step) { + return new Position(row, column.moveRight(step)); + } + + public boolean canMoveLeftUp() { + return canMoveLeft() && canMoveUp(); + } + + public Position moveLeftUp() { + return moveLeft().moveUp(); + } + + public boolean canMoveLeftDown() { + return canMoveLeft() && canMoveDown(); + } + + public Position moveLeftDown() { + return moveLeft().moveDown(); + } + + public boolean canMoveRightUp() { + return canMoveUp() && canMoveRight(); + } + + public Position moveRightUp() { + return moveRight().moveUp(); + } + + public boolean canMoveRightDown() { + return canMoveRight() && canMoveDown(); + } + + public Position moveRightDown() { + return moveRight().moveDown(); + } + + public boolean isTop() { + return row.isTop(); + } + + public boolean isBottom() { + return row.isBottom(); + } + + public boolean isFarLeft() { + return column.isFarLeft(); + } + + public boolean isFarRight() { + return column.isFarRight(); + } + + public boolean canMove(final Movement movement) { + return canMoveVertical(movement.y()) && canMoveHorizontal(movement.x()); + } + + public boolean canMoveVertical(final int step) { + if (step > 0) { + return canMoveUp(step); + } + if (step < 0) { + return canMoveDown(-step); + } + return true; + } + + public boolean canMoveHorizontal(final int step) { + if (step > 0) { + return canMoveRight(step); + } + if (step < 0) { + return canMoveLeft(-step); + } + return true; + } + + public Position move(final Movement movement) { + return moveVertical(movement.y()).moveHorizontal(movement.x()); + } + + public Position moveVertical(final int step) { + if (step > 0) { + return moveUp(step); + } + if (step < 0) { + return moveDown(-step); + } + return this; + } + + public Position moveHorizontal(final int step) { + if (step > 0) { + return moveRight(step); + } + if (step < 0) { + return moveLeft(-step); + } + return this; + } +} diff --git a/src/main/java/chess/Row.java b/src/main/java/chess/Row.java new file mode 100644 index 00000000000..5e106d4de0b --- /dev/null +++ b/src/main/java/chess/Row.java @@ -0,0 +1,89 @@ +package chess; + +public enum Row { + + EIGHT, + SEVEN, + SIX, + FIVE, + FOUR, + THREE, + TWO, + ONE; + + public static Row change(char value) { + if (value == '1') { + return ONE; + } + + if (value == '2') { + return TWO; + } + + if (value == '3') { + return THREE; + } + + if (value == '4') { + return FOUR; + } + + if (value == '5') { + return FIVE; + } + + if (value == '6') { + return SIX; + } + + if (value == '7') { + return SEVEN; + } + + if (value == '8') { + return EIGHT; + } + + throw new IllegalArgumentException("[ERROR] 그런 값은 없어요."); + } + + public boolean isTop() { + return ordinal() == 0; + } + + public boolean isBottom() { + return ordinal() + 1 == values().length; + } + + public boolean canMoveUp(final int step) { + return ordinal() - step >= 0; + } + + public Row moveUp() { + return moveUp(1); + } + + public Row moveUp(final int step) { + if (canMoveUp(step)) { + return values()[ordinal() - step]; + } + + throw new IllegalStateException("움직일 수 없는 위치입니다."); + } + + public boolean canMoveDown(final int step) { + return ordinal() + step < values().length; + } + + public Row moveDown() { + return moveDown(1); + } + + public Row moveDown(final int step) { + if (canMoveDown(step)) { + return values()[ordinal() + step]; + } + + throw new IllegalStateException("움직일 수 없는 위치입니다."); + } +} diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java new file mode 100644 index 00000000000..75fe9f68c2a --- /dev/null +++ b/src/main/java/chess/piece/Bishop.java @@ -0,0 +1,32 @@ +package chess.piece; + +import chess.Color; +import chess.Position; + +public class Bishop extends Piece { + + public Bishop(Color color, Position position) { + super(color, position); + } + + @Override + public void move(final Position position) { + int rowabs = Math.abs(this.position.row().ordinal() - position.row().ordinal()); + int colabs = Math.abs(this.position.column().ordinal() - position.column().ordinal()); + + if (rowabs != colabs) { + throw new IllegalArgumentException("[ERROR] 비숍이 이동할 수 없습니다."); + } + + this.position = position; + } + + public Position position() { + return position; + } + + @Override + public String name() { + return "Bishop"; + } +} diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java new file mode 100644 index 00000000000..7627503ac91 --- /dev/null +++ b/src/main/java/chess/piece/King.java @@ -0,0 +1,40 @@ +package chess.piece; + +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.List; + +public class King extends Piece { + + private final List movements = List.of( + Movement.UP, Movement.DOWN, Movement.LEFT, + Movement.RIGHT, Movement.LEFT_UP, Movement.RIGHT_UP, + Movement.LEFT_DOWN, Movement.RIGHT_DOWN + ); + + public King(Color color, Position position) { + super(color, position); + } + + @Override + public void move(final Position position) { + for (Movement movement : movements) { + if (this.position.canMove(movement) && this.position.move(movement).equals(position)) { + this.position = this.position.move(movement); + return; + } + } + + throw new IllegalArgumentException("[ERROR] 움직일 수 없음."); + } + + public Position position() { + return new Position(position.column(), position.row()); + } + + @Override + public String name() { + return "King"; + } +} diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java new file mode 100644 index 00000000000..f7d03b161cf --- /dev/null +++ b/src/main/java/chess/piece/Knight.java @@ -0,0 +1,45 @@ +package chess.piece; + +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.List; + +public class Knight extends Piece { + + private final List movements = List.of( + Movement.LEFT_LEFT_UP, + Movement.LEFT_LEFT_DOWN, + Movement.RIGHT_RIGHT_UP, + Movement.RIGHT_RIGHT_DOWN, + Movement.UP_UP_LEFT, + Movement.UP_UP_RIGHT, + Movement.DOWN_DOWN_LEFT, + Movement.DOWN_DOWN_RIGHT + ); + + public Knight(Color color, Position position) { + super(color, position); + } + + @Override + public void move(final Position position) { + for (Movement movement : movements) { + if (this.position.canMove(movement) && this.position.move(movement).equals(position)) { + this.position = this.position.move(movement); + return; + } + } + + throw new IllegalArgumentException("[ERROR] 나이트가 움직일 수 없는 경로입니다."); + } + + public Position position() { + return new Position(position.column(), position.row()); + } + + @Override + public String name() { + return "Knight"; + } +} diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java new file mode 100644 index 00000000000..8b29936b6c3 --- /dev/null +++ b/src/main/java/chess/piece/Pawn.java @@ -0,0 +1,58 @@ +package chess.piece; + +import chess.Color; +import chess.Movement; +import chess.Position; + +public class Pawn extends Piece { + + private static boolean INITIAL_STATE = true; + + public Pawn(Color color, Position position) { + super(color, position); + } + + @Override + public void move(final Position position) { + if (color.isBlack()) { + if (INITIAL_STATE) { + if (this.position.canMoveDown(2) && this.position.moveDown(2).equals(position)) { + this.position = this.position.moveDown(2); + INITIAL_STATE = false; + return; + } + } + if (this.position.canMove(Movement.DOWN) && this.position.move(Movement.DOWN).equals(position)) { + this.position = this.position.move(Movement.DOWN); + INITIAL_STATE = false; + return; + } + } + + if (color.isWhite()) { + if (INITIAL_STATE) { + if (this.position.canMoveUp(2) && this.position.moveUp(2).equals(position)) { + this.position = this.position.moveUp(2); + INITIAL_STATE = false; + return; + } + } + if (this.position.canMove(Movement.UP) && this.position.move(Movement.UP).equals(position)) { + this.position = this.position.move(Movement.UP); + INITIAL_STATE = false; + return; + } + } + + throw new IllegalArgumentException("[ERROR] 움직일 수 없음"); + } + + public Position position() { + return new Position(position.column(), position.row()); + } + + @Override + public String name() { + return "Pawn"; + } +} diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java new file mode 100644 index 00000000000..ed6d75c9aa3 --- /dev/null +++ b/src/main/java/chess/piece/Piece.java @@ -0,0 +1,31 @@ +package chess.piece; + +import chess.Color; +import chess.Position; + +public abstract class Piece { + + protected final Color color; + protected Position position; + + public Piece(Color color, Position position) { + this.color = color; + this.position = position; + } + + public boolean isSameTeam(Color color) { + return this.color.compareTo(color) == 0; + } + + public Position getPosition() { + return position; + } + + public boolean isSamePosition(Position position) { + return this.position.equals(position); + } + + public abstract void move(Position end); + + public abstract String name(); +} diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java new file mode 100644 index 00000000000..4a40cb71da8 --- /dev/null +++ b/src/main/java/chess/piece/Queen.java @@ -0,0 +1,29 @@ +package chess.piece; + +import chess.Color; +import chess.Position; + +public class Queen extends Piece { + + public Queen(Color color, Position position) { + super(color, position); + } + + @Override + public void move(Position end) { + int rowabs = Math.abs(this.position.row().ordinal() - position.row().ordinal()); + int colabs = Math.abs(this.position.column().ordinal() - position.column().ordinal()); + + if (rowabs != colabs || (this.position.row().compareTo(position.row()) != 0 && + this.position.column().compareTo(position.column()) != 0)) { + throw new IllegalArgumentException("[ERROR] 퀸이 이동할 수 없습니다."); + } + + this.position = end; + } + + @Override + public String name() { + return "Queen"; + } +} diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java new file mode 100644 index 00000000000..01aeadb47a2 --- /dev/null +++ b/src/main/java/chess/piece/Rook.java @@ -0,0 +1,30 @@ +package chess.piece; + +import chess.Color; +import chess.Position; + +public class Rook extends Piece { + + public Rook(Color color, Position position) { + super(color, position); + } + + @Override + public void move(final Position position) { + if (this.position.row().compareTo(position.row()) != 0 && + this.position.column().compareTo(position.column()) != 0) { + throw new IllegalArgumentException("[ERROR] 룩이 이동할 수 없는 경로입니다."); + } + + this.position = position; + } + + public Position position() { + return position; + } + + @Override + public String name() { + return "Rook"; + } +} diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/test/java/chess/ColumnTest.java b/src/test/java/chess/ColumnTest.java new file mode 100644 index 00000000000..e43523240f7 --- /dev/null +++ b/src/test/java/chess/ColumnTest.java @@ -0,0 +1,95 @@ +package chess; + +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.assertThatThrownBy; + +@DisplayName("열") +class ColumnTest { + + @DisplayName("A는 맨 왼쪽이다.") + @Test + void isFarLeft_A() { + assertThat(Column.A.isFarLeft()).isTrue(); + } + + @DisplayName("B는 맨 왼쪽이 아니다.") + @Test + void isFarLeft_B() { + assertThat(Column.B.isFarLeft()).isFalse(); + } + + @DisplayName("H는 맨 오른쪽이다.") + @Test + void isFarRight_H() { + assertThat(Column.H.isFarRight()).isTrue(); + } + + @DisplayName("F는 맨 오른쪽이 아니다.") + @Test + void isFarRight_F() { + assertThat(Column.F.isFarRight()).isFalse(); + } + + @DisplayName("A는 왼쪽으로 이동할 수 없다.") + @Test + void moveLeft_A() { + assertThatThrownBy(Column.A::moveLeft) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("B는 왼쪽으로 이동하면 A다.") + @Test + void moveLeft_B() { + final var moved = Column.B.moveLeft(); + + assertThat(moved).isEqualTo(Column.A); + } + + @DisplayName("B는 왼쪽으로 2번 이동할 수 없다.") + @Test + void moveLeft_2_B() { + assertThatThrownBy(() -> Column.B.moveLeft(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("C는 왼쪽으로 2번 이동하면 A다.") + @Test + void moveLeft_2_C() { + final var moved = Column.C.moveLeft(2); + + assertThat(moved).isEqualTo(Column.A); + } + + @DisplayName("H는 오른쪽으로 이동할 수 없다.") + @Test + void moveRight_H() { + assertThatThrownBy(Column.H::moveRight) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("G는 오른쪽으로 이동하면 H다.") + @Test + void moveRight_G() { + final var moved = Column.G.moveRight(); + + assertThat(moved).isEqualTo(Column.H); + } + + @DisplayName("G는 오른쪽으로 2번 이동할 수 없다.") + @Test + void moveRight_2_G() { + assertThatThrownBy(() -> Column.G.moveRight(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("F는 오른쪽으로 2번 이동하면 H다.") + @Test + void moveRight_2_F() { + final var moved = Column.F.moveRight(2); + + assertThat(moved).isEqualTo(Column.H); + } +} diff --git a/src/test/java/chess/Fixtures.java b/src/test/java/chess/Fixtures.java new file mode 100644 index 00000000000..f940ab37137 --- /dev/null +++ b/src/test/java/chess/Fixtures.java @@ -0,0 +1,80 @@ +package chess; + +@SuppressWarnings("unused") +public final class Fixtures { + + public static final Position A1 = new Position(Column.A, Row.ONE); + public static final Position A2 = new Position(Column.A, Row.TWO); + public static final Position A3 = new Position(Column.A, Row.THREE); + public static final Position A4 = new Position(Column.A, Row.FOUR); + public static final Position A5 = new Position(Column.A, Row.FIVE); + public static final Position A6 = new Position(Column.A, Row.SIX); + public static final Position A7 = new Position(Column.A, Row.SEVEN); + public static final Position A8 = new Position(Column.A, Row.EIGHT); + + public static final Position B1 = new Position(Column.B, Row.ONE); + public static final Position B2 = new Position(Column.B, Row.TWO); + public static final Position B3 = new Position(Column.B, Row.THREE); + public static final Position B4 = new Position(Column.B, Row.FOUR); + public static final Position B5 = new Position(Column.B, Row.FIVE); + public static final Position B6 = new Position(Column.B, Row.SIX); + public static final Position B7 = new Position(Column.B, Row.SEVEN); + public static final Position B8 = new Position(Column.B, Row.EIGHT); + + public static final Position C1 = new Position(Column.C, Row.ONE); + public static final Position C2 = new Position(Column.C, Row.TWO); + public static final Position C3 = new Position(Column.C, Row.THREE); + public static final Position C4 = new Position(Column.C, Row.FOUR); + public static final Position C5 = new Position(Column.C, Row.FIVE); + public static final Position C6 = new Position(Column.C, Row.SIX); + public static final Position C7 = new Position(Column.C, Row.SEVEN); + public static final Position C8 = new Position(Column.C, Row.EIGHT); + + public static final Position D1 = new Position(Column.D, Row.ONE); + public static final Position D2 = new Position(Column.D, Row.TWO); + public static final Position D3 = new Position(Column.D, Row.THREE); + public static final Position D4 = new Position(Column.D, Row.FOUR); + public static final Position D5 = new Position(Column.D, Row.FIVE); + public static final Position D6 = new Position(Column.D, Row.SIX); + public static final Position D7 = new Position(Column.D, Row.SEVEN); + public static final Position D8 = new Position(Column.D, Row.EIGHT); + + public static final Position E1 = new Position(Column.E, Row.ONE); + public static final Position E2 = new Position(Column.E, Row.TWO); + public static final Position E3 = new Position(Column.E, Row.THREE); + public static final Position E4 = new Position(Column.E, Row.FOUR); + public static final Position E5 = new Position(Column.E, Row.FIVE); + public static final Position E6 = new Position(Column.E, Row.SIX); + public static final Position E7 = new Position(Column.E, Row.SEVEN); + public static final Position E8 = new Position(Column.E, Row.EIGHT); + + public static final Position F1 = new Position(Column.F, Row.ONE); + public static final Position F2 = new Position(Column.F, Row.TWO); + public static final Position F3 = new Position(Column.F, Row.THREE); + public static final Position F4 = new Position(Column.F, Row.FOUR); + public static final Position F5 = new Position(Column.F, Row.FIVE); + public static final Position F6 = new Position(Column.F, Row.SIX); + public static final Position F7 = new Position(Column.F, Row.SEVEN); + public static final Position F8 = new Position(Column.F, Row.EIGHT); + + public static final Position G1 = new Position(Column.G, Row.ONE); + public static final Position G2 = new Position(Column.G, Row.TWO); + public static final Position G3 = new Position(Column.G, Row.THREE); + public static final Position G4 = new Position(Column.G, Row.FOUR); + public static final Position G5 = new Position(Column.G, Row.FIVE); + public static final Position G6 = new Position(Column.G, Row.SIX); + public static final Position G7 = new Position(Column.G, Row.SEVEN); + public static final Position G8 = new Position(Column.G, Row.EIGHT); + + public static final Position H1 = new Position(Column.H, Row.ONE); + public static final Position H2 = new Position(Column.H, Row.TWO); + public static final Position H3 = new Position(Column.H, Row.THREE); + public static final Position H4 = new Position(Column.H, Row.FOUR); + public static final Position H5 = new Position(Column.H, Row.FIVE); + public static final Position H6 = new Position(Column.H, Row.SIX); + public static final Position H7 = new Position(Column.H, Row.SEVEN); + public static final Position H8 = new Position(Column.H, Row.EIGHT); + + private Fixtures() { + } +} diff --git a/src/test/java/chess/PositionTest.java b/src/test/java/chess/PositionTest.java new file mode 100644 index 00000000000..3ad7cc64084 --- /dev/null +++ b/src/test/java/chess/PositionTest.java @@ -0,0 +1,392 @@ +package chess; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static chess.Fixtures.A1; +import static chess.Fixtures.A2; +import static chess.Fixtures.A3; +import static chess.Fixtures.A6; +import static chess.Fixtures.A7; +import static chess.Fixtures.A8; +import static chess.Fixtures.B1; +import static chess.Fixtures.B2; +import static chess.Fixtures.B3; +import static chess.Fixtures.B7; +import static chess.Fixtures.B8; +import static chess.Fixtures.C1; +import static chess.Fixtures.F1; +import static chess.Fixtures.F8; +import static chess.Fixtures.G1; +import static chess.Fixtures.G2; +import static chess.Fixtures.G6; +import static chess.Fixtures.G7; +import static chess.Fixtures.G8; +import static chess.Fixtures.H1; +import static chess.Fixtures.H2; +import static chess.Fixtures.H7; +import static chess.Fixtures.H8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@DisplayName("위치") +class PositionTest { + + + @DisplayName("A1은 맨 왼쪽이다.") + @Test + void nonFarLeft_A1() { + assertThat(A1.isFarLeft()).isTrue(); + } + + @DisplayName("B1은 맨 왼쪽이 아니다.") + @Test + void nonFarLeft_B1() { + assertThat(B1.isFarLeft()).isFalse(); + } + + @DisplayName("H1은 맨 오른쪽이다.") + @Test + void nonFarRight_H1() { + assertThat(H1.isFarRight()).isTrue(); + } + + @DisplayName("F1은 맨 오른쪽이 아니다.") + @Test + void nonFarRight_F1() { + assertThat(F1.isFarRight()).isFalse(); + } + + @DisplayName("A1은 왼쪽으로 이동할 수 없다.") + @Test + void canMoveLeft_A1() { + assertThat(A1.canMoveLeft()).isFalse(); + } + + @DisplayName("A1은 왼쪽으로 이동할 수 없다.") + @Test + void canMoveLeft_Movement_A1() { + assertThat(A1.canMove(Movement.LEFT)).isFalse(); + } + + @DisplayName("B1은 왼쪽으로 이동할 수 있다.") + @Test + void canMoveLeft_B1() { + assertThat(B1.canMoveLeft()).isTrue(); + } + + @DisplayName("A1은 왼쪽으로 이동하면 예외가 발생한다.") + @Test + void moveLeft_A1() { + assertThatThrownBy(A1::moveLeft) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("B1은 왼쪽으로 이동하면 A1이다.") + @Test + void moveLeft_B1() { + final var moved = B1.moveLeft(); + + assertThat(moved).isEqualTo(A1); + } + + @DisplayName("B1은 왼쪽으로 2번 이동할 수 없다.") + @Test + void canMoveLeft_2_B1() { + assertThat(B1.canMoveLeft(2)).isFalse(); + } + + @DisplayName("B1은 왼쪽으로 2번 이동하면 예외가 발생한다.") + @Test + void moveLeft_2_B1() { + assertThatThrownBy(() -> B1.moveLeft(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("C1은 왼쪽으로 2번 이동하면 A1이다.") + @Test + void moveLeft_C2() { + final var moved = C1.moveLeft(2); + + assertThat(moved).isEqualTo(A1); + } + + @DisplayName("H1은 오른쪽으로 이동할 수 없다.") + @Test + void canMoveRight_H1() { + assertThat(H1.canMoveRight()).isFalse(); + } + + @DisplayName("H1은 오른쪽으로 이동할 수 없다.") + @Test + void canMoveRight_Movement_H1() { + assertThat(H1.canMove(Movement.RIGHT)).isFalse(); + } + + @DisplayName("H1은 오른쪽으로 이동하면 예외가 발생한다.") + @Test + void moveRight_H1() { + assertThatThrownBy(H1::moveRight) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("G1은 오른쪽으로 이동하면 H1다.") + @Test + void moveRight_G1() { + final var moved = G1.moveRight(); + + assertThat(moved).isEqualTo(H1); + } + + @DisplayName("G1은 오른쪽으로 2번 이동할 수 없다.") + @Test + void canMoveRight_2_G1() { + assertThat(G1.canMoveRight(2)).isFalse(); + } + + @DisplayName("G1은 오른쪽으로 2번 이동하면 예외가 발생한다.") + @Test + void moveRight_2_G1() { + assertThatThrownBy(() -> G1.moveRight(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("F1은 오른쪽으로 2번 이동하면 H1이다.") + @Test + void moveRight_2_F1() { + final var moved = F1.moveRight(2); + + assertThat(moved).isEqualTo(H1); + } + + ///// + + @DisplayName("A8은 맨 위다.") + @Test + void nonTop_A8() { + assertThat(A8.isTop()).isTrue(); + } + + @DisplayName("A7은 맨 위가 아니다.") + @Test + void nonTop_7() { + assertThat(A7.isTop()).isFalse(); + } + + @DisplayName("A1은 맨 아래다.") + @Test + void nonBottom_A1() { + assertThat(A1.isBottom()).isTrue(); + } + + @DisplayName("A2는 맨 아래가 아니다.") + @Test + void nonBottom_A2() { + assertThat(A2.isBottom()).isFalse(); + } + + @DisplayName("A8은 위로 이동할 수 없다.") + @Test + void canMoveUp_A8() { + assertThat(A8.canMoveUp()).isFalse(); + } + + @DisplayName("A8은 위로 이동하면 예외가 발생한다.") + @Test + void moveUp_A8() { + assertThatThrownBy(A8::moveUp) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("A7은 위로 이동하면 A8이다.") + @Test + void moveUp_A7() { + final var moved = A7.moveUp(); + + assertThat(moved).isEqualTo(A8); + } + + @DisplayName("A7은 위로 이동하면 A8이다.") + @Test + void moveUp_Movement_A7() { + final var moved = A7.move(Movement.UP); + + assertThat(moved).isEqualTo(A8); + } + + @DisplayName("A7은 위로 2번 이동할 수 없다.") + @Test + void canMoveUp_2_A7() { + assertThat(A7.canMoveUp(2)).isFalse(); + } + + @DisplayName("A7은 위로 2번 이동하면 예외가 발생한다.") + @Test + void moveUp_2_A7() { + assertThatThrownBy(() -> A7.moveUp(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("A6은 위로 2번 이동하면 A8이다.") + @Test + void moveUp_2_A6() { + final var moved = A6.moveUp(2); + + assertThat(moved).isEqualTo(A8); + } + + @DisplayName("A1은 아래로 이동할 수 없다.") + @Test + void canMoveDown_A1() { + assertThat(A1.canMoveDown()).isFalse(); + } + + @DisplayName("A1은 아래로 이동하면 예외가 발생한다.") + @Test + void moveDown_A1() { + assertThatThrownBy(A1::moveDown) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("A2는 아래로 이동하면 A1이다.") + @Test + void moveDown_A2() { + final var moved = A2.moveDown(); + + assertThat(moved).isEqualTo(A1); + } + + @DisplayName("A2는 아래로 2번 이동할 수 없다.") + @Test + void canMoveDown_2_A2() { + assertThat(A2.canMoveDown(2)).isFalse(); + } + + @DisplayName("A2는 아래로 2번 이동하면 예외가 발생한다.") + @Test + void moveDown_2_A2() { + assertThatThrownBy(() -> A2.moveDown(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("A3는 아래로 2번 이동하면 A1이다.") + @Test + void moveDown_2_A3() { + final var moved = A3.moveDown(2); + + assertThat(moved).isEqualTo(A1); + } + + @DisplayName("왼쪽 위 대각선으로 움직이면 예외가 발생한다.") + @MethodSource("immovableLeftUpSource") + @ParameterizedTest(name = "{0}은 왼쪽 위 대각선으로 움직이면 예외가 발생한다.") + void moveLeftUp_immovable(final Position position) { + assertThatThrownBy(position::moveLeftUp) + .isInstanceOf(IllegalStateException.class); + } + + static Stream immovableLeftUpSource() { + final var canMoveLeftPositions = Stream.of(A1, A2, A7, A8); + final var canMoveUpPositions = Stream.of(A8, B8, F8, H8); + + return Stream.concat(canMoveLeftPositions, canMoveUpPositions); + } + + @DisplayName("왼쪽 위 대각선으로 움직인다.") + @MethodSource("movableLeftUpSource") + @ParameterizedTest(name = "{0}을 왼쪽 위 대각선으로 움직인다.") + void moveLeftUp_movable(final Position position) { + assertThatCode(position::moveLeftUp) + .doesNotThrowAnyException(); + } + + static Stream movableLeftUpSource() { + return Stream.of(B2, B3, B7, G1, G2, G6, G7); + } + + @DisplayName("오른쪽 위 대각선으로 움직이면 예외가 발생한다.") + @MethodSource("immovableRightUpSource") + @ParameterizedTest(name = "{0}은 오른쪽 위 대각선으로 움직이면 예외가 발생한다.") + void moveRightUp_immovable(final Position position) { + assertThatThrownBy(position::moveRightUp) + .isInstanceOf(IllegalStateException.class); + } + + static Stream immovableRightUpSource() { + final var canMoveRightPositions = Stream.of(H1, H2, H7, H8); + final var canMoveUpPositions = Stream.of(A8, B8, F8, H8); + + return Stream.concat(canMoveRightPositions, canMoveUpPositions); + } + + @DisplayName("오른쪽 위 대각선으로 움직인다.") + @MethodSource("movableRightUpSource") + @ParameterizedTest(name = "{0}을 왼쪽 위 대각선으로 움직인다.") + void moveRightUp_movable(final Position position) { + assertThatCode(position::moveRightUp) + .doesNotThrowAnyException(); + } + + static Stream movableRightUpSource() { + return Stream.of(B1, B2, B3, B7, A2, A6, A7, G1, G2, G7); + } + + @DisplayName("왼쪽 아래 대각선으로 움직이면 예외가 발생한다.") + @MethodSource("immovableLeftDownSource") + @ParameterizedTest(name = "{0}은 왼쪽 아래 대각선으로 움직이면 예외가 발생한다.") + void moveLeftDown_immovable(final Position position) { + assertThatThrownBy(position::moveLeftDown) + .isInstanceOf(IllegalStateException.class); + } + + static Stream immovableLeftDownSource() { + final var canMoveLeftPositions = Stream.of(A1, A2, A7, A8); + final var canMoveDownPositions = Stream.of(A1, B1, F1, H1); + + return Stream.concat(canMoveLeftPositions, canMoveDownPositions); + } + + @DisplayName("왼쪽 아래 대각선으로 움직인다.") + @MethodSource("movableLeftDownSource") + @ParameterizedTest(name = "{0}을 왼쪽 아래 대각선으로 움직인다.") + void moveLeftDown_movable(final Position position) { + assertThatCode(position::moveLeftDown) + .doesNotThrowAnyException(); + } + + static Stream movableLeftDownSource() { + return Stream.of(B2, B3, B7, G8, G2, G6, G7); + } + + @DisplayName("오른쪽 아래 대각선으로 움직이면 예외가 발생한다.") + @MethodSource("immovableRightDownSource") + @ParameterizedTest(name = "{0}은 오른쪽 아래 대각선으로 움직이면 예외가 발생한다.") + void moveRightDown_immovable(final Position position) { + assertThatThrownBy(position::moveRightDown) + .isInstanceOf(IllegalStateException.class); + } + + static Stream immovableRightDownSource() { + final var canMoveRightPositions = Stream.of(H1, H2, H7, H8); + final var canMoveDownPositions = Stream.of(A1, B1, F1, H1); + + return Stream.concat(canMoveRightPositions, canMoveDownPositions); + } + + @DisplayName("오른쪽 아래 대각선으로 움직인다.") + @MethodSource("movableRightDownSource") + @ParameterizedTest(name = "{0}을 왼쪽 아래 대각선으로 움직인다.") + void moveRightDown_movable(final Position position) { + assertThatCode(position::moveRightDown) + .doesNotThrowAnyException(); + } + + static Stream movableRightDownSource() { + return Stream.of(B8, B2, B3, B7, A2, A6, A7, G8, G2, G7); + } +} diff --git a/src/test/java/chess/RowTest.java b/src/test/java/chess/RowTest.java new file mode 100644 index 00000000000..fcb65485410 --- /dev/null +++ b/src/test/java/chess/RowTest.java @@ -0,0 +1,95 @@ +package chess; + +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.assertThatThrownBy; + +@DisplayName("행") +class RowTest { + + @DisplayName("8은 맨 위다.") + @Test + void isTop_8() { + assertThat(Row.EIGHT.isTop()).isTrue(); + } + + @DisplayName("7은 맨 위가 아니다.") + @Test + void isTop_7() { + assertThat(Row.SEVEN.isTop()).isFalse(); + } + + @DisplayName("1은 맨 아래다.") + @Test + void isBottom_1() { + assertThat(Row.ONE.isBottom()).isTrue(); + } + + @DisplayName("2는 맨 아래가 아니다.") + @Test + void isBottom_2() { + assertThat(Row.TWO.isBottom()).isFalse(); + } + + @DisplayName("8은 위로 이동할 수 없다.") + @Test + void moveUp_8() { + assertThatThrownBy(Row.EIGHT::moveUp) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("7은 위로 이동하면 8이다.") + @Test + void moveUp_7() { + final var moved = Row.SEVEN.moveUp(); + + assertThat(moved).isEqualTo(Row.EIGHT); + } + + @DisplayName("7은 위로 2번 이동할 수 없다.") + @Test + void moveUp_2_7() { + assertThatThrownBy(() -> Row.SEVEN.moveUp(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("6은 위로 2번 이동하면 8이다.") + @Test + void moveUp_2_6() { + final var moved = Row.SIX.moveUp(2); + + assertThat(moved).isEqualTo(Row.EIGHT); + } + + @DisplayName("1은 아래로 이동할 수 없다.") + @Test + void moveDown_1() { + assertThatThrownBy(Row.ONE::moveDown) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("2는 아래로 이동하면 1이다.") + @Test + void moveDown_2() { + final var moved = Row.TWO.moveDown(); + + assertThat(moved).isEqualTo(Row.ONE); + } + + @DisplayName("2는 아래로 2번 이동할 수 없다.") + @Test + void moveDown_2_2() { + assertThatThrownBy(() -> Row.TWO.moveDown(2)) + .isInstanceOf(IllegalStateException.class); + } + + @DisplayName("3은 아래로 2번 이동하면 1이다.") + @Test + void moveDown_2_3() { + final var moved = Row.THREE.moveDown(2); + + assertThat(moved).isEqualTo(Row.ONE); + } +} diff --git a/src/test/java/chess/piece/BishopTest.java b/src/test/java/chess/piece/BishopTest.java new file mode 100644 index 00000000000..b766c4ac6cf --- /dev/null +++ b/src/test/java/chess/piece/BishopTest.java @@ -0,0 +1,37 @@ +package chess.piece; + +import chess.Color; +import chess.Fixtures; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class BishopTest { + + @Test + @DisplayName("비숍은 대각선으로만 움직일 수 있다.") + void test1() { + // given + Bishop bishop = new Bishop(Color.EMPTY, Fixtures.E4); + + // when + bishop.move(Fixtures.B7); + + // then + Assertions.assertThat(bishop.position()) + .isEqualTo(Fixtures.B7); + } + + @Test + @DisplayName("비숍은 대각선아니면 움직일 수 없다.") + void test2() { + // given + Bishop bishop = new Bishop(Color.EMPTY, Fixtures.E4); + + // when + // then + Assertions.assertThatThrownBy(() -> bishop.move(Fixtures.B6)) + .isInstanceOf(IllegalArgumentException.class); + } + +} diff --git a/src/test/java/chess/piece/KingTest.java b/src/test/java/chess/piece/KingTest.java new file mode 100644 index 00000000000..40ef4655ad9 --- /dev/null +++ b/src/test/java/chess/piece/KingTest.java @@ -0,0 +1,147 @@ +package chess.piece; + +import chess.Color; +import chess.Fixtures; +import chess.Movement; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class KingTest { + + @Test + @DisplayName("킹은 E1에서 E2으로 이동할 수 있다.") + void test1() { + // given + King king = new King(Color.BLACK, Fixtures.E1); + + // when + king.move(Fixtures.E2); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.E2); + } + + @Test + @DisplayName("킹은 E2에서 E1로 이동할 수 있다.") + void test2() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + king.move(Fixtures.E1); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.E1); + } + + @Test + @DisplayName("킹은 E2에서 D2로 이동할 수 있다.") + void test3() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + king.move(Fixtures.D2); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.D2); + } + + @Test + @DisplayName("킹은 E2에서 F2로 이동할 수 있다.") + void test4() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + king.move(Fixtures.F2); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.F2); + } + + @Test + @DisplayName("킹은 E2에서 D3로 이동할 수 있다.") + void test5() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + king.move(Fixtures.D3); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.D3); + } + + @Test + @DisplayName("킹은 E2에서 D1로 이동할 수 있다.") + void test6() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + king.move(Fixtures.D1); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.D1); + } + + @Test + @DisplayName("킹은 E2에서 F1로 이동할 수 있다.") + void test7() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + king.move(Fixtures.F1); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.F1); + } + + @Test + @DisplayName("킹은 E2에서 F3로 이동할 수 있다.") + void test8() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + king.move(Fixtures.F3); + + // then + Assertions.assertThat(king.position()) + .isEqualTo(Fixtures.F3); + } + + @Test + @DisplayName("킹은 E2에서 E4로 이동할 수 없다.") + void test9() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + // then + Assertions.assertThatThrownBy(() -> king.move(Fixtures.E4)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("킹은 E2에서 G2로 이동할 수 없다.") + void test10() { + // given + King king = new King(Color.BLACK, Fixtures.E2); + + // when + // then + Assertions.assertThatThrownBy(() -> king.move(Fixtures.G2)) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/chess/piece/KnightTest.java b/src/test/java/chess/piece/KnightTest.java new file mode 100644 index 00000000000..feae540f237 --- /dev/null +++ b/src/test/java/chess/piece/KnightTest.java @@ -0,0 +1,134 @@ +package chess.piece; + +import chess.Color; +import chess.Fixtures; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class KnightTest { + + @Test + @DisplayName("나이트는 E4에서 C5으로 이동할 수 있다.") + void test1() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.C5); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.C5); + } + + @Test + @DisplayName("나이트는 E4에서 C3으로 이동할 수 있다.") + void test2() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.C3); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.C3); + } + + @Test + @DisplayName("나이트는 E4에서 D2으로 이동할 수 있다.") + void test3() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.D2); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.D2); + } + + @Test + @DisplayName("나이트는 E4에서 F2으로 이동할 수 있다.") + void test4() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.F2); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.F2); + } + + @Test + @DisplayName("나이트는 E4에서 C5으로 이동할 수 있다.") + void test5() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.G3); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.G3); + } + + @Test + @DisplayName("나이트는 E4에서 G5으로 이동할 수 있다.") + void test6() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.G5); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.G5); + } + + @Test + @DisplayName("나이트는 E4에서 F6으로 이동할 수 있다.") + void test7() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.F6); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.F6); + } + + @Test + @DisplayName("나이트는 E4에서 D6으로 이동할 수 있다.") + void test8() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + knight.move(Fixtures.D6); + + // then + Assertions.assertThat(knight.position()) + .isEqualTo(Fixtures.D6); + } + + @Test + @DisplayName("나이트는 본인의 경로가 아니면 이동할 수 없다.") + void test9() { + // given + Knight knight = new Knight(Color.EMPTY, Fixtures.E4); + + // when + // then + Assertions.assertThatThrownBy(() -> knight.move(Fixtures.C7)) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/chess/piece/PawnTest.java b/src/test/java/chess/piece/PawnTest.java new file mode 100644 index 00000000000..da3cecfbfad --- /dev/null +++ b/src/test/java/chess/piece/PawnTest.java @@ -0,0 +1,86 @@ +package chess.piece; + +import chess.Color; +import chess.Fixtures; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PawnTest { + + @Test + @DisplayName("화이트 폰은 A2에서 A3으로 이동할 수 있다.") + void test1() { + // given + Pawn pawn = new Pawn(Color.WHITE, Fixtures.A2); + + // when + pawn.move(Fixtures.A3); + + // then + Assertions.assertThat(pawn.position()) + .isEqualTo(Fixtures.A3); + } + + @Test + @DisplayName("화이트 폰은 A3에서 A2로 이동할 수 없다.") + void test2() { + // given + Pawn pawn = new Pawn(Color.WHITE, Fixtures.A3); + + // when + // then + Assertions.assertThatThrownBy(() -> pawn.move(Fixtures.A2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("폰은 A2에서 B2로 이동할 수 없다.") + void test3() { + // given + Pawn pawn = new Pawn(Color.BLACK, Fixtures.A2); + + // when + // then + Assertions.assertThatThrownBy(() -> pawn.move(Fixtures.B2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("폰은 B2에서 A2로 이동할 수 없다.") + void test4() { + // given + Pawn pawn = new Pawn(Color.BLACK, Fixtures.B2); + + // when + // then + Assertions.assertThatThrownBy(() -> pawn.move(Fixtures.A2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("블랙 폰은 A2에서 A1로 이동할 수 있다.") + void test5() { + // given + Pawn pawn = new Pawn(Color.BLACK, Fixtures.A2); + + // when + pawn.move(Fixtures.A1); + + // then + Assertions.assertThat(pawn.position()) + .isEqualTo(Fixtures.A1); + } + + @Test + @DisplayName("화이트 폰은 A2에서 A3로 이동할 수 없다.") + void test6() { + // given + Pawn pawn = new Pawn(Color.BLACK, Fixtures.A2); + + // when + // then + Assertions.assertThatThrownBy(() -> pawn.move(Fixtures.A3)) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/src/test/java/chess/piece/QueenTest.java b/src/test/java/chess/piece/QueenTest.java new file mode 100644 index 00000000000..daa4399145e --- /dev/null +++ b/src/test/java/chess/piece/QueenTest.java @@ -0,0 +1,52 @@ +package chess.piece; + +import chess.Color; +import chess.Fixtures; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class QueenTest { + + @Test + @DisplayName("퀸은 대각, 직선 이동 가능") + void test1() { + // g + Queen queen = new Queen(Color.EMPTY, Fixtures.D5); + + // w + queen.move(Fixtures.A8); + + // t + Assertions.assertThat(queen.position) + .isEqualTo(Fixtures.A8); + } + + @Test + @DisplayName("퀸은 대각, 직선 이동 가능") + void test2() { + // g + Queen queen = new Queen(Color.EMPTY, Fixtures.D5); + + // w + queen.move(Fixtures.D8); + + // t + Assertions.assertThat(queen.position) + .isEqualTo(Fixtures.D8); + } + + @Test + @DisplayName("퀸은 대각, 직선 이동 가능") + void test4() { + // g + Queen queen = new Queen(Color.EMPTY, Fixtures.D5); + + // w + queen.move(Fixtures.C4); + + // t + Assertions.assertThat(queen.position) + .isEqualTo(Fixtures.C4); + } +} diff --git a/src/test/java/chess/piece/RookTest.java b/src/test/java/chess/piece/RookTest.java new file mode 100644 index 00000000000..cd5ec7e9245 --- /dev/null +++ b/src/test/java/chess/piece/RookTest.java @@ -0,0 +1,50 @@ +package chess.piece; + +import chess.Color; +import chess.Fixtures; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class RookTest { + + @Test + @DisplayName("룩은 A1에서 B1~H1으로 이동할 수 있다.") + void test1() { + // given + Rook rook = new Rook(Color.EMPTY, Fixtures.A1); + + // when + rook.move(Fixtures.F1); + + // then + Assertions.assertThat(rook.position()) + .isEqualTo(Fixtures.F1); + } + + @Test + @DisplayName("룩은 A1에서 A2~A8으로 이동할 수 있다.") + void test2() { + // given + Rook rook = new Rook(Color.EMPTY, Fixtures.A1); + + // when + rook.move(Fixtures.A7); + + // then + Assertions.assertThat(rook.position()) + .isEqualTo(Fixtures.A7); + } + + @Test + @DisplayName("룩은 A1에서 B2로 이동할 수 없다.") + void test3() { + // given + Rook rook = new Rook(Color.EMPTY, Fixtures.A1); + + // when + // then + Assertions.assertThatThrownBy(() -> rook.move(Fixtures.B2)) + .isInstanceOf(IllegalArgumentException.class); + } +}