add castling + fix promote undo
This commit is contained in:
@@ -2,23 +2,62 @@ package chess.controller.commands;
|
|||||||
|
|
||||||
import chess.controller.OutputSystem;
|
import chess.controller.OutputSystem;
|
||||||
import chess.controller.PlayerCommand;
|
import chess.controller.PlayerCommand;
|
||||||
|
import chess.model.ChessBoard;
|
||||||
|
import chess.model.Color;
|
||||||
|
import chess.model.Coordinate;
|
||||||
import chess.model.Game;
|
import chess.model.Game;
|
||||||
|
import chess.model.Move;
|
||||||
|
|
||||||
public class CastlingCommand extends PlayerCommand {
|
public class CastlingCommand extends PlayerCommand {
|
||||||
|
|
||||||
|
private Move kingMove;
|
||||||
|
private Move rookMove;
|
||||||
|
private final boolean bigCastling;
|
||||||
|
|
||||||
|
public CastlingCommand(boolean bigCastling) {
|
||||||
|
this.bigCastling = bigCastling;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute(Game game, OutputSystem outputSystem) {
|
public CommandResult execute(Game game, OutputSystem outputSystem) {
|
||||||
// we must promote the pending pawn before
|
// we must promote the pending pawn before
|
||||||
if (game.pawnShouldBePromoted())
|
if (game.pawnShouldBePromoted())
|
||||||
return CommandResult.NotAllowed;
|
return CommandResult.NotAllowed;
|
||||||
|
|
||||||
|
final ChessBoard board = game.getBoard();
|
||||||
|
|
||||||
|
if (bigCastling && !board.canBigCastle(game.getPlayerTurn()))
|
||||||
return CommandResult.NotAllowed;
|
return CommandResult.NotAllowed;
|
||||||
|
|
||||||
|
if (!bigCastling && !board.canSmallCastle(game.getPlayerTurn()))
|
||||||
|
return CommandResult.NotAllowed;
|
||||||
|
|
||||||
|
int rookBeginX = bigCastling ? 0 : 7;
|
||||||
|
int rookEndX = bigCastling ? 3 : 5;
|
||||||
|
|
||||||
|
int kingBeginX = 4;
|
||||||
|
int kingEndX = bigCastling ? 2 : 6;
|
||||||
|
|
||||||
|
int colorLine = game.getPlayerTurn() == Color.White ? 7 : 0;
|
||||||
|
|
||||||
|
Coordinate kingCoords = new Coordinate(kingBeginX, colorLine);
|
||||||
|
Coordinate rookCoords = new Coordinate(rookBeginX, colorLine);
|
||||||
|
|
||||||
|
this.kingMove = new Move(kingCoords, new Coordinate(kingEndX, colorLine));
|
||||||
|
this.rookMove = new Move(rookCoords, new Coordinate(rookEndX, colorLine));
|
||||||
|
|
||||||
|
board.applyMove(this.kingMove);
|
||||||
|
board.applyMove(this.rookMove);
|
||||||
|
|
||||||
|
return CommandResult.Moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CommandResult undoImpl(Game game, OutputSystem outputSystem) {
|
protected CommandResult undoImpl(Game game, OutputSystem outputSystem) {
|
||||||
// TODO Auto-generated method stub
|
game.getBoard().undoMove(this.kingMove, null);
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'undo'");
|
game.getBoard().undoMove(this.rookMove, null);
|
||||||
|
|
||||||
|
return CommandResult.Moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
package chess.controller.commands;
|
|
||||||
|
|
||||||
import chess.controller.OutputSystem;
|
|
||||||
import chess.controller.PlayerCommand;
|
|
||||||
import chess.model.Game;
|
|
||||||
|
|
||||||
public class GrandCastlingCommand extends PlayerCommand {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CommandResult execute(Game game, OutputSystem outputSystem) {
|
|
||||||
// we must promote the pending pawn before
|
|
||||||
if (game.pawnShouldBePromoted())
|
|
||||||
return CommandResult.NotAllowed;
|
|
||||||
|
|
||||||
return CommandResult.NotAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CommandResult undoImpl(Game game, OutputSystem outputSystem) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'undo'");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@ import chess.model.Game;
|
|||||||
import chess.model.Piece;
|
import chess.model.Piece;
|
||||||
import chess.model.pieces.Bishop;
|
import chess.model.pieces.Bishop;
|
||||||
import chess.model.pieces.Knight;
|
import chess.model.pieces.Knight;
|
||||||
import chess.model.pieces.Pawn;
|
|
||||||
import chess.model.pieces.Queen;
|
import chess.model.pieces.Queen;
|
||||||
import chess.model.pieces.Rook;
|
import chess.model.pieces.Rook;
|
||||||
import chess.model.visitor.PawnIdentifier;
|
import chess.model.visitor.PawnIdentifier;
|
||||||
@@ -25,9 +24,12 @@ public class PromoteCommand extends PlayerCommand {
|
|||||||
|
|
||||||
private final PromoteType promoteType;
|
private final PromoteType promoteType;
|
||||||
private Coordinate pieceCoords;
|
private Coordinate pieceCoords;
|
||||||
|
private Piece oldPawn;
|
||||||
|
|
||||||
public PromoteCommand(PromoteType promoteType) {
|
public PromoteCommand(PromoteType promoteType) {
|
||||||
this.promoteType = promoteType;
|
this.promoteType = promoteType;
|
||||||
|
this.pieceCoords = null;
|
||||||
|
this.oldPawn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -50,6 +52,7 @@ public class PromoteCommand extends PlayerCommand {
|
|||||||
if (destY != enemyLine)
|
if (destY != enemyLine)
|
||||||
return CommandResult.NotAllowed;
|
return CommandResult.NotAllowed;
|
||||||
|
|
||||||
|
this.oldPawn = pawn;
|
||||||
board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords);
|
board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords);
|
||||||
|
|
||||||
return CommandResult.Moved;
|
return CommandResult.Moved;
|
||||||
@@ -82,10 +85,11 @@ public class PromoteCommand extends PlayerCommand {
|
|||||||
|
|
||||||
assert promoted != null;
|
assert promoted != null;
|
||||||
|
|
||||||
Color player = promoted.getColor();
|
board.pieceComes(this.oldPawn, this.pieceCoords);
|
||||||
board.pieceComes(new Pawn(player), this.pieceCoords);
|
|
||||||
|
|
||||||
return CommandResult.ActionNeeded;
|
game.getLastAction().undo(game, outputSystem);
|
||||||
|
|
||||||
|
return CommandResult.Moved;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,6 +181,45 @@ public class ChessBoard {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canCastle(Color color, int rookX, Direction kingDirection) {
|
||||||
|
if (isKingInCheck(color))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int colorLine = color == Color.White ? 7 : 0;
|
||||||
|
|
||||||
|
Coordinate kingCoords = new Coordinate(4, colorLine);
|
||||||
|
Coordinate rookCoords = new Coordinate(rookX, colorLine);
|
||||||
|
Piece king = pieceAt(kingCoords);
|
||||||
|
Piece rook = pieceAt(rookCoords);
|
||||||
|
|
||||||
|
if (king == null || rook == null || king.hasMoved() || rook.hasMoved())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int step = 1; step <= 2; step++) {
|
||||||
|
Coordinate dest = Coordinate.fromIndex(kingCoords.toIndex() + step * kingDirection.getIndexOffset());
|
||||||
|
Piece obstacle = pieceAt(dest);
|
||||||
|
if (obstacle != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
applyMove(new Move(kingCoords, dest));
|
||||||
|
if (isKingInCheck(color)) {
|
||||||
|
undoLastMove();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
undoLastMove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canSmallCastle(Color color) {
|
||||||
|
return canCastle(color, 7, Direction.Right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canBigCastle(Color color) {
|
||||||
|
return canCastle(color, 0, Direction.Left);
|
||||||
|
}
|
||||||
|
|
||||||
public Move getLastMove() {
|
public Move getLastMove() {
|
||||||
return this.lastMove;
|
return this.lastMove;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import chess.controller.OutputSystem;
|
|||||||
import chess.controller.commands.CastlingCommand;
|
import chess.controller.commands.CastlingCommand;
|
||||||
import chess.controller.commands.GetAllowedMovesCommand;
|
import chess.controller.commands.GetAllowedMovesCommand;
|
||||||
import chess.controller.commands.GetPieceAtCommand;
|
import chess.controller.commands.GetPieceAtCommand;
|
||||||
import chess.controller.commands.GrandCastlingCommand;
|
|
||||||
import chess.controller.commands.MoveCommand;
|
import chess.controller.commands.MoveCommand;
|
||||||
import chess.controller.commands.PromoteCommand;
|
import chess.controller.commands.PromoteCommand;
|
||||||
import chess.controller.commands.PromoteCommand.PromoteType;
|
import chess.controller.commands.PromoteCommand.PromoteType;
|
||||||
@@ -61,11 +60,11 @@ public class Window extends JFrame implements OutputSystem {
|
|||||||
|
|
||||||
private void buildButtons(JPanel bottom) {
|
private void buildButtons(JPanel bottom) {
|
||||||
castlingButton.addActionListener((event) -> {
|
castlingButton.addActionListener((event) -> {
|
||||||
sendCommand(new CastlingCommand());
|
sendCommand(new CastlingCommand(false));
|
||||||
});
|
});
|
||||||
|
|
||||||
bigCastlingButton.addActionListener((event) -> {
|
bigCastlingButton.addActionListener((event) -> {
|
||||||
sendCommand(new GrandCastlingCommand());
|
sendCommand(new CastlingCommand(true));
|
||||||
});
|
});
|
||||||
|
|
||||||
undoButton.addActionListener((event) -> {
|
undoButton.addActionListener((event) -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user