diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 0000000000..0fb979a468 --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,10 @@ +import chess.ChessRunner; +import view.InputView; +import view.OutputView; + +public class Application { + public static void main(String[] args) { + ChessRunner chessRunner = new ChessRunner(new InputView(),new OutputView()); + chessRunner.run(); + } +} diff --git a/src/main/java/chess/ChessBoard.java b/src/main/java/chess/ChessBoard.java new file mode 100644 index 0000000000..4f7bc6c45c --- /dev/null +++ b/src/main/java/chess/ChessBoard.java @@ -0,0 +1,54 @@ +package chess; + +import chess.piece.King; +import chess.piece.Piece; +import chess.piece.PieceType; +import java.util.List; +import java.util.Optional; + +public class ChessBoard { + + private final List pieces; + + public ChessBoard(List pieces) { + this.pieces = pieces; + } + + public void movePiece(Position startPosition, Position endPosition, Color turn){ + Piece startPiece = pieces.stream().filter(piece -> piece.isSamePosition(startPosition) && piece.isSameColor(turn)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("해당 자리에는 말이 없거나 상대 말입니다.")); + boolean canMove = startPiece.canMove(endPosition, findAlivePiece()); + + if(!canMove){ + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + + Optional endPiece = pieces.stream() + .filter(piece -> piece.isSamePosition(endPosition) && piece.isAnotherTeam(startPiece)) + .findAny(); + startPiece.moveTo(endPosition,findAlivePiece()); + endPiece.ifPresent(Piece::changePieceToDead); + } + + public boolean isKingDead(){ + return pieces.stream() + .anyMatch(piece -> piece.isSamePieceType(PieceType.KING) && !piece.isAlive()); + } + + public Color findWinColor(){ + Optional deadKing = pieces.stream() + .filter(piece -> piece.isSamePieceType(PieceType.KING) && !piece.isAlive()) + .findAny(); + if(deadKing.isEmpty()){ + throw new IllegalArgumentException("게임이 아직 안끝났습니다."); + } + return deadKing.get().getColor().opposite(); + } + + public List findAlivePiece(){ + return pieces.stream() + .filter(Piece::isAlive) + .toList(); + } +} diff --git a/src/main/java/chess/ChessRunner.java b/src/main/java/chess/ChessRunner.java new file mode 100644 index 0000000000..cd2cc4e98e --- /dev/null +++ b/src/main/java/chess/ChessRunner.java @@ -0,0 +1,57 @@ +package chess; + +import chess.piece.Piece; +import java.util.List; +import view.InputView; +import view.OutputView; + +public class ChessRunner { + + private final InputView inputView; + private final OutputView outputView; + + public ChessRunner(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void run(){ + ChessBoard chessBoard = initializeBoard(); + showBoard(chessBoard); + startGame(chessBoard); + } + + private void showBoard(ChessBoard chessBoard){ + List alivePiece = chessBoard.findAlivePiece(); + outputView.printBoard(alivePiece); + } + + + private void startGame(ChessBoard chessBoard){ + Color turn = Color.WHITE; + while (!chessBoard.isKingDead()) { + move(chessBoard,turn); + showBoard(chessBoard); + turn = turn.opposite(); + } + Color winColor = chessBoard.findWinColor(); + outputView.printWinner(winColor); + } + + public void move(ChessBoard chessBoard,Color turn){ + while(true){ + try{ + Position startPosition = inputView.getStartPosition(turn); + Position endPosition = inputView.getEndPosition(); + chessBoard.movePiece(startPosition,endPosition,turn); + return; + }catch(IllegalArgumentException e){ + outputView.printExceptionMessage(e.getMessage()); + } + } + } + + private ChessBoard initializeBoard(){ + return new ChessBoard(PiecesFactory.getInitializedPieces()); + } +} diff --git a/src/main/java/chess/Color.java b/src/main/java/chess/Color.java index 55cd020b68..8e25bf4d98 100644 --- a/src/main/java/chess/Color.java +++ b/src/main/java/chess/Color.java @@ -2,9 +2,13 @@ public enum Color { - BLACK, - WHITE, - EMPTY; + BLACK("흑"), + WHITE("백"), + EMPTY("없음"); + + Color(String name) { + this.name = name; + } public boolean isWhite() { return this == WHITE; @@ -25,4 +29,10 @@ public Color opposite() { default -> EMPTY; }; } + + private final String name; + + public String getName() { + return name; + } } diff --git a/src/main/java/chess/Column.java b/src/main/java/chess/Column.java index b64b4dc77a..8cfd4b35f9 100644 --- a/src/main/java/chess/Column.java +++ b/src/main/java/chess/Column.java @@ -1,15 +1,34 @@ package chess; +import java.util.Arrays; + 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 char name; + + Column(char name) { + this.name = name; + } + + public char getName() { + return name; + } + + public static Column findColumn(char input){ + return Arrays.stream(Column.values()) + .filter(row -> row.name==input) + .findAny() + .orElseThrow(()->new IllegalArgumentException("A부터 H까지 열을 선택해주세요(대문자만 가능합니다)")); + } public boolean isFarLeft() { return ordinal() == 0; @@ -50,4 +69,5 @@ public Column moveRight(final int step) { throw new IllegalStateException("움직일 수 없는 위치입니다."); } + } diff --git a/src/main/java/chess/PiecesFactory.java b/src/main/java/chess/PiecesFactory.java new file mode 100644 index 0000000000..2617c27447 --- /dev/null +++ b/src/main/java/chess/PiecesFactory.java @@ -0,0 +1,57 @@ +package chess; + +import chess.piece.Bishop; +import chess.piece.King; +import chess.piece.Knight; +import chess.piece.Pawn; +import chess.piece.Piece; +import chess.piece.Queen; +import chess.piece.Rook; +import java.util.List; +import java.util.Map; + +public class PiecesFactory { + + private static final List pieces; + + static { + pieces=List.of( + new Pawn(Color.WHITE,new Position(Row.TWO,Column.A)), + new Pawn(Color.WHITE,new Position(Row.TWO,Column.B)), + new Pawn(Color.WHITE,new Position(Row.TWO,Column.C)), + new Pawn(Color.WHITE,new Position(Row.TWO,Column.D)), + new Pawn(Color.WHITE,new Position(Row.TWO,Column.E)), + new Pawn(Color.WHITE,new Position(Row.TWO,Column.F)), + new Pawn(Color.WHITE,new Position(Row.TWO,Column.G)), + new Pawn(Color.WHITE,new Position(Row.TWO,Column.H)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.A)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.B)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.C)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.D)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.E)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.F)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.G)), + new Pawn(Color.BLACK,new Position(Row.SEVEN,Column.H)), + new King(Color.WHITE,new Position(Row.ONE,Column.E)), + new King(Color.BLACK,new Position(Row.EIGHT,Column.E)), + new Queen(Color.WHITE,new Position(Row.ONE,Column.D)), + new Queen(Color.BLACK,new Position(Row.EIGHT,Column.D)), + new Rook(Color.WHITE,new Position(Row.ONE,Column.A)), + new Rook(Color.WHITE,new Position(Row.ONE,Column.H)), + new Rook(Color.BLACK,new Position(Row.EIGHT,Column.A)), + new Rook(Color.BLACK,new Position(Row.EIGHT,Column.H)), + new Knight(Color.WHITE,new Position(Row.ONE,Column.B)), + new Knight(Color.WHITE,new Position(Row.ONE,Column.G)), + new Knight(Color.BLACK,new Position(Row.EIGHT,Column.B)), + new Knight(Color.BLACK,new Position(Row.EIGHT,Column.G)), + new Bishop(Color.WHITE,new Position(Row.ONE,Column.C)), + new Bishop(Color.WHITE,new Position(Row.ONE,Column.F)), + new Bishop(Color.BLACK,new Position(Row.EIGHT,Column.C)), + new Bishop(Color.BLACK,new Position(Row.EIGHT,Column.F)) + ); + } + + public static List getInitializedPieces(){ + return pieces; + } +} diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/Position.java index 3ebeb0ea18..1fd9fda8ab 100644 --- a/src/main/java/chess/Position.java +++ b/src/main/java/chess/Position.java @@ -8,6 +8,10 @@ public Position(final Row row, final Column column) { this(column, row); } + public static Position copyOf(final Position position){ + return new Position(position.row,position.column); + } + public boolean canMoveUp() { return row.canMoveUp(1); } @@ -167,4 +171,10 @@ public Position moveHorizontal(final int step) { } return this; } + + public boolean isSamePosition(Position position){ + return row.equals(position.row) && column.equals(position.column); + } + + } diff --git a/src/main/java/chess/Row.java b/src/main/java/chess/Row.java index 126ed048da..8cc6b7a132 100644 --- a/src/main/java/chess/Row.java +++ b/src/main/java/chess/Row.java @@ -1,15 +1,34 @@ package chess; +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 char name; + + Row(char name) { + this.name = name; + } + + public char getName() { + return name; + } + + public static Row findRow(char input){ + return Arrays.stream(Row.values()) + .filter(row -> row.name==input) + .findAny() + .orElseThrow(()->new IllegalArgumentException("1부터 8까지 행을 선택해주세요")); + } public boolean isTop() { return ordinal() == 0; diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index b14ab70f98..2f3b379870 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -1,5 +1,93 @@ package chess.piece; -public class Bishop { +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +public class Bishop extends Piece { + + private static final List movements; + + static { + movements = List.of(Movement.LEFT_UP,Movement.RIGHT_UP,Movement.LEFT_DOWN,Movement.RIGHT_DOWN); + } + + public Bishop(Color color, Position position) { + super(color, position); + } + + @Override + public PieceType getPieceType() { + return PieceType.BISHOP; + } + + @Override + public boolean canMove(Position position, List pieces) { + Optional findMovement = getFindMovement(position, movements); + + if (findMovement.isEmpty()) { + return false; + } + + Movement movement = findMovement.get(); + List paths = getPath(position, movement); + + boolean hasIntermediatePieces = hasIntermediatePieces(pieces, paths); + + if(hasIntermediatePieces){ + return false; + } + + boolean hasPiece = pieces.stream().anyMatch(piece -> piece.isSamePosition(position)); + + if(hasPiece){ + return pieces.stream().anyMatch(piece -> piece.isSamePosition(position) && piece.isAnotherTeam(this)); + } + return true; + } + + private boolean hasIntermediatePieces(List pieces, List paths) { + for (Piece piece : pieces) { + for (Position path : paths) { + if(piece.isSamePosition(path)){ + return true; + } + } + } + return false; + } + + private Optional getFindMovement(Position position, List movements) { + for (Movement movement : movements) { + Position nowPosition = this.position; + while(nowPosition.canMove(movement)){ + nowPosition = nowPosition.move(movement); + if(nowPosition.equals(position)){ + return Optional.of(movement); + } + } + } + return Optional.empty(); + } + + private List getPath(Position endPosition,Movement movement){ + List path = new ArrayList<>(); + Position nowPosition = this.position.move(movement); + while(!nowPosition.equals(endPosition)){ + path.add(nowPosition); + nowPosition = nowPosition.move(movement); + } + return path; + } + + @Override + public void moveTo(Position position, List pieces) { + if (!canMove(position,pieces)) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + this.position = Position.copyOf(position); + } } diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java index d64210cad1..196eb8f487 100644 --- a/src/main/java/chess/piece/King.java +++ b/src/main/java/chess/piece/King.java @@ -1,5 +1,64 @@ package chess.piece; -public class King { +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.List; +import java.util.Optional; +public class King extends Piece { + + private static final List movements; + + static { + movements = List.of(Movement.DOWN,Movement.UP,Movement.LEFT,Movement.RIGHT, + Movement.RIGHT_UP,Movement.LEFT_UP,Movement.RIGHT_DOWN,Movement.LEFT_DOWN); + } + + public King(Color color, Position position) { + super(color, position); + } + + @Override + public PieceType getPieceType() { + return PieceType.KING; + } + + @Override + public boolean canMove(Position position, List pieces) { + Optional findMovement = getFindMovement(position, movements); + + if (findMovement.isEmpty()) { + return false; + } + + boolean hasPiece = pieces.stream().anyMatch(piece -> piece.isSamePosition(position)); + + if(hasPiece){ + return pieces.stream().anyMatch(piece -> piece.isSamePosition(position) && piece.isAnotherTeam(this)); + } + return true; + } + + private Optional getFindMovement(Position position, List movements) { + return movements.stream().filter(movement -> { + boolean canMove = this.position.canMove(movement); + if(!canMove){ + return false; + } + Position newPosition = this.position.move(movement); + return newPosition.isSamePosition(position); + }).findAny(); + } + @Override + public void moveTo(Position position, List pieces) { + if (!canMove(position,pieces)) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + Optional findMovement = getFindMovement(position, movements); + if (findMovement.isEmpty()) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + this.position = this.position.move(findMovement.get()); + } } diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java index 2ee7c47a3b..c7423055c2 100644 --- a/src/main/java/chess/piece/Knight.java +++ b/src/main/java/chess/piece/Knight.java @@ -1,5 +1,66 @@ package chess.piece; -public class Knight { +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.List; +import java.util.Optional; + +public class Knight extends Piece { + + private static final List movements; + + static { + movements = List.of(Movement.UP_UP_LEFT,Movement.UP_UP_RIGHT,Movement.DOWN_DOWN_LEFT,Movement.DOWN_DOWN_RIGHT, + Movement.RIGHT_RIGHT_DOWN,Movement.RIGHT_RIGHT_UP,Movement.LEFT_LEFT_DOWN,Movement.LEFT_LEFT_UP); + } + + public Knight(Color color, Position position) { + super(color, position); + } + + @Override + public PieceType getPieceType() { + return PieceType.KNIGHT; + } + + @Override + public boolean canMove(Position position, List pieces) { + Optional findMovement = getFindMovement(position, movements); + + if (findMovement.isEmpty()) { + return false; + } + + boolean hasPiece = pieces.stream().anyMatch(piece -> piece.isSamePosition(position)); + + if(hasPiece){ + return pieces.stream().anyMatch(piece -> piece.isSamePosition(position) && piece.isAnotherTeam(this)); + } + return true; + } + + private Optional getFindMovement(Position position, List movements) { + return movements.stream().filter(movement -> { + boolean canMove = this.position.canMove(movement); + if(!canMove){ + return false; + } + Position newPosition = this.position.move(movement); + return newPosition.isSamePosition(position); + }).findAny(); + } + @Override + public void moveTo(Position position, List pieces) { + if (!canMove(position,pieces)) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + Optional findMovement = getFindMovement(position, movements); + if (findMovement.isEmpty()) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + this.position = this.position.move(findMovement.get()); + } + } diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java index c8b6cafa51..ac86cf0629 100644 --- a/src/main/java/chess/piece/Pawn.java +++ b/src/main/java/chess/piece/Pawn.java @@ -1,5 +1,82 @@ package chess.piece; -public class Pawn { +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class Pawn extends Piece { + + private static final Map> movementForColor; + + static { + movementForColor = Map.of( + Color.WHITE, + List.of(Movement.UP, Movement.UP_UP,Movement.RIGHT_UP,Movement.LEFT_UP), + Color.BLACK, + List.of(Movement.DOWN, Movement.DOWN_DOWN,Movement.RIGHT_DOWN,Movement.LEFT_DOWN) + ); + } + + private boolean hasMoved; + + public Pawn(Color color, Position position) { + super(color, position); + hasMoved = false; + } + + @Override + public PieceType getPieceType() { + return PieceType.PAWN; + } + + @Override + public boolean canMove(Position position, List pieces) { + List movements = movementForColor.get(this.color); + + Optional findMovement = getFindMovement(position, movements); + + if (findMovement.isEmpty()) { + return false; + } + + Movement movement = findMovement.get(); + boolean hasFriendlyPiece = pieces.stream().anyMatch(piece -> piece.isSamePosition(position)); + if (movement.equals(Movement.UP_UP) || movement.equals(Movement.DOWN_DOWN)) { + return !hasMoved && !hasFriendlyPiece; + } + + if(!(movement.equals(Movement.UP) || movement.equals(Movement.DOWN))){ + return pieces.stream().anyMatch(piece -> piece.isSamePosition(position) && piece.isAnotherTeam(this)); + } + return !hasFriendlyPiece; + } + + private Optional getFindMovement(Position position, List movements) { + return movements.stream().filter(movement -> { + boolean canMove = this.position.canMove(movement); + if(!canMove){ + return false; + } + Position newPosition = this.position.move(movement); + return newPosition.isSamePosition(position); + }).findAny(); + } + @Override + public void moveTo(Position position, List pieces) { + if (!canMove(position,pieces)) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + List movements = movementForColor.get(this.color); + Optional findMovement = getFindMovement(position, movements); + if (findMovement.isEmpty()) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + this.position = this.position.move(findMovement.get()); + hasMoved = true; + } + } diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java new file mode 100644 index 0000000000..ec04687b56 --- /dev/null +++ b/src/main/java/chess/piece/Piece.java @@ -0,0 +1,53 @@ +package chess.piece; + +import chess.Color; +import chess.Position; +import java.util.List; + +public abstract class Piece { + protected Position position; + protected final Color color; + protected boolean isAlive; + + protected Piece(Color color,Position position) { + this.color = color; + this.position = position; + isAlive = true; + } + + public Position getPosition() { + return position; + } + + public boolean isAnotherTeam(Piece piece){ + return !isSameColor(piece.color); + } + + public boolean isSameColor(Color color){ + return this.color.equals(color); + } + + public boolean isSamePosition(Position position){ + return this.position.equals(position); + } + + public boolean isAlive(){ + return isAlive; + } + + public void changePieceToDead(){ + isAlive = false; + } + + public boolean isSamePieceType(PieceType pieceType){ + return getPieceType().equals(pieceType); + } + + public Color getColor() { + return color; + } + + public abstract PieceType getPieceType(); + public abstract void moveTo(Position position, List pieces); + public abstract boolean canMove(Position position, List pieces); +} diff --git a/src/main/java/chess/piece/PieceType.java b/src/main/java/chess/piece/PieceType.java new file mode 100644 index 0000000000..7c0c87647a --- /dev/null +++ b/src/main/java/chess/piece/PieceType.java @@ -0,0 +1,20 @@ +package chess.piece; + +public enum PieceType { + BISHOP("B"), + KING("K"), + KNIGHT("N"), + PAWN("P"), + QUEEN("Q"), + ROCK("R"); + + private final String name; + + PieceType(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 9b547261c4..acd72ba332 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -1,5 +1,100 @@ package chess.piece; -public class Queen { +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class Queen extends Piece { + + private static final List movements; + + static { + movements = List.of(Movement.LEFT_UP,Movement.RIGHT_UP,Movement.LEFT_DOWN,Movement.RIGHT_DOWN, + Movement.UP,Movement.DOWN,Movement.LEFT,Movement.RIGHT); + } + + public Queen(Color color, Position position) { + super(color, position); + } + + @Override + public PieceType getPieceType() { + return PieceType.QUEEN; + } + + @Override + public boolean canMove(Position position, List pieces) { + Optional findMovement = getFindMovement(position, movements); + + if (findMovement.isEmpty()) { + return false; + } + + Movement movement = findMovement.get(); + List paths = getPath(position, movement); + + boolean hasIntermediatePieces = hasIntermediatePieces(pieces, paths); + + if(hasIntermediatePieces){ + return false; + } + + boolean hasPiece = pieces.stream().anyMatch(piece -> piece.isSamePosition(position)); + + if(hasPiece){ + return pieces.stream().anyMatch(piece -> piece.isSamePosition(position) && piece.isAnotherTeam(this)); + } + return true; + } + + private boolean hasIntermediatePieces(List pieces, List paths) { + for (Piece piece : pieces) { + for (Position path : paths) { + if(piece.isSamePosition(path)){ + return true; + } + } + } + return false; + } + + private Optional getFindMovement(Position position, List movements) { + for (Movement movement : movements) { + Position nowPosition = this.position; + while(nowPosition.canMove(movement)){ + nowPosition = nowPosition.move(movement); + if(nowPosition.equals(position)){ + return Optional.of(movement); + } + } + } + return Optional.empty(); + } + + private List getPath(Position endPosition,Movement movement){ + List path = new ArrayList<>(); + Position nowPosition = this.position.move(movement); + while(!nowPosition.equals(endPosition)){ + path.add(nowPosition); + nowPosition = nowPosition.move(movement); + } + return path; + } + @Override + public void moveTo(Position position, List pieces) { + if (!canMove(position,pieces)) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + Optional findMovement = getFindMovement(position, movements); + if (findMovement.isEmpty()) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + this.position = this.position.move(findMovement.get()); + } + + } diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index 7ed4d08bf0..9e1b76f2bb 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -1,5 +1,97 @@ package chess.piece; -public class Rook { +import chess.Color; +import chess.Movement; +import chess.Position; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class Rook extends Piece { + + private static final List movements; + + static { + movements = List.of(Movement.UP,Movement.DOWN,Movement.LEFT,Movement.RIGHT); + } + + public Rook(Color color, Position position) { + super(color, position); + } + + @Override + public PieceType getPieceType() { + return PieceType.ROCK; + } + + @Override + public boolean canMove(Position position, List pieces) { + Optional findMovement = getFindMovement(position, movements); + + if (findMovement.isEmpty()) { + return false; + } + + Movement movement = findMovement.get(); + List paths = getPath(position, movement); + + boolean hasIntermediatePieces = hasIntermediatePieces(pieces, paths); + + if(hasIntermediatePieces){ + return false; + } + + boolean hasPiece = pieces.stream().anyMatch(piece -> piece.isSamePosition(position)); + + if(hasPiece){ + return pieces.stream().anyMatch(piece -> piece.isSamePosition(position) && piece.isAnotherTeam(this)); + } + return true; + } + + private boolean hasIntermediatePieces(List pieces, List paths) { + for (Piece piece : pieces) { + for (Position path : paths) { + if(piece.isSamePosition(path)){ + return true; + } + } + } + return false; + } + + private Optional getFindMovement(Position position, List movements) { + for (Movement movement : movements) { + Position nowPosition = this.position; + while(nowPosition.canMove(movement)){ + nowPosition = nowPosition.move(movement); + if(nowPosition.equals(position)){ + return Optional.of(movement); + } + } + } + return Optional.empty(); + } + + private List getPath(Position endPosition,Movement movement){ + List path = new ArrayList<>(); + Position nowPosition = this.position.move(movement); + while(!nowPosition.equals(endPosition)){ + path.add(nowPosition); + nowPosition = nowPosition.move(movement); + } + return path; + } + @Override + public void moveTo(Position position, List pieces) { + if (!canMove(position,pieces)) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + Optional findMovement = getFindMovement(position, movements); + if (findMovement.isEmpty()) { + throw new IllegalArgumentException("해당 자리에 이동할 수 없습니다."); + } + this.position = this.position.move(findMovement.get()); + } } diff --git a/src/main/java/util/PositionConvertor.java b/src/main/java/util/PositionConvertor.java new file mode 100644 index 0000000000..0ed59132e8 --- /dev/null +++ b/src/main/java/util/PositionConvertor.java @@ -0,0 +1,29 @@ +package util; + +import chess.Column; +import chess.Position; +import chess.Row; + +public class PositionConvertor { + + public static Position convertInputToPosition(String input) { + validateLength(input); + char colInput = getColInput(input); + char rowInput = getRowInput(input); + return new Position(Row.findRow(rowInput), Column.findColumn(colInput)); + } + + private static char getColInput(String input) { + return input.charAt(0); + } + + private static char getRowInput(String input) { + return input.charAt(1); + } + + private static void validateLength(String input) { + if (input.length() != 2) { + throw new IllegalArgumentException("열과 행 정보를 정확히 입력해주세요"); + } + } +} diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000000..a2e42d4d4d --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,21 @@ +package view; + +import chess.Color; +import chess.Position; +import java.util.Scanner; +import util.PositionConvertor; + +public class InputView { + + private final Scanner scanner = new Scanner(System.in); + + public Position getStartPosition(Color turn){ + System.out.printf("%s의 차례입니다. 이동하고 싶은 말의 위치를 선택해주세요. 예) A4\n",turn.getName()); + return PositionConvertor.convertInputToPosition(scanner.nextLine().trim()); + } + + public Position getEndPosition(){ + System.out.println("이동하려는 위치를 입력해주세요."); + return PositionConvertor.convertInputToPosition(scanner.nextLine().trim()); + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000000..271824e8b9 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,70 @@ +package view; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import chess.piece.Piece; +import chess.piece.PieceType; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class OutputView { + + public void printWinner(Color color){ + System.out.printf("축하합니다! %s의 승리입니다!\n",color.getName()); + } + + public void printBoard(List pieces){ + String columnInfo = Arrays.stream(Column.values()) + .map(Column::getName) + .map(String::valueOf) + .collect(Collectors.joining(" ")); + System.out.println(" "+columnInfo); + Row[] rows = Row.values(); + Column[] columns = Column.values(); + for (int row = 0; row < rows.length; row++) { + printRowInfo(rows[row]); + for (int col = 0; col < columns.length; col++) { + Position position = new Position(rows[row],columns[col]); + Optional findPiece = getFindPiece(pieces, position); + printPositionState(findPiece.orElse(null)); + } + System.out.println(); + } + System.out.println(); + System.out.println(); + } + + public void printExceptionMessage(String message){ + System.out.println(message); + } + + private void printRowInfo(Row row) { + System.out.printf("%2s ", row.getName()); + } + + private void printPositionState(Piece findPiece) { + if (findPiece == null) { + System.out.print("- "); + return; + } + System.out.print(getDescription(findPiece) + " "); + } + + private Optional getFindPiece(List pieces, Position position) { + return pieces.stream().filter(piece -> piece.isSamePosition(position)) + .findAny(); + } + + private String getDescription(Piece piece){ + Color color = piece.getColor(); + PieceType pieceType = piece.getPieceType(); + if (color.isWhite()){ + return pieceType.getName(); + } + return pieceType.getName().toLowerCase(); + } +} diff --git a/src/test/java/chess/piece/BishopTest.java b/src/test/java/chess/piece/BishopTest.java new file mode 100644 index 0000000000..cbf7c18ad1 --- /dev/null +++ b/src/test/java/chess/piece/BishopTest.java @@ -0,0 +1,117 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.List; +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.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class BishopTest { + + @ParameterizedTest + @MethodSource + @DisplayName("주위에 비어있는 경우") + void moveCheckTest(Position movePosition, boolean expected) { + Position position = new Position(Row.THREE, Column.B); + Bishop bishop = new Bishop(Color.BLACK, position); + + boolean canMove = bishop.canMove(movePosition, List.of()); + + assertThat(canMove).isEqualTo(expected); + } + + public static Stream moveCheckTest() { + return Stream.of( + Arguments.of( + new Position(Row.FOUR, Column.C), true + ), + Arguments.of( + new Position(Row.FIVE, Column.D), true + ), + Arguments.of( + new Position(Row.SIX, Column.E), true + ), + Arguments.of( + new Position(Row.SEVEN, Column.F), true + ), + Arguments.of( + new Position(Row.EIGHT, Column.G), true + ), + Arguments.of( + new Position(Row.TWO, Column.A), true + ), + Arguments.of( + new Position(Row.FOUR, Column.A), true + ), + Arguments.of( + new Position(Row.TWO, Column.C), true + ), + Arguments.of( + new Position(Row.ONE, Column.D), true + ), + Arguments.of( + new Position(Row.FOUR, Column.B), false + ), + Arguments.of( + new Position(Row.FIVE, Column.B), false + ), + Arguments.of( + new Position(Row.SIX, Column.B), false + ), + Arguments.of( + new Position(Row.SEVEN, Column.B), false + ), + Arguments.of( + new Position(Row.EIGHT, Column.B), false + ), + Arguments.of( + new Position(Row.EIGHT, Column.E), false + ), + Arguments.of( + new Position(Row.EIGHT, Column.F), false + ) + ); + } + + @Test + @DisplayName("주위에 아군이 있으면 못 움직인다.") + void canMoveTest2(){ + Position position = new Position(Row.THREE, Column.B); + Bishop bishop = new Bishop(Color.BLACK, position); + Position toPosition = new Position(Row.TWO, Column.C); + Pawn pawn = new Pawn(Color.BLACK,toPosition); + boolean canMove = bishop.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } + + @Test + @DisplayName("주위에 적이면 이동가능") + void canMoveTest3(){ + Position position = new Position(Row.THREE, Column.B); + Bishop bishop = new Bishop(Color.BLACK, position); + Position toPosition = new Position(Row.TWO, Column.C); + Pawn pawn = new Pawn(Color.WHITE,toPosition); + boolean canMove = bishop.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isTrue(); + } + + @Test + @DisplayName("중간에 누가 있으면 갈 수 없다.") + void canMoveTest4(){ + Position position = new Position(Row.THREE, Column.B); + Bishop bishop = new Bishop(Color.BLACK, position); + Position pawnPosition = new Position(Row.TWO, Column.C); + Position toPosition = new Position(Row.ONE, Column.D); + Pawn pawn = new Pawn(Color.WHITE,pawnPosition); + boolean canMove = bishop.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } +} diff --git a/src/test/java/chess/piece/KingTest.java b/src/test/java/chess/piece/KingTest.java new file mode 100644 index 0000000000..da72edead7 --- /dev/null +++ b/src/test/java/chess/piece/KingTest.java @@ -0,0 +1,89 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.List; +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class KingTest { + + @ParameterizedTest + @MethodSource + @DisplayName("주위에 비어있는 경우") + void moveCheckTest(Position movePosition, boolean expected){ + Position position = new Position(Row.THREE, Column.B); + King king = new King(Color.BLACK,position); + + boolean canMove = king.canMove(movePosition, List.of()); + + assertThat(canMove).isEqualTo(expected); + } + + public static Stream moveCheckTest() { + return Stream.of( + Arguments.of( + new Position(Row.TWO, Column.B), true + ), + Arguments.of( + new Position(Row.FOUR, Column.B), true + ), + Arguments.of( + new Position(Row.THREE, Column.A), true + ), + Arguments.of( + new Position(Row.THREE, Column.C), true + ), + Arguments.of( + new Position(Row.FOUR, Column.A), true + ), + Arguments.of( + new Position(Row.FOUR, Column.C), true + ), + Arguments.of( + new Position(Row.TWO, Column.A), true + ), + Arguments.of( + new Position(Row.TWO, Column.C), true + ), + Arguments.of( + new Position(Row.FIVE, Column.C), false + ), + Arguments.of( + new Position(Row.THREE, Column.D), false + ) + ); + } + + @Test + @DisplayName("주위에 아군이 있으면 못 움직인다.") + void canMoveTest2(){ + Position position = new Position(Row.THREE, Column.B); + King king = new King(Color.BLACK,position); + Position toPosition = new Position(Row.TWO, Column.C); + Pawn pawn = new Pawn(Color.BLACK,toPosition); + boolean canMove = king.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } + + @Test + @DisplayName("주위에 적이면 이동가능") + void canMoveTest3(){ + Position position = new Position(Row.THREE, Column.B); + King king = new King(Color.BLACK,position); + Position toPosition = new Position(Row.TWO, Column.C); + Pawn pawn = new Pawn(Color.WHITE,toPosition); + boolean canMove = king.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isTrue(); + } +} \ No newline at end of file diff --git a/src/test/java/chess/piece/KnightTest.java b/src/test/java/chess/piece/KnightTest.java new file mode 100644 index 0000000000..f22c9eaa18 --- /dev/null +++ b/src/test/java/chess/piece/KnightTest.java @@ -0,0 +1,99 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.List; +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.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class KnightTest { + + @ParameterizedTest + @MethodSource + @DisplayName("주위에 비어있는 경우") + void moveCheckTest(Position movePosition, boolean expected){ + Position position = new Position(Row.THREE, Column.C); + Knight knight = new Knight(Color.BLACK, position); + + boolean canMove = knight.canMove(movePosition, List.of()); + + assertThat(canMove).isEqualTo(expected); + } + + public static Stream moveCheckTest() { + return Stream.of( + Arguments.of( + new Position(Row.FIVE, Column.D), true + ), + Arguments.of( + new Position(Row.FIVE, Column.B), true + ), + Arguments.of( + new Position(Row.FOUR, Column.E), true + ), + Arguments.of( + new Position(Row.TWO, Column.E), true + ), + Arguments.of( + new Position(Row.FOUR, Column.A), true + ), + Arguments.of( + new Position(Row.TWO, Column.A), true + ), + Arguments.of( + new Position(Row.ONE, Column.B), true + ), + Arguments.of( + new Position(Row.ONE, Column.D), true + ), + Arguments.of( + new Position(Row.SIX, Column.B), false + ), + Arguments.of( + new Position(Row.SEVEN, Column.D), false + ) + ); + } + + @Test + @DisplayName("주위에 아군이 있으면 못 움직인다.") + void canMoveTest2(){ + Position position = new Position(Row.THREE, Column.C); + Knight knight = new Knight(Color.BLACK, position); + Position toPosition = new Position(Row.TWO, Column.A); + Pawn pawn = new Pawn(Color.BLACK,toPosition); + boolean canMove = knight.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } + + @Test + @DisplayName("주위에 적이면 이동가능") + void canMoveTest3(){ + Position position = new Position(Row.THREE, Column.C); + Knight knight = new Knight(Color.BLACK, position); + Position toPosition = new Position(Row.TWO, Column.A); + Pawn pawn = new Pawn(Color.WHITE,toPosition); + boolean canMove = knight.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isTrue(); + } + + @Test + @DisplayName("중간에 누가 있어도 지나갈 수 있다.") + void canMoveTest4(){ + Position position = new Position(Row.THREE, Column.C); + Knight knight = new Knight(Color.BLACK, position); + Position pawnPosition = new Position(Row.THREE, Column.B); + Position toPosition = new Position(Row.TWO, Column.A); + Pawn pawn = new Pawn(Color.WHITE,pawnPosition); + boolean canMove = knight.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isTrue(); + } +} \ No newline at end of file diff --git a/src/test/java/chess/piece/PawnTest.java b/src/test/java/chess/piece/PawnTest.java new file mode 100644 index 0000000000..3817ddc008 --- /dev/null +++ b/src/test/java/chess/piece/PawnTest.java @@ -0,0 +1,111 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.*; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.List; +import java.util.stream.Stream; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class PawnTest { + + @ParameterizedTest + @MethodSource + @DisplayName("이동 가능한지 판별") + void canMoveTest(Color color ,Position movePosition, boolean expected){ + Position position = new Position(Row.THREE, Column.A); + Pawn pawn = new Pawn(color,position); + + boolean canMove = pawn.canMove(movePosition, List.of()); + + assertThat(canMove).isEqualTo(expected); + } + + public static Stream canMoveTest(){ + return Stream.of( + Arguments.of( + Color.WHITE,new Position(Row.FIVE,Column.A),true + ), + Arguments.of( + Color.WHITE,new Position(Row.FOUR,Column.A),true + ), + Arguments.of( + Color.WHITE,new Position(Row.SIX,Column.A),false + ), + Arguments.of( + Color.WHITE,new Position(Row.TWO,Column.B),false + ), + Arguments.of( + Color.BLACK,new Position(Row.TWO,Column.A),true + ), + Arguments.of( + Color.BLACK,new Position(Row.ONE,Column.A),true + ), + Arguments.of( + Color.BLACK,new Position(Row.FOUR,Column.A),false + ), + Arguments.of( + Color.BLACK,new Position(Row.FIVE,Column.B),false + ) + ); + } + + @Test + @DisplayName("이동 테스트") + void moveToTest(){ + Position position = new Position(Row.THREE, Column.A); + Pawn pawn = new Pawn(Color.WHITE,position); + Position toPosition = new Position(Row.FIVE, Column.A); + + pawn.moveTo(toPosition,List.of()); + + Position nowPosition = pawn.getPosition(); + assertThat(nowPosition).isEqualTo(toPosition); + } + + @Test + @DisplayName("이동 경로에 아군이 있으면 예외 발생") + void moveToTestException(){ + Position position = new Position(Row.THREE, Column.A); + Pawn pawn = new Pawn(Color.WHITE,position); + Position toPosition = new Position(Row.FIVE, Column.A); + Pawn pawn1 = new Pawn(Color.WHITE,toPosition); + + assertThatThrownBy(()->pawn.moveTo(toPosition,List.of(pawn1))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("이동 경로에 적이 있으면 대각선은 가능하다.") + void moveToTest2(){ + Position position = new Position(Row.THREE, Column.A); + Pawn pawn = new Pawn(Color.WHITE,position); + Position toPosition = new Position(Row.FOUR, Column.B); + Pawn pawn1 = new Pawn(Color.BLACK,toPosition); + + boolean canMove = pawn.canMove(toPosition, List.of(pawn1)); + + assertThat(canMove).isTrue(); + } + + @Test + @DisplayName("이동 경로에 적이 없는데 대각선으로 못감") + void moveToTestException2(){ + Position position = new Position(Row.THREE, Column.A); + Pawn pawn = new Pawn(Color.WHITE,position); + Position toPosition = new Position(Row.FOUR, Column.B); + Pawn pawn1 = new Pawn(Color.WHITE,toPosition); + + boolean canMove = pawn.canMove(toPosition, List.of(pawn1)); + + assertThat(canMove).isFalse(); + } +} \ No newline at end of file diff --git a/src/test/java/chess/piece/QeenTest.java b/src/test/java/chess/piece/QeenTest.java new file mode 100644 index 0000000000..22c139ae06 --- /dev/null +++ b/src/test/java/chess/piece/QeenTest.java @@ -0,0 +1,144 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.List; +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.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class QeenTest { + + @ParameterizedTest + @MethodSource + @DisplayName("주위에 비어있는 경우") + void moveCheckTest(Position movePosition, boolean expected) { + Position position = new Position(Row.THREE, Column.B); + Queen queen = new Queen(Color.BLACK, position); + + boolean canMove = queen.canMove(movePosition, List.of()); + + assertThat(canMove).isEqualTo(expected); + } + + public static Stream moveCheckTest() { + return Stream.of( + Arguments.of( + new Position(Row.FOUR, Column.C), true + ), + Arguments.of( + new Position(Row.FIVE, Column.D), true + ), + Arguments.of( + new Position(Row.SIX, Column.E), true + ), + Arguments.of( + new Position(Row.SEVEN, Column.F), true + ), + Arguments.of( + new Position(Row.EIGHT, Column.G), true + ), + Arguments.of( + new Position(Row.TWO, Column.A), true + ), + Arguments.of( + new Position(Row.FOUR, Column.A), true + ), + Arguments.of( + new Position(Row.TWO, Column.C), true + ), + Arguments.of( + new Position(Row.ONE, Column.D), true + ), + Arguments.of( + new Position(Row.THREE, Column.A), true + ), + Arguments.of( + new Position(Row.THREE, Column.C), true + ), + Arguments.of( + new Position(Row.THREE, Column.D), true + ), + Arguments.of( + new Position(Row.THREE, Column.E), true + ), + Arguments.of( + new Position(Row.THREE, Column.F), true + ), + Arguments.of( + new Position(Row.THREE, Column.G), true + ), + Arguments.of( + new Position(Row.THREE, Column.H), true + ), + Arguments.of( + new Position(Row.ONE, Column.B), true + ), + Arguments.of( + new Position(Row.TWO, Column.B), true + ), + Arguments.of( + new Position(Row.FOUR, Column.B), true + ), + Arguments.of( + new Position(Row.FIVE, Column.B), true + ), + Arguments.of( + new Position(Row.SIX, Column.B), true + ), + Arguments.of( + new Position(Row.SEVEN, Column.B), true + ), + Arguments.of( + new Position(Row.EIGHT, Column.B), true + ), + Arguments.of( + new Position(Row.EIGHT, Column.E), false + ), + Arguments.of( + new Position(Row.EIGHT, Column.F), false + ) + ); + } + + @Test + @DisplayName("주위에 아군이 있으면 못 움직인다.") + void canMoveTest2(){ + Position position = new Position(Row.THREE, Column.B); + Queen queen = new Queen(Color.BLACK, position); + Position toPosition = new Position(Row.TWO, Column.C); + Pawn pawn = new Pawn(Color.BLACK,toPosition); + boolean canMove = queen.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } + + @Test + @DisplayName("주위에 적이면 이동가능") + void canMoveTest3(){ + Position position = new Position(Row.THREE, Column.B); + Queen queen = new Queen(Color.BLACK, position); + Position toPosition = new Position(Row.TWO, Column.C); + Pawn pawn = new Pawn(Color.WHITE,toPosition); + boolean canMove = queen.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isTrue(); + } + + @Test + @DisplayName("중간에 누가 있으면 갈 수 없다.") + void canMoveTest4(){ + Position position = new Position(Row.THREE, Column.B); + Queen queen = new Queen(Color.BLACK, position); + Position pawnPosition = new Position(Row.TWO, Column.C); + Position toPosition = new Position(Row.ONE, Column.D); + Pawn pawn = new Pawn(Color.WHITE,pawnPosition); + boolean canMove = queen.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } +} diff --git a/src/test/java/chess/piece/RockTest.java b/src/test/java/chess/piece/RockTest.java new file mode 100644 index 0000000000..179191dbce --- /dev/null +++ b/src/test/java/chess/piece/RockTest.java @@ -0,0 +1,117 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import java.util.List; +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.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class RockTest { + + @ParameterizedTest + @MethodSource + @DisplayName("주위에 비어있는 경우") + void moveCheckTest(Position movePosition, boolean expected) { + Position position = new Position(Row.THREE, Column.B); + Rook rook = new Rook(Color.BLACK, position); + + boolean canMove = rook.canMove(movePosition, List.of()); + + assertThat(canMove).isEqualTo(expected); + } + + public static Stream moveCheckTest() { + return Stream.of( + Arguments.of( + new Position(Row.THREE, Column.A), true + ), + Arguments.of( + new Position(Row.THREE, Column.C), true + ), + Arguments.of( + new Position(Row.THREE, Column.D), true + ), + Arguments.of( + new Position(Row.THREE, Column.E), true + ), + Arguments.of( + new Position(Row.THREE, Column.F), true + ), + Arguments.of( + new Position(Row.THREE, Column.G), true + ), + Arguments.of( + new Position(Row.THREE, Column.H), true + ), + Arguments.of( + new Position(Row.ONE, Column.B), true + ), + Arguments.of( + new Position(Row.TWO, Column.B), true + ), + Arguments.of( + new Position(Row.FOUR, Column.B), true + ), + Arguments.of( + new Position(Row.FIVE, Column.B), true + ), + Arguments.of( + new Position(Row.SIX, Column.B), true + ), + Arguments.of( + new Position(Row.SEVEN, Column.B), true + ), + Arguments.of( + new Position(Row.EIGHT, Column.B), true + ), + Arguments.of( + new Position(Row.EIGHT, Column.E), false + ), + Arguments.of( + new Position(Row.EIGHT, Column.F), false + ) + ); + } + + @Test + @DisplayName("주위에 아군이 있으면 못 움직인다.") + void canMoveTest2(){ + Position position = new Position(Row.THREE, Column.C); + Rook rook = new Rook(Color.BLACK, position); + Position toPosition = new Position(Row.THREE, Column.D); + Pawn pawn = new Pawn(Color.BLACK,toPosition); + boolean canMove = rook.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } + + @Test + @DisplayName("주위에 적이면 이동가능") + void canMoveTest3(){ + Position position = new Position(Row.THREE, Column.C); + Rook rook = new Rook(Color.BLACK, position); + Position toPosition = new Position(Row.THREE, Column.D); + Pawn pawn = new Pawn(Color.WHITE,toPosition); + boolean canMove = rook.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isTrue(); + } + + @Test + @DisplayName("중간에 누가 있으면 갈 수 없다.") + void canMoveTest4(){ + Position position = new Position(Row.THREE, Column.C); + Knight knight = new Knight(Color.BLACK, position); + Position pawnPosition = new Position(Row.THREE, Column.B); + Position toPosition = new Position(Row.THREE, Column.D); + Pawn pawn = new Pawn(Color.WHITE,pawnPosition); + boolean canMove = knight.canMove(toPosition, List.of(pawn)); + assertThat(canMove).isFalse(); + } +}