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/chess/Board.java b/src/main/java/chess/Board.java new file mode 100644 index 00000000000..279c8ce5400 --- /dev/null +++ b/src/main/java/chess/Board.java @@ -0,0 +1,113 @@ +package chess; + +import chess.piece.Piece; +import chess.piece.PieceMoveType; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class Board { + + private final Map pieces; + + public Board(final Map pieces) { + this.pieces = pieces; + } + + public void move(final Position startPosition, final Position arrivalPosition, final Team currentTeam) { + Piece piece = getPiece(startPosition, currentTeam); + Set routes = makeTotalRoute(piece, startPosition, arrivalPosition); + // 경로 찾기 + Route route = getRoute(routes, arrivalPosition); + if (piece.getMoveType() != PieceMoveType.KNIGHT && hasPiece(route)) { + throw new IllegalArgumentException("중간에 장애물이 있습니다."); + } + catchPiece(arrivalPosition); + pieces.remove(startPosition); + pieces.put(arrivalPosition, piece); + } + + private void catchPiece(final Position arrivalPosition) { + if (pieces.containsKey(arrivalPosition)) { + pieces.remove(arrivalPosition); + } + } + + private boolean hasPiece(final Route route) { + return route.getPositions().stream() + .anyMatch(position -> pieces.containsKey(position)); + } + + private Route getRoute(final Set routes, final Position arrivalPosition) { + return routes.stream() + .filter(route -> route.getLast().equals(arrivalPosition)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("움직일 수 없는 위치입니다.")); + } + + private Set makeTotalRoute(final Piece piece, final Position startPosition, + final Position arrivalPosition) { + Set routes = new HashSet<>(); + if (piece.canMovePerpendicular()) { + add(routes, piece.moveUp(startPosition)); + add(routes, piece.moveDown(startPosition)); + add(routes, piece.moveRight(startPosition)); + add(routes, piece.moveLeft(startPosition)); + } + + if (piece.canMoveDiagonal()) { + add(routes, piece.moveRightUp(startPosition)); + add(routes, piece.moveRightDown(startPosition)); + add(routes, piece.moveLeftUp(startPosition)); + add(routes, piece.moveLeftDown(startPosition)); + } + + if (piece.canLMove()) { + add(routes, piece.moveUpRightUp(startPosition)); + add(routes, piece.moveUpLeftUp(startPosition)); + add(routes, piece.moveRightUpRight(startPosition)); + add(routes, piece.moveUpRightUp(startPosition)); + add(routes, piece.moveUpLeftUp(startPosition)); + add(routes, piece.moveRightUpRight(startPosition)); + add(routes, piece.moveRightDownRight(startPosition)); + add(routes, piece.moveDownRightDown(startPosition)); + add(routes, piece.moveDownLeftDown(startPosition)); + add(routes, piece.moveLeftUpLeft(startPosition)); + add(routes, piece.moveLeftDownLeft(startPosition)); + } + return routes; + } + + private void add(final Set routes, final Route route) { + if (route == null) { + return; + } + routes.add(route); + } + + private Piece getPiece(final Position position, final Team currentTeam) { + if (pieces.containsKey(position)) { + Piece piece = pieces.get(position); + if (piece.getTeam() == currentTeam) { + return piece; + } + throw new IllegalArgumentException("같은 팀의 기물을 잡을 수 없습니다."); + } + throw new IllegalArgumentException("해당 위치에 기물이 없습니다."); + } + + public Map getPieces() { + return Collections.unmodifiableMap(pieces); + } + + public boolean isFinished() { + int count = 0; + for (Piece piece : pieces.values()) { + if (piece.getMoveType() == PieceMoveType.KING) { + count++; + } + } + return count != 2; + } +} diff --git a/src/main/java/chess/BoardFactory.java b/src/main/java/chess/BoardFactory.java new file mode 100644 index 00000000000..c445d3c152a --- /dev/null +++ b/src/main/java/chess/BoardFactory.java @@ -0,0 +1,66 @@ +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.HashMap; +import java.util.Map; + +public class BoardFactory { + + public static Board makeBoard() { + Map pieces = new HashMap<>(); + Piece whitePawn = new Piece(null, new Pawn(Team.WHITE), null); + Piece blackPawn = new Piece(null, new Pawn(Team.BLACK), null); + Piece whiteRook = new Piece(null, new Rook(Team.WHITE), null); + Piece blackRook = new Piece(null, new Rook(Team.BLACK), null); + Piece whiteBishop = new Piece(new Bishop(Team.WHITE), null, null); + Piece blackBishop = new Piece(new Bishop(Team.BLACK), null, null); + Piece whiteQueen = new Piece(new Queen(Team.WHITE), new Queen(Team.WHITE), null); + Piece blackQueen = new Piece(new Queen(Team.BLACK), new Queen(Team.BLACK), null); + Piece whiteKing = new Piece(new King(Team.WHITE), new Queen(Team.WHITE), null); + Piece blackKing = new Piece(new King(Team.BLACK), new Queen(Team.WHITE), null); + Piece whiteKnight = new Piece(null, null, new Knight(Team.WHITE)); + Piece blackKnight = new Piece(null, null, new Knight(Team.WHITE)); + + pieces.put(new Position(Column.A, Row.TWO), whitePawn); + pieces.put(new Position(Column.B, Row.TWO), whitePawn); + pieces.put(new Position(Column.C, Row.TWO), whitePawn); + pieces.put(new Position(Column.D, Row.TWO), whitePawn); + pieces.put(new Position(Column.E, Row.TWO), whitePawn); + pieces.put(new Position(Column.F, Row.TWO), whitePawn); + pieces.put(new Position(Column.G, Row.TWO), whitePawn); + pieces.put(new Position(Column.H, Row.TWO), whitePawn); + pieces.put(new Position(Column.A, Row.ONE), whiteRook); + pieces.put(new Position(Column.B, Row.ONE), whiteKnight); + pieces.put(new Position(Column.C, Row.ONE), whiteBishop); + pieces.put(new Position(Column.D, Row.ONE), whiteQueen); + pieces.put(new Position(Column.E, Row.ONE), whiteKing); + pieces.put(new Position(Column.F, Row.ONE), whiteBishop); + pieces.put(new Position(Column.G, Row.ONE), whiteKnight); + pieces.put(new Position(Column.H, Row.ONE), whiteRook); + + pieces.put(new Position(Column.A, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.B, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.C, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.D, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.E, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.F, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.G, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.H, Row.SEVEN), blackPawn); + pieces.put(new Position(Column.A, Row.EIGHT), blackRook); + pieces.put(new Position(Column.B, Row.EIGHT), blackKnight); + pieces.put(new Position(Column.C, Row.EIGHT), blackBishop); + pieces.put(new Position(Column.D, Row.EIGHT), blackQueen); + pieces.put(new Position(Column.E, Row.EIGHT), blackKing); + pieces.put(new Position(Column.F, Row.EIGHT), blackBishop); + pieces.put(new Position(Column.G, Row.EIGHT), blackKnight); + pieces.put(new Position(Column.H, Row.EIGHT), blackRook); + + return new Board(pieces); + } +} diff --git a/src/main/java/chess/ChessConsole.java b/src/main/java/chess/ChessConsole.java new file mode 100644 index 00000000000..69c4b45af9c --- /dev/null +++ b/src/main/java/chess/ChessConsole.java @@ -0,0 +1,28 @@ +package chess; + +import chess.view.InputView; +import chess.view.ResultView; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.List; + +public class ChessConsole { + + public static void main(String[] args) { + InputView inputView = new InputView(); + ResultView resultView = new ResultView(); + Board board = BoardFactory.makeBoard(); + + Deque deque = new ArrayDeque<>(List.of(Team.WHITE, Team.BLACK)); + while (!board.isFinished()){ + Team currentTeam = deque.poll(); + resultView.showBoard(board); + resultView.showTeam(currentTeam); + List positions = inputView.readPosition(); + + board.move(positions.getFirst(), positions.getLast(), currentTeam); + deque.offer(currentTeam); + resultView.showBoard(board); + } + } +} 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..66366b4e62b --- /dev/null +++ b/src/main/java/chess/Column.java @@ -0,0 +1,62 @@ +package chess; + +public enum Column { + + A, + B, + C, + D, + E, + F, + G, + H; + + public static Column from(final String input) { + for (Column col : Column.values()) { + if (input.toUpperCase().equals(col.name())) { + return col; + } + } + throw new IllegalArgumentException(); + } + + 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..17842cb3094 --- /dev/null +++ b/src/main/java/chess/Position.java @@ -0,0 +1,235 @@ +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; + } + + public Position moveUpRightUp() { + return moveRightUp().moveUp(); + } + + public boolean canMoveUpRightUp() { + return canMoveRightUp() && moveRightUp().canMoveUp(); + } + + public Position moveUpLeftUp() { + return moveLeftUp().moveUp(); + } + + public boolean canMoveUpLeftUp() { + return canMoveLeftUp() && moveLeftUp().canMoveUp(); + } + + public Position moveRightUpRight() { + return moveRightUp().moveRight(); + } + + public boolean canMoveRightUpRight() { + return canMoveRightUp() && moveRightUp().canMoveRight(); + } + + public Position moveRightDownRight() { + return moveRightDown().moveRight(); + } + + public boolean canMoveRightDownRight() { + return canMoveRightDown() && moveRightDown().canMoveRight(); + } + + public Position moveDownRightDown() { + return moveRightDown().moveDown(); + } + + public boolean canMoveDownRightDown() { + return canMoveRightDown() && moveRightDown().canMoveDown(); + } + + public Position moveDownLeftDown() { + return moveLeftDown().moveDown(); + } + + public boolean canMoveDownLeftDown() { + return canMoveLeftDown() && moveLeftDown().canMoveDown(); + } + + public Position moveLeftUpLeft() { + return moveLeftUp().moveLeft(); + } + + public boolean canMoveLeftUpLeft() { + return canMoveLeftUp() && moveLeftUp().canMoveLeft(); + } + + public Position moveLeftDownLeft() { + return moveLeftDown().moveLeft(); + } + + public boolean canMoveLeftDownLeft() { + return canMoveLeftDown() && moveLeftDown().canMoveLeft(); + } + +} diff --git a/src/main/java/chess/Route.java b/src/main/java/chess/Route.java new file mode 100644 index 00000000000..9ed3a853200 --- /dev/null +++ b/src/main/java/chess/Route.java @@ -0,0 +1,48 @@ +package chess; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class Route { + + private final List positions; + + public Route(final List positions) { + this.positions = new ArrayList<>(positions); + } + + public static Route from(final Position position) { + return new Route(List.of(position)); + } + + public Route() { + this(new ArrayList<>()); + } + + public void add(final Position position) { + positions.add(position); + } + + @Override + public boolean equals(final Object o) { + if (!(o instanceof final Route route)) { + return false; + } + return Objects.equals(getPositions(), route.getPositions()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getPositions()); + } + + public List getPositions() { + return Collections.unmodifiableList(positions); + } + + public Position getLast() { + return positions.getLast(); + } +} diff --git a/src/main/java/chess/Row.java b/src/main/java/chess/Row.java new file mode 100644 index 00000000000..168872b33e3 --- /dev/null +++ b/src/main/java/chess/Row.java @@ -0,0 +1,68 @@ +package chess; + +public enum Row { + + EIGHT("8"), + SEVEN("7"), + SIX("6"), + FIVE("5"), + FOUR("4"), + THREE("3"), + TWO("2"), + ONE("1"); + + private final String number; + + Row(final String number) { + this.number = number; + } + + public static Row from(final String input) { + for (Row row : Row.values()) { + if (input.equals(row.number)) { + return row; + } + } + throw new IllegalArgumentException(); + } + + 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/Team.java b/src/main/java/chess/Team.java new file mode 100644 index 00000000000..0677713cb48 --- /dev/null +++ b/src/main/java/chess/Team.java @@ -0,0 +1,6 @@ +package chess; + +public enum Team { + + BLACK, WHITE; +} diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java new file mode 100644 index 00000000000..a9d6a193f5a --- /dev/null +++ b/src/main/java/chess/piece/Bishop.java @@ -0,0 +1,60 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public class Bishop implements DiagonalMove { + + private final Team team; + + public Bishop(final Team team) { + this.team = team; + } + + public Route moveRightUp(Position position) { + Route route = new Route(); + while (!(position.isTop() || position.isFarRight())) { + position = position.moveRightUp(); + route.add(position); + } + return route; + } + + public Route moveRightDown(Position position) { + Route route = new Route(); + while (!(position.isBottom() || position.isFarRight())) { + position = position.moveRightDown(); + route.add(position); + } + return route; + } + + public Route moveLeftUp(Position position) { + Route route = new Route(); + while (!(position.isTop() || position.isFarLeft())) { + position = position.moveLeftUp(); + route.add(position); + } + return route; + } + + public Route moveLeftDown(Position position) { + Route route = new Route(); + while (!(position.isBottom() || position.isFarLeft())) { + position = position.moveLeftDown(); + route.add(position); + } + return route; + } + + @Override + public PieceMoveType getMoveType() { + return PieceMoveType.BISHOP; + } + + @Override + public Team getTeam() { + return team; + } +} diff --git a/src/main/java/chess/piece/DiagonalMove.java b/src/main/java/chess/piece/DiagonalMove.java new file mode 100644 index 00000000000..028416f7cb7 --- /dev/null +++ b/src/main/java/chess/piece/DiagonalMove.java @@ -0,0 +1,20 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public interface DiagonalMove { + + Route moveRightUp(Position position); + + Route moveRightDown(Position position); + + Route moveLeftUp(Position position); + + Route moveLeftDown(Position position); + + PieceMoveType getMoveType(); + + Team getTeam(); +} diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java new file mode 100644 index 00000000000..2452b088b03 --- /dev/null +++ b/src/main/java/chess/piece/King.java @@ -0,0 +1,112 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public class King implements DiagonalMove, PerpendicularMove { + + private final Team team; + + public King(final Team team) { + this.team = team; + } + + @Override + public Route moveRightUp(Position position) { + Route route = new Route(); + if (position.canMoveRightUp()) { + position = position.moveRightUp(); + route.add(position); + return route; + } + return null; + } + + @Override + public Route moveRightDown(Position position) { + Route route = new Route(); + if (position.canMoveRightDown()) { + position = position.moveRightDown(); + route.add(position); + return route; + } + return null; + } + + @Override + public Route moveLeftUp(Position position) { + Route route = new Route(); + if (position.canMoveLeftUp()) { + position = position.moveLeftUp(); + route.add(position); + return route; + } + return null; + } + + @Override + public Route moveLeftDown(Position position) { + Route route = new Route(); + if (position.canMoveLeftDown()) { + position = position.moveLeftDown(); + route.add(position); + return route; + } + return null; + } + + @Override + public PieceMoveType getMoveType() { + return PieceMoveType.KING; + } + + @Override + public Team getTeam() { + return team; + } + + @Override + public Route moveUp(Position position) { + Route route = new Route(); + if (position.canMoveUp()) { + position = position.moveUp(); + route.add(position); + return route; + } + return null; + } + + @Override + public Route moveDown(Position position) { + Route route = new Route(); + if (position.canMoveDown()) { + position = position.moveDown(); + route.add(position); + return route; + } + return null; + } + + @Override + public Route moveRight(Position position) { + Route route = new Route(); + if (position.canMoveRight()) { + position = position.moveRight(); + route.add(position); + return route; + } + return null; + } + + @Override + public Route moveLeft(Position position) { + Route route = new Route(); + if (position.canMoveLeft()) { + position = position.moveLeft(); + route.add(position); + return route; + } + return null; + } +} diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java new file mode 100644 index 00000000000..7fc37f7442f --- /dev/null +++ b/src/main/java/chess/piece/Knight.java @@ -0,0 +1,138 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public class Knight implements LMove { + + private final Team team; + + public Knight(final Team team) { + this.team = team; + } + + public Route moveUpRightUp(Position position) { + Route route = new Route(); + if (position.canMoveUpRightUp()) { + position = position.moveUp(); + route.add(position); + position = position.moveRight(); + route.add(position); + position = position.moveUp(); + route.add(position); + return route; + } + return null; + } + + + public Route moveUpLeftUp(Position position) { + Route route = new Route(); + if (position.canMoveUpLeftUp()) { + position = position.moveUp(); + route.add(position); + position = position.moveLeft(); + route.add(position); + position = position.moveUp(); + route.add(position); + return route; + } + return null; + } + + public Route moveRightUpRight(Position position) { + Route route = new Route(); + if (position.canMoveRightUpRight()) { + position = position.moveRight(); + route.add(position); + position = position.moveUp(); + route.add(position); + position = position.moveRight(); + route.add(position); + return route; + } + return null; + } + + public Route moveRightDownRight(Position position) { + Route route = new Route(); + if (position.canMoveRightDownRight()) { + position = position.moveRight(); + route.add(position); + position = position.moveDown(); + route.add(position); + position = position.moveRight(); + route.add(position); + return route; + } + return null; + } + + public Route moveDownRightDown(Position position) { + Route route = new Route(); + if (position.canMoveDownRightDown()) { + position = position.moveDown(); + route.add(position); + position = position.moveRight(); + route.add(position); + position = position.moveDown(); + route.add(position); + return route; + } + return null; + } + + public Route moveDownLeftDown(Position position) { + Route route = new Route(); + if (position.canMoveDownLeftDown()) { + position = position.moveDown(); + route.add(position); + position = position.moveLeft(); + route.add(position); + position = position.moveDown(); + route.add(position); + return route; + } + return null; + } + + public Route moveLeftUpLeft(Position position) { + Route route = new Route(); + if (position.canMoveLeftUpLeft()) { + position = position.moveLeft(); + route.add(position); + position = position.moveUp(); + route.add(position); + position = position.moveLeft(); + route.add(position); + return route; + } + return null; + } + + public Route moveLeftDownLeft(Position position) { + Route route = new Route(); + if (position.canMoveLeftDownLeft()) { + position = position.moveLeft(); + route.add(position); + position = position.moveDown(); + route.add(position); + position = position.moveLeft(); + route.add(position); + return route; + } + return null; + } + + @Override + public PieceMoveType getMoveType() { + return PieceMoveType.KNIGHT; + } + + @Override + public Team getTeam() { + return team; + } + +} diff --git a/src/main/java/chess/piece/LMove.java b/src/main/java/chess/piece/LMove.java new file mode 100644 index 00000000000..b133e7eae1e --- /dev/null +++ b/src/main/java/chess/piece/LMove.java @@ -0,0 +1,28 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public interface LMove { + + Route moveUpRightUp(Position position); + + Route moveUpLeftUp(Position position); + + Route moveRightUpRight(Position position); + + Route moveRightDownRight(Position position); + + Route moveDownRightDown(Position position); + + Route moveDownLeftDown(Position position); + + Route moveLeftUpLeft(Position position); + + Route moveLeftDownLeft(Position position); + + PieceMoveType getMoveType(); + + Team getTeam(); +} diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java new file mode 100644 index 00000000000..b5d7b6066cf --- /dev/null +++ b/src/main/java/chess/piece/Pawn.java @@ -0,0 +1,63 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public class Pawn implements PerpendicularMove { + + private final Team team; + + public Pawn(final Team team) { + this.team = team; + } + + @Override + public Route moveUp(final Position position) { + if (team == Team.BLACK) { + return null; + } + return Route.from(position.moveUp()); + } + + @Override + public Route moveDown(final Position position) { + if (team == Team.WHITE) { + return null; + } + return Route.from(position.moveDown()); + } + + @Override + public Route moveRight(final Position position) { + return null; + + } + + @Override + public Route moveLeft(final Position position) { + return null; + } + + public Route moveUpUp(final Position position) { + Route route = moveUp(position); + route.add(route.getLast().moveUp()); + return route; + } + + public Route moveDownDown(final Position position) { + Route route = moveDown(position); + route.add(route.getLast().moveDown()); + return route; + } + + @Override + public PieceMoveType getMoveType() { + return PieceMoveType.PAWN; + } + + @Override + public Team getTeam() { + return team; + } +} diff --git a/src/main/java/chess/piece/PerpendicularMove.java b/src/main/java/chess/piece/PerpendicularMove.java new file mode 100644 index 00000000000..a884024802a --- /dev/null +++ b/src/main/java/chess/piece/PerpendicularMove.java @@ -0,0 +1,20 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public interface PerpendicularMove { + + Route moveUp(Position position); + + Route moveDown(Position position); + + Route moveRight(Position position); + + Route moveLeft(Position position); + + PieceMoveType getMoveType(); + + Team getTeam(); +} diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java new file mode 100644 index 00000000000..0368d09f234 --- /dev/null +++ b/src/main/java/chess/piece/Piece.java @@ -0,0 +1,114 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public class Piece { + + private final DiagonalMove diagonalMove; + private final PerpendicularMove perpendicularMove; + private final LMove lMove; + + public Piece(final DiagonalMove diagonalMove, final PerpendicularMove perpendicularMove, final LMove lMove) { + this.diagonalMove = diagonalMove; + this.perpendicularMove = perpendicularMove; + this.lMove = lMove; + } + + public boolean canMoveDiagonal() { + return diagonalMove != null; + } + + public boolean canMovePerpendicular() { + return perpendicularMove != null; + } + + public boolean canLMove() { + return lMove != null; + } + + public Route moveRightUp(final Position position) { + return diagonalMove.moveRightUp(position); + } + + public Route moveRightDown(final Position position) { + return diagonalMove.moveRightDown(position); + } + + public Route moveLeftUp(final Position position) { + return diagonalMove.moveLeftUp(position); + } + + public Route moveLeftDown(final Position position) { + return diagonalMove.moveLeftDown(position); + } + + public Route moveUp(final Position position) { + return perpendicularMove.moveUp(position); + } + + public Route moveDown(final Position position) { + return perpendicularMove.moveDown(position); + } + + public Route moveRight(final Position position) { + return perpendicularMove.moveRight(position); + } + + public Route moveLeft(final Position position) { + return perpendicularMove.moveLeft(position); + } + + public Route moveUpRightUp(final Position position) { + return lMove.moveUpRightUp(position); + } + + public Route moveUpLeftUp(final Position position) { + return lMove.moveUpLeftUp(position); + } + + public Route moveRightUpRight(final Position position) { + return lMove.moveRightUpRight(position); + } + + public Route moveRightDownRight(final Position position) { + return lMove.moveRightDownRight(position); + } + + public Route moveDownRightDown(final Position position) { + return lMove.moveDownRightDown(position); + } + + public Route moveDownLeftDown(final Position position) { + return lMove.moveDownLeftDown(position); + } + + public Route moveLeftUpLeft(final Position position) { + return lMove.moveLeftUpLeft(position); + } + + public Route moveLeftDownLeft(final Position position) { + return lMove.moveLeftDownLeft(position); + } + + public PieceMoveType getMoveType() { + if (diagonalMove != null) { + return diagonalMove.getMoveType(); + } + if (perpendicularMove != null) { + return perpendicularMove.getMoveType(); + } + return lMove.getMoveType(); + } + + public Team getTeam() { + if (diagonalMove != null) { + return diagonalMove.getTeam(); + } + if (perpendicularMove != null) { + return perpendicularMove.getTeam(); + } + return lMove.getTeam(); + } +} diff --git a/src/main/java/chess/piece/PieceMoveType.java b/src/main/java/chess/piece/PieceMoveType.java new file mode 100644 index 00000000000..644ae31d44c --- /dev/null +++ b/src/main/java/chess/piece/PieceMoveType.java @@ -0,0 +1,17 @@ +package chess.piece; + +public enum PieceMoveType { + + BISHOP("B"), KING("K"), KNIGHT("N"), + PAWN("P"), QUEEN("Q"), ROOK("R"); + + private final String value; + + PieceMoveType(final String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java new file mode 100644 index 00000000000..3b94834c2a1 --- /dev/null +++ b/src/main/java/chess/piece/Queen.java @@ -0,0 +1,68 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public class Queen implements DiagonalMove, PerpendicularMove { + + private final Team team; + private final Rook rook; + private final Bishop bishop; + + public Queen(final Team team) { + this.team = team; + this.rook = new Rook(team); + this.bishop = new Bishop(team); + } + + @Override + public Route moveRightUp(final Position position) { + return bishop.moveRightUp(position); + } + + @Override + public Route moveRightDown(final Position position) { + return bishop.moveRightDown(position); + } + + @Override + public Route moveLeftUp(final Position position) { + return bishop.moveLeftUp(position); + } + + @Override + public Route moveLeftDown(final Position position) { + return bishop.moveLeftDown(position); + } + + @Override + public Route moveUp(final Position position) { + return rook.moveUp(position); + } + + @Override + public Route moveDown(final Position position) { + return rook.moveDown(position); + } + + @Override + public Route moveRight(final Position position) { + return rook.moveRight(position); + } + + @Override + public Route moveLeft(final Position position) { + return rook.moveLeft(position); + } + + @Override + public PieceMoveType getMoveType() { + return PieceMoveType.QUEEN; + } + + @Override + public Team getTeam() { + return team; + } +} diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java new file mode 100644 index 00000000000..f1467d1bdd4 --- /dev/null +++ b/src/main/java/chess/piece/Rook.java @@ -0,0 +1,60 @@ +package chess.piece; + +import chess.Position; +import chess.Route; +import chess.Team; + +public class Rook implements PerpendicularMove { + + private final Team team; + + public Rook(final Team team) { + this.team = team; + } + + public Route moveUp(Position position) { + Route route = new Route(); + while (!position.isTop()) { + position = position.moveUp(); + route.add(position); + } + return route; + } + + public Route moveDown(Position position) { + Route route = new Route(); + while (!position.isBottom()) { + position = position.moveDown(); + route.add(position); + } + return route; + } + + public Route moveRight(Position position) { + Route route = new Route(); + while (!position.isFarRight()) { + position = position.moveRight(); + route.add(position); + } + return route; + } + + public Route moveLeft(Position position) { + Route route = new Route(); + while (!position.isFarLeft()) { + position = position.moveLeft(); + route.add(position); + } + return route; + } + + @Override + public PieceMoveType getMoveType() { + return PieceMoveType.ROOK; + } + + @Override + public Team getTeam() { + return team; + } +} diff --git a/src/main/java/chess/view/InputView.java b/src/main/java/chess/view/InputView.java new file mode 100644 index 00000000000..2a795ece0db --- /dev/null +++ b/src/main/java/chess/view/InputView.java @@ -0,0 +1,32 @@ +package chess.view; + +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private static final Scanner SCANNER = new Scanner(System.in); + + public void start() { + System.out.println("체스 게임 시작!"); + } + + public List readPosition() { + System.out.println("이동할 위치를 입력해주세요 ex) d4 d5"); + String s = readLine(); + String[] split = s.split(" "); + Column startCol = Column.from(split[0].substring(0, 1)); + Row startRow = Row.from(split[0].substring(1, 2)); + + Column arrivalCol = Column.from(split[1].substring(0, 1)); + Row arrivalRow = Row.from(split[1].substring(1, 2)); + return List.of(new Position(startCol, startRow), new Position(arrivalCol, arrivalRow)); + } + + private String readLine() { + return SCANNER.nextLine(); + } +} diff --git a/src/main/java/chess/view/ResultView.java b/src/main/java/chess/view/ResultView.java new file mode 100644 index 00000000000..0a32aae26d9 --- /dev/null +++ b/src/main/java/chess/view/ResultView.java @@ -0,0 +1,53 @@ +package chess.view; + +import chess.Board; +import chess.Column; +import chess.Position; +import chess.Row; +import chess.Team; +import chess.piece.Piece; +import java.util.Map; + +public class ResultView { + + private static final String BLANK = " "; + + public void showBoard(final Board board) { + Map pieces = board.getPieces(); + Column col = Column.A; + Row row = Row.EIGHT; + + StringBuilder sb = new StringBuilder(); + + while (true) { + while (true) { + Position position = new Position(col, row); + if (!pieces.containsKey(position)) { + sb.append("."); + if (col.isFarRight()) { + break; + } + col = col.moveRight(); + continue; + } + Piece piece = pieces.get(position); + sb.append(piece.getMoveType().getValue()); + if (col.isFarRight()) { + break; + } + col = col.moveRight(); + } + sb.append("\n"); + if (row.isBottom()) { + break; + } + row = row.moveDown(); + col = Column.A; + } + System.out.println(sb.toString()); + } + + public void showTeam(final Team team){ + System.out.printf("%s 팀 차례입니다\n", team.name()); + } +} 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..b4b1ead7bc9 --- /dev/null +++ b/src/test/java/chess/piece/BishopTest.java @@ -0,0 +1,68 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Column; +import chess.Position; +import chess.Route; +import chess.Row; +import chess.Team; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class BishopTest { + + private Bishop bishop; + private final Position position = new Position(Column.D, Row.FOUR); + + @BeforeEach + void setUp() { + bishop = new Bishop(Team.BLACK); + } + + @Test + void moveRightUp() { + + assertThat(bishop.moveRightUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.FIVE), + new Position(Column.F, Row.SIX), + new Position(Column.G, Row.SEVEN), + new Position(Column.H, Row.EIGHT) + ))); + } + + @Test + void moveRightDown() { + + assertThat(bishop.moveRightDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.THREE), + new Position(Column.F, Row.TWO), + new Position(Column.G, Row.ONE) + ))); + } + + @Test + void moveLeftUp() { + + assertThat(bishop.moveLeftUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.FIVE), + new Position(Column.B, Row.SIX), + new Position(Column.A, Row.SEVEN) + ))); + } + + @Test + void moveLeftDown() { + + assertThat(bishop.moveLeftDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.THREE), + new Position(Column.B, Row.TWO), + new Position(Column.A, Row.ONE) + ))); + } +} diff --git a/src/test/java/chess/piece/KingTest.java b/src/test/java/chess/piece/KingTest.java new file mode 100644 index 00000000000..d80014adcee --- /dev/null +++ b/src/test/java/chess/piece/KingTest.java @@ -0,0 +1,70 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Column; +import chess.Position; +import chess.Route; +import chess.Row; +import chess.Team; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class KingTest { + + private King king; + private final Position position = new Position(Column.E, Row.FOUR); + + @BeforeEach + void setUp() { + king = new King(Team.BLACK); + } + + @Test + void moveRightUp() { + + assertThat(king.moveRightUp(position)).isEqualTo(Route.from(new Position(Column.F, Row.FIVE))); + } + + @Test + void moveRightDown() { + + assertThat(king.moveRightDown(position)).isEqualTo(Route.from(new Position(Column.F, Row.THREE))); + } + + @Test + void moveLeftUp() { + + assertThat(king.moveLeftUp(position)).isEqualTo(Route.from(new Position(Column.D, Row.FIVE))); + } + + @Test + void moveLeftDown() { + + assertThat(king.moveLeftDown(position)).isEqualTo(Route.from(new Position(Column.D, Row.THREE))); + } + + @Test + void moveUp() { + + assertThat(king.moveUp(position)).isEqualTo(Route.from(new Position(Column.E, Row.FIVE))); + } + + @Test + void moveDown() { + + assertThat(king.moveDown(position)).isEqualTo(Route.from(new Position(Column.E, Row.THREE))); + } + + @Test + void moveRight() { + + assertThat(king.moveRight(position)).isEqualTo(Route.from(new Position(Column.F, Row.FOUR))); + } + + @Test + void moveLeft() { + + assertThat(king.moveLeft(position)).isEqualTo(Route.from(new Position(Column.D, Row.FOUR))); + } +} diff --git a/src/test/java/chess/piece/KnightTest.java b/src/test/java/chess/piece/KnightTest.java new file mode 100644 index 00000000000..6f03d487103 --- /dev/null +++ b/src/test/java/chess/piece/KnightTest.java @@ -0,0 +1,111 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Column; +import chess.Position; +import chess.Route; +import chess.Row; +import chess.Team; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class KnightTest { + + private Knight knight; + private final Position position = new Position(Column.D, Row.FOUR); + + @BeforeEach + void setUp() { + knight = new Knight(Team.BLACK); + } + + @Test + void moveUpRightUp() { + + assertThat(knight.moveUpRightUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.FIVE), + new Position(Column.E, Row.FIVE), + new Position(Column.E, Row.SIX) + ))); + } + + @Test + void moveUpLeftUp() { + + assertThat(knight.moveUpLeftUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.FIVE), + new Position(Column.C, Row.FIVE), + new Position(Column.C, Row.SIX) + ))); + } + + @Test + void moveRightUpRight() { + + assertThat(knight.moveRightUpRight(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.FOUR), + new Position(Column.E, Row.FIVE), + new Position(Column.F, Row.FIVE) + ))); + } + + @Test + void moveRightDownRight() { + + assertThat(knight.moveRightDownRight(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.FOUR), + new Position(Column.E, Row.THREE), + new Position(Column.F, Row.THREE) + ))); + } + + @Test + void moveDownRightDown() { + + assertThat(knight.moveDownRightDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.THREE), + new Position(Column.E, Row.THREE), + new Position(Column.E, Row.TWO) + ))); + } + + @Test + void moveDownLeftDown() { + + assertThat(knight.moveDownLeftDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.THREE), + new Position(Column.C, Row.THREE), + new Position(Column.C, Row.TWO) + ))); + } + + @Test + void moveLeftUpLeft() { + + assertThat(knight.moveLeftUpLeft(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.FOUR), + new Position(Column.C, Row.FIVE), + new Position(Column.B, Row.FIVE) + ))); + } + + @Test + void moveLeftDownLeft() { + + assertThat(knight.moveLeftDownLeft(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.FOUR), + new Position(Column.C, Row.THREE), + new Position(Column.B, Row.THREE) + ))); + } +} diff --git a/src/test/java/chess/piece/PawnTest.java b/src/test/java/chess/piece/PawnTest.java new file mode 100644 index 00000000000..47c934cc629 --- /dev/null +++ b/src/test/java/chess/piece/PawnTest.java @@ -0,0 +1,86 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Column; +import chess.Position; +import chess.Route; +import chess.Row; +import chess.Team; +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class PawnTest { + + private final Position position = new Position(Column.D, Row.THREE); + private Pawn blackPawn; + private Pawn whitePawn; + + @BeforeEach + void setUp() { + blackPawn = new Pawn(Team.BLACK); + whitePawn = new Pawn(Team.WHITE); + } + + @Test + void moveUp() { + + assertThat(whitePawn.moveUp(position)).isEqualTo(Route.from(new Position(Column.D, Row.FOUR))); + } + + @Test + void moveUpFail() { + + Assertions.assertThatThrownBy(() -> blackPawn.moveUp(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void moveDown() { + + assertThat(blackPawn.moveDown(position)).isEqualTo(Route.from(new Position(Column.D, Row.TWO))); + } + + @Test + void moveDownFail() { + Assertions.assertThatThrownBy(() -> whitePawn.moveDown(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void moveRight() { + + Assertions.assertThatThrownBy(() -> whitePawn.moveRight(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void moveLeft() { + + Assertions.assertThatThrownBy(() -> whitePawn.moveLeft(position)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void moveUpUp() { + + assertThat(whitePawn.moveUpUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.FOUR), + new Position(Column.D, Row.FIVE) + ))); + } + + + @Test + void moveDownDown() { + + assertThat(blackPawn.moveDownDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.TWO), + new Position(Column.D, Row.ONE) + ))); + } +} diff --git a/src/test/java/chess/piece/QueenTest.java b/src/test/java/chess/piece/QueenTest.java new file mode 100644 index 00000000000..d9a3fe47ee3 --- /dev/null +++ b/src/test/java/chess/piece/QueenTest.java @@ -0,0 +1,114 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Column; +import chess.Position; +import chess.Route; +import chess.Row; +import chess.Team; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class QueenTest { + + private Queen queen; + private final Position position = new Position(Column.D, Row.FOUR); + + @BeforeEach + void setUp() { + queen = new Queen(Team.BLACK); + } + + @Test + void moveRightUp() { + + assertThat(queen.moveRightUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.FIVE), + new Position(Column.F, Row.SIX), + new Position(Column.G, Row.SEVEN), + new Position(Column.H, Row.EIGHT) + ))); + } + + @Test + void moveRightDown() { + + assertThat(queen.moveRightDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.THREE), + new Position(Column.F, Row.TWO), + new Position(Column.G, Row.ONE) + ))); + } + + @Test + void moveLeftUp() { + + assertThat(queen.moveLeftUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.FIVE), + new Position(Column.B, Row.SIX), + new Position(Column.A, Row.SEVEN) + ))); + } + + @Test + void moveLeftDown() { + + assertThat(queen.moveLeftDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.THREE), + new Position(Column.B, Row.TWO), + new Position(Column.A, Row.ONE) + ))); + } + + @Test + void moveUp() { + + assertThat(queen.moveUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.FIVE), + new Position(Column.D, Row.SIX), + new Position(Column.D, Row.SEVEN), + new Position(Column.D, Row.EIGHT) + ))); + } + + @Test + void moveDown() { + + assertThat(queen.moveDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.THREE), + new Position(Column.D, Row.TWO), + new Position(Column.D, Row.ONE) + ))); + } + + @Test + void moveRight() { + + assertThat(queen.moveRight(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.FOUR), + new Position(Column.F, Row.FOUR), + new Position(Column.G, Row.FOUR), + new Position(Column.H, Row.FOUR) + ))); + } + + @Test + void moveLeft() { + + assertThat(queen.moveLeft(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.FOUR), + new Position(Column.B, Row.FOUR), + new Position(Column.A, Row.FOUR) + ))); + } +} diff --git a/src/test/java/chess/piece/RookTest.java b/src/test/java/chess/piece/RookTest.java new file mode 100644 index 00000000000..0834bc931e6 --- /dev/null +++ b/src/test/java/chess/piece/RookTest.java @@ -0,0 +1,69 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Column; +import chess.Position; +import chess.Route; +import chess.Row; +import chess.Team; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class RookTest { + + private Rook rook; + private final Position position = new Position(Column.D, Row.FOUR); + + @BeforeEach + void setUp() { + rook = new Rook(Team.BLACK); + } + + @Test + void moveUp() { + + assertThat(rook.moveUp(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.FIVE), + new Position(Column.D, Row.SIX), + new Position(Column.D, Row.SEVEN), + new Position(Column.D, Row.EIGHT) + ))); + } + + @Test + void moveDown() { + + assertThat(rook.moveDown(position)).isEqualTo(new Route( + List.of( + new Position(Column.D, Row.THREE), + new Position(Column.D, Row.TWO), + new Position(Column.D, Row.ONE) + ))); + } + + @Test + void moveRight() { + + assertThat(rook.moveRight(position)).isEqualTo(new Route( + List.of( + new Position(Column.E, Row.FOUR), + new Position(Column.F, Row.FOUR), + new Position(Column.G, Row.FOUR), + new Position(Column.H, Row.FOUR) + ))); + } + + @Test + void moveLeft() { + + assertThat(rook.moveLeft(position)).isEqualTo(new Route( + List.of( + new Position(Column.C, Row.FOUR), + new Position(Column.B, Row.FOUR), + new Position(Column.A, Row.FOUR) + ))); + } +}