better undo

This commit is contained in:
2025-04-04 20:06:32 +02:00
parent 48a215eae5
commit 810934aea1
8 changed files with 48 additions and 56 deletions

View File

@@ -32,7 +32,7 @@ public class CommandExecutor {
return;
if (command instanceof MoveCommand move) {
boolean needsPromote = this.game.checkPromotion(move.getMove().getFinish());
boolean needsPromote = this.game.pawnShouldBePromoted();
if (needsPromote)
this.outputSystem.promotePawn(move.getMove().getFinish());

View File

@@ -10,10 +10,13 @@ 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() {
@@ -39,6 +42,7 @@ public class MoveCommand extends PlayerCommand {
if (!valid)
return CommandResult.NotAllowed;
this.deadPiece = board.pieceAt(move.getFinish());
board.applyMove(move);
if (board.isKingInCheck(game.getPlayerTurn())) {
@@ -51,7 +55,9 @@ public class MoveCommand extends PlayerCommand {
@Override
public void undo(Game game, OutputSystem outputSystem) {
game.getBoard().undoLastMove();
final ChessBoard board = game.getBoard();
board.undoMove(move, deadPiece);
}
}

View File

@@ -16,7 +16,9 @@ import chess.model.pieces.Rook;
public class NewGameCommand extends Command {
public CommandResult execute(Game game, OutputSystem outputSystem) {
ChessBoard board = game.getBoard();
final ChessBoard board = game.getBoard();
board.clearBoard();
for (int i = 0; i < 8; i++) {
board.pieceComes(new Pawn(Color.Black), new Coordinate(i, 1));

View File

@@ -24,17 +24,21 @@ public class PromoteCommand extends PlayerCommand {
}
private final PromoteType promoteType;
private final Coordinate pieceCoords;
private Coordinate pieceCoords;
public PromoteCommand(PromoteType promoteType, Coordinate pieceCoords) {
public PromoteCommand(PromoteType promoteType) {
this.promoteType = promoteType;
this.pieceCoords = pieceCoords;
}
@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;
@@ -46,7 +50,6 @@ public class PromoteCommand extends PlayerCommand {
if (destY != enemyLine)
return CommandResult.NotAllowed;
board.pieceLeaves(this.pieceCoords);
board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords);
return CommandResult.Moved;
@@ -80,7 +83,6 @@ public class PromoteCommand extends PlayerCommand {
assert promoted != null;
Color player = promoted.getColor();
board.pieceLeaves(this.pieceCoords);
board.pieceComes(new Pawn(player), this.pieceCoords);
}

View File

@@ -57,19 +57,14 @@ public class ChessBoard {
public void undoLastMove() {
assert this.lastMove != null: "Can't undo at the beginning!";
Move move = this.lastMove;
undoMove(this.lastMove, this.lastEjectedPiece);
}
public void undoMove(Move move, Piece deadPiece) {
Piece movingPiece = pieceAt(move.getFinish());
pieceComes(movingPiece, move.getStart());
pieceLeaves(move.getFinish());
pieceComes(deadPiece, move.getFinish());
movingPiece.unMove();
if (this.lastEjectedPiece == null)
return;
Piece piece = this.lastEjectedPiece;
pieceComes(piece, move.getFinish());
}
public boolean isCellEmpty(Coordinate coordinate) {

View File

@@ -30,23 +30,6 @@ public class Game {
playerTurn = Color.getEnemy(playerTurn);
}
public boolean checkPromotion(Coordinate pieceCoords) {
Piece piece = getBoard().pieceAt(pieceCoords);
if (piece == null || !(piece instanceof Pawn))
return false;
int destY = pieceCoords.getY();
int enemyLine = piece.getColor() == Color.White ? 0 : 7;
if (destY != enemyLine)
return false;
return true;
}
public GameStatus checkGameStatus() {
final Color enemy = Color.getEnemy(getPlayerTurn());
@@ -63,20 +46,38 @@ public class Game {
}
public boolean pawnShouldBePromoted() {
if (pawnShouldBePromoted(Color.White))
return true;
return pawnShouldBePromoted(Color.Black);
return pawnPromotePosition() != null;
}
private boolean pawnShouldBePromoted(Color color) {
/**
*
* @return Null if there is no pawn to promote
*/
public Coordinate pawnPromotePosition() {
Coordinate piecePos = pawnPromotePosition(Color.White);
if (piecePos != null)
return piecePos;
return pawnPromotePosition(Color.Black);
}
/**
*
* @return Null if there is no pawn to promote
*/
private Coordinate pawnPromotePosition(Color color) {
int enemyLineY = color == Color.White ? 0 : 7;
for (int x = 0; x < Coordinate.VALUE_MAX; x++) {
if (checkPromotion(new Coordinate(x, enemyLineY)))
return true;
Coordinate pieceCoords = new Coordinate(x, enemyLineY);
Piece piece = getBoard().pieceAt(pieceCoords);
if (piece == null || !(piece instanceof Pawn) || piece.getColor() != color)
continue;
return pieceCoords;
}
return false;
return null;
}
}

View File

@@ -4,12 +4,10 @@ public abstract class Piece {
private final Color color;
private int moved;
private int ejectedMoveNumber;
public Piece(Color color) {
this.color = color;
this.moved = 0;
this.ejectedMoveNumber = -1;
}
public void move() {
@@ -28,18 +26,6 @@ public abstract class Piece {
this.moved--;
}
public boolean isEjected() {
return this.ejectedMoveNumber != -1;
}
public int getEjectedMoveNumber() {
return ejectedMoveNumber;
}
public void eject(int moveNumber) {
this.ejectedMoveNumber = moveNumber;
}
public abstract <T> T accept(PieceVisitor<T> visitor);
}

View File

@@ -237,7 +237,7 @@ public class Window extends JFrame implements OutputSystem {
}
if (choosedType != null)
sendCommand(new PromoteCommand(choosedType, pieceCoords));
sendCommand(new PromoteCommand(choosedType));
});
}