From 2d6d654326f6ed278c95aff10752764e57af702b Mon Sep 17 00:00:00 2001 From: Firedrago95 Date: Sat, 22 Mar 2025 14:40:35 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EC=B2=B4=EC=8A=A4=ED=8C=90=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=ED=99=94=20=EB=B0=8F=20=EA=B8=B0=EB=AC=BC=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++ src/main/java/.gitkeep | 0 src/main/java/chess/Application.java | 11 ++ .../chess/controller/ChessController.java | 20 +++ .../java/chess/domain/board/ChessBoard.java | 18 +++ .../domain/board/InitBoardGenerator.java | 61 ++++++++ src/main/java/chess/domain/piece/Bishop.java | 8 ++ .../java/chess/{ => domain/piece}/Color.java | 2 +- .../java/chess/{ => domain/piece}/Column.java | 9 +- src/main/java/chess/domain/piece/King.java | 8 ++ src/main/java/chess/domain/piece/Knight.java | 8 ++ .../chess/{ => domain/piece}/Movement.java | 2 +- src/main/java/chess/domain/piece/Pawn.java | 8 ++ src/main/java/chess/domain/piece/Piece.java | 30 ++++ .../java/chess/domain/piece/PieceType.java | 11 ++ .../chess/{ => domain/piece}/Position.java | 6 +- src/main/java/chess/domain/piece/Queen.java | 8 ++ src/main/java/chess/domain/piece/Rook.java | 8 ++ .../java/chess/{ => domain/piece}/Row.java | 9 +- src/main/java/chess/piece/Bishop.java | 5 - src/main/java/chess/piece/King.java | 5 - src/main/java/chess/piece/Knight.java | 5 - src/main/java/chess/piece/Pawn.java | 5 - src/main/java/chess/piece/Queen.java | 5 - src/main/java/chess/piece/Rook.java | 5 - src/main/java/chess/view/InputView.java | 4 + src/main/java/chess/view/OutputVIew.java | 135 ++++++++++++++++++ src/test/java/chess/ColumnTest.java | 1 + src/test/java/chess/Fixtures.java | 4 + src/test/java/chess/PositionTest.java | 2 + src/test/java/chess/RowTest.java | 1 + 31 files changed, 379 insertions(+), 35 deletions(-) delete mode 100644 src/main/java/.gitkeep create mode 100644 src/main/java/chess/Application.java create mode 100644 src/main/java/chess/controller/ChessController.java create mode 100644 src/main/java/chess/domain/board/ChessBoard.java create mode 100644 src/main/java/chess/domain/board/InitBoardGenerator.java create mode 100644 src/main/java/chess/domain/piece/Bishop.java rename src/main/java/chess/{ => domain/piece}/Color.java (93%) rename src/main/java/chess/{ => domain/piece}/Column.java (84%) create mode 100644 src/main/java/chess/domain/piece/King.java create mode 100644 src/main/java/chess/domain/piece/Knight.java rename src/main/java/chess/{ => domain/piece}/Movement.java (97%) create mode 100644 src/main/java/chess/domain/piece/Pawn.java create mode 100644 src/main/java/chess/domain/piece/Piece.java create mode 100644 src/main/java/chess/domain/piece/PieceType.java rename src/main/java/chess/{ => domain/piece}/Position.java (95%) create mode 100644 src/main/java/chess/domain/piece/Queen.java create mode 100644 src/main/java/chess/domain/piece/Rook.java rename src/main/java/chess/{ => domain/piece}/Row.java (85%) delete mode 100644 src/main/java/chess/piece/Bishop.java delete mode 100644 src/main/java/chess/piece/King.java delete mode 100644 src/main/java/chess/piece/Knight.java delete mode 100644 src/main/java/chess/piece/Pawn.java delete mode 100644 src/main/java/chess/piece/Queen.java delete mode 100644 src/main/java/chess/piece/Rook.java create mode 100644 src/main/java/chess/view/InputView.java create mode 100644 src/main/java/chess/view/OutputVIew.java diff --git a/README.md b/README.md index 8102f91c870..c2d1909c919 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,13 @@ ## 우아한테크코스 코드리뷰 - [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) + +## 기능 구현 목록 + +- 체스 게임판을 초기화 한다. +- 체스 게임판을 출력한다. +- 백의 이동 좌표를 입력 받는다. +- 백 기물을 이동한다. +- 흑 기물 이동 좌표를 입력 받는다. +- 흑 기물을 이동한다. +- 왕이 죽으면 게임이 끝난다. diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/main/java/chess/Application.java b/src/main/java/chess/Application.java new file mode 100644 index 00000000000..751518ea7a1 --- /dev/null +++ b/src/main/java/chess/Application.java @@ -0,0 +1,11 @@ +package chess; + +import chess.controller.ChessController; + +public class Application { + + public static void main(String[] args) { + ChessController controller = new ChessController(); + controller.run(); + } +} diff --git a/src/main/java/chess/controller/ChessController.java b/src/main/java/chess/controller/ChessController.java new file mode 100644 index 00000000000..a79cb616a85 --- /dev/null +++ b/src/main/java/chess/controller/ChessController.java @@ -0,0 +1,20 @@ +package chess.controller; + +import chess.domain.board.ChessBoard; +import chess.domain.board.InitBoardGenerator; +import chess.view.InputView; +import chess.view.OutputVIew; + +public class ChessController { + + public void run() { + ChessBoard chessBoard = new ChessBoard(InitBoardGenerator.initChessBoard()); + OutputVIew.printChessBoard(chessBoard); + +// while (!chessBoard.isEnd()) { +// moveWhite(); +// if (chessBoard.isEnd()) break; +// moveBlack(); +// } + } +} diff --git a/src/main/java/chess/domain/board/ChessBoard.java b/src/main/java/chess/domain/board/ChessBoard.java new file mode 100644 index 00000000000..3d9342a384a --- /dev/null +++ b/src/main/java/chess/domain/board/ChessBoard.java @@ -0,0 +1,18 @@ +package chess.domain.board; + +import chess.domain.piece.Piece; + +import java.util.List; + +public class ChessBoard { + + private List pieces; + + public ChessBoard(List pieces) { + this.pieces = pieces; + } + + public List getPieces() { + return pieces; + } +} diff --git a/src/main/java/chess/domain/board/InitBoardGenerator.java b/src/main/java/chess/domain/board/InitBoardGenerator.java new file mode 100644 index 00000000000..16632357141 --- /dev/null +++ b/src/main/java/chess/domain/board/InitBoardGenerator.java @@ -0,0 +1,61 @@ +package chess.domain.board; + +import chess.domain.piece.Bishop; +import chess.domain.piece.Color; +import chess.domain.piece.Column; +import chess.domain.piece.King; +import chess.domain.piece.Knight; +import chess.domain.piece.Pawn; +import chess.domain.piece.Piece; +import chess.domain.piece.PieceType; +import chess.domain.piece.Position; +import chess.domain.piece.Queen; +import chess.domain.piece.Rook; +import chess.domain.piece.Row; + +import java.util.ArrayList; +import java.util.List; + +public class InitBoardGenerator { + + public static List initChessBoard() { + List initPieces = new ArrayList<>(); + + for (Row row : Row.getAllRows()) { + if (row == Row.EIGHT) { + initPieces.add(new Rook(PieceType.ROOK, new Position(row, Column.A), Color.BLACK)); + initPieces.add(new Knight(PieceType.KNIGHT, new Position(row, Column.B), Color.BLACK)); + initPieces.add(new Bishop(PieceType.BISHOP, new Position(row, Column.C), Color.BLACK)); + initPieces.add(new Queen(PieceType.QUEEN, new Position(row, Column.D), Color.BLACK)); + initPieces.add(new King(PieceType.KING, new Position(row, Column.E), Color.BLACK)); + initPieces.add(new Bishop(PieceType.BISHOP, new Position(row, Column.F), Color.BLACK)); + initPieces.add(new Knight(PieceType.KNIGHT, new Position(row, Column.G), Color.BLACK)); + initPieces.add(new Rook(PieceType.ROOK, new Position(row, Column.H), Color.BLACK)); + } + + if (row == Row.SEVEN) { + for (Column column : Column.getAllColumns()) { + initPieces.add(new Pawn(PieceType.PAWN, new Position(row, column), Color.BLACK)); + } + } + + if (row == Row.TWO) { + for (Column column : Column.getAllColumns()) { + initPieces.add(new Pawn(PieceType.PAWN, new Position(row, column), Color.WHITE)); + } + } + + if (row == Row.ONE) { + initPieces.add(new Rook(PieceType.ROOK, new Position(row, Column.A), Color.WHITE)); + initPieces.add(new Knight(PieceType.KNIGHT, new Position(row, Column.B), Color.WHITE)); + initPieces.add(new Bishop(PieceType.BISHOP, new Position(row, Column.C), Color.WHITE)); + initPieces.add(new Queen(PieceType.QUEEN, new Position(row, Column.D), Color.WHITE)); + initPieces.add(new King(PieceType.KING, new Position(row, Column.E), Color.WHITE)); + initPieces.add(new Bishop(PieceType.BISHOP, new Position(row, Column.F), Color.WHITE)); + initPieces.add(new Knight(PieceType.KNIGHT, new Position(row, Column.G), Color.WHITE)); + initPieces.add(new Rook(PieceType.ROOK, new Position(row, Column.H), Color.WHITE)); + } + } + return initPieces; + } +} diff --git a/src/main/java/chess/domain/piece/Bishop.java b/src/main/java/chess/domain/piece/Bishop.java new file mode 100644 index 00000000000..04e314a34a5 --- /dev/null +++ b/src/main/java/chess/domain/piece/Bishop.java @@ -0,0 +1,8 @@ +package chess.domain.piece; + +public class Bishop extends Piece { + + public Bishop(PieceType pieceType, Position position, Color color) { + super(pieceType, position, color); + } +} diff --git a/src/main/java/chess/Color.java b/src/main/java/chess/domain/piece/Color.java similarity index 93% rename from src/main/java/chess/Color.java rename to src/main/java/chess/domain/piece/Color.java index 55cd020b681..d599dbed3fb 100644 --- a/src/main/java/chess/Color.java +++ b/src/main/java/chess/domain/piece/Color.java @@ -1,4 +1,4 @@ -package chess; +package chess.domain.piece; public enum Color { diff --git a/src/main/java/chess/Column.java b/src/main/java/chess/domain/piece/Column.java similarity index 84% rename from src/main/java/chess/Column.java rename to src/main/java/chess/domain/piece/Column.java index b64b4dc77a3..0a63a90a1ec 100644 --- a/src/main/java/chess/Column.java +++ b/src/main/java/chess/domain/piece/Column.java @@ -1,4 +1,7 @@ -package chess; +package chess.domain.piece; + +import java.util.Arrays; +import java.util.List; public enum Column { @@ -50,4 +53,8 @@ public Column moveRight(final int step) { throw new IllegalStateException("움직일 수 없는 위치입니다."); } + + public static List getAllColumns() { + return Arrays.stream(values()).toList(); + } } diff --git a/src/main/java/chess/domain/piece/King.java b/src/main/java/chess/domain/piece/King.java new file mode 100644 index 00000000000..2ba27ec0af7 --- /dev/null +++ b/src/main/java/chess/domain/piece/King.java @@ -0,0 +1,8 @@ +package chess.domain.piece; + +public class King extends Piece { + + public King(PieceType pieceType, Position position, Color color) { + super(pieceType, position, color); + } +} diff --git a/src/main/java/chess/domain/piece/Knight.java b/src/main/java/chess/domain/piece/Knight.java new file mode 100644 index 00000000000..df2515b97c4 --- /dev/null +++ b/src/main/java/chess/domain/piece/Knight.java @@ -0,0 +1,8 @@ +package chess.domain.piece; + +public class Knight extends Piece { + + public Knight(PieceType pieceType, Position position, Color color) { + super(pieceType, position, color); + } +} diff --git a/src/main/java/chess/Movement.java b/src/main/java/chess/domain/piece/Movement.java similarity index 97% rename from src/main/java/chess/Movement.java rename to src/main/java/chess/domain/piece/Movement.java index e57c6e91bb9..0912c0a5226 100644 --- a/src/main/java/chess/Movement.java +++ b/src/main/java/chess/domain/piece/Movement.java @@ -1,4 +1,4 @@ -package chess; +package chess.domain.piece; public enum Movement { UP(0, 1), diff --git a/src/main/java/chess/domain/piece/Pawn.java b/src/main/java/chess/domain/piece/Pawn.java new file mode 100644 index 00000000000..679b8faf897 --- /dev/null +++ b/src/main/java/chess/domain/piece/Pawn.java @@ -0,0 +1,8 @@ +package chess.domain.piece; + +public class Pawn extends Piece { + + public Pawn(PieceType pieceType, Position position, Color color) { + super(pieceType, position, color); + } +} diff --git a/src/main/java/chess/domain/piece/Piece.java b/src/main/java/chess/domain/piece/Piece.java new file mode 100644 index 00000000000..761b0244852 --- /dev/null +++ b/src/main/java/chess/domain/piece/Piece.java @@ -0,0 +1,30 @@ +package chess.domain.piece; + +public abstract class Piece { + + protected PieceType pieceType; + protected Position position; + protected Color color; + + public Piece(PieceType pieceType, Position position, Color color) { + this.pieceType = pieceType; + this.position = position; + this.color = color; + } + + public PieceType getPieceType() { + return pieceType; + } + + public Position getPosition() { + return position; + } + + public Color getColor() { + return color; + } + + public boolean isExist(Row row, Column column) { + return position.hasSameRowAndColumn(row, column); + } +} diff --git a/src/main/java/chess/domain/piece/PieceType.java b/src/main/java/chess/domain/piece/PieceType.java new file mode 100644 index 00000000000..38e8430a344 --- /dev/null +++ b/src/main/java/chess/domain/piece/PieceType.java @@ -0,0 +1,11 @@ +package chess.domain.piece; + +public enum PieceType { + + PAWN, + BISHOP, + KING, + KNIGHT, + QUEEN, + ROOK +} diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/domain/piece/Position.java similarity index 95% rename from src/main/java/chess/Position.java rename to src/main/java/chess/domain/piece/Position.java index 3ebeb0ea185..6f9ab875df8 100644 --- a/src/main/java/chess/Position.java +++ b/src/main/java/chess/domain/piece/Position.java @@ -1,4 +1,4 @@ -package chess; +package chess.domain.piece; public record Position( Column column, @@ -167,4 +167,8 @@ public Position moveHorizontal(final int step) { } return this; } + + public boolean hasSameRowAndColumn(Row row, Column column) { + return this.row == row && this.column == column; + } } diff --git a/src/main/java/chess/domain/piece/Queen.java b/src/main/java/chess/domain/piece/Queen.java new file mode 100644 index 00000000000..72e80470671 --- /dev/null +++ b/src/main/java/chess/domain/piece/Queen.java @@ -0,0 +1,8 @@ +package chess.domain.piece; + +public class Queen extends Piece { + + public Queen(PieceType pieceType, Position position, Color color) { + super(pieceType, position, color); + } +} diff --git a/src/main/java/chess/domain/piece/Rook.java b/src/main/java/chess/domain/piece/Rook.java new file mode 100644 index 00000000000..fd1ce77eb5a --- /dev/null +++ b/src/main/java/chess/domain/piece/Rook.java @@ -0,0 +1,8 @@ +package chess.domain.piece; + +public class Rook extends Piece{ + + public Rook(PieceType pieceType, Position position, Color color) { + super(pieceType, position, color); + } +} diff --git a/src/main/java/chess/Row.java b/src/main/java/chess/domain/piece/Row.java similarity index 85% rename from src/main/java/chess/Row.java rename to src/main/java/chess/domain/piece/Row.java index 126ed048daa..85e633e026c 100644 --- a/src/main/java/chess/Row.java +++ b/src/main/java/chess/domain/piece/Row.java @@ -1,4 +1,7 @@ -package chess; +package chess.domain.piece; + +import java.util.Arrays; +import java.util.List; public enum Row { @@ -50,4 +53,8 @@ public Row moveDown(final int step) { throw new IllegalStateException("움직일 수 없는 위치입니다."); } + + public static List getAllRows() { + return Arrays.stream(values()).toList(); + } } diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java deleted file mode 100644 index b14ab70f981..00000000000 --- a/src/main/java/chess/piece/Bishop.java +++ /dev/null @@ -1,5 +0,0 @@ -package chess.piece; - -public class Bishop { - -} diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java deleted file mode 100644 index d64210cad13..00000000000 --- a/src/main/java/chess/piece/King.java +++ /dev/null @@ -1,5 +0,0 @@ -package chess.piece; - -public class King { - -} diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java deleted file mode 100644 index 2ee7c47a3bc..00000000000 --- a/src/main/java/chess/piece/Knight.java +++ /dev/null @@ -1,5 +0,0 @@ -package chess.piece; - -public class Knight { - -} diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java deleted file mode 100644 index c8b6cafa51e..00000000000 --- a/src/main/java/chess/piece/Pawn.java +++ /dev/null @@ -1,5 +0,0 @@ -package chess.piece; - -public class Pawn { - -} diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java deleted file mode 100644 index 9b547261c4b..00000000000 --- a/src/main/java/chess/piece/Queen.java +++ /dev/null @@ -1,5 +0,0 @@ -package chess.piece; - -public class Queen { - -} diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java deleted file mode 100644 index 7ed4d08bf03..00000000000 --- a/src/main/java/chess/piece/Rook.java +++ /dev/null @@ -1,5 +0,0 @@ -package chess.piece; - -public class Rook { - -} diff --git a/src/main/java/chess/view/InputView.java b/src/main/java/chess/view/InputView.java new file mode 100644 index 00000000000..d9666f96fdb --- /dev/null +++ b/src/main/java/chess/view/InputView.java @@ -0,0 +1,4 @@ +package chess.view; + +public class InputView { +} diff --git a/src/main/java/chess/view/OutputVIew.java b/src/main/java/chess/view/OutputVIew.java new file mode 100644 index 00000000000..09d3dd85794 --- /dev/null +++ b/src/main/java/chess/view/OutputVIew.java @@ -0,0 +1,135 @@ +package chess.view; + +import chess.domain.board.ChessBoard; +import chess.domain.piece.Color; +import chess.domain.piece.Column; +import chess.domain.piece.Piece; +import chess.domain.piece.PieceType; +import chess.domain.piece.Row; + +import java.util.List; + +public class OutputVIew { + public static void printChessBoard(ChessBoard chessBoard) { + List allPieces = chessBoard.getPieces(); + + System.out.print(" "); + for (Column column : Column.getAllColumns()) { + System.out.printf("%s", convertToString(column)); + } + + System.out.println(); + + for (Row row : Row.getAllRows()) { + System.out.printf("%s", convertToString(row)); + for (Column column : Column.getAllColumns()) { + if (hasPiece(allPieces, row, column)) { + Piece findPiece = getPieceByRowAndColum(allPieces, row, column); + System.out.printf((convertToString(findPiece.getPieceType(), findPiece.getColor()))); + continue; + } + System.out.print("."); + } + System.out.println(); + } + + } + + private static Piece getPieceByRowAndColum(List pieces, Row row, Column column) { + return pieces.stream() + .filter(piece -> piece.isExist(row, column)) + .findFirst().get(); + } + + private static boolean hasPiece(List allPieces, Row row, Column column) { + return allPieces.stream() + .anyMatch(piece -> piece.isExist(row, column)); + } + + private static String convertToString(Row row) { + if (row == Row.EIGHT) { + return "8 "; + } + if (row == Row.SEVEN) { + return "7 "; + } + if (row == Row.SIX) { + return "6 "; + } + if (row == Row.FIVE) { + return "5 "; + } + if (row == Row.FOUR) { + return "4 "; + } + if (row == Row.THREE) { + return "3 "; + } + if (row == Row.TWO) { + return "2 "; + } + return "1 "; + } + + private static String convertToString(PieceType pieceType, Color color) { + if (color == Color.BLACK) { + if (pieceType == PieceType.BISHOP) { + return "B"; + } + if (pieceType == PieceType.ROOK) { + return "R"; + } + if (pieceType == PieceType.KING) { + return "K"; + } + if (pieceType == PieceType.KNIGHT) { + return "N"; + } + if (pieceType == PieceType.QUEEN) { + return "Q"; + } + return "P"; + } + if (pieceType == PieceType.BISHOP) { + return "b"; + } + if (pieceType == PieceType.ROOK) { + return "r"; + } + if (pieceType == PieceType.KING) { + return "k"; + } + if (pieceType == PieceType.KNIGHT) { + return "n"; + } + if (pieceType == PieceType.QUEEN) { + return "q"; + } + return "p"; + } + + private static String convertToString(Column column) { + if (column == Column.A) { + return "A"; + } + if (column == Column.B) { + return "B"; + } + if (column == Column.C) { + return "C"; + } + if (column == Column.D) { + return "D"; + } + if (column == Column.E) { + return "E"; + } + if (column == Column.F) { + return "F"; + } + if (column == Column.G) { + return "G"; + } + return "H "; + } +} diff --git a/src/test/java/chess/ColumnTest.java b/src/test/java/chess/ColumnTest.java index e43523240f7..36924537515 100644 --- a/src/test/java/chess/ColumnTest.java +++ b/src/test/java/chess/ColumnTest.java @@ -1,5 +1,6 @@ package chess; +import chess.domain.piece.Column; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/chess/Fixtures.java b/src/test/java/chess/Fixtures.java index f940ab37137..ad9f6769b6b 100644 --- a/src/test/java/chess/Fixtures.java +++ b/src/test/java/chess/Fixtures.java @@ -1,5 +1,9 @@ package chess; +import chess.domain.piece.Column; +import chess.domain.piece.Position; +import chess.domain.piece.Row; + @SuppressWarnings("unused") public final class Fixtures { diff --git a/src/test/java/chess/PositionTest.java b/src/test/java/chess/PositionTest.java index 3ad7cc64084..6f4952ded49 100644 --- a/src/test/java/chess/PositionTest.java +++ b/src/test/java/chess/PositionTest.java @@ -1,5 +1,7 @@ package chess; +import chess.domain.piece.Movement; +import chess.domain.piece.Position; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/chess/RowTest.java b/src/test/java/chess/RowTest.java index fcb65485410..9a0375d75de 100644 --- a/src/test/java/chess/RowTest.java +++ b/src/test/java/chess/RowTest.java @@ -1,5 +1,6 @@ package chess; +import chess.domain.piece.Row; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 3914456c98d1a0b1e21fc1ea1e72e4a8c8787771 Mon Sep 17 00:00:00 2001 From: Firedrago95 Date: Sat, 22 Mar 2025 19:30:08 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=EA=B5=AC=ED=98=84=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/Application.java | 3 +- .../chess/controller/ChessController.java | 32 ++++- .../java/chess/domain/board/ChessBoard.java | 71 +++++++++- src/main/java/chess/domain/piece/Bishop.java | 77 +++++++++++ src/main/java/chess/domain/piece/Column.java | 4 + src/main/java/chess/domain/piece/King.java | 53 ++++++++ src/main/java/chess/domain/piece/Knight.java | 69 ++++++++++ src/main/java/chess/domain/piece/Pawn.java | 58 ++++++++ src/main/java/chess/domain/piece/Piece.java | 30 ++++- .../java/chess/domain/piece/Position.java | 26 +++- src/main/java/chess/domain/piece/Queen.java | 124 ++++++++++++++++++ src/main/java/chess/domain/piece/Rook.java | 67 +++++++++- src/main/java/chess/domain/piece/Row.java | 4 + src/main/java/chess/util/ErrorUtil.java | 15 +++ src/main/java/chess/view/InputView.java | 82 ++++++++++++ src/main/java/chess/view/OutputVIew.java | 4 +- 16 files changed, 705 insertions(+), 14 deletions(-) create mode 100644 src/main/java/chess/util/ErrorUtil.java diff --git a/src/main/java/chess/Application.java b/src/main/java/chess/Application.java index 751518ea7a1..c0e8def9db2 100644 --- a/src/main/java/chess/Application.java +++ b/src/main/java/chess/Application.java @@ -1,11 +1,12 @@ package chess; import chess.controller.ChessController; +import chess.util.ErrorUtil; public class Application { public static void main(String[] args) { ChessController controller = new ChessController(); - controller.run(); + ErrorUtil.computeError(controller::run); } } diff --git a/src/main/java/chess/controller/ChessController.java b/src/main/java/chess/controller/ChessController.java index a79cb616a85..2eff1dbd3f9 100644 --- a/src/main/java/chess/controller/ChessController.java +++ b/src/main/java/chess/controller/ChessController.java @@ -2,19 +2,39 @@ import chess.domain.board.ChessBoard; import chess.domain.board.InitBoardGenerator; +import chess.domain.piece.Column; +import chess.domain.piece.Row; import chess.view.InputView; import chess.view.OutputVIew; +import java.util.Map.Entry; + public class ChessController { + private ChessBoard chessBoard; + public void run() { - ChessBoard chessBoard = new ChessBoard(InitBoardGenerator.initChessBoard()); + chessBoard = new ChessBoard(InitBoardGenerator.initChessBoard()); OutputVIew.printChessBoard(chessBoard); -// while (!chessBoard.isEnd()) { -// moveWhite(); -// if (chessBoard.isEnd()) break; -// moveBlack(); -// } + while (!chessBoard.isEnd()) { + moveWhite(); + OutputVIew.printChessBoard(chessBoard); + if (chessBoard.isEnd()) break; + moveBlack(); + OutputVIew.printChessBoard(chessBoard); + } + } + + private void moveWhite() { + Entry currentPosition = InputView.choiceWhitePiece(); + Entry destination = InputView.choiceDestination(); + chessBoard.moveWhite(currentPosition, destination); + } + + private void moveBlack() { + Entry currentPosition = InputView.choiceBlackPiece(); + Entry destination = InputView.choiceDestination(); + chessBoard.moveBlack(currentPosition, destination); } } diff --git a/src/main/java/chess/domain/board/ChessBoard.java b/src/main/java/chess/domain/board/ChessBoard.java index 3d9342a384a..7e2d63df61d 100644 --- a/src/main/java/chess/domain/board/ChessBoard.java +++ b/src/main/java/chess/domain/board/ChessBoard.java @@ -1,18 +1,87 @@ package chess.domain.board; +import chess.domain.piece.Color; +import chess.domain.piece.Column; import chess.domain.piece.Piece; +import chess.domain.piece.PieceType; +import chess.domain.piece.Position; +import chess.domain.piece.Row; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Optional; public class ChessBoard { private List pieces; public ChessBoard(List pieces) { - this.pieces = pieces; + this.pieces = new ArrayList<>(pieces); } public List getPieces() { return pieces; } + + public boolean isEnd() { + int kingCount = (int) pieces.stream() + .filter(piece -> piece.getPieceType() == PieceType.KING) + .count(); + return kingCount != 2; + } + + public void moveWhite(Map.Entry currentPosition, Map.Entry destination) { + validateExistPiece(currentPosition, Color.WHITE); + Piece choicedPiece = findChoicedPiece(currentPosition); + validateStop(choicedPiece, destination); + List allPiecesExceptMovingPiece = getAllPiecesExceptMovingPiece(choicedPiece); + choicedPiece.move(destination, allPiecesExceptMovingPiece); + removeDestinationPiece(Color.WHITE, destination); + } + + public void moveBlack(Map.Entry currentPosition, Map.Entry destination) { + validateExistPiece(currentPosition, Color.BLACK); + Piece choicedPiece = findChoicedPiece(currentPosition); + validateStop(choicedPiece, destination); + List allPiecesExceptMovingPiece = getAllPiecesExceptMovingPiece(choicedPiece); + choicedPiece.move(destination, allPiecesExceptMovingPiece); + removeDestinationPiece(Color.BLACK, destination); + } + + private void validateExistPiece(Map.Entry position, Color color) { + boolean isExist = pieces.stream() + .anyMatch(piece -> piece.isExist(position.getKey(), position.getValue()) + && piece.getColor() == color); + if (!isExist) { + throw new IllegalArgumentException("해당 좌표에 움직일 수 있는 기물이 없습니다."); + } + } + + private void validateStop(Piece choicedPiece, Map.Entry destination) { + if (choicedPiece.isExist(destination.getKey(), destination.getValue())) { + throw new IllegalArgumentException("선택된 기물은 반드시 다른 위치로 이동해야 합니다."); + } + } + + private List getAllPiecesExceptMovingPiece(Piece choicedPiece) { + List allPieces = new ArrayList<>(pieces); + allPieces.remove(choicedPiece); + return allPieces; + } + + private Piece findChoicedPiece(Map.Entry currentPosition) { + return pieces.stream() + .filter(piece -> piece.isExist(currentPosition.getKey(), currentPosition.getValue())) + .findFirst().get(); + } + + private void removeDestinationPiece(Color color, Map.Entry destination) { + Optional enemyPieceAtDestination = pieces.stream() + .filter(piece -> piece.isExist(destination.getKey(), destination.getValue()) + && piece.getColor() == color.opposite()) + .findFirst(); + + enemyPieceAtDestination.ifPresent(piece -> pieces.remove(piece)); + } } diff --git a/src/main/java/chess/domain/piece/Bishop.java b/src/main/java/chess/domain/piece/Bishop.java index 04e314a34a5..4c9e38ba929 100644 --- a/src/main/java/chess/domain/piece/Bishop.java +++ b/src/main/java/chess/domain/piece/Bishop.java @@ -1,8 +1,85 @@ package chess.domain.piece; +import java.util.List; +import java.util.Map; + public class Bishop extends Piece { public Bishop(PieceType pieceType, Position position, Color color) { super(pieceType, position, color); } + + @Override + protected boolean isMoveablePosition(Position destinationPosition) { + Map.Entry columAndRowDistance = this.position.calculateColumnAndRowDistance(destinationPosition); + int xDistance = Math.abs(columAndRowDistance.getKey()); + int yDistance = Math.abs(columAndRowDistance.getValue()); + return xDistance == yDistance; + } + + @Override + protected boolean isMoveablePath(Position destinationPosition, List allPiecesExceptMovingPiece) { + Map.Entry columAndRowDistance = this.position.calculateColumnAndRowDistance(destinationPosition); + int xDistance = columAndRowDistance.getKey(); + int yDistance = columAndRowDistance.getValue(); + + List otherPiecesPositions = allPiecesExceptMovingPiece.stream() + .map(Piece::getPosition) + .toList(); + + Position testMovingPosition = this.position; + if (xDistance > 0) { + if (yDistance > 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveRightUp(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + if (yDistance < 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveRightDown(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + } + if (xDistance < 0) { + if (yDistance > 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveLeftUp(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + if (yDistance < 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveLeftDown(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + } + return true; + } } diff --git a/src/main/java/chess/domain/piece/Column.java b/src/main/java/chess/domain/piece/Column.java index 0a63a90a1ec..792e19684bb 100644 --- a/src/main/java/chess/domain/piece/Column.java +++ b/src/main/java/chess/domain/piece/Column.java @@ -57,4 +57,8 @@ public Column moveRight(final int step) { public static List getAllColumns() { return Arrays.stream(values()).toList(); } + + public int calculateDistance(Column column) { + return column.ordinal() - this.ordinal(); + } } diff --git a/src/main/java/chess/domain/piece/King.java b/src/main/java/chess/domain/piece/King.java index 2ba27ec0af7..bfdd32a68f2 100644 --- a/src/main/java/chess/domain/piece/King.java +++ b/src/main/java/chess/domain/piece/King.java @@ -1,8 +1,61 @@ package chess.domain.piece; +import java.util.List; +import java.util.Map; + public class King extends Piece { public King(PieceType pieceType, Position position, Color color) { super(pieceType, position, color); } + + @Override + protected boolean isMoveablePosition(Position destinationPosition) { + if (this.position.moveRight().equals(destinationPosition)) { + return true; + } + if (this.position.moveLeft().equals(destinationPosition)) { + return true; + } + if (this.position.moveRight().equals(destinationPosition)) { + return true; + } + if (this.position.moveDown().equals(destinationPosition)) { + return true; + } + return false; + } + + @Override + protected boolean isMoveablePath(Position destinationPosition, List allPiecesExceptMovingPiece) { + List allPositions = allPiecesExceptMovingPiece.stream() + .map(Piece::getPosition) + .toList(); + + if (allPositions.contains(this.position.moveRight())) { + Position finalTestMovingPosition = this.position.moveRight(); + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (allPositions.contains(this.position.moveLeft())) { + Position finalTestMovingPosition = this.position.moveLeft(); + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (allPositions.contains(this.position.moveDown())) { + Position finalTestMovingPosition = this.position.moveDown(); + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (allPositions.contains(this.position.moveUp())) { + Position finalTestMovingPosition = this.position.moveUp(); + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + return true; + } } diff --git a/src/main/java/chess/domain/piece/Knight.java b/src/main/java/chess/domain/piece/Knight.java index df2515b97c4..217806c2b76 100644 --- a/src/main/java/chess/domain/piece/Knight.java +++ b/src/main/java/chess/domain/piece/Knight.java @@ -1,8 +1,77 @@ package chess.domain.piece; +import java.util.List; +import java.util.Map; + public class Knight extends Piece { public Knight(PieceType pieceType, Position position, Color color) { super(pieceType, position, color); } + + @Override + protected boolean isMoveablePosition(Position destinationPosition) { + return true; + } + + @Override + protected boolean isMoveablePath(Position destinationPosition, List allPiecesExceptMovingPiece) { + if (destinationPosition.equals(position.moveUp().moveRightUp())) { + Position finalTestMovingPosition = position.moveUp().moveRightUp(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (destinationPosition.equals(position.moveUp().moveLeftUp())) { + Position finalTestMovingPosition = position.moveUp().moveLeftUp(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (destinationPosition.equals(position.moveDown().moveRightDown())) { + Position finalTestMovingPosition = position.moveDown().moveRightDown(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (destinationPosition.equals(position.moveDown().moveLeftDown())) { + Position finalTestMovingPosition = position.moveDown().moveLeftDown(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (destinationPosition.equals(position.moveLeft().moveLeftUp())) { + Position finalTestMovingPosition = position.moveLeft().moveLeftUp(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (destinationPosition.equals(position.moveLeft().moveLeftDown())) { + Position finalTestMovingPosition = position.moveLeft().moveLeftDown(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (destinationPosition.equals(position.moveRight().moveRightUp())) { + Position finalTestMovingPosition = position.moveRight().moveRightUp(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (destinationPosition.equals(position.moveRight().moveRightDown())) { + Position finalTestMovingPosition = position.moveRight().moveRightDown(); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + return false; + } } diff --git a/src/main/java/chess/domain/piece/Pawn.java b/src/main/java/chess/domain/piece/Pawn.java index 679b8faf897..efd0106ff44 100644 --- a/src/main/java/chess/domain/piece/Pawn.java +++ b/src/main/java/chess/domain/piece/Pawn.java @@ -1,8 +1,66 @@ package chess.domain.piece; +import java.util.List; + public class Pawn extends Piece { public Pawn(PieceType pieceType, Position position, Color color) { super(pieceType, position, color); } + + @Override + protected boolean isMoveablePosition(Position destinationPosition) { + if (this.color == Color.BLACK) { + if (this.position.hasSameRow(Row.SEVEN)) return position.moveDown(2).equals(destinationPosition); + if (this.position.moveUp().equals(destinationPosition)) return true; + if (this.position.moveRight().equals(destinationPosition)) return true; + if (this.position.moveLeft().equals(destinationPosition)) return true; + if (this.position.moveRightUp().equals(destinationPosition) + || this.position.moveLeftUp().equals(destinationPosition)) return true; + return false; + } + if (this.position.hasSameRow(Row.TWO)) return position.moveUp(2).equals(destinationPosition); + if (this.position.moveDown().equals(destinationPosition)) return true; + if (this.position.moveRight().equals(destinationPosition)) return true; + if (this.position.moveLeft().equals(destinationPosition)) return true; + if (this.position.moveRightDown().equals(destinationPosition) + || this.position.moveLeftDown().equals(destinationPosition)) return true; + return false; + } + + @Override + protected boolean isMoveablePath(Position destinationPosition, List allPiecesExceptMovingPiece) { + if (this.color == Color.BLACK) { + if (this.position.hasSameRow(Row.SEVEN)) return position.moveDown(2).equals(destinationPosition); + if (this.position.moveUp().equals(destinationPosition)) return true; + if (this.position.moveRight().equals(destinationPosition)) return true; + if (this.position.moveLeft().equals(destinationPosition)) return true; + if (this.position.moveRightUp().equals(destinationPosition)) { + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(destinationPosition) + && piece.getColor() != this.color); + } + if (this.position.moveLeftUp().equals(destinationPosition)) { + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(destinationPosition) + && piece.getColor() != this.color); + } + return false; + } + if (this.position.hasSameRow(Row.TWO)) return position.moveUp(2).equals(destinationPosition); + if (this.position.moveDown().equals(destinationPosition)) return true; + if (this.position.moveRight().equals(destinationPosition)) return true; + if (this.position.moveLeft().equals(destinationPosition)) return true; + if (this.position.moveRightDown().equals(destinationPosition)) { + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(destinationPosition) + && piece.getColor() != this.color); + } + if (this.position.moveLeftDown().equals(destinationPosition)) { + return allPiecesExceptMovingPiece.stream() + .noneMatch(piece -> piece.isExist(destinationPosition) + && piece.getColor() != this.color); + } + return false; + } } diff --git a/src/main/java/chess/domain/piece/Piece.java b/src/main/java/chess/domain/piece/Piece.java index 761b0244852..be64e1fb62d 100644 --- a/src/main/java/chess/domain/piece/Piece.java +++ b/src/main/java/chess/domain/piece/Piece.java @@ -1,5 +1,8 @@ package chess.domain.piece; +import java.util.List; +import java.util.Map; + public abstract class Piece { protected PieceType pieceType; @@ -24,7 +27,30 @@ public Color getColor() { return color; } - public boolean isExist(Row row, Column column) { - return position.hasSameRowAndColumn(row, column); + public boolean isExist(Column column, Row row) { + return position.hasSameRowAndColumn(column, row); + } + + public boolean isExist(Position destination) { + return this.position.equals(destination); + } + + public void move(Map.Entry destination, List allPiecesExceptMovingPiece) { + Position destinationPosition = new Position(destination.getKey(), destination.getValue()); + if (!isMoveablePosition(destinationPosition)) { + throw new IllegalArgumentException("이동할 수 없는 좌표입니다."); + } + if (!isMoveablePath(destinationPosition, allPiecesExceptMovingPiece)) { + throw new IllegalArgumentException("이동할 수 없는 경로입니다."); + } + this.position = destinationPosition; } + + protected Map.Entry calculateDistance(Position destination) { + return position.calculateColumnAndRowDistance(destination); + } + + protected abstract boolean isMoveablePosition(Position destinationPosition); + + protected abstract boolean isMoveablePath(Position destinationPosition, List allPiecesExceptMovingPiece); } diff --git a/src/main/java/chess/domain/piece/Position.java b/src/main/java/chess/domain/piece/Position.java index 6f9ab875df8..86ba658c277 100644 --- a/src/main/java/chess/domain/piece/Position.java +++ b/src/main/java/chess/domain/piece/Position.java @@ -1,5 +1,8 @@ package chess.domain.piece; +import java.util.Map; +import java.util.Objects; + public record Position( Column column, Row row @@ -168,7 +171,28 @@ public Position moveHorizontal(final int step) { return this; } - public boolean hasSameRowAndColumn(Row row, Column column) { + public boolean hasSameRowAndColumn(Column column, Row row) { return this.row == row && this.column == column; } + + public boolean hasSameRow(Row row) { + return this.row == row; + } + + public Map.Entry calculateColumnAndRowDistance(Position destination) { + int columnDistance = this.column.calculateDistance(destination.column); + int rowDistance = this.row.calculateDistance(destination.row); + return Map.entry(columnDistance, rowDistance); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Position(Column column1, Row row1))) return false; + return row == row1 && column == column1; + } + + @Override + public int hashCode() { + return Objects.hash(column, row); + } } diff --git a/src/main/java/chess/domain/piece/Queen.java b/src/main/java/chess/domain/piece/Queen.java index 72e80470671..fe678d97d0a 100644 --- a/src/main/java/chess/domain/piece/Queen.java +++ b/src/main/java/chess/domain/piece/Queen.java @@ -1,8 +1,132 @@ package chess.domain.piece; +import java.util.List; +import java.util.Map; + public class Queen extends Piece { public Queen(PieceType pieceType, Position position, Color color) { super(pieceType, position, color); } + + @Override + protected boolean isMoveablePosition(Position destinationPosition) { + Map.Entry columnAndRowDistance = position.calculateColumnAndRowDistance(destinationPosition); + int xDistance = columnAndRowDistance.getKey(); + int yDistance = columnAndRowDistance.getValue(); + + if (xDistance == 0) { + return yDistance != 0; + } + if (yDistance == 0) { + return true; + } + return Math.abs(xDistance) == Math.abs(yDistance); + } + + @Override + protected boolean isMoveablePath(Position destinationPosition, List allPiecesExceptMovingPiece) { + Map.Entry columAndRowDistance = this.position.calculateColumnAndRowDistance(destinationPosition); + int xDistance = columAndRowDistance.getKey(); + int yDistance = columAndRowDistance.getValue(); + + List otherPiecesPositions = allPiecesExceptMovingPiece.stream() + .map(Piece::getPosition) + .toList(); + + Position testMovingPosition = this.position; + if (xDistance > 0) { + if (yDistance > 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveRightUp(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + if (yDistance < 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveRightDown(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + } + if (xDistance < 0) { + if (yDistance > 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveLeftUp(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + if (yDistance < 0) { + for (int i = 0; i < Math.abs(xDistance); i++) { + testMovingPosition = testMovingPosition.moveLeftDown(); + if (otherPiecesPositions.contains(testMovingPosition)) { + Position finalTestMovingPosition = testMovingPosition; + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + } + } + } + if (xDistance == 0) { + for (Position position : otherPiecesPositions) { + Map.Entry integerIntegerEntry = this.position.calculateColumnAndRowDistance(position); + int otherPieceYDistance = integerIntegerEntry.getValue(); + if (yDistance == otherPieceYDistance) { + Position finalTestMovingPosition = this.position.moveUp(yDistance); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (yDistance > 0 && otherPieceYDistance > 0) { + return yDistance > otherPieceYDistance; + } + if (yDistance < 0 && otherPieceYDistance < 0) { + return yDistance < otherPieceYDistance; + } + return false; + } + } + if (yDistance == 0) { + for (Position position : otherPiecesPositions) { + Map.Entry integerIntegerEntry = this.position.calculateColumnAndRowDistance(position); + int otherPieceXDistance = integerIntegerEntry.getKey(); + if (xDistance == otherPieceXDistance) { + Position finalTestMovingPosition = this.position.moveUp(yDistance); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (xDistance > 0 && otherPieceXDistance > 0) { + return xDistance > otherPieceXDistance; + } + if (xDistance < 0 && otherPieceXDistance < 0) { + return xDistance < otherPieceXDistance; + } + return false; + } + } + return false; + } } diff --git a/src/main/java/chess/domain/piece/Rook.java b/src/main/java/chess/domain/piece/Rook.java index fd1ce77eb5a..922d9ce7ceb 100644 --- a/src/main/java/chess/domain/piece/Rook.java +++ b/src/main/java/chess/domain/piece/Rook.java @@ -1,8 +1,73 @@ package chess.domain.piece; -public class Rook extends Piece{ +import java.util.List; +import java.util.Map; + +public class Rook extends Piece{ public Rook(PieceType pieceType, Position position, Color color) { super(pieceType, position, color); } + + @Override + protected boolean isMoveablePosition(Position destinationPosition) { + Map.Entry columnAndRowDistance = position.calculateColumnAndRowDistance(destinationPosition); + int xDistance = columnAndRowDistance.getKey(); + int yDistance = columnAndRowDistance.getValue(); + + return xDistance == 0 || yDistance == 0; + } + + @Override + protected boolean isMoveablePath(Position destinationPosition, List allPiecesExceptMovingPiece) { + Map.Entry columnAndRowDistance = position.calculateColumnAndRowDistance(destinationPosition); + int xDistance = columnAndRowDistance.getKey(); + int yDistance = columnAndRowDistance.getValue(); + + List positions = allPiecesExceptMovingPiece.stream() + .map(Piece::getPosition) + .toList(); + + if (xDistance == 0) { + for (Position position : positions) { + Map.Entry integerIntegerEntry = this.position.calculateColumnAndRowDistance(position); + int otherPieceYDistance = integerIntegerEntry.getValue(); + if (yDistance == otherPieceYDistance) { + Position finalTestMovingPosition = this.position.moveUp(yDistance); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (yDistance > 0 && otherPieceYDistance > 0) { + return yDistance > otherPieceYDistance; + } + if (yDistance < 0 && otherPieceYDistance < 0) { + return yDistance < otherPieceYDistance; + } + return false; + } + } + if (yDistance == 0) { + for (Position position : positions) { + Map.Entry integerIntegerEntry = this.position.calculateColumnAndRowDistance(position); + int otherPieceXDistance = integerIntegerEntry.getKey(); + if (xDistance == otherPieceXDistance) { + Position finalTestMovingPosition = this.position.moveUp(yDistance); + return allPiecesExceptMovingPiece.stream() + .noneMatch( + piece -> piece.isExist(finalTestMovingPosition) + && piece.getColor() == this.color); + } + if (xDistance > 0 && otherPieceXDistance > 0) { + return xDistance > otherPieceXDistance; + } + if (xDistance < 0 && otherPieceXDistance < 0) { + return xDistance < otherPieceXDistance; + } + return false; + } + } + return false; + } } diff --git a/src/main/java/chess/domain/piece/Row.java b/src/main/java/chess/domain/piece/Row.java index 85e633e026c..0ab460028fe 100644 --- a/src/main/java/chess/domain/piece/Row.java +++ b/src/main/java/chess/domain/piece/Row.java @@ -57,4 +57,8 @@ public Row moveDown(final int step) { public static List getAllRows() { return Arrays.stream(values()).toList(); } + + public int calculateDistance(Row row) { + return row.ordinal() - this.ordinal(); + } } diff --git a/src/main/java/chess/util/ErrorUtil.java b/src/main/java/chess/util/ErrorUtil.java new file mode 100644 index 00000000000..9fa26e7dc84 --- /dev/null +++ b/src/main/java/chess/util/ErrorUtil.java @@ -0,0 +1,15 @@ +package chess.util; + +import java.util.function.Consumer; + +public class ErrorUtil { + + public static void computeError (Runnable runnable) { + try { + runnable.run(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + runnable.run(); + } + } +} diff --git a/src/main/java/chess/view/InputView.java b/src/main/java/chess/view/InputView.java index d9666f96fdb..bc124d92fc0 100644 --- a/src/main/java/chess/view/InputView.java +++ b/src/main/java/chess/view/InputView.java @@ -1,4 +1,86 @@ package chess.view; +import chess.domain.piece.Column; +import chess.domain.piece.Row; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.Scanner; + public class InputView { + + private static Scanner scanner = new Scanner(System.in); + + public static Entry choiceWhitePiece() { + System.out.println("움직일 백 기물을 선택해주세요 예) A,3"); + return choicePiece(); + } + + public static Entry choiceBlackPiece() { + System.out.println("움직일 흑 기물을 선택해주세요 예) A,3"); + return choicePiece(); + } + + public static Entry choiceDestination() { + System.out.println("움직이고 싶은 좌표를 입력해주세요 예) A,3"); + return choicePiece(); + } + + private static Entry choicePiece() { + String[] input = scanner.nextLine().split(","); + return Map.entry(convertToColumn(input[0]), convertToRaw(input[1])); + } + + private static Column convertToColumn(String input) { + if (input.equals("A")) { + return Column.A; + } + if (input.equals("B")) { + return Column.B; + } + if (input.equals("C")) { + return Column.C; + } + if (input.equals("D")) { + return Column.D; + } + if (input.equals("E")) { + return Column.E; + } + if (input.equals("F")) { + return Column.F; + } + if (input.equals("G")) { + return Column.G; + } + throw new IllegalArgumentException("좌표를 잘못 입력하셨습니다."); + } + + private static Row convertToRaw(String input) { + if (input.equals("1")) { + return Row.ONE; + } + if (input.equals("2")) { + return Row.TWO; + } + if (input.equals("3")) { + return Row.THREE; + } + if (input.equals("4")) { + return Row.FOUR; + } + if (input.equals("5")) { + return Row.FIVE; + } + if (input.equals("6")) { + return Row.SIX; + } + if (input.equals("7")) { + return Row.SEVEN; + } + if (input.equals("8")) { + return Row.EIGHT; + } + throw new IllegalArgumentException("좌표를 잘못 입력하셨습니다."); + } } diff --git a/src/main/java/chess/view/OutputVIew.java b/src/main/java/chess/view/OutputVIew.java index 09d3dd85794..d4ed02fbb40 100644 --- a/src/main/java/chess/view/OutputVIew.java +++ b/src/main/java/chess/view/OutputVIew.java @@ -37,13 +37,13 @@ public static void printChessBoard(ChessBoard chessBoard) { private static Piece getPieceByRowAndColum(List pieces, Row row, Column column) { return pieces.stream() - .filter(piece -> piece.isExist(row, column)) + .filter(piece -> piece.isExist(column, row)) .findFirst().get(); } private static boolean hasPiece(List allPieces, Row row, Column column) { return allPieces.stream() - .anyMatch(piece -> piece.isExist(row, column)); + .anyMatch(piece -> piece.isExist(column, row)); } private static String convertToString(Row row) {