package chess.controller.commands; import chess.controller.PlayerCommand; import chess.controller.event.GameListener; 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, GameListener outputSystem) { final ChessBoard board = game.getBoard(); // we must promote the pending pawn before if (board.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.getDeadPieceCoords()); board.applyMove(move); if (board.isKingInCheck(game.getPlayerTurn())) { board.undoLastMove(); return CommandResult.NotAllowed; } if (board.pawnShouldBePromoted()) return CommandResult.ActionNeeded; board.setLastMove(this.move); return CommandResult.Moved; } @Override protected CommandResult undoImpl(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); board.undoMove(move, deadPiece); return CommandResult.Moved; } @Override public void postExec(Game game, GameListener outputSystem) { tryPromote(game, outputSystem); } private void tryPromote(Game game, GameListener outputSystem) { Coordinate pawnPos = game.getBoard().pawnPromotePosition(); if (pawnPos == null) return; outputSystem.promotePawn(pawnPos); } }