package chess.io.commands; import chess.io.OutputSystem; import chess.io.PlayerCommand; import chess.model.ChessBoard; import chess.model.Color; import chess.model.Coordinate; import chess.model.Game; import chess.model.Piece; import chess.model.pieces.Bishop; import chess.model.pieces.Knight; import chess.model.pieces.Pawn; import chess.model.pieces.Queen; import chess.model.pieces.Rook; public class PromoteCommand extends PlayerCommand { public enum PromoteType { Queen, Rook, Bishop, Knight } private final PromoteType promoteType; private Coordinate pieceCoords; public PromoteCommand(PromoteType promoteType) { this.promoteType = promoteType; } @Override public CommandResult execute(Game game, OutputSystem outputSystem) { final ChessBoard board = game.getBoard(); this.pieceCoords = game.pawnPromotePosition(); if (this.pieceCoords == null) return CommandResult.NotAllowed; Piece pawn = board.pieceAt(this.pieceCoords); if (pawn == null || !(pawn instanceof Pawn)) return CommandResult.NotAllowed; int destY = this.pieceCoords.getY(); int enemyLine = pawn.getColor() == Color.White ? 0 : 7; if (destY != enemyLine) return CommandResult.NotAllowed; board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords); return CommandResult.Moved; } private Piece createPiece(PromoteType promoteType, Color color) { switch (promoteType) { case Queen: return new Queen(color); case Bishop: return new Bishop(color); case Knight: return new Knight(color); case Rook: return new Rook(color); default: return null; } } @Override public void undo(Game game, OutputSystem outputSystem) { final ChessBoard board = game.getBoard(); Piece promoted = board.pieceAt(this.pieceCoords); assert promoted != null; Color player = promoted.getColor(); board.pieceComes(new Pawn(player), this.pieceCoords); } }