From 810934aea1a55dcb0ed193fda217698bd35faa28 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Fri, 4 Apr 2025 20:06:32 +0200 Subject: [PATCH] better undo --- .../main/java/chess/io/CommandExecutor.java | 2 +- .../java/chess/io/commands/MoveCommand.java | 8 ++- .../chess/io/commands/NewGameCommand.java | 4 +- .../chess/io/commands/PromoteCommand.java | 12 +++-- app/src/main/java/chess/model/ChessBoard.java | 13 ++--- app/src/main/java/chess/model/Game.java | 49 ++++++++++--------- app/src/main/java/chess/model/Piece.java | 14 ------ .../main/java/chess/simplerender/Window.java | 2 +- 8 files changed, 48 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/chess/io/CommandExecutor.java b/app/src/main/java/chess/io/CommandExecutor.java index d2dcb84..a8f4f98 100644 --- a/app/src/main/java/chess/io/CommandExecutor.java +++ b/app/src/main/java/chess/io/CommandExecutor.java @@ -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()); diff --git a/app/src/main/java/chess/io/commands/MoveCommand.java b/app/src/main/java/chess/io/commands/MoveCommand.java index 0dec394..b914890 100644 --- a/app/src/main/java/chess/io/commands/MoveCommand.java +++ b/app/src/main/java/chess/io/commands/MoveCommand.java @@ -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); } } diff --git a/app/src/main/java/chess/io/commands/NewGameCommand.java b/app/src/main/java/chess/io/commands/NewGameCommand.java index 4d6f465..f060212 100644 --- a/app/src/main/java/chess/io/commands/NewGameCommand.java +++ b/app/src/main/java/chess/io/commands/NewGameCommand.java @@ -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)); diff --git a/app/src/main/java/chess/io/commands/PromoteCommand.java b/app/src/main/java/chess/io/commands/PromoteCommand.java index a7a7bef..f19c5f9 100644 --- a/app/src/main/java/chess/io/commands/PromoteCommand.java +++ b/app/src/main/java/chess/io/commands/PromoteCommand.java @@ -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); } diff --git a/app/src/main/java/chess/model/ChessBoard.java b/app/src/main/java/chess/model/ChessBoard.java index ef380b8..2da729f 100644 --- a/app/src/main/java/chess/model/ChessBoard.java +++ b/app/src/main/java/chess/model/ChessBoard.java @@ -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) { diff --git a/app/src/main/java/chess/model/Game.java b/app/src/main/java/chess/model/Game.java index 9a63c94..93e9e6d 100644 --- a/app/src/main/java/chess/model/Game.java +++ b/app/src/main/java/chess/model/Game.java @@ -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; } } diff --git a/app/src/main/java/chess/model/Piece.java b/app/src/main/java/chess/model/Piece.java index d35ff97..f0d9efe 100644 --- a/app/src/main/java/chess/model/Piece.java +++ b/app/src/main/java/chess/model/Piece.java @@ -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 accept(PieceVisitor visitor); } diff --git a/app/src/main/java/chess/simplerender/Window.java b/app/src/main/java/chess/simplerender/Window.java index 8f75786..0bd04be 100644 --- a/app/src/main/java/chess/simplerender/Window.java +++ b/app/src/main/java/chess/simplerender/Window.java @@ -237,7 +237,7 @@ public class Window extends JFrame implements OutputSystem { } if (choosedType != null) - sendCommand(new PromoteCommand(choosedType, pieceCoords)); + sendCommand(new PromoteCommand(choosedType)); }); }