diff --git a/src/main/java/chess/Board.java b/src/main/java/chess/Board.java new file mode 100644 index 0000000000..5c11d94672 --- /dev/null +++ b/src/main/java/chess/Board.java @@ -0,0 +1,41 @@ +package chess; + +import chess.piece.Piece; +import java.util.ArrayList; +import java.util.List; + +public class Board { + private final List pieces = new ArrayList<>(); + + public void put(Piece piece) { + pieces.add(piece); + } + + public boolean existSameTeam(Position position, Color color) { + return pieces.stream().anyMatch(piece -> + piece.getPosition().equals(position) && + piece.getColor() == color); + } + + public boolean existPiece(Position position) { + return pieces.stream().anyMatch(piece -> piece.getPosition().equals(position)); + } + + public Piece findPiece(Position position, Color color) { + return pieces.stream() + .filter(piece -> piece.getPosition().equals(position) && piece.getColor() == color) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("움직일 수 없는 기물입니다.")); + } + + public Piece findPiece(Position position) { + return pieces.stream() + .filter(piece -> piece.getPosition().equals(position)) + .findFirst() + .get(); + } + + public void removeByPosition(Position position) { + pieces.removeIf(piece -> piece.getPosition().equals(position)); + } +} diff --git a/src/main/java/chess/BoardInitializer.java b/src/main/java/chess/BoardInitializer.java new file mode 100644 index 0000000000..7704b7910b --- /dev/null +++ b/src/main/java/chess/BoardInitializer.java @@ -0,0 +1,61 @@ +package chess; + +import chess.piece.Bishop; +import chess.piece.King; +import chess.piece.Knight; +import chess.piece.Pawn; +import chess.piece.Queen; +import chess.piece.Rook; +import java.util.Arrays; + +public class BoardInitializer { + + public Board generateBoard() { + Board board = new Board(); + putPawn(board); + putRook(board); + putKnight(board); + putBishop(board); + putQueen(board); + putKing(board); + return board; + } + + private static void putKing(Board board) { + board.put(new King(new Position(Row.EIGHT, Column.D), board, Color.BLACK)); + board.put(new King(new Position(Row.ONE, Column.D), board, Color.WHITE)); + } + + private static void putQueen(Board board) { + board.put(new Queen(new Position(Row.EIGHT, Column.E), board, Color.BLACK)); + board.put(new Queen(new Position(Row.ONE, Column.E), board, Color.WHITE)); + } + + private static void putBishop(Board board) { + board.put(new Bishop(new Position(Row.EIGHT, Column.C), board, Color.BLACK)); + board.put(new Bishop(new Position(Row.ONE, Column.C), board, Color.WHITE)); + board.put(new Bishop(new Position(Row.EIGHT, Column.F), board, Color.BLACK)); + board.put(new Bishop(new Position(Row.ONE, Column.F), board, Color.WHITE)); + } + + private static void putKnight(Board board) { + board.put(new Knight(new Position(Row.EIGHT, Column.B), board, Color.BLACK)); + board.put(new Knight(new Position(Row.ONE, Column.B), board, Color.WHITE)); + board.put(new Knight(new Position(Row.EIGHT, Column.G), board, Color.BLACK)); + board.put(new Knight(new Position(Row.ONE, Column.G), board, Color.WHITE)); + } + + private static void putRook(Board board) { + board.put(new Rook(new Position(Row.EIGHT, Column.A), board, Color.BLACK)); + board.put(new Rook(new Position(Row.ONE, Column.A), board, Color.WHITE)); + board.put(new Rook(new Position(Row.EIGHT, Column.H), board, Color.BLACK)); + board.put(new Rook(new Position(Row.ONE, Column.H), board, Color.WHITE)); + } + + private void putPawn(Board board) { + Arrays.stream(Column.values()).forEach(column -> { + board.put(new Pawn(new Position(Row.SEVEN, column), board, Color.BLACK)); + board.put(new Pawn(new Position(Row.TWO, column), board, Color.WHITE)); + }); + } +} diff --git a/src/main/java/chess/ChessApplication.java b/src/main/java/chess/ChessApplication.java new file mode 100644 index 0000000000..30924edc1b --- /dev/null +++ b/src/main/java/chess/ChessApplication.java @@ -0,0 +1,15 @@ +package chess; + +import chess.controller.Controller; +import chess.view.InputView; +import chess.view.OutputView; + +public class ChessApplication { + + public static void main(String[] args) { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + Controller controller = new Controller(inputView, outputView); + controller.run(); + } +} diff --git a/src/main/java/chess/Column.java b/src/main/java/chess/Column.java index b64b4dc77a..3f8e243a31 100644 --- a/src/main/java/chess/Column.java +++ b/src/main/java/chess/Column.java @@ -1,15 +1,31 @@ package chess; +import java.util.Arrays; +import javax.lang.model.element.NestingKind; + public enum Column { - A, - B, - C, - D, - E, - F, - G, - H; + A("A"), + B("B"), + C("C"), + D("D"), + E("E"), + F("F"), + G("G"), + H("H"); + + private final String index; + + Column(String index) { + this.index = index; + } + + public static Column from(String index) { + return Arrays.stream(Column.values()) + .filter(column -> column.index.equals(index)) + .findFirst() + .get(); + } public boolean isFarLeft() { return ordinal() == 0; diff --git a/src/main/java/chess/Movement.java b/src/main/java/chess/Movement.java index e57c6e91bb..f8362daf32 100644 --- a/src/main/java/chess/Movement.java +++ b/src/main/java/chess/Movement.java @@ -45,4 +45,16 @@ public boolean isVertical() { public boolean isDiagonal() { return x != 0 && y != 0 && Math.abs(x) == Math.abs(y); } + + public boolean isStraightOneStep() { + return (x == 0 && Math.abs(y) == 1) || (y == 0 && Math.abs(x) == 1); + } + + public boolean isCrossOneStep() { + return Math.abs(x) + Math.abs(y) == 2 && Math.abs(x) == 1 && Math.abs(y) == 1; + } + + public boolean isMoveThreeStep() { + return Math.abs(x) + Math.abs(y) == 3; + } } diff --git a/src/main/java/chess/Row.java b/src/main/java/chess/Row.java index 126ed048da..7965474550 100644 --- a/src/main/java/chess/Row.java +++ b/src/main/java/chess/Row.java @@ -1,15 +1,35 @@ package chess; +import java.lang.module.FindException; +import java.util.Arrays; + public enum Row { - EIGHT, - SEVEN, - SIX, - FIVE, - FOUR, - THREE, - TWO, - ONE; + EIGHT(8), + SEVEN(7), + SIX(6), + FIVE(5), + FOUR(4), + THREE(3), + TWO(2), + ONE(1); + + private final int index; + + Row(int index) { + this.index = index; + } + + public static Row from(int index) { + return Arrays.stream(Row.values()) + .filter(row -> row.index == index) + .findFirst() + .get(); + } + + public String getRowName() { + return String.valueOf(index); + } public boolean isTop() { return ordinal() == 0; diff --git a/src/main/java/chess/controller/Controller.java b/src/main/java/chess/controller/Controller.java new file mode 100644 index 0000000000..d42563b15d --- /dev/null +++ b/src/main/java/chess/controller/Controller.java @@ -0,0 +1,61 @@ +package chess.controller; + +import chess.Board; +import chess.BoardInitializer; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import chess.piece.Piece; +import chess.view.InputView; +import chess.view.OutputView; + +public class Controller { + private final InputView inputView; + private final OutputView outputView; + Color turn = Color.BLACK; + + public Controller(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void run() { + BoardInitializer boardInitializer = new BoardInitializer(); + Board board = boardInitializer.generateBoard(); + retry(() -> processe(board, turn)); + } + + private void processe(Board board, Color turn) { + outputView.printBoard(board); + String command = inputView.inputMoveCommand(turn); + if (command.equals("Q")) { + System.exit(0); + } + String[] positions = command.split(", "); + Position movePiecePosition = parsePosition(positions[0]); + Position targetPosition = parsePosition(positions[1]); + Piece piece = board.findPiece(movePiecePosition, turn); + piece.move(targetPosition); + turn = turn.opposite(); + processe(board, turn); + } + + private Position parsePosition(String position) { + String[] splited = position.split(""); + return new Position( + Row.from(Integer.parseInt(splited[0])), + Column.from(splited[1]) + ); + } + + private void retry(Runnable runnable) { + try { + runnable.run(); + } catch (Exception e) { + System.out.println(e.getMessage()); + retry(runnable); + } + } + +} diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index b14ab70f98..a10f38c912 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -1,5 +1,41 @@ package chess.piece; -public class Bishop { +import chess.Board; +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +public class Bishop extends Piece { + + public Bishop(Position position, Board board, Color color) { + super(position, board, color); + } + + @Override + protected Set getMovablePositions() { + Set movablePositions = new HashSet<>(); + Arrays.stream(Movement.values()) + .filter(Movement::isCrossOneStep) + .forEach(movement -> { + Position currPosition = getPosition(); + while(currPosition.canMove(movement)) { + currPosition = currPosition.move(movement); + if (!board.existSameTeam(currPosition, getColor())) { + movablePositions.add(currPosition); + } + if (board.existPiece(currPosition)) { + break; + } + } + }); + return movablePositions; + } + + @Override + public String toString() { + return "BI"; + } } diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java index d64210cad1..58472a83e9 100644 --- a/src/main/java/chess/piece/King.java +++ b/src/main/java/chess/piece/King.java @@ -1,5 +1,38 @@ package chess.piece; -public class King { +import chess.Board; +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; +public class King extends Piece { + + public King(Position position, Board board, Color color) { + super(position, board, color); + } + + @Override + public Set getMovablePositions() { + return Arrays.stream(Movement.values()) + .filter(this::isOneStepMovement) + .filter(movement -> canMove(movement, getPosition())) + .map(getPosition()::move) + .collect(Collectors.toSet()); + } + + private boolean canMove(Movement movement, Position currentPosition) { + return currentPosition.canMove(movement) && !board.existSameTeam(currentPosition.move(movement), getColor()); + } + + private boolean isOneStepMovement(Movement movement) { + return movement.isCrossOneStep() || movement.isStraightOneStep(); + } + + @Override + public String toString() { + return "KI"; + } } diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java index 2ee7c47a3b..faf38e49f8 100644 --- a/src/main/java/chess/piece/Knight.java +++ b/src/main/java/chess/piece/Knight.java @@ -1,5 +1,34 @@ package chess.piece; -public class Knight { +import chess.Board; +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; +public class Knight extends Piece { + + public Knight(Position position, Board board, Color color) { + super(position, board, color); + } + + @Override + public Set getMovablePositions() { + return Arrays.stream(Movement.values()) + .filter(Movement::isMoveThreeStep) + .filter(movement -> canMove(movement, getPosition())) + .map(getPosition()::move) + .collect(Collectors.toSet()); + } + + private boolean canMove(Movement movement, Position currentPosition) { + return currentPosition.canMove(movement) && !board.existSameTeam(currentPosition.move(movement), getColor()); + } + + @Override + public String toString() { + return "KN"; + } } diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java index c8b6cafa51..589feae03a 100644 --- a/src/main/java/chess/piece/Pawn.java +++ b/src/main/java/chess/piece/Pawn.java @@ -1,5 +1,75 @@ package chess.piece; -public class Pawn { +import chess.Board; +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.HashSet; +import java.util.Set; +public class Pawn extends Piece { + + boolean isFirstMove = true; + + public Pawn(Position position, Board board, Color color) { + super(position, board, color); + } + + @Override + public void move(Position position) { + super.move(position); + isFirstMove = false; + } + + @Override + public Set getMovablePositions() { + Set movablePositions = new HashSet<>(); + Movement movement = getMovableMovement(); + Position currPosition = getPosition(); + for (int i = 0; i < computeMovableCount(); i++) { + if (!currPosition.canMove(movement)) { + continue; + } + currPosition = currPosition.move(movement); + if (currPosition.canMove(Movement.LEFT) && i == 0 && + board.existSameTeam(currPosition.move(Movement.LEFT), getColor().opposite()) + ) { + movablePositions.add(currPosition.move(Movement.LEFT)); + } + if (currPosition.canMove(Movement.RIGHT) && i == 0 && + board.existSameTeam(currPosition.move(Movement.LEFT), getColor().opposite()) + ) { + movablePositions.add(currPosition.move(Movement.LEFT)); + } + Color otherTeam = getColor().opposite(); + if (board.existSameTeam(currPosition, otherTeam)) { + movablePositions.add(currPosition); + return movablePositions; + } + if (board.existSameTeam(currPosition, getColor())) { + return movablePositions; + } + movablePositions.add(currPosition); + } + return movablePositions; + } + + private int computeMovableCount() { + if (isFirstMove) { + return 2; + } + return 1; + } + + private Movement getMovableMovement() { + if (getColor().isBlack()) { + return Movement.DOWN; + } + return Movement.UP; + } + + @Override + public String toString() { + return "PA"; + } } diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java new file mode 100644 index 0000000000..3a15878472 --- /dev/null +++ b/src/main/java/chess/piece/Piece.java @@ -0,0 +1,37 @@ +package chess.piece; + +import chess.Board; +import chess.Color; +import chess.Position; +import java.util.Set; + +public abstract class Piece { + protected final Board board; + private Position position; + private final Color color; + + protected Piece(Position position, Board board, Color color) { + this.board = board; + this.position = position; + this.color = color; + } + + public Position getPosition() { + return position; + } + + public Color getColor() { + return color; + } + + public void move(Position position) { + Set positions = getMovablePositions(); + if (!positions.contains(position)) { + throw new IllegalArgumentException("이동할 수 없는 위치입니다."); + } + board.removeByPosition(position); + this.position = position; + } + + protected abstract Set getMovablePositions(); +} diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 9b547261c4..88705bdfe8 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -1,5 +1,41 @@ package chess.piece; -public class Queen { +import chess.Board; +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +public class Queen extends Piece { + + public Queen(Position position, Board board, Color color) { + super(position, board, color); + } + + @Override + protected Set getMovablePositions() { + Set movablePositions = new HashSet<>(); + Arrays.stream(Movement.values()) + .filter(movement -> movement.isCrossOneStep() || movement.isStraightOneStep()) + .forEach(movement -> { + Position currPosition = getPosition(); + while(currPosition.canMove(movement)) { + currPosition = currPosition.move(movement); + if (!board.existSameTeam(currPosition, getColor())) { + movablePositions.add(currPosition); + } + if (board.existPiece(currPosition)) { + break; + } + } + }); + return movablePositions; + } + + @Override + public String toString() { + return "QU"; + } } diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index 7ed4d08bf0..be5590f585 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -1,5 +1,41 @@ package chess.piece; -public class Rook { +import chess.Board; +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +public class Rook extends Piece { + + public Rook(Position position, Board board, Color color) { + super(position, board, color); + } + + @Override + protected Set getMovablePositions() { + Set movablePositions = new HashSet<>(); + Arrays.stream(Movement.values()) + .filter(Movement::isStraightOneStep) + .forEach(movement -> { + Position currPosition = getPosition(); + while(currPosition.canMove(movement)) { + currPosition = currPosition.move(movement); + if (!board.existSameTeam(currPosition, getColor())) { + movablePositions.add(currPosition); + } + if (board.existPiece(currPosition)) { + break; + } + } + }); + return movablePositions; + } + + @Override + public String toString() { + return "RO"; + } } diff --git a/src/main/java/chess/view/CustomStringBuilder.java b/src/main/java/chess/view/CustomStringBuilder.java new file mode 100644 index 0000000000..de3e543b02 --- /dev/null +++ b/src/main/java/chess/view/CustomStringBuilder.java @@ -0,0 +1,21 @@ +package chess.view; + +public class CustomStringBuilder { + private final StringBuilder stringBuilder = new StringBuilder(); + + public void appendLine(String content) { + stringBuilder.append(content).append('\n'); + } + + public void append(String content) { + stringBuilder.append(content); + } + + public void print() { + System.out.println(stringBuilder); + } + + public void appendCell(String content) { + stringBuilder.append(content).append(" "); + } +} diff --git a/src/main/java/chess/view/InputView.java b/src/main/java/chess/view/InputView.java new file mode 100644 index 0000000000..101558593e --- /dev/null +++ b/src/main/java/chess/view/InputView.java @@ -0,0 +1,18 @@ +package chess.view; + +import chess.Color; +import java.util.Scanner; + +public class InputView { + + Scanner scanner = new Scanner(System.in); + + public String inputMoveCommand(Color turn) { + System.out.println(String.format(""" + 현재 턴: %s + 이동시킬 기물의 위치와 목표 위치를 입력해 주세요. (종료Q) + ex) 7A, 6A + """, turn.name())); + return scanner.nextLine(); + } +} diff --git a/src/main/java/chess/view/OutputView.java b/src/main/java/chess/view/OutputView.java new file mode 100644 index 0000000000..e05f3e0c29 --- /dev/null +++ b/src/main/java/chess/view/OutputView.java @@ -0,0 +1,46 @@ +package chess.view; + +import chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import chess.piece.Piece; + +public class OutputView { + + public static final String black = "\u001B[30m"; + public static final String white = "\u001B[37m"; + public static final String exit = "\u001B[0m"; + + public void printBoard(Board board) { + CustomStringBuilder stringBuilder = new CustomStringBuilder(); + stringBuilder.appendCell(" "); + for (Column column : Column.values()) { + stringBuilder.appendCell(column.name()); + stringBuilder.append(" "); + } + stringBuilder.appendLine(""); + for (Row row : Row.values()) { + stringBuilder.appendCell(row.getRowName()); + for (Column column : Column.values()) { + Position position = new Position(row, column); + if (!board.existPiece(position)) { + stringBuilder.appendCell("- "); + continue; + } + Piece piece = board.findPiece(position); + stringBuilder.appendCell(convertContentColor(piece)); + } + stringBuilder.appendLine(""); + } + stringBuilder.print(); + } + + private String convertContentColor(Piece piece) { + if (piece.getColor() == Color.WHITE) { + return String.format("%s%s%s", white, piece.toString(), exit); + } + return String.format("%s%s%s", black, piece.toString(), exit); + } +} diff --git a/src/test/java/chess/BoardInitializerTest.java b/src/test/java/chess/BoardInitializerTest.java new file mode 100644 index 0000000000..4ccc1f4db8 --- /dev/null +++ b/src/test/java/chess/BoardInitializerTest.java @@ -0,0 +1,68 @@ +package chess; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +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 org.junit.jupiter.api.Test; + +class BoardInitializerTest { + + @Test + void 체스판을_초기화_한다() { + BoardInitializer boardInitializer = new BoardInitializer(); + Board board = boardInitializer.generateBoard(); + assertBlack(board); + assertWhite(board); + } + + private void assertBlack(Board board) { + assertThat(board.findPiece(new Position(Row.EIGHT, Column.A), Color.BLACK)).isInstanceOf(Rook.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.B), Color.BLACK)).isInstanceOf(Knight.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.C), Color.BLACK)).isInstanceOf(Bishop.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.D), Color.BLACK)).isInstanceOf(King.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.E), Color.BLACK)).isInstanceOf(Queen.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.F), Color.BLACK)).isInstanceOf(Bishop.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.G), Color.BLACK)).isInstanceOf(Knight.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.H), Color.BLACK)).isInstanceOf(Rook.class); + assertThat(board.findPiece(new Position(Row.EIGHT, Column.H), Color.BLACK)).isInstanceOf(Rook.class); + + assertThat(board.findPiece(new Position(Row.SEVEN, Column.A), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.B), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.C), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.D), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.E), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.F), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.G), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.H), Color.BLACK)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.SEVEN, Column.H), Color.BLACK)).isInstanceOf(Pawn.class); + } + + private void assertWhite(Board board) { + assertThat(board.findPiece(new Position(Row.ONE, Column.A), Color.WHITE)).isInstanceOf(Rook.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.B), Color.WHITE)).isInstanceOf(Knight.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.C), Color.WHITE)).isInstanceOf(Bishop.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.D), Color.WHITE)).isInstanceOf(King.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.E), Color.WHITE)).isInstanceOf(Queen.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.F), Color.WHITE)).isInstanceOf(Bishop.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.G), Color.WHITE)).isInstanceOf(Knight.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.H), Color.WHITE)).isInstanceOf(Rook.class); + assertThat(board.findPiece(new Position(Row.ONE, Column.H), Color.WHITE)).isInstanceOf(Rook.class); + + assertThat(board.findPiece(new Position(Row.TWO, Column.A), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.B), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.C), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.D), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.E), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.F), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.G), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.H), Color.WHITE)).isInstanceOf(Pawn.class); + assertThat(board.findPiece(new Position(Row.TWO, Column.H), Color.WHITE)).isInstanceOf(Pawn.class); + } +} diff --git a/src/test/java/chess/BoardTest.java b/src/test/java/chess/BoardTest.java new file mode 100644 index 0000000000..efda798d5e --- /dev/null +++ b/src/test/java/chess/BoardTest.java @@ -0,0 +1,53 @@ +package chess; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.piece.Knight; +import chess.piece.Piece; +import org.junit.jupiter.api.Test; + +class BoardTest { + + @Test + void 체스판의_특정_위치에_아군_말이_존재하는지_확인한다() { + Board board = new Board(); + Position position = new Position(Row.SEVEN, Column.C); + board.put(new Knight(position, board, Color.BLACK)); + + assertThat(board.existSameTeam(position, Color.BLACK)).isTrue(); + } + + @Test + void 체스판에서_특정_위치에_있는_특정_팀의_기물을_찾는다() { + Board board = new Board(); + Position position = new Position(Row.SEVEN, Column.C); + board.put(new Knight(position, board, Color.BLACK)); + + Piece piece = board.findPiece(position, Color.BLACK); + + assertThat(piece.getPosition()).isEqualTo(position); + assertThat(piece.getColor()).isEqualTo(Color.BLACK); + } + + @Test + void 자신의_기물이_아닌_것을_움직이면_예외가_발생한다() { + Board board = new Board(); + Position position = new Position(Row.SEVEN, Column.C); + board.put(new Knight(position, board, Color.BLACK)); + + assertThatThrownBy(() -> board.findPiece(position, Color.WHITE)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void 특정_위치에_있는_기물을_제거한다() { + Board board = new Board(); + Position position = new Position(Row.SEVEN, Column.C); + board.put(new Knight(position, board, Color.WHITE)); + + board.removeByPosition(position); + + assertThat(board.existPiece(position)).isFalse(); + } +} diff --git a/src/test/java/chess/piece/BishopTest.java b/src/test/java/chess/piece/BishopTest.java new file mode 100644 index 0000000000..6d61ea78d7 --- /dev/null +++ b/src/test/java/chess/piece/BishopTest.java @@ -0,0 +1,26 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class BishopTest { + + @Test + void 비숍이_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.SIX, Column.B), board, Color.WHITE)); + board.put(new Knight(new Position(Row.TWO, Column.F), board, Color.BLACK)); + Piece rook = new Bishop(new Position(Row.FOUR, Column.D), board, Color.WHITE); + + Set positions = rook.getMovablePositions(); + + assertThat(positions).hasSize(10); + } +} diff --git a/src/test/java/chess/piece/KingTest.java b/src/test/java/chess/piece/KingTest.java new file mode 100644 index 0000000000..3f603103b6 --- /dev/null +++ b/src/test/java/chess/piece/KingTest.java @@ -0,0 +1,37 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class KingTest { + + @Test + void 킹이_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.SIX, Column.E), board, Color.WHITE)); + board.put(new Knight(new Position(Row.SIX, Column.F), board, Color.WHITE)); + board.put(new Knight(new Position(Row.SIX, Column.G), board, Color.BLACK)); + Piece king = new King(new Position(Row.FIVE, Column.F), board, Color.WHITE); + + Set positions = king.getMovablePositions(); + + assertThat(positions).hasSize(6); + } + + @Test + void 킹이_뒤로_이동할_수_없는_위치에_있는_경우_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + Piece king = new King(new Position(Row.ONE, Column.D), board, Color.WHITE); + + Set positions = king.getMovablePositions(); + + assertThat(positions).hasSize(5); + } +} diff --git a/src/test/java/chess/piece/KnightTest.java b/src/test/java/chess/piece/KnightTest.java new file mode 100644 index 0000000000..3b386795cc --- /dev/null +++ b/src/test/java/chess/piece/KnightTest.java @@ -0,0 +1,39 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class KnightTest { + + @Test + void 나이트가_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.SEVEN, Column.C), board, Color.WHITE)); + board.put(new Knight(new Position(Row.SEVEN, Column.E), board, Color.WHITE)); + board.put(new Knight(new Position(Row.FOUR, Column.B), board, Color.BLACK)); + Piece knight = new Knight(new Position(Row.FIVE, Column.D), board, Color.WHITE); + + Set positions = knight.getMovablePositions(); + + assertThat(positions).hasSize(6); + } + + @Test + void 나이트가_앞으로_이동할_수_없는_위치에_있는_경우_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.SIX, Column.B), board, Color.WHITE)); + board.put(new Knight(new Position(Row.SIX, Column.B), board, Color.BLACK)); + Piece knight = new Knight(new Position(Row.SEVEN, Column.D), board, Color.WHITE); + + Set positions = knight.getMovablePositions(); + + assertThat(positions).hasSize(5); + } +} diff --git a/src/test/java/chess/piece/PawnTest.java b/src/test/java/chess/piece/PawnTest.java new file mode 100644 index 0000000000..d65feccc04 --- /dev/null +++ b/src/test/java/chess/piece/PawnTest.java @@ -0,0 +1,68 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class PawnTest { + + @Test + void 폰이_처음_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + Piece pawn = new Pawn(new Position(Row.SEVEN, Column.G), board, Color.BLACK); + + Set positions = pawn.getMovablePositions(); + + assertThat(positions).hasSize(2); + } + + @Test + void 폰의_이동이_처음이_아니면_한_칸만_이동할_수_있다() { + Board board = new Board(); + Piece pawn = new Pawn(new Position(Row.SEVEN, Column.G), board, Color.BLACK); + pawn.move(new Position(Row.SIX, Column.G)); + + Set positions = pawn.getMovablePositions(); + + assertThat(positions).hasSize(1); + } + + @Test + void 폰_앞에_우리팀_기물이_있으면_두_칸을_움직일_수_없다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.SIX, Column.G), board, Color.WHITE)); + Piece pawn = new Pawn(new Position(Row.SEVEN, Column.G), board, Color.BLACK); + + Set positions = pawn.getMovablePositions(); + + assertThat(positions).hasSize(1); + } + + @Test + void 폰의_대각선에_상대_기물이_있으면_이동할_수_있다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.FOUR, Column.F), board, Color.WHITE)); + Piece pawn = new Pawn(new Position(Row.FIVE, Column.G), board, Color.BLACK); + + Set positions = pawn.getMovablePositions(); + + assertThat(positions).hasSize(3); + } + + + @Test + void 폰이_끝까지_가면_갈_곳이_없다() { + Board board = new Board(); + Piece pawn = new Pawn(new Position(Row.ONE, Column.D), board, Color.BLACK); + + Set positions = pawn.getMovablePositions(); + + assertThat(positions).isEmpty(); + } +} diff --git a/src/test/java/chess/piece/PieceTest.java b/src/test/java/chess/piece/PieceTest.java new file mode 100644 index 0000000000..4bb5e1e595 --- /dev/null +++ b/src/test/java/chess/piece/PieceTest.java @@ -0,0 +1,29 @@ +package chess.piece; + +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 chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class PieceTest { + + @Test + void 기물을_특정_위치로_움직인다() { + Board board = new Board(); + Position position = new Position(Row.FIVE, Column.D); + board.put(new Knight(position, board, Color.BLACK)); + + Piece piece = board.findPiece(position, Color.BLACK); + Position targetPosition = new Position(Row.SEVEN, Column.C); + piece.move(targetPosition); + + assertThat(piece.getPosition()).isEqualTo(targetPosition); + } +} diff --git a/src/test/java/chess/piece/QueenTest.java b/src/test/java/chess/piece/QueenTest.java new file mode 100644 index 0000000000..0dc02cb7a6 --- /dev/null +++ b/src/test/java/chess/piece/QueenTest.java @@ -0,0 +1,28 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class QueenTest { + + @Test + void 퀸이_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.SIX, Column.B), board, Color.WHITE)); + board.put(new Knight(new Position(Row.TWO, Column.F), board, Color.BLACK)); + board.put(new Knight(new Position(Row.FOUR, Column.G), board, Color.WHITE)); + board.put(new Knight(new Position(Row.FOUR, Column.B), board, Color.BLACK)); + Piece rook = new Queen(new Position(Row.FOUR, Column.D), board, Color.WHITE); + + Set positions = rook.getMovablePositions(); + + assertThat(positions).hasSize(21); + } +} diff --git a/src/test/java/chess/piece/RookTest.java b/src/test/java/chess/piece/RookTest.java new file mode 100644 index 0000000000..4e707f8f02 --- /dev/null +++ b/src/test/java/chess/piece/RookTest.java @@ -0,0 +1,26 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Board; +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class RookTest { + + @Test + void 룩이_이동할_수_있는_위치를_계산한다() { + Board board = new Board(); + board.put(new Knight(new Position(Row.FIVE, Column.G), board, Color.WHITE)); + board.put(new Knight(new Position(Row.FIVE, Column.B), board, Color.BLACK)); + Piece rook = new Rook(new Position(Row.FIVE, Column.D), board, Color.WHITE); + + Set positions = rook.getMovablePositions(); + + assertThat(positions).hasSize(11); + } +}