From 9179b3cda9ea5e78e11482fa93e25dc2008b2142 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 2 Apr 2025 17:19:26 +0200 Subject: [PATCH] promote not that uggly --- app/src/main/java/chess/App.java | 4 +- .../main/java/chess/io/CommandExecutor.java | 46 +++++++++++- app/src/main/java/chess/io/OutputSystem.java | 5 ++ .../java/chess/io/commands/MoveCommand.java | 24 ++---- .../chess/io/commands/PromoteCommand.java | 74 +++++++++++++++++++ .../model/visitor/PermissiveRuleChecker.java | 4 +- .../main/java/chess/simplerender/Window.java | 12 ++- 7 files changed, 142 insertions(+), 27 deletions(-) create mode 100644 app/src/main/java/chess/io/commands/PromoteCommand.java diff --git a/app/src/main/java/chess/App.java b/app/src/main/java/chess/App.java index bc87e18..923f845 100644 --- a/app/src/main/java/chess/App.java +++ b/app/src/main/java/chess/App.java @@ -12,10 +12,10 @@ import chess.simplerender.Window; public class App { public static void main(String[] args) { CommandExecutor commandExecutor = new CommandExecutor(); - + Game game = new Game(new ChessBoard()); Window window = new Window(commandExecutor); - + commandExecutor.setGame(game); commandExecutor.setOutputSystem(window); diff --git a/app/src/main/java/chess/io/CommandExecutor.java b/app/src/main/java/chess/io/CommandExecutor.java index 99ff429..677d09a 100644 --- a/app/src/main/java/chess/io/CommandExecutor.java +++ b/app/src/main/java/chess/io/CommandExecutor.java @@ -1,6 +1,12 @@ package chess.io; +import chess.io.commands.MoveCommand; +import chess.model.ChessBoard; +import chess.model.Color; +import chess.model.Coordinate; import chess.model.Game; +import chess.model.Piece; +import chess.model.pieces.Pawn; public class CommandExecutor { @@ -14,15 +20,18 @@ public class CommandExecutor { public CommandResult executeCommand(Command command) { CommandResult result = command.execute(this.game, this.outputSystem); - if (result == CommandResult.Moved) + if (result == CommandResult.Moved) { + checkPromotion(((MoveCommand) command).getMove().getFinish()); + checkGameStatus(); alternatePlayers(); + } return result; } private void alternatePlayers() { this.game.switchPlayerTurn(); this.outputSystem.playerTurn(this.game.getPlayerTurn()); - } + } public void setOutputSystem(OutputSystem outputSystem) { this.outputSystem = outputSystem; @@ -32,4 +41,37 @@ public class CommandExecutor { this.game = game; } + private void checkPromotion(Coordinate pieceCoords) { + + Piece piece = this.game.getBoard().pieceAt(pieceCoords); + + if (piece == null || !(piece instanceof Pawn)) + return; + + int destY = pieceCoords.getY(); + + int enemyLine = piece.getColor() == Color.White ? 0 : 7; + + if (destY == enemyLine) { + outputSystem.promotePawn(pieceCoords); + } + } + + private void checkGameStatus() { + final ChessBoard board = game.getBoard(); + + final Color enemy = Color.getEnemy(game.getPlayerTurn()); + + if (board.isKingInCheck(enemy)) { + if (board.hasAllowedMoves(enemy)) { + outputSystem.kingIsInCheck(); + } else { + outputSystem.kingIsInMat(); + outputSystem.winnerIs(game.getPlayerTurn()); + } + } else if (!board.hasAllowedMoves(enemy)) { + outputSystem.patSituation(); + } + } + } diff --git a/app/src/main/java/chess/io/OutputSystem.java b/app/src/main/java/chess/io/OutputSystem.java index 2f16fea..dd488c2 100644 --- a/app/src/main/java/chess/io/OutputSystem.java +++ b/app/src/main/java/chess/io/OutputSystem.java @@ -1,6 +1,9 @@ package chess.io; +import chess.io.commands.MoveCommand; +import chess.io.commands.PromoteCommand; import chess.model.Color; +import chess.model.Coordinate; public interface OutputSystem { @@ -17,4 +20,6 @@ public interface OutputSystem { void hasSurrendered(Color color); void gameStarted(); + + void promotePawn(Coordinate pieceCoords); } diff --git a/app/src/main/java/chess/io/commands/MoveCommand.java b/app/src/main/java/chess/io/commands/MoveCommand.java index 5d9bc9d..bb3e59c 100644 --- a/app/src/main/java/chess/io/commands/MoveCommand.java +++ b/app/src/main/java/chess/io/commands/MoveCommand.java @@ -3,8 +3,8 @@ package chess.io.commands; import chess.io.Command; import chess.io.CommandResult; import chess.io.OutputSystem; +import chess.io.commands.PromoteCommand.PromoteType; import chess.model.ChessBoard; -import chess.model.Color; import chess.model.Game; import chess.model.Move; import chess.model.Piece; @@ -17,6 +17,10 @@ public class MoveCommand extends Command { this.move = move; } + public Move getMove() { + return move; + } + @Override public CommandResult execute(Game game, OutputSystem outputSystem) { final ChessBoard board = game.getBoard(); @@ -39,25 +43,7 @@ public class MoveCommand extends Command { return CommandResult.NotAllowed; } - checkGameStatus(game, outputSystem); - return CommandResult.Moved; } - private void checkGameStatus(Game game, OutputSystem outputSystem) { - final ChessBoard board = game.getBoard(); - - final Color enemy = Color.getEnemy(game.getPlayerTurn()); - - if (board.isKingInCheck(enemy)) { - if (board.hasAllowedMoves(enemy)) { - outputSystem.kingIsInCheck(); - } else { - outputSystem.kingIsInMat(); - outputSystem.winnerIs(game.getPlayerTurn()); - } - } else if(!board.hasAllowedMoves(enemy)) { - outputSystem.patSituation(); - } - } } diff --git a/app/src/main/java/chess/io/commands/PromoteCommand.java b/app/src/main/java/chess/io/commands/PromoteCommand.java new file mode 100644 index 0000000..aa75bef --- /dev/null +++ b/app/src/main/java/chess/io/commands/PromoteCommand.java @@ -0,0 +1,74 @@ +package chess.io.commands; + +import chess.io.Command; +import chess.io.CommandResult; +import chess.io.OutputSystem; +import chess.model.ChessBoard; +import chess.model.Color; +import chess.model.Coordinate; +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; + +public class PromoteCommand extends Command { + + public enum PromoteType { + Queen, + Rook, + Bishop, + Knight + } + + private final PromoteType promoteType; + private final Coordinate pieceCoords; + + public PromoteCommand(PromoteType promoteType, Coordinate pieceCoords) { + this.promoteType = promoteType; + this.pieceCoords = pieceCoords; + } + + @Override + public CommandResult execute(Game game, OutputSystem outputSystem) { + final ChessBoard board = game.getBoard(); + + Piece pawn = board.pieceAt(this.pieceCoords); + if (pawn == null || !(pawn instanceof Pawn)) + return CommandResult.NotAllowed; + + int destY = this.pieceCoords.getY(); + + int enemyLine = pawn.getColor() == Color.White ? 0 : 7; + + if (destY != enemyLine) + return CommandResult.NotAllowed; + + board.pieceLeaves(this.pieceCoords); + board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords); + + return CommandResult.NotMoved; + } + + private Piece createPiece(PromoteType promoteType, Color color) { + switch (promoteType) { + case Queen: + return new Queen(color); + + case Bishop: + return new Bishop(color); + + case Knight: + return new Knight(color); + + case Rook: + return new Rook(color); + + default: + return null; + } + } + +} diff --git a/app/src/main/java/chess/model/visitor/PermissiveRuleChecker.java b/app/src/main/java/chess/model/visitor/PermissiveRuleChecker.java index 8af813e..1ba7fb4 100644 --- a/app/src/main/java/chess/model/visitor/PermissiveRuleChecker.java +++ b/app/src/main/java/chess/model/visitor/PermissiveRuleChecker.java @@ -86,8 +86,8 @@ public class PermissiveRuleChecker implements PieceVisitor { } // Allowing small diagonal moves - if (directionIndexOffset == Direction.FrontLeft.getIndexOffset() - || directionIndexOffset == Direction.FrontRight.getIndexOffset()) { + if (directionIndexOffset * pawn.multiplier() == Direction.FrontLeft.getIndexOffset() + || directionIndexOffset * pawn.multiplier() == Direction.FrontRight.getIndexOffset()) { return distance == 1; } diff --git a/app/src/main/java/chess/simplerender/Window.java b/app/src/main/java/chess/simplerender/Window.java index c332958..7d168db 100644 --- a/app/src/main/java/chess/simplerender/Window.java +++ b/app/src/main/java/chess/simplerender/Window.java @@ -17,6 +17,8 @@ import chess.io.OutputSystem; import chess.io.commands.GetAllowedMovesCommand; import chess.io.commands.GetPieceAtCommand; import chess.io.commands.MoveCommand; +import chess.io.commands.PromoteCommand; +import chess.io.commands.PromoteCommand.PromoteType; import chess.model.Coordinate; import chess.model.Move; import chess.model.Piece; @@ -96,9 +98,9 @@ public class Window extends JFrame implements OutputSystem { private boolean previewMoves(int x, int y) { GetAllowedMovesCommand movesCommand = new GetAllowedMovesCommand(new Coordinate(x, y)); - if(sendCommand(movesCommand) == CommandResult.NotAllowed) + if (sendCommand(movesCommand) == CommandResult.NotAllowed) return false; - + List allowedMoves = movesCommand.getDestinations(); if (allowedMoves.isEmpty()) return false; @@ -180,4 +182,10 @@ public class Window extends JFrame implements OutputSystem { buildBoard(); } + @Override + public void promotePawn(Coordinate pieceCoords) { + System.out.println("PROMOTE"); + sendCommand(new PromoteCommand(PromoteType.Queen, pieceCoords)); + } + }