Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@
## 우아한테크코스 코드리뷰

- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md)

## 기능 구현 목록

- 체스 게임판을 초기화 한다.
- 체스 게임판을 출력한다.
- 백의 이동 좌표를 입력 받는다.
- 백 기물을 이동한다.
- 흑 기물 이동 좌표를 입력 받는다.
- 흑 기물을 이동한다.
- 왕이 죽으면 게임이 끝난다.
Empty file removed src/main/java/.gitkeep
Empty file.
12 changes: 12 additions & 0 deletions src/main/java/chess/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +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();
ErrorUtil.computeError(controller::run);
}
}
40 changes: 40 additions & 0 deletions src/main/java/chess/controller/ChessController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package chess.controller;

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 = new ChessBoard(InitBoardGenerator.initChessBoard());
OutputVIew.printChessBoard(chessBoard);

while (!chessBoard.isEnd()) {
moveWhite();
OutputVIew.printChessBoard(chessBoard);
if (chessBoard.isEnd()) break;
moveBlack();
OutputVIew.printChessBoard(chessBoard);
}
}

private void moveWhite() {
Entry<Column, Row> currentPosition = InputView.choiceWhitePiece();
Entry<Column, Row> destination = InputView.choiceDestination();
chessBoard.moveWhite(currentPosition, destination);
}

private void moveBlack() {
Entry<Column, Row> currentPosition = InputView.choiceBlackPiece();
Entry<Column, Row> destination = InputView.choiceDestination();
chessBoard.moveBlack(currentPosition, destination);
}
}
87 changes: 87 additions & 0 deletions src/main/java/chess/domain/board/ChessBoard.java
Original file line number Diff line number Diff line change
@@ -0,0 +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<Piece> pieces;

public ChessBoard(List<Piece> pieces) {
this.pieces = new ArrayList<>(pieces);
}

public List<Piece> 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<Column, Row> currentPosition, Map.Entry<Column, Row> destination) {
validateExistPiece(currentPosition, Color.WHITE);
Piece choicedPiece = findChoicedPiece(currentPosition);
validateStop(choicedPiece, destination);
List<Piece> allPiecesExceptMovingPiece = getAllPiecesExceptMovingPiece(choicedPiece);
choicedPiece.move(destination, allPiecesExceptMovingPiece);
removeDestinationPiece(Color.WHITE, destination);
}

public void moveBlack(Map.Entry<Column, Row> currentPosition, Map.Entry<Column, Row> destination) {
validateExistPiece(currentPosition, Color.BLACK);
Piece choicedPiece = findChoicedPiece(currentPosition);
validateStop(choicedPiece, destination);
List<Piece> allPiecesExceptMovingPiece = getAllPiecesExceptMovingPiece(choicedPiece);
choicedPiece.move(destination, allPiecesExceptMovingPiece);
removeDestinationPiece(Color.BLACK, destination);
}

private void validateExistPiece(Map.Entry<Column, Row> 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<Column, Row> destination) {
if (choicedPiece.isExist(destination.getKey(), destination.getValue())) {
throw new IllegalArgumentException("선택된 기물은 반드시 다른 위치로 이동해야 합니다.");
}
}

private List<Piece> getAllPiecesExceptMovingPiece(Piece choicedPiece) {
List<Piece> allPieces = new ArrayList<>(pieces);
allPieces.remove(choicedPiece);
return allPieces;
}

private Piece findChoicedPiece(Map.Entry<Column, Row> currentPosition) {
return pieces.stream()
.filter(piece -> piece.isExist(currentPosition.getKey(), currentPosition.getValue()))
.findFirst().get();
}

private void removeDestinationPiece(Color color, Map.Entry<Column, Row> destination) {
Optional<Piece> enemyPieceAtDestination = pieces.stream()
.filter(piece -> piece.isExist(destination.getKey(), destination.getValue())
&& piece.getColor() == color.opposite())
.findFirst();

enemyPieceAtDestination.ifPresent(piece -> pieces.remove(piece));
}
}
61 changes: 61 additions & 0 deletions src/main/java/chess/domain/board/InitBoardGenerator.java
Original file line number Diff line number Diff line change
@@ -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<Piece> initChessBoard() {
List<Piece> 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;
}
}
85 changes: 85 additions & 0 deletions src/main/java/chess/domain/piece/Bishop.java
Original file line number Diff line number Diff line change
@@ -0,0 +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<Integer, Integer> 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<Piece> allPiecesExceptMovingPiece) {
Map.Entry<Integer, Integer> columAndRowDistance = this.position.calculateColumnAndRowDistance(destinationPosition);
int xDistance = columAndRowDistance.getKey();
int yDistance = columAndRowDistance.getValue();

List<Position> 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;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package chess;
package chess.domain.piece;

public enum Color {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package chess;
package chess.domain.piece;

import java.util.Arrays;
import java.util.List;

public enum Column {

Expand Down Expand Up @@ -50,4 +53,12 @@ public Column moveRight(final int step) {

throw new IllegalStateException("움직일 수 없는 위치입니다.");
}

public static List<Column> getAllColumns() {
return Arrays.stream(values()).toList();
}

public int calculateDistance(Column column) {
return column.ordinal() - this.ordinal();
}
}
61 changes: 61 additions & 0 deletions src/main/java/chess/domain/piece/King.java
Original file line number Diff line number Diff line change
@@ -0,0 +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<Piece> allPiecesExceptMovingPiece) {
List<Position> 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;
}
}
Loading