128 lines
2.9 KiB
Java
128 lines
2.9 KiB
Java
package chess.controller;
|
|
|
|
import java.util.List;
|
|
|
|
import chess.controller.Command.CommandResult;
|
|
import chess.controller.commands.UndoCommand;
|
|
import chess.controller.event.AsyncGameDispatcher;
|
|
import chess.controller.event.GameDispatcher;
|
|
import chess.controller.event.GameListener;
|
|
import chess.model.Game;
|
|
import chess.model.Game.GameStatus;
|
|
|
|
/**
|
|
* Execute commands.
|
|
*/
|
|
public class CommandExecutor {
|
|
|
|
private Game game;
|
|
private final GameDispatcher dispatcher;
|
|
|
|
public CommandExecutor() {
|
|
this(null);
|
|
}
|
|
|
|
public CommandExecutor(Game game) {
|
|
this(game, new AsyncGameDispatcher());
|
|
}
|
|
|
|
public CommandExecutor(Game game, GameDispatcher dispatcher) {
|
|
this.game = game;
|
|
this.dispatcher = dispatcher;
|
|
}
|
|
|
|
public synchronized CommandResult executeCommand(Command command) {
|
|
assert this.game != null : "No input game specified !";
|
|
|
|
CommandResult result = command.execute(this.game, this.dispatcher);
|
|
|
|
// non player commands are not supposed to return move result
|
|
assert result != CommandResult.Moved || command instanceof PlayerCommand || command instanceof UndoCommand;
|
|
|
|
processResult(command, result);
|
|
|
|
if (command instanceof PlayerCommand playerCommand && result != CommandResult.NotAllowed)
|
|
this.game.addAction(playerCommand);
|
|
|
|
return result;
|
|
}
|
|
|
|
public void executeCommands(List<? extends Command> commands) {
|
|
for (Command command : commands) {
|
|
CommandResult result = executeCommand(command);
|
|
assert result != CommandResult.NotAllowed;
|
|
}
|
|
}
|
|
|
|
private void processResult(Command command, CommandResult result) {
|
|
switch (result) {
|
|
case NotAllowed:
|
|
case NotMoved:
|
|
return;
|
|
|
|
case ActionNeeded:
|
|
this.dispatcher.onBoardUpdate();
|
|
return;
|
|
|
|
case Moved:
|
|
boolean notifyPlayerTurn = true;
|
|
this.dispatcher.onBoardUpdate();
|
|
if (!(command instanceof UndoCommand) && checkGameStatus()) {
|
|
this.dispatcher.onGameEnd();
|
|
notifyPlayerTurn = false;
|
|
}
|
|
switchPlayerTurn(command instanceof UndoCommand, notifyPlayerTurn);
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void switchPlayerTurn(boolean undone, boolean notifyPlayerTurn) {
|
|
this.game.switchPlayerTurn();
|
|
if (notifyPlayerTurn)
|
|
this.dispatcher.onPlayerTurn(this.game.getPlayerTurn(), undone);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @return True if the game is over
|
|
*/
|
|
private boolean checkGameStatus() {
|
|
GameStatus gameStatus = this.game.checkGameStatus();
|
|
|
|
switch (gameStatus) {
|
|
case Draw:
|
|
this.dispatcher.onDraw();
|
|
return true;
|
|
case Check:
|
|
this.dispatcher.onKingInCheck();
|
|
return false;
|
|
|
|
case CheckMate:
|
|
this.dispatcher.onKingInMat();
|
|
this.dispatcher.onWin(this.game.getPlayerTurn());
|
|
return true;
|
|
|
|
case OnGoing:
|
|
return false;
|
|
|
|
case Pat:
|
|
this.dispatcher.onPatSituation();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void addListener(GameListener listener) {
|
|
this.dispatcher.addListener(listener);
|
|
}
|
|
|
|
public void setGame(Game game) {
|
|
this.game = game;
|
|
}
|
|
|
|
public void close() {
|
|
this.dispatcher.close();
|
|
}
|
|
}
|