diff --git a/app/src/main/java/chess/io/CommandExecutor.java b/app/src/main/java/chess/io/CommandExecutor.java index b452b8a..4462bbe 100644 --- a/app/src/main/java/chess/io/CommandExecutor.java +++ b/app/src/main/java/chess/io/CommandExecutor.java @@ -1,6 +1,7 @@ package chess.io; import chess.io.commands.MoveCommand; +import chess.io.commands.PromoteCommand; import chess.model.Game; public class CommandExecutor { @@ -18,12 +19,24 @@ public class CommandExecutor { assert this.outputSystem != null : "No output system specified !"; CommandResult result = command.execute(this.game, this.outputSystem); - if (result == CommandResult.Moved) { - this.game.checkPromotion(((MoveCommand) command).getMove().getFinish()); - this.game.checkGameStatus(); + processResult(command, result); + return result; + } + + private void processResult(Command command, CommandResult result) { + if (result != CommandResult.Moved) + return; + + if (command instanceof MoveCommand move) { + boolean needsPromote = this.game.checkPromotion(move.getMove().getFinish()); + if (this.game.checkGameStatus()) + return; + + if (!needsPromote) + this.game.switchPlayerTurn(); + } else if (command instanceof PromoteCommand) { this.game.switchPlayerTurn(); } - return result; } public void setOutputSystem(OutputSystem outputSystem) { @@ -60,6 +73,4 @@ public class CommandExecutor { this.game.OnPlayerTurn.connect(outputSystem::playerTurn); } - - } diff --git a/app/src/main/java/chess/io/commands/MoveCommand.java b/app/src/main/java/chess/io/commands/MoveCommand.java index 0a23565..c51901d 100644 --- a/app/src/main/java/chess/io/commands/MoveCommand.java +++ b/app/src/main/java/chess/io/commands/MoveCommand.java @@ -24,6 +24,10 @@ public class MoveCommand extends Command { public CommandResult execute(Game game, OutputSystem outputSystem) { final ChessBoard board = game.getBoard(); + // we must promote the pending pawn before + if (game.pawnShouldBePromoted()) + return CommandResult.NotAllowed; + Piece piece = board.pieceAt(move.getStart()); if (piece == null) return CommandResult.NotAllowed; diff --git a/app/src/main/java/chess/io/commands/PromoteCommand.java b/app/src/main/java/chess/io/commands/PromoteCommand.java index aa75bef..018852b 100644 --- a/app/src/main/java/chess/io/commands/PromoteCommand.java +++ b/app/src/main/java/chess/io/commands/PromoteCommand.java @@ -49,7 +49,7 @@ public class PromoteCommand extends Command { board.pieceLeaves(this.pieceCoords); board.pieceComes(createPiece(this.promoteType, pawn.getColor()), this.pieceCoords); - return CommandResult.NotMoved; + return CommandResult.Moved; } private Piece createPiece(PromoteType promoteType, Color color) { diff --git a/app/src/main/java/chess/model/Game.java b/app/src/main/java/chess/model/Game.java index 6999b45..52ea4eb 100644 --- a/app/src/main/java/chess/model/Game.java +++ b/app/src/main/java/chess/model/Game.java @@ -16,7 +16,6 @@ public class Game { public final Signal0 OnMat = new Signal0(); public final Signal0 OnPat = new Signal0(); - public Game(ChessBoard board) { this.board = board; } @@ -39,23 +38,30 @@ public class Game { this.OnPlayerTurn.emit(playerTurn); } - public void checkPromotion(Coordinate pieceCoords) { + public boolean checkPromotion(Coordinate pieceCoords) { Piece piece = getBoard().pieceAt(pieceCoords); if (piece == null || !(piece instanceof Pawn)) - return; + return false; int destY = pieceCoords.getY(); int enemyLine = piece.getColor() == Color.White ? 0 : 7; - if (destY == enemyLine) { - OnPromote.emit(pieceCoords); - } + if (destY != enemyLine) + return false; + + OnPromote.emit(pieceCoords); + return true; + } - public void checkGameStatus() { + /** + * + * @return true if game should end + */ + public boolean checkGameStatus() { final ChessBoard board = getBoard(); final Color enemy = Color.getEnemy(getPlayerTurn()); @@ -66,10 +72,30 @@ public class Game { } else { OnMat.emit(); OnWin.emit(getPlayerTurn()); + return true; } } else if (!board.hasAllowedMoves(enemy)) { OnPat.emit(); + return true; } + return false; + } + + public boolean pawnShouldBePromoted() { + if (pawnShouldBePromoted(Color.White)) + return true; + return pawnShouldBePromoted(Color.Black); + } + + private boolean pawnShouldBePromoted(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; + } + + return false; } } diff --git a/app/src/main/java/chess/simplerender/Window.java b/app/src/main/java/chess/simplerender/Window.java index ff61fd9..958d284 100644 --- a/app/src/main/java/chess/simplerender/Window.java +++ b/app/src/main/java/chess/simplerender/Window.java @@ -196,7 +196,42 @@ public class Window extends JFrame implements OutputSystem { @Override public void promotePawn(Coordinate pieceCoords) { - sendCommand(new PromoteCommand(PromoteType.Queen, pieceCoords)); + SwingUtilities.invokeLater(() -> { + // String result = JOptionPane.showInputDialog(this, "Choisissez le type !"); + // sendCommand(new PromoteCommand(PromoteType.Queen, pieceCoords)); + + String result = null; + + Object[] possibilities = new Object[PromoteType.values().length]; + int i = 0; + for (PromoteType type : PromoteType.values()) { + possibilities[i] = type.name(); + i++; + } + + while (result == null || result.isEmpty()) { + result = (String) JOptionPane.showInputDialog( + this, + "Choose the type of piece to upgrade the pawn", + "Promote Dialog", + JOptionPane.PLAIN_MESSAGE, + null, + possibilities, + possibilities[0]); + } + + PromoteType choosedType = null; + + for (PromoteType type : PromoteType.values()) { + if (type.name().equals(result)) { + choosedType = type; + break; + } + } + + if (choosedType != null) + sendCommand(new PromoteCommand(choosedType, pieceCoords)); + }); } }