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; return;
if (command instanceof MoveCommand move) { if (command instanceof MoveCommand move) {
boolean needsPromote = this.game.checkPromotion(move.getMove().getFinish()); boolean needsPromote = this.game.pawnShouldBePromoted();
if (needsPromote) if (needsPromote)
this.outputSystem.promotePawn(move.getMove().getFinish()); this.outputSystem.promotePawn(move.getMove().getFinish());

View File

@@ -10,10 +10,13 @@ import chess.model.Piece;
import chess.model.visitor.PiecePathChecker; import chess.model.visitor.PiecePathChecker;
public class MoveCommand extends PlayerCommand { public class MoveCommand extends PlayerCommand {
private final Move move; private final Move move;
private Piece deadPiece;
public MoveCommand(Move move) { public MoveCommand(Move move) {
this.move = move; this.move = move;
this.deadPiece = null;
} }
public Move getMove() { public Move getMove() {
@@ -39,6 +42,7 @@ public class MoveCommand extends PlayerCommand {
if (!valid) if (!valid)
return CommandResult.NotAllowed; return CommandResult.NotAllowed;
this.deadPiece = board.pieceAt(move.getFinish());
board.applyMove(move); board.applyMove(move);
if (board.isKingInCheck(game.getPlayerTurn())) { if (board.isKingInCheck(game.getPlayerTurn())) {
@@ -51,7 +55,9 @@ public class MoveCommand extends PlayerCommand {
@Override @Override
public void undo(Game game, OutputSystem outputSystem) { 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 class NewGameCommand extends Command {
public CommandResult execute(Game game, OutputSystem outputSystem) { 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++) { for (int i = 0; i < 8; i++) {
board.pieceComes(new Pawn(Color.Black), new Coordinate(i, 1)); 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 PromoteType promoteType;
private final Coordinate pieceCoords; private Coordinate pieceCoords;
public PromoteCommand(PromoteType promoteType, Coordinate pieceCoords) { public PromoteCommand(PromoteType promoteType) {
this.promoteType = promoteType; this.promoteType = promoteType;
this.pieceCoords = pieceCoords;
} }
@Override @Override
public CommandResult execute(Game game, OutputSystem outputSystem) { public CommandResult execute(Game game, OutputSystem outputSystem) {
final ChessBoard board = game.getBoard(); final ChessBoard board = game.getBoard();
this.pieceCoords = game.pawnPromotePosition();
if (this.pieceCoords == null)
return CommandResult.NotAllowed;
Piece pawn = board.pieceAt(this.pieceCoords); Piece pawn = board.pieceAt(this.pieceCoords);
if (pawn == null || !(pawn instanceof Pawn)) if (pawn == null || !(pawn instanceof Pawn))
return CommandResult.NotAllowed; return CommandResult.NotAllowed;
@@ -46,7 +50,6 @@ public class PromoteCommand extends PlayerCommand {
if (destY != enemyLine) if (destY != enemyLine)
return CommandResult.NotAllowed; return CommandResult.NotAllowed;
board.pieceLeaves(this.pieceCoords);
board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords); board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords);
return CommandResult.Moved; return CommandResult.Moved;
@@ -80,7 +83,6 @@ public class PromoteCommand extends PlayerCommand {
assert promoted != null; assert promoted != null;
Color player = promoted.getColor(); Color player = promoted.getColor();
board.pieceLeaves(this.pieceCoords);
board.pieceComes(new Pawn(player), this.pieceCoords); board.pieceComes(new Pawn(player), this.pieceCoords);
} }

View File

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

View File

@@ -30,23 +30,6 @@ public class Game {
playerTurn = Color.getEnemy(playerTurn); 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() { public GameStatus checkGameStatus() {
final Color enemy = Color.getEnemy(getPlayerTurn()); final Color enemy = Color.getEnemy(getPlayerTurn());
@@ -63,20 +46,38 @@ public class Game {
} }
public boolean pawnShouldBePromoted() { public boolean pawnShouldBePromoted() {
if (pawnShouldBePromoted(Color.White)) return pawnPromotePosition() != null;
return true;
return pawnShouldBePromoted(Color.Black);
} }
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; int enemyLineY = color == Color.White ? 0 : 7;
for (int x = 0; x < Coordinate.VALUE_MAX; x++) { for (int x = 0; x < Coordinate.VALUE_MAX; x++) {
if (checkPromotion(new Coordinate(x, enemyLineY))) Coordinate pieceCoords = new Coordinate(x, enemyLineY);
return true; 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 final Color color;
private int moved; private int moved;
private int ejectedMoveNumber;
public Piece(Color color) { public Piece(Color color) {
this.color = color; this.color = color;
this.moved = 0; this.moved = 0;
this.ejectedMoveNumber = -1;
} }
public void move() { public void move() {
@@ -28,18 +26,6 @@ public abstract class Piece {
this.moved--; 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); public abstract <T> T accept(PieceVisitor<T> visitor);
} }

View File

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