package chess.io.commands; import chess.io.OutputSystem; import chess.io.PlayerCommand; import chess.model.ChessBoard; import chess.model.Coordinate; import chess.model.Game; import chess.model.Move; import chess.model.Piece; import chess.model.visitor.PiecePathChecker; public class MoveCommand extends PlayerCommand { private final Move move; private Piece deadPiece; public MoveCommand(Move move) { this.move = move; this.deadPiece = null; } public Move getMove() { return move; } @Override public CommandResult execute(Game game, OutputSystem outputSystem) { final ChessBoard board = game.getBoard(); // we must promote the pending pawn before if (game.pawnShouldBePromoted()) return CommandResult.NotAllowed; Piece piece = board.pieceAt(move.getStart()); if (piece == null) return CommandResult.NotAllowed; if (piece.getColor() != game.getPlayerTurn()) return CommandResult.NotAllowed; boolean valid = new PiecePathChecker(board, move).isValid(); if (!valid) return CommandResult.NotAllowed; this.deadPiece = board.pieceAt(move.getFinish()); board.applyMove(move); if (board.isKingInCheck(game.getPlayerTurn())) { board.undoLastMove(); return CommandResult.NotAllowed; } if (game.pawnShouldBePromoted()) return CommandResult.ActionNeeded; return CommandResult.Moved; } @Override public void undo(Game game, OutputSystem outputSystem) { final ChessBoard board = game.getBoard(); board.undoMove(move, deadPiece); } @Override public void postExec(Game game, OutputSystem outputSystem) { tryPromote(game, outputSystem); } private void tryPromote(Game game, OutputSystem outputSystem) { Coordinate pawnPos = game.pawnPromotePosition(); if (pawnPos == null) return; outputSystem.promotePawn(pawnPos); } }