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.PlayerCommand;
|
||||
import chess.model.ChessBoard;
|
||||
import chess.model.Color;
|
||||
import chess.model.Coordinate;
|
||||
import chess.model.Game;
|
||||
import chess.model.Move;
|
||||
|
||||
public class CastlingCommand extends PlayerCommand {
|
||||
|
||||
private Move kingMove;
|
||||
private Move rookMove;
|
||||
private final boolean bigCastling;
|
||||
|
||||
public CastlingCommand(boolean bigCastling) {
|
||||
this.bigCastling = bigCastling;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult execute(Game game, OutputSystem outputSystem) {
|
||||
// we must promote the pending pawn before
|
||||
if (game.pawnShouldBePromoted())
|
||||
return CommandResult.NotAllowed;
|
||||
|
||||
return CommandResult.NotAllowed;
|
||||
final ChessBoard board = game.getBoard();
|
||||
|
||||
if (bigCastling && !board.canBigCastle(game.getPlayerTurn()))
|
||||
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
|
||||
protected CommandResult undoImpl(Game game, OutputSystem outputSystem) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'undo'");
|
||||
game.getBoard().undoMove(this.kingMove, null);
|
||||
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.pieces.Bishop;
|
||||
import chess.model.pieces.Knight;
|
||||
import chess.model.pieces.Pawn;
|
||||
import chess.model.pieces.Queen;
|
||||
import chess.model.pieces.Rook;
|
||||
import chess.model.visitor.PawnIdentifier;
|
||||
@@ -25,9 +24,12 @@ public class PromoteCommand extends PlayerCommand {
|
||||
|
||||
private final PromoteType promoteType;
|
||||
private Coordinate pieceCoords;
|
||||
private Piece oldPawn;
|
||||
|
||||
public PromoteCommand(PromoteType promoteType) {
|
||||
this.promoteType = promoteType;
|
||||
this.pieceCoords = null;
|
||||
this.oldPawn = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,6 +52,7 @@ public class PromoteCommand extends PlayerCommand {
|
||||
if (destY != enemyLine)
|
||||
return CommandResult.NotAllowed;
|
||||
|
||||
this.oldPawn = pawn;
|
||||
board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords);
|
||||
|
||||
return CommandResult.Moved;
|
||||
@@ -82,10 +85,11 @@ public class PromoteCommand extends PlayerCommand {
|
||||
|
||||
assert promoted != null;
|
||||
|
||||
Color player = promoted.getColor();
|
||||
board.pieceComes(new Pawn(player), this.pieceCoords);
|
||||
board.pieceComes(this.oldPawn, this.pieceCoords);
|
||||
|
||||
return CommandResult.ActionNeeded;
|
||||
game.getLastAction().undo(game, outputSystem);
|
||||
|
||||
return CommandResult.Moved;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class ChessBoard {
|
||||
}
|
||||
|
||||
public void undoLastMove() {
|
||||
assert this.lastVirtualMove != null: "Can't undo at the beginning!";
|
||||
assert this.lastVirtualMove != null : "Can't undo at the beginning!";
|
||||
|
||||
undoMove(this.lastVirtualMove, this.lastEjectedPiece);
|
||||
}
|
||||
@@ -181,6 +181,45 @@ public class ChessBoard {
|
||||
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() {
|
||||
return this.lastMove;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import chess.controller.OutputSystem;
|
||||
import chess.controller.commands.CastlingCommand;
|
||||
import chess.controller.commands.GetAllowedMovesCommand;
|
||||
import chess.controller.commands.GetPieceAtCommand;
|
||||
import chess.controller.commands.GrandCastlingCommand;
|
||||
import chess.controller.commands.MoveCommand;
|
||||
import chess.controller.commands.PromoteCommand;
|
||||
import chess.controller.commands.PromoteCommand.PromoteType;
|
||||
@@ -61,11 +60,11 @@ public class Window extends JFrame implements OutputSystem {
|
||||
|
||||
private void buildButtons(JPanel bottom) {
|
||||
castlingButton.addActionListener((event) -> {
|
||||
sendCommand(new CastlingCommand());
|
||||
sendCommand(new CastlingCommand(false));
|
||||
});
|
||||
|
||||
bigCastlingButton.addActionListener((event) -> {
|
||||
sendCommand(new GrandCastlingCommand());
|
||||
sendCommand(new CastlingCommand(true));
|
||||
});
|
||||
|
||||
undoButton.addActionListener((event) -> {
|
||||
|
||||
Reference in New Issue
Block a user