diff --git a/README.md b/README.md index 8102f91c870..07cce7421cf 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,24 @@ 체스 미션 저장소 -## 우아한테크코스 코드리뷰 +## 게임 설명 + +``` +RNBQKBNR 8 (rank 8) +PPPPPPPP 7 (rank 7) +........ 6 +........ 5 +........ 4 +........ 3 +pppppppp 2 +rnbqkbnr 1 (rank 1) + +abcdefgh +``` + +- 체스판에서 각 진영은 검은색(대문자)과 흰색(소문자) 편으로 구분한다. +- 각 진영이 번갈아가면서 기물을 움직여야 하며 흰색(소문자)가 먼저 움직인다. +- 게임 시작: start +- 게임 종료: end +- 게임 이동: move source target - 예) move b2 b3 -- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) diff --git a/src/main/java/chess/Game.java b/src/main/java/chess/Game.java new file mode 100644 index 00000000000..784ca306fb3 --- /dev/null +++ b/src/main/java/chess/Game.java @@ -0,0 +1,74 @@ +package chess; + +import chess.board.Board; +import chess.position.Column; +import chess.position.Position; +import chess.position.Row; +import chess.view.BoardView; +import java.util.Map; +import java.util.Scanner; + +public class Game { + private final BoardView boardView = new BoardView(); + private final Scanner scanner = new Scanner(System.in); + private final Map columnInput = Map.of( + 'A', Column.A, + 'B', Column.B, + 'C', Column.C, + 'D', Column.D, + 'F', Column.F, + 'G', Column.G, + 'H', Column.H); + private final Map rowInput = Map.of( + '1', Row.ONE, + '2', Row.TWO, + '3', Row.THREE, + '4', Row.FOUR, + '5', Row.FIVE, + '6', Row.SIX, + '7', Row.SEVEN); + + public static void main(String[] args) { + new Game().start(); + } + + public void start() { + + System.out.println("\n" + + "RNBQKBNR 8 (rank 8)\n" + + "PPPPPPPP 7 (rank 7)\n" + + "........ 6\n" + + "........ 5\n" + + "........ 4\n" + + "........ 3\n" + + "pppppppp 2\n" + + "rnbqkbnr 1 (rank 1)\n" + + "abcdefgh\n" + + "\n" + + "- 체스판에서 각 진영은 검은색(대문자)과 흰색(소문자) 편으로 구분한다.\n" + + "- 각 진영이 번갈아가면서 기물을 움직여야 하며 흰색(소문자)가 먼저 움직인다.\n" + + "- 게임 종료: end\n" + + "- 게임 이동: move source target - 예) move B2 B3"); + + Board board = new Board(); + String input = "start"; + while (true) { + boardView.display(board); + input = scanner.nextLine(); + if (input.equals("end")) { + return; + } + char srcColumn = input.charAt(5); + char srcRow = input.charAt(6); + char desColumn = input.charAt(8); + char desRow = input.charAt(9); + try { + Position start = new Position(rowInput.get(srcRow), columnInput.get(srcColumn)); + Position end = new Position(rowInput.get(desRow), columnInput.get(desColumn)); + board.move(start, end); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } +} diff --git a/src/main/java/chess/board/Board.java b/src/main/java/chess/board/Board.java new file mode 100644 index 00000000000..9dec5ebbd52 --- /dev/null +++ b/src/main/java/chess/board/Board.java @@ -0,0 +1,158 @@ +package chess.board; + +import chess.piece.Bishop; +import chess.piece.King; +import chess.piece.Knight; +import chess.piece.Pawn; +import chess.piece.Piece; +import chess.piece.PieceType; +import chess.piece.Queen; +import chess.piece.Rook; +import chess.position.Column; +import chess.position.Movement; +import chess.position.Position; +import chess.position.Row; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public final class Board { + + private final Map colors; + private final Map pieces; + private Color turn = Color.WHITE; + + { + // 기본 Empty + Map colors = new HashMap<>(); + for (Row row : Row.values()) { + for (Column column : Column.values()) { + colors.put(new Position(row, column), Color.EMPTY); + } + } + this.colors = colors; + } + + public Board(Map colors, Map pieces) { + for (Entry newColorEntry : colors.entrySet()) { + Position position = newColorEntry.getKey(); + Color color = newColorEntry.getValue(); + this.colors.put(position, color); + } + this.pieces = new HashMap<>(pieces); + } + + public Board() { + // 색깔 넣기 + for (Column column : Column.values()) { + // Rank 8, 7 -> Black + colors.put(new Position(Row.EIGHT, column), Color.BLACK); + colors.put(new Position(Row.SEVEN, column), Color.BLACK); + // Rank 2, 1 -> White + colors.put(new Position(Row.TWO, column), Color.WHITE); + colors.put(new Position(Row.ONE, column), Color.WHITE); + } + // 기물 넣기 + Map pieces = new HashMap<>(); + for (Column column : Column.values()) { // 폰 + pieces.put(new Position(Row.SEVEN, column), Pawn.black()); + pieces.put(new Position(Row.TWO, column), Pawn.white()); + } + for (Row row : List.of(Row.ONE, Row.EIGHT)) { // 폰을 제외한 기물 + pieces.put(new Position(row, Column.A), Rook.create()); + pieces.put(new Position(row, Column.B), Knight.create()); + pieces.put(new Position(row, Column.C), Bishop.create()); + pieces.put(new Position(row, Column.D), Queen.create()); + pieces.put(new Position(row, Column.E), King.create()); + pieces.put(new Position(row, Column.F), Bishop.create()); + pieces.put(new Position(row, Column.G), Knight.create()); + pieces.put(new Position(row, Column.H), Rook.create()); + } + this.pieces = pieces; + } + + public void move(Position start, Position end) { + Piece piece = findPiece(start); + Color color = colorAt(start); + if (color != turn) { + throw new IllegalArgumentException("[ERROR] 선택한 색깔의 턴이 아닙니다."); + } + validateEndPosition(start, end); + piece.validateMove(start, end); + if (piece.type().canBeBlocked()) { + validateRouteNotBlocked(piece.getValidateMovement(start, end), start, end); + } + if (piece.type() == PieceType.PAWN) { + validatePawn(piece, start, end); + } + pieces.put(end, piece); + colors.put(end, color); + pieces.remove(start); + colors.put(start, Color.EMPTY); + piece.recordMoved(); + turn = turn.opposite(); + } + + private void validatePawn(Piece piece, Position start, Position end) { + Movement validateMovement = piece.getValidateMovement(start, end); + if (validateMovement == Movement.UP_UP) { + if (piece.moved()) { + throw new IllegalArgumentException("[ERROR] 폰은 첫 움직임에만 두 칸 이동할 수 있습니다."); + } + if (colorAt(start.move(Movement.UP)) != Color.EMPTY) { + throw new IllegalArgumentException("[ERROR] 다른 기물에 의해 막혀서 이동할 수 없는 경로입니다."); + } + } + if (validateMovement == Movement.DOWN_DOWN) { + if (piece.moved()) { + throw new IllegalArgumentException("[ERROR] 폰은 첫 움직임에만 두 칸 이동할 수 있습니다."); + } + if (colorAt(start.move(Movement.DOWN)) != Color.EMPTY) { + throw new IllegalArgumentException("[ERROR] 다른 기물에 의해 막혀서 이동할 수 없는 경로입니다."); + } + } + if (validateMovement.isDiagonal() && colorAt(end) == Color.EMPTY) { + throw new IllegalArgumentException("[ERROR] 해당 위치에 잡을 수 있는 기물이 없습니다."); + } + } + + private void validateRouteNotBlocked(Movement movement, Position start, Position end) { + Position nextPosition = start; + while (!(nextPosition = nextPosition.move(movement)).equals(end)) { // end 끝까지 가면 끝 + if (pieces.containsKey(nextPosition)) { // 이 위치에 어떤 기물이 있는 경우 + throw new IllegalArgumentException("[ERROR] 다른 기물에 의해 막혀서 이동할 수 없는 경로입니다."); + } + } + } + + private void validateEndPosition(Position start, Position end) { + if (colorAt(end).isEmpty()) { + return; + } + if (colorAt(end) == colorAt(start)) { + throw new IllegalArgumentException("[ERROR] 같은 팀의 기물은 잡을 수 없습니다."); + } + } + + public Color colorAt(Position position) { + if (!colors.containsKey(position)) { + throw new IllegalStateException("[ERROR] 해당 위치의 색깔을 찾을 수 없습니다."); + } + return colors.get(position); + } + + public PieceType pieceTypeAt(Position position) { + if (!pieces.containsKey(position)) { + throw new IllegalStateException("[ERROR] 해당 위치에 기물이 없습니다."); + } + return pieces.get(position).type(); + } + + private Piece findPiece(Position position) { + if (!pieces.containsKey(position)) { + throw new IllegalArgumentException("[ERROR] 해당 위치에 기물이 없습니다."); + } + return pieces.get(position); + } +} diff --git a/src/main/java/chess/Color.java b/src/main/java/chess/board/Color.java similarity index 95% rename from src/main/java/chess/Color.java rename to src/main/java/chess/board/Color.java index 55cd020b681..43e8dfdc4e7 100644 --- a/src/main/java/chess/Color.java +++ b/src/main/java/chess/board/Color.java @@ -1,4 +1,4 @@ -package chess; +package chess.board; public enum Color { diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index b14ab70f981..09faabacc8e 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -1,5 +1,36 @@ package chess.piece; -public class Bishop { +import static chess.position.Movement.LEFT_DOWN; +import static chess.position.Movement.LEFT_UP; +import static chess.position.Movement.RIGHT_DOWN; +import static chess.position.Movement.RIGHT_UP; +import chess.position.Movement; +import chess.position.Position; +import java.util.List; + +public final class Bishop extends Piece { + + private Bishop(List movements, PieceType pieceType) { + super(movements, pieceType); + } + + public static Bishop create() { + return new Bishop(List.of(LEFT_UP, LEFT_DOWN, RIGHT_UP, RIGHT_DOWN), PieceType.BISHOP); + } + + @Override + public void validateMove(Position start, Position end) { + for (Movement movement : movements) { + Position nextPosition = start; + while (nextPosition.canMove(movement)) { // 보드 끝까지 가면 끝 + nextPosition = nextPosition.move(movement); // 1칸 움직임 + if (nextPosition.equals(end)) { // 가고자 하는 위치랑 일치함 + return; + } + } + } + // 일치하는거 못찾음 + throw new IllegalArgumentException("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } } diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java index d64210cad13..c7cbd97ae57 100644 --- a/src/main/java/chess/piece/King.java +++ b/src/main/java/chess/piece/King.java @@ -1,5 +1,36 @@ package chess.piece; -public class King { +import static chess.position.Movement.DOWN; +import static chess.position.Movement.LEFT; +import static chess.position.Movement.RIGHT; +import static chess.position.Movement.UP; +import chess.position.Movement; +import chess.position.Position; +import java.util.List; + +public class King extends Piece { + + public King(List movements, PieceType pieceType) { + super(movements, pieceType); + } + + public static King create() { + return new King(List.of(UP, DOWN, LEFT, RIGHT), PieceType.KING); + } + + @Override + public void validateMove(Position start, Position end) { + for (Movement movement : movements) { + if (!start.canMove(movement)) { + continue; + } + Position nextPosition = start.move(movement); + if (nextPosition.equals(end)) { // 일치하는게 있음 + return; + } + } + // 일치하는거 못찾음 + throw new IllegalArgumentException("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } } diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java index 2ee7c47a3bc..07f101a48fa 100644 --- a/src/main/java/chess/piece/Knight.java +++ b/src/main/java/chess/piece/Knight.java @@ -1,5 +1,43 @@ package chess.piece; -public class Knight { +import static chess.position.Movement.DOWN_DOWN_LEFT; +import static chess.position.Movement.DOWN_DOWN_RIGHT; +import static chess.position.Movement.LEFT_LEFT_DOWN; +import static chess.position.Movement.LEFT_LEFT_UP; +import static chess.position.Movement.RIGHT_RIGHT_DOWN; +import static chess.position.Movement.RIGHT_RIGHT_UP; +import static chess.position.Movement.UP_UP_LEFT; +import static chess.position.Movement.UP_UP_RIGHT; +import chess.position.Movement; +import chess.position.Position; +import java.util.List; + +public final class Knight extends Piece { + + public Knight(List movements, PieceType pieceType) { + super(movements, pieceType); + } + + public static Knight create() { + return new Knight( + List.of(LEFT_LEFT_UP, LEFT_LEFT_DOWN, RIGHT_RIGHT_UP, RIGHT_RIGHT_DOWN, + DOWN_DOWN_LEFT, DOWN_DOWN_RIGHT, UP_UP_LEFT, UP_UP_RIGHT), + PieceType.KNIGHT); + } + + @Override + public void validateMove(Position start, Position end) { + for (Movement movement : movements) { + if (!start.canMove(movement)) { + continue; + } + Position nextPosition = start.move(movement); + if (nextPosition.equals(end)) { // 일치하는게 있음 + return; + } + } + // 일치하는거 못찾음 + throw new IllegalArgumentException("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } } diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java index c8b6cafa51e..2d2483f69bd 100644 --- a/src/main/java/chess/piece/Pawn.java +++ b/src/main/java/chess/piece/Pawn.java @@ -1,5 +1,46 @@ package chess.piece; -public class Pawn { +import static chess.position.Movement.DOWN; +import static chess.position.Movement.DOWN_DOWN; +import static chess.position.Movement.LEFT_DOWN; +import static chess.position.Movement.LEFT_UP; +import static chess.position.Movement.RIGHT_DOWN; +import static chess.position.Movement.RIGHT_UP; +import static chess.position.Movement.UP; +import static chess.position.Movement.UP_UP; + +import chess.position.Movement; +import chess.position.Position; +import java.util.List; + +public final class Pawn extends Piece { + + public Pawn(List movements, PieceType pieceType) { + super(movements, pieceType); + } + + public static Pawn white() { + return new Pawn(List.of(UP_UP, UP, RIGHT_UP, LEFT_UP), PieceType.PAWN); + } + + public static Pawn black() { + return new Pawn(List.of(DOWN_DOWN, DOWN, RIGHT_DOWN, LEFT_DOWN), PieceType.PAWN); + } + + @Override + public void validateMove(Position start, Position end) { + for (Movement movement : movements) { + if (!start.canMove(movement)) { + continue; + } + Position nextPosition = start.move(movement); + if (nextPosition.equals(end)) { // 일치하는게 있음 + return; + } + } + // 일치하는거 못찾음 + throw new IllegalArgumentException("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } + } diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java new file mode 100644 index 00000000000..c3cc19b98fd --- /dev/null +++ b/src/main/java/chess/piece/Piece.java @@ -0,0 +1,46 @@ +package chess.piece; + +import chess.position.Movement; +import chess.position.Position; +import java.util.List; + +public abstract class Piece { + + protected final List movements; + protected final PieceType pieceType; + private boolean moved = false; + + + public Piece(List movements, PieceType pieceType) { + this.movements = movements; + this.pieceType = pieceType; + } + + public abstract void validateMove(Position start, Position end); + + public Movement getValidateMovement(Position start, Position end) { + for (Movement movement : movements) { + Position nextPosition = start; + while (nextPosition.canMove(movement)) { // 보드 끝까지 가면 끝 + nextPosition = nextPosition.move(movement); // 1칸 움직임 + if (nextPosition.equals(end)) { // 가고자 하는 위치랑 일치함 + return movement; + } + } + } + // 일치하는거 못찾음 + throw new IllegalStateException("[ERROR] 해당하는 규칙을 찾을 수 없습니다.."); + } + + public PieceType type() { + return pieceType; + } + + public void recordMoved() { + this.moved = true; + } + + public boolean moved() { + return moved; + } +} diff --git a/src/main/java/chess/piece/PieceType.java b/src/main/java/chess/piece/PieceType.java new file mode 100644 index 00000000000..1bc2ce61f49 --- /dev/null +++ b/src/main/java/chess/piece/PieceType.java @@ -0,0 +1,21 @@ +package chess.piece; + +public enum PieceType { + + BISHOP(true), + KING(false), + KNIGHT(false), + PAWN(false), + QUEEN(true), + ROOK(true); + + private final boolean canBeBlocked; + + PieceType(boolean canBeBlocked) { + this.canBeBlocked = canBeBlocked; + } + + public boolean canBeBlocked() { + return canBeBlocked; + } +} diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 9b547261c4b..893dc6ef66e 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -1,5 +1,42 @@ package chess.piece; -public class Queen { +import static chess.position.Movement.DOWN; +import static chess.position.Movement.LEFT; +import static chess.position.Movement.LEFT_DOWN; +import static chess.position.Movement.LEFT_UP; +import static chess.position.Movement.RIGHT; +import static chess.position.Movement.RIGHT_DOWN; +import static chess.position.Movement.RIGHT_UP; +import static chess.position.Movement.UP; +import chess.position.Movement; +import chess.position.Position; +import java.util.List; + +public final class Queen extends Piece { + + public Queen(List movements, PieceType pieceType) { + super(movements, pieceType); + } + + public static Queen create() { + return new Queen(List.of(LEFT_UP, LEFT_DOWN, RIGHT_UP, RIGHT_DOWN, + LEFT, RIGHT, UP, DOWN) + , PieceType.QUEEN); + } + + @Override + public void validateMove(Position start, Position end) { + for (Movement movement : movements) { + Position nextPosition = start; + while (nextPosition.canMove(movement)) { // 보드 끝까지 가면 끝 + nextPosition = nextPosition.move(movement); // 1칸 움직임 + if (nextPosition.equals(end)) { // 가고자 하는 위치랑 일치함 + return; + } + } + } + // 일치하는거 못찾음 + throw new IllegalArgumentException("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } } diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index 7ed4d08bf03..1d4a3a52fcb 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -1,5 +1,37 @@ package chess.piece; -public class Rook { +import static chess.position.Movement.DOWN; +import static chess.position.Movement.LEFT; +import static chess.position.Movement.RIGHT; +import static chess.position.Movement.UP; +import chess.position.Movement; +import chess.position.Position; +import java.util.List; + +public final class Rook extends Piece { + + public Rook(List movements, PieceType pieceType) { + super(movements, pieceType); + } + + public static Rook create() { + return new Rook(List.of(LEFT, RIGHT, UP, DOWN), + PieceType.ROOK); + } + + @Override + public void validateMove(Position start, Position end) { + for (Movement movement : movements) { + Position nextPosition = start; + while (nextPosition.canMove(movement)) { // 보드 끝까지 가면 끝 + nextPosition = nextPosition.move(movement); // 1칸 움직임 + if (nextPosition.equals(end)) { // 가고자 하는 위치랑 일치함 + return; + } + } + } + // 일치하는거 못찾음 + throw new IllegalArgumentException("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } } diff --git a/src/main/java/chess/Column.java b/src/main/java/chess/position/Column.java similarity index 97% rename from src/main/java/chess/Column.java rename to src/main/java/chess/position/Column.java index b64b4dc77a3..4099a335b6a 100644 --- a/src/main/java/chess/Column.java +++ b/src/main/java/chess/position/Column.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public enum Column { diff --git a/src/main/java/chess/Movement.java b/src/main/java/chess/position/Movement.java similarity index 97% rename from src/main/java/chess/Movement.java rename to src/main/java/chess/position/Movement.java index e57c6e91bb9..60d4815db36 100644 --- a/src/main/java/chess/Movement.java +++ b/src/main/java/chess/position/Movement.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public enum Movement { UP(0, 1), diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/position/Position.java similarity index 99% rename from src/main/java/chess/Position.java rename to src/main/java/chess/position/Position.java index 3ebeb0ea185..14b12e1a74d 100644 --- a/src/main/java/chess/Position.java +++ b/src/main/java/chess/position/Position.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public record Position( Column column, diff --git a/src/main/java/chess/Row.java b/src/main/java/chess/position/Row.java similarity index 97% rename from src/main/java/chess/Row.java rename to src/main/java/chess/position/Row.java index 126ed048daa..12ff8956d5f 100644 --- a/src/main/java/chess/Row.java +++ b/src/main/java/chess/position/Row.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public enum Row { diff --git a/src/main/java/chess/view/BoardView.java b/src/main/java/chess/view/BoardView.java new file mode 100644 index 00000000000..f2bb1e8ba7a --- /dev/null +++ b/src/main/java/chess/view/BoardView.java @@ -0,0 +1,40 @@ +package chess.view; + +import chess.board.Board; +import chess.board.Color; +import chess.position.Column; +import chess.position.Position; +import chess.position.Row; +import java.util.Map; + +public final class BoardView { + + private final Map rowMap = Map.of( + Row.ONE, '1', + Row.TWO, '2', + Row.THREE, '3', + Row.FOUR, '4', + Row.FIVE, '5', + Row.SIX, '6', + Row.SEVEN, '7', + Row.EIGHT, '8'); + + public void display(Board board) { + System.out.println(); + for (Row row : Row.values()) { + System.out.printf("%c ", rowMap.get(row)); + for (Column column : Column.values()) { + Position position = new Position(row, column); + Color color = board.colorAt(position); + if (color == Color.EMPTY) { + System.out.print("."); + } else { + System.out.printf("%c", PieceNotation.of(color, board.pieceTypeAt(position))); + } + } + System.out.println(); + } + System.out.println(" ABCDEFGH"); + System.out.print("> "); + } +} diff --git a/src/main/java/chess/view/PieceNotation.java b/src/main/java/chess/view/PieceNotation.java new file mode 100644 index 00000000000..4f76b4502c8 --- /dev/null +++ b/src/main/java/chess/view/PieceNotation.java @@ -0,0 +1,43 @@ +package chess.view; + +import chess.board.Color; +import chess.piece.PieceType; +import java.util.Arrays; + +public enum PieceNotation { + + BISHOP('b', PieceType.BISHOP), + KING('k', PieceType.KING), + KNIGHT('n', PieceType.KNIGHT), + PAWN('p', PieceType.PAWN), + QUEEN('q', PieceType.QUEEN), + ROOk('r', PieceType.ROOK); + + private final Character notation; + private final PieceType pieceType; + + PieceNotation(Character notation, PieceType pieceType) { + this.notation = notation; + this.pieceType = pieceType; + } + + public static Character of(Color color, PieceType targetPieceType) { + PieceNotation targetNotation = Arrays.stream(PieceNotation.values()) + .filter(pieceNotation -> pieceNotation.getPieceType() == targetPieceType) + .findAny() + .orElseThrow(() -> new IllegalStateException("[ERROR] 기물의 표기법을 찾을 수 없습니다.")); + if (color.isBlack()) { + return Character.toUpperCase(targetNotation.getNotation()); + } + // white + return Character.toLowerCase(targetNotation.getNotation()); + } + + public Character getNotation() { + return notation; + } + + public PieceType getPieceType() { + return pieceType; + } +} diff --git a/src/test/java/chess/board/BoardTest.java b/src/test/java/chess/board/BoardTest.java new file mode 100644 index 00000000000..affc088b00e --- /dev/null +++ b/src/test/java/chess/board/BoardTest.java @@ -0,0 +1,556 @@ +package chess.board; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.fixture.BoardFixture; +import chess.fixture.PositionFixture; +import chess.piece.Bishop; +import chess.piece.King; +import chess.piece.Knight; +import chess.piece.Pawn; +import chess.piece.Piece; +import chess.piece.PieceType; +import chess.piece.Queen; +import chess.piece.Rook; +import chess.position.Position; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BoardTest { + + @Nested + @DisplayName("킹의 움직임") + class KingTest { + + // 킹의 움직임 + @DisplayName("킹은 C2에서 C1으로 이동할 수 있다.") + @Test + void test1() { + // given + Position start = PositionFixture.C2; + Position end = PositionFixture.C1; + Board board = BoardFixture.createBoardWithOneWhitePiece(start, King.create()); + // when + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.KING); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + + @DisplayName("시작 위치에 기물이 없을 경우 에외가 발생한다.") + @Test + void test11() { + // given + Position start = PositionFixture.C2; + Position end = PositionFixture.C3; + Board board = BoardFixture.createBoardWithOneWhitePiece(PositionFixture.C1, King.create()); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 해당 위치에 기물이 없습니다."); + } + + @DisplayName("킹이 도착할 위치에 같은 팀의 기물이 있는 경우 예외가 발생한다.") + @Test + void test3() { + // given + Position start = PositionFixture.C2; + Position end = PositionFixture.C3; + Board board = BoardFixture.createBoardWithTWoWhitePiece(PositionFixture.C2, PositionFixture.C3, + King.create(), Pawn.white()); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 같은 팀의 기물은 잡을 수 없습니다."); + } + + @DisplayName("킹이 움직일 수 없는 위치를 입력한 경우 에외가 발생한다.") + @Test + void test2() { + // given + Position start = PositionFixture.C2; + Position end = PositionFixture.C4; + Board board = BoardFixture.createBoardWithOneWhitePiece(start, King.create()); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } + + @DisplayName("킹이 도착할 위치에 다른 팀의 기물이 있는 경우 해당 기물을 잡을 수 있다.") + @Test + void test4() { + // given + Position start = PositionFixture.C2; + Position end = PositionFixture.C3; + Board board = BoardFixture.createBoardWithTwoOppositePiece(PositionFixture.C2, PositionFixture.C3, + King.create(), Pawn.black()); + // when + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(end)).isEqualTo(Color.BLACK); + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.KING); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + } + + @Nested + @DisplayName("나이트의 움직임") + class KnightTest { + private final Position start = PositionFixture.C2; + private final Position end = PositionFixture.E3; + private final Piece knight = Knight.create(); + + // 나이트의 움직임 + @DisplayName("나이트는 C2에서 E3로 움직일 수 있다.") + @Test + void test1() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, knight); + // when + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.KNIGHT); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + + @DisplayName("시작 위치에 기물이 없을 경우 에외가 발생한다.") + @Test + void test11() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(PositionFixture.C1, knight); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 해당 위치에 기물이 없습니다."); + } + + @DisplayName("도착할 위치에 같은 팀의 기물이 있는 경우 예외가 발생한다.") + @Test + void test3() { + // given + Board board = BoardFixture.createBoardWithTWoWhitePiece(start, end, + knight, knight); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 같은 팀의 기물은 잡을 수 없습니다."); + } + + @DisplayName("움직일 수 없는 위치를 입력한 경우 에외가 발생한다.") + @Test + void test2() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, knight); + // when + // then + assertThatThrownBy(() -> board.move(start, PositionFixture.A2)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } + + @DisplayName("도착할 위치에 다른 팀의 기물이 있는 경우 해당 기물을 잡을 수 있다.") + @Test + void test4() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, end, + knight, Pawn.black()); + // when + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(end)).isEqualTo(Color.BLACK); + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.KNIGHT); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + } + + + @Nested + @DisplayName("룩의 움직임") + class RookTest { + private final Position start = PositionFixture.A1; + private final Position end = PositionFixture.A8; + private final Piece rook = Rook.create(); + + @DisplayName("A1에서 A8로 움직일 수 있다.") + @Test + void test1() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, rook); + // when + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.ROOK); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + + @DisplayName("시작 위치에 기물이 없을 경우 에외가 발생한다.") + @Test + void test11() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(PositionFixture.C1, rook); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 해당 위치에 기물이 없습니다."); + } + + @DisplayName("도착할 위치에 같은 팀의 기물이 있는 경우 예외가 발생한다.") + @Test + void test3() { + // given + Board board = BoardFixture.createBoardWithTWoWhitePiece(start, end, + rook, rook); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 같은 팀의 기물은 잡을 수 없습니다."); + } + + @DisplayName("움직일 수 없는 위치를 입력한 경우 에외가 발생한다.") + @Test + void test2() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, rook); + // when + // then + assertThatThrownBy(() -> board.move(start, PositionFixture.B2)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } + + @DisplayName("도착할 위치에 다른 팀의 기물이 있는 경우 해당 기물을 잡을 수 있다.") + @Test + void test4() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, end, + rook, Pawn.black()); + // when + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(end)).isEqualTo(Color.BLACK); + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.ROOK); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + + @DisplayName("중간 경로에 기물이 존재할 경우 예외가 발생한다.") + @Test + void test5() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, PositionFixture.A3, + rook, Pawn.black()); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 다른 기물에 의해 막혀서 이동할 수 없는 경로입니다."); + } + } + + @Nested + @DisplayName("비숍의 움직임") + class BishopTest { + private final Position start = PositionFixture.A1; + private final Position end = PositionFixture.H8; + private final Piece bishop = Bishop.create(); + + @DisplayName("A1에서 H8로 움직일 수 있다.") + @Test + void test1() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, bishop); + // when + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.BISHOP); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + + @DisplayName("시작 위치에 기물이 없을 경우 에외가 발생한다.") + @Test + void test11() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(PositionFixture.C1, bishop); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 해당 위치에 기물이 없습니다."); + } + + @DisplayName("도착할 위치에 같은 팀의 기물이 있는 경우 예외가 발생한다.") + @Test + void test3() { + // given + Board board = BoardFixture.createBoardWithTWoWhitePiece(start, end, + bishop, bishop); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 같은 팀의 기물은 잡을 수 없습니다."); + } + + @DisplayName("움직일 수 없는 위치를 입력한 경우 에외가 발생한다.") + @Test + void test2() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, bishop); + // when + // then + assertThatThrownBy(() -> board.move(start, PositionFixture.B1)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } + + @DisplayName("도착할 위치에 다른 팀의 기물이 있는 경우 해당 기물을 잡을 수 있다.") + @Test + void test4() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, end, + bishop, Pawn.black()); + // when + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(end)).isEqualTo(Color.BLACK); + board.move(start, end); + // then + assertThat(board.pieceTypeAt(end)).isEqualTo(PieceType.BISHOP); + assertThat(board.colorAt(end)).isEqualTo(Color.WHITE); + } + + @DisplayName("중간 경로에 기물이 존재할 경우 예외가 발생한다.") + @Test + void test5() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, PositionFixture.C3, + bishop, Pawn.black()); + // when + // then + assertThatThrownBy(() -> board.move(start, end)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 다른 기물에 의해 막혀서 이동할 수 없는 경로입니다."); + } + } + + @Nested + @DisplayName("퀸의 움직임") + class QueenTest { + private final Position start = PositionFixture.A1; + private final Position end1 = PositionFixture.H8; + private final Position end2 = PositionFixture.A8; + private final Position end3 = PositionFixture.H1; + private final Piece queen = Queen.create(); + + @DisplayName("A1에서 H8로 움직일 수 있다.") + @Test + void test1() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, queen); + // when + board.move(start, end1); + // then + assertThat(board.pieceTypeAt(end1)).isEqualTo(PieceType.QUEEN); + assertThat(board.colorAt(end1)).isEqualTo(Color.WHITE); + } + + @DisplayName("A1에서 A8로 움직일 수 있다.") + @Test + void test111() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, queen); + // when + board.move(start, end2); + // then + assertThat(board.pieceTypeAt(end2)).isEqualTo(PieceType.QUEEN); + assertThat(board.colorAt(end2)).isEqualTo(Color.WHITE); + } + + @DisplayName("A1에서 H1으로 움직일 수 있다.") + @Test + void test1111() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, queen); + // when + board.move(start, end3); + // then + assertThat(board.pieceTypeAt(end3)).isEqualTo(PieceType.QUEEN); + assertThat(board.colorAt(end3)).isEqualTo(Color.WHITE); + } + + @DisplayName("시작 위치에 기물이 없을 경우 에외가 발생한다.") + @Test + void test11() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(PositionFixture.C1, queen); + // when + // then + assertThatThrownBy(() -> board.move(start, end2)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 해당 위치에 기물이 없습니다."); + } + + @DisplayName("도착할 위치에 같은 팀의 기물이 있는 경우 예외가 발생한다.") + @Test + void test3() { + // given + Board board = BoardFixture.createBoardWithTWoWhitePiece(start, end2, + queen, queen); + // when + // then + assertThatThrownBy(() -> board.move(start, end2)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 같은 팀의 기물은 잡을 수 없습니다."); + } + + @DisplayName("움직일 수 없는 위치를 입력한 경우 에외가 발생한다.") + @Test + void test2() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, queen); + // when + // then + assertThatThrownBy(() -> board.move(start, PositionFixture.C2)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 기물의 이동 규칙에 어긋나는 움직임입니다."); + } + + @DisplayName("도착할 위치에 다른 팀의 기물이 있는 경우 해당 기물을 잡을 수 있다.") + @Test + void test4() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, end2, + queen, Pawn.black()); + // when + assertThat(board.pieceTypeAt(end2)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(end2)).isEqualTo(Color.BLACK); + board.move(start, end2); + // then + assertThat(board.pieceTypeAt(end2)).isEqualTo(PieceType.QUEEN); + assertThat(board.colorAt(end2)).isEqualTo(Color.WHITE); + } + + @DisplayName("중간 경로에 기물이 존재할 경우 예외가 발생한다.") + @Test + void test5() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, PositionFixture.A4, + queen, Pawn.black()); + // when + // then + assertThatThrownBy(() -> board.move(start, end2)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 다른 기물에 의해 막혀서 이동할 수 없는 경로입니다."); + } + } + + @Nested + @DisplayName("흰색 폰의 움직임") + class WhitePawnTest { + private final Position start = PositionFixture.C2; + private final Position upEnd = PositionFixture.C3; + private final Position upUpEnd = PositionFixture.C4; + private final Position rightUpEnd = PositionFixture.D3; + private final Position leftUpEnd = PositionFixture.B3; + private final Piece whitePawn = Pawn.white(); + + @DisplayName("C2에서 C3로 이동할 수 있다.") + @Test + void test1() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, whitePawn); + // when + board.move(start, upEnd); + // then + assertThat(board.pieceTypeAt(upEnd)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(upEnd)).isEqualTo(Color.WHITE); + } + + @DisplayName("C2에서 C4로 이동할 수 있다.") + @Test + void test2() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, whitePawn); + // when + board.move(start, upUpEnd); + // then + assertThat(board.pieceTypeAt(upUpEnd)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(upUpEnd)).isEqualTo(Color.WHITE); + } + + @DisplayName("중간에 기물이 있을 경우 두 칸 이동할 수 없다.") + @Test + void test22() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, upEnd, whitePawn, Pawn.black()); + // when + // then + assertThatThrownBy(() -> board.move(start, upUpEnd)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 다른 기물에 의해 막혀서 이동할 수 없는 경로입니다."); + } + + @DisplayName("첫 이동이 아닌 경우 앞으로 2칸 이동할 수 없다.") + @Test + void test3() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, PositionFixture.A8, Pawn.white(), + Pawn.black()); + // when + board.move(start, PositionFixture.C3); + board.move(PositionFixture.A8, PositionFixture.A6); + // then + assertThatThrownBy(() -> board.move(PositionFixture.C3, PositionFixture.C5)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 폰은 첫 움직임에만 두 칸 이동할 수 있습니다."); + } + + @DisplayName("대각선 위에 아무 것도 없으면 이동할 수 없다.") + @Test + void test44() { + // given + Board board = BoardFixture.createBoardWithOneWhitePiece(start, whitePawn); + // when + // then + assertThatThrownBy(() -> board.move(start, rightUpEnd)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 해당 위치에 잡을 수 있는 기물이 없습니다."); + } + + @DisplayName("대각선 위에 상대 기물이 있으면 잡을 수 있다.") + @Test + void test4() { + // given + Board board = BoardFixture.createBoardWithTwoOppositePiece(start, leftUpEnd, whitePawn, Pawn.black()); + // when + assertThat(board.pieceTypeAt(leftUpEnd)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(leftUpEnd)).isEqualTo(Color.BLACK); + board.move(start, leftUpEnd); + // then + assertThat(board.pieceTypeAt(leftUpEnd)).isEqualTo(PieceType.PAWN); + assertThat(board.colorAt(leftUpEnd)).isEqualTo(Color.WHITE); + } + } + + @Nested + @DisplayName("검은색 폰의 움직임") + class BlackPawnTest { + private final Position start = PositionFixture.C3; + private final Position downEnd = PositionFixture.C2; + private final Position downDownEnd = PositionFixture.C1; + private final Position rightDownEnd = PositionFixture.D2; + private final Position leftDownEnd = PositionFixture.B2; + private final Piece blackPawn = Pawn.black(); + } +} diff --git a/src/test/java/chess/fixture/BoardFixture.java b/src/test/java/chess/fixture/BoardFixture.java new file mode 100644 index 00000000000..d29096ff8d8 --- /dev/null +++ b/src/test/java/chess/fixture/BoardFixture.java @@ -0,0 +1,27 @@ +package chess.fixture; + +import chess.board.Board; +import chess.board.Color; +import chess.piece.Piece; +import chess.position.Position; +import java.util.Map; + +public class BoardFixture { + public static Board createBoardWithOneWhitePiece(Position position, Piece piece) { + return new Board(Map.of(position, Color.WHITE), Map.of(position, piece)); + } + + public static Board createBoardWithTWoWhitePiece(Position position1, Position position2, Piece piece1, + Piece piece2) { + return new Board(Map.of(position1, Color.WHITE, position2, Color.WHITE), + Map.of(position1, piece1, position2, piece2)); + } + + public static Board createBoardWithTwoOppositePiece(Position whitePosition, + Position blackPosition, + Piece whitePiece, + Piece blackPiece) { + return new Board(Map.of(whitePosition, Color.WHITE, blackPosition, Color.BLACK), + Map.of(whitePosition, whitePiece, blackPosition, blackPiece)); + } +} diff --git a/src/test/java/chess/Fixtures.java b/src/test/java/chess/fixture/PositionFixture.java similarity index 96% rename from src/test/java/chess/Fixtures.java rename to src/test/java/chess/fixture/PositionFixture.java index f940ab37137..426c6484896 100644 --- a/src/test/java/chess/Fixtures.java +++ b/src/test/java/chess/fixture/PositionFixture.java @@ -1,7 +1,11 @@ -package chess; +package chess.fixture; + +import chess.position.Column; +import chess.position.Position; +import chess.position.Row; @SuppressWarnings("unused") -public final class Fixtures { +public final class PositionFixture { public static final Position A1 = new Position(Column.A, Row.ONE); public static final Position A2 = new Position(Column.A, Row.TWO); @@ -75,6 +79,6 @@ public final class Fixtures { public static final Position H7 = new Position(Column.H, Row.SEVEN); public static final Position H8 = new Position(Column.H, Row.EIGHT); - private Fixtures() { + private PositionFixture() { } } diff --git a/src/test/java/chess/ColumnTest.java b/src/test/java/chess/position/ColumnTest.java similarity index 99% rename from src/test/java/chess/ColumnTest.java rename to src/test/java/chess/position/ColumnTest.java index e43523240f7..5c386b7dc05 100644 --- a/src/test/java/chess/ColumnTest.java +++ b/src/test/java/chess/position/ColumnTest.java @@ -1,11 +1,11 @@ -package chess; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +package chess.position; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + @DisplayName("열") class ColumnTest { diff --git a/src/test/java/chess/PositionTest.java b/src/test/java/chess/position/PositionTest.java similarity index 90% rename from src/test/java/chess/PositionTest.java rename to src/test/java/chess/position/PositionTest.java index 3ad7cc64084..e07222ab682 100644 --- a/src/test/java/chess/PositionTest.java +++ b/src/test/java/chess/position/PositionTest.java @@ -1,39 +1,38 @@ -package chess; +package chess.position; + +import static chess.fixture.PositionFixture.A1; +import static chess.fixture.PositionFixture.A2; +import static chess.fixture.PositionFixture.A3; +import static chess.fixture.PositionFixture.A6; +import static chess.fixture.PositionFixture.A7; +import static chess.fixture.PositionFixture.A8; +import static chess.fixture.PositionFixture.B1; +import static chess.fixture.PositionFixture.B2; +import static chess.fixture.PositionFixture.B3; +import static chess.fixture.PositionFixture.B7; +import static chess.fixture.PositionFixture.B8; +import static chess.fixture.PositionFixture.C1; +import static chess.fixture.PositionFixture.F1; +import static chess.fixture.PositionFixture.F8; +import static chess.fixture.PositionFixture.G1; +import static chess.fixture.PositionFixture.G2; +import static chess.fixture.PositionFixture.G6; +import static chess.fixture.PositionFixture.G7; +import static chess.fixture.PositionFixture.G8; +import static chess.fixture.PositionFixture.H1; +import static chess.fixture.PositionFixture.H2; +import static chess.fixture.PositionFixture.H7; +import static chess.fixture.PositionFixture.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; +import java.util.stream.Stream; 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 { diff --git a/src/test/java/chess/RowTest.java b/src/test/java/chess/position/RowTest.java similarity index 99% rename from src/test/java/chess/RowTest.java rename to src/test/java/chess/position/RowTest.java index fcb65485410..d222f1affc4 100644 --- a/src/test/java/chess/RowTest.java +++ b/src/test/java/chess/position/RowTest.java @@ -1,11 +1,11 @@ -package chess; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +package chess.position; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + @DisplayName("행") class RowTest {