diff --git a/app/src/main/java/chess/App.java b/app/src/main/java/chess/ConsoleMain.java similarity index 89% rename from app/src/main/java/chess/App.java rename to app/src/main/java/chess/ConsoleMain.java index dede586..55f5edb 100644 --- a/app/src/main/java/chess/App.java +++ b/app/src/main/java/chess/ConsoleMain.java @@ -9,7 +9,7 @@ import chess.model.ChessBoard; import chess.model.Game; import chess.view.consolerender.Console; -public class App { +public class ConsoleMain { public static void main(String[] args) { CommandExecutor commandExecutor = new CommandExecutor(); @@ -17,7 +17,7 @@ public class App { Console console = new Console(commandExecutor); commandExecutor.setGame(game); - commandExecutor.setOutputSystem(console); + commandExecutor.addListener(console); commandExecutor.executeCommand(new NewGameCommand()); } diff --git a/app/src/main/java/chess/SwingMain.java b/app/src/main/java/chess/SwingMain.java new file mode 100644 index 0000000..74af6f3 --- /dev/null +++ b/app/src/main/java/chess/SwingMain.java @@ -0,0 +1,21 @@ +package chess; + +import chess.controller.CommandExecutor; +import chess.controller.commands.NewGameCommand; +import chess.model.ChessBoard; +import chess.model.Game; +import chess.view.simplerender.Window; + +public class SwingMain { + 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.addListener(window); + + commandExecutor.executeCommand(new NewGameCommand()); + } +} diff --git a/app/src/main/java/chess/controller/Command.java b/app/src/main/java/chess/controller/Command.java index d2c3230..2e39bfb 100644 --- a/app/src/main/java/chess/controller/Command.java +++ b/app/src/main/java/chess/controller/Command.java @@ -1,5 +1,6 @@ package chess.controller; +import chess.controller.event.GameListener; import chess.model.Game; public abstract class Command { @@ -15,7 +16,7 @@ public abstract class Command { NotAllowed; } - public abstract CommandResult execute(Game game, OutputSystem outputSystem); + public abstract CommandResult execute(Game game, GameListener outputSystem); - public void postExec(Game game, OutputSystem outputSystem) {} + public void postExec(Game game, GameListener outputSystem) {} } diff --git a/app/src/main/java/chess/controller/CommandExecutor.java b/app/src/main/java/chess/controller/CommandExecutor.java index c29d92d..d25990e 100644 --- a/app/src/main/java/chess/controller/CommandExecutor.java +++ b/app/src/main/java/chess/controller/CommandExecutor.java @@ -2,24 +2,25 @@ package chess.controller; import chess.controller.Command.CommandResult; import chess.controller.commands.UndoCommand; +import chess.controller.event.GameDispatcher; +import chess.controller.event.GameListener; import chess.model.Game; import chess.model.Game.GameStatus; public class CommandExecutor { private Game game; - private OutputSystem outputSystem; + private final GameDispatcher dispatcher; public CommandExecutor() { this.game = null; - this.outputSystem = null; + this.dispatcher = new GameDispatcher(); } public synchronized CommandResult executeCommand(Command command) { assert this.game != null : "No input game specified !"; - assert this.outputSystem != null : "No output system specified !"; - CommandResult result = command.execute(this.game, this.outputSystem); + 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; @@ -29,7 +30,7 @@ public class CommandExecutor { if (command instanceof PlayerCommand playerCommand && result != CommandResult.NotAllowed) this.game.addAction(playerCommand); - command.postExec(game, outputSystem); + command.postExec(game, dispatcher); return result; } @@ -40,21 +41,21 @@ public class CommandExecutor { return; case ActionNeeded: - this.outputSystem.updateDisplay(); + this.dispatcher.updateDisplay(); return; case Moved: if (checkGameStatus()) return; switchPlayerTurn(); - this.outputSystem.updateDisplay(); + this.dispatcher.updateDisplay(); return; } } private void switchPlayerTurn() { this.game.switchPlayerTurn(); - this.outputSystem.playerTurn(this.game.getPlayerTurn()); + this.dispatcher.playerTurn(this.game.getPlayerTurn()); } /** @@ -66,27 +67,27 @@ public class CommandExecutor { switch (gameStatus) { case Check: - this.outputSystem.kingIsInCheck(); + this.dispatcher.kingIsInCheck(); return false; case CheckMate: - this.outputSystem.kingIsInMat(); - this.outputSystem.winnerIs(this.game.getPlayerTurn()); + this.dispatcher.kingIsInMat(); + this.dispatcher.winnerIs(this.game.getPlayerTurn()); return true; case OnGoing: return false; case Pat: - this.outputSystem.patSituation(); + this.dispatcher.patSituation(); return true; } return false; } - public void setOutputSystem(OutputSystem outputSystem) { - this.outputSystem = outputSystem; + public void addListener(GameListener listener) { + this.dispatcher.addListener(listener); } public void setGame(Game game) { diff --git a/app/src/main/java/chess/controller/PlayerCommand.java b/app/src/main/java/chess/controller/PlayerCommand.java index 42ca979..bc30e18 100644 --- a/app/src/main/java/chess/controller/PlayerCommand.java +++ b/app/src/main/java/chess/controller/PlayerCommand.java @@ -1,14 +1,15 @@ package chess.controller; +import chess.controller.event.GameListener; import chess.model.Game; public abstract class PlayerCommand extends Command{ - public CommandResult undo(Game game, OutputSystem outputSystem) { + public CommandResult undo(Game game, GameListener outputSystem) { CommandResult result = undoImpl(game, outputSystem); game.updateLastMove(); return result; } - protected abstract CommandResult undoImpl(Game game, OutputSystem outputSystem); + protected abstract CommandResult undoImpl(Game game, GameListener outputSystem); } diff --git a/app/src/main/java/chess/controller/commands/CastlingCommand.java b/app/src/main/java/chess/controller/commands/CastlingCommand.java index ce96453..6bd3a20 100644 --- a/app/src/main/java/chess/controller/commands/CastlingCommand.java +++ b/app/src/main/java/chess/controller/commands/CastlingCommand.java @@ -1,7 +1,7 @@ package chess.controller.commands; -import chess.controller.OutputSystem; import chess.controller.PlayerCommand; +import chess.controller.event.GameListener; import chess.model.ChessBoard; import chess.model.Color; import chess.model.Coordinate; @@ -19,7 +19,7 @@ public class CastlingCommand extends PlayerCommand { } @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); // we must promote the pending pawn before @@ -53,7 +53,7 @@ public class CastlingCommand extends PlayerCommand { } @Override - protected CommandResult undoImpl(Game game, OutputSystem outputSystem) { + protected CommandResult undoImpl(Game game, GameListener outputSystem) { game.getBoard().undoMove(this.kingMove, null); game.getBoard().undoMove(this.rookMove, null); diff --git a/app/src/main/java/chess/controller/commands/GetAllowedMovesPieceCommand.java b/app/src/main/java/chess/controller/commands/GetAllowedMovesPieceCommand.java index a040214..a8054ed 100644 --- a/app/src/main/java/chess/controller/commands/GetAllowedMovesPieceCommand.java +++ b/app/src/main/java/chess/controller/commands/GetAllowedMovesPieceCommand.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; import chess.controller.Command; -import chess.controller.OutputSystem; +import chess.controller.event.GameListener; import chess.model.ChessBoard; import chess.model.Coordinate; import chess.model.Game; @@ -21,7 +21,7 @@ public class GetAllowedMovesPieceCommand extends Command { } @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); Piece piece = board.pieceAt(start); diff --git a/app/src/main/java/chess/controller/commands/GetPieceAtCommand.java b/app/src/main/java/chess/controller/commands/GetPieceAtCommand.java index ac8bfb5..6ba951f 100644 --- a/app/src/main/java/chess/controller/commands/GetPieceAtCommand.java +++ b/app/src/main/java/chess/controller/commands/GetPieceAtCommand.java @@ -1,7 +1,7 @@ package chess.controller.commands; import chess.controller.Command; -import chess.controller.OutputSystem; +import chess.controller.event.GameListener; import chess.model.Coordinate; import chess.model.Game; import chess.model.Piece; @@ -17,7 +17,7 @@ public class GetPieceAtCommand extends Command{ } @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { if (!pieceCoords.isValid()) return CommandResult.NotAllowed; diff --git a/app/src/main/java/chess/controller/commands/GetPlayerMovesCommand.java b/app/src/main/java/chess/controller/commands/GetPlayerMovesCommand.java index 35f0cae..b0b0f82 100644 --- a/app/src/main/java/chess/controller/commands/GetPlayerMovesCommand.java +++ b/app/src/main/java/chess/controller/commands/GetPlayerMovesCommand.java @@ -3,7 +3,7 @@ package chess.controller.commands; import java.util.List; import chess.controller.Command; -import chess.controller.OutputSystem; +import chess.controller.event.GameListener; import chess.model.Game; import chess.model.Move; @@ -12,7 +12,7 @@ public class GetPlayerMovesCommand extends Command { private List moves; @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { this.moves = game.getBoard().getAllowedMoves(game.getPlayerTurn()); return CommandResult.NotMoved; } diff --git a/app/src/main/java/chess/controller/commands/MoveCommand.java b/app/src/main/java/chess/controller/commands/MoveCommand.java index c20a32d..fe0773f 100644 --- a/app/src/main/java/chess/controller/commands/MoveCommand.java +++ b/app/src/main/java/chess/controller/commands/MoveCommand.java @@ -1,7 +1,7 @@ package chess.controller.commands; -import chess.controller.OutputSystem; import chess.controller.PlayerCommand; +import chess.controller.event.GameListener; import chess.model.ChessBoard; import chess.model.Coordinate; import chess.model.Game; @@ -24,7 +24,7 @@ public class MoveCommand extends PlayerCommand { } @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); // we must promote the pending pawn before @@ -58,7 +58,7 @@ public class MoveCommand extends PlayerCommand { } @Override - protected CommandResult undoImpl(Game game, OutputSystem outputSystem) { + protected CommandResult undoImpl(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); board.undoMove(move, deadPiece); @@ -66,11 +66,11 @@ public class MoveCommand extends PlayerCommand { } @Override - public void postExec(Game game, OutputSystem outputSystem) { + public void postExec(Game game, GameListener outputSystem) { tryPromote(game, outputSystem); } - private void tryPromote(Game game, OutputSystem outputSystem) { + private void tryPromote(Game game, GameListener outputSystem) { Coordinate pawnPos = game.getBoard().pawnPromotePosition(); if (pawnPos == null) diff --git a/app/src/main/java/chess/controller/commands/NewGameCommand.java b/app/src/main/java/chess/controller/commands/NewGameCommand.java index fe9fb9a..96f2f87 100644 --- a/app/src/main/java/chess/controller/commands/NewGameCommand.java +++ b/app/src/main/java/chess/controller/commands/NewGameCommand.java @@ -1,7 +1,7 @@ package chess.controller.commands; import chess.controller.Command; -import chess.controller.OutputSystem; +import chess.controller.event.GameListener; import chess.model.ChessBoard; import chess.model.Color; import chess.model.Coordinate; @@ -14,7 +14,7 @@ import chess.model.pieces.Queen; import chess.model.pieces.Rook; public class NewGameCommand extends Command { - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); board.clearBoard(); diff --git a/app/src/main/java/chess/controller/commands/PromoteCommand.java b/app/src/main/java/chess/controller/commands/PromoteCommand.java index 5bb0326..4df4eb9 100644 --- a/app/src/main/java/chess/controller/commands/PromoteCommand.java +++ b/app/src/main/java/chess/controller/commands/PromoteCommand.java @@ -1,7 +1,7 @@ package chess.controller.commands; -import chess.controller.OutputSystem; import chess.controller.PlayerCommand; +import chess.controller.event.GameListener; import chess.model.ChessBoard; import chess.model.Color; import chess.model.Coordinate; @@ -33,7 +33,7 @@ public class PromoteCommand extends PlayerCommand { } @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); this.pieceCoords = board.pawnPromotePosition(); @@ -78,7 +78,7 @@ public class PromoteCommand extends PlayerCommand { } @Override - protected CommandResult undoImpl(Game game, OutputSystem outputSystem) { + protected CommandResult undoImpl(Game game, GameListener outputSystem) { final ChessBoard board = game.getBoard(); Piece promoted = board.pieceAt(this.pieceCoords); diff --git a/app/src/main/java/chess/controller/commands/SurrenderCommand.java b/app/src/main/java/chess/controller/commands/SurrenderCommand.java index 7c6e2bc..191475a 100644 --- a/app/src/main/java/chess/controller/commands/SurrenderCommand.java +++ b/app/src/main/java/chess/controller/commands/SurrenderCommand.java @@ -1,7 +1,7 @@ package chess.controller.commands; import chess.controller.Command; -import chess.controller.OutputSystem; +import chess.controller.event.GameListener; import chess.model.Color; import chess.model.Game; @@ -14,7 +14,7 @@ public class SurrenderCommand extends Command { } @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { outputSystem.hasSurrendered(player); outputSystem.winnerIs(Color.getEnemy(player)); return CommandResult.NotMoved; diff --git a/app/src/main/java/chess/controller/commands/UndoCommand.java b/app/src/main/java/chess/controller/commands/UndoCommand.java index 6ec2566..3b4f45a 100644 --- a/app/src/main/java/chess/controller/commands/UndoCommand.java +++ b/app/src/main/java/chess/controller/commands/UndoCommand.java @@ -1,14 +1,14 @@ package chess.controller.commands; import chess.controller.Command; -import chess.controller.OutputSystem; import chess.controller.PlayerCommand; +import chess.controller.event.GameListener; import chess.model.Game; public class UndoCommand extends Command{ @Override - public CommandResult execute(Game game, OutputSystem outputSystem) { + public CommandResult execute(Game game, GameListener outputSystem) { PlayerCommand lastAction = game.getLastAction(); if (lastAction == null) return CommandResult.NotAllowed; diff --git a/app/src/main/java/chess/controller/event/GameAdaptator.java b/app/src/main/java/chess/controller/event/GameAdaptator.java new file mode 100644 index 0000000..16f5510 --- /dev/null +++ b/app/src/main/java/chess/controller/event/GameAdaptator.java @@ -0,0 +1,35 @@ +package chess.controller.event; + +import chess.model.Color; +import chess.model.Coordinate; + +public class GameAdaptator implements GameListener { + + @Override + public void playerTurn(Color color) {} + + @Override + public void winnerIs(Color color) {} + + @Override + public void kingIsInCheck() {} + + @Override + public void kingIsInMat() {} + + @Override + public void patSituation() {} + + @Override + public void hasSurrendered(Color color) {} + + @Override + public void gameStarted() {} + + @Override + public void promotePawn(Coordinate pieceCoords) {} + + @Override + public void updateDisplay() {} + +} diff --git a/app/src/main/java/chess/controller/event/GameDispatcher.java b/app/src/main/java/chess/controller/event/GameDispatcher.java new file mode 100644 index 0000000..af2fc48 --- /dev/null +++ b/app/src/main/java/chess/controller/event/GameDispatcher.java @@ -0,0 +1,68 @@ +package chess.controller.event; + +import java.util.ArrayList; +import java.util.List; + +import chess.model.Color; +import chess.model.Coordinate; + +public class GameDispatcher implements GameListener{ + + private final List listeners; + + public GameDispatcher() { + this.listeners = new ArrayList<>(); + } + + public void addListener(GameListener listener) { + this.listeners.add(listener); + } + + @Override + public void playerTurn(Color color) { + this.listeners.forEach((l) -> l.playerTurn(color)); + } + + @Override + public void winnerIs(Color color) { + this.listeners.forEach((l) -> l.winnerIs(color)); + } + + @Override + public void kingIsInCheck() { + this.listeners.forEach((l) -> l.kingIsInCheck()); + } + + @Override + public void kingIsInMat() { + this.listeners.forEach((l) -> l.kingIsInMat()); + } + + @Override + public void patSituation() { + this.listeners.forEach((l) -> l.patSituation()); + } + + @Override + public void hasSurrendered(Color color) { + this.listeners.forEach((l) -> l.hasSurrendered(color)); + } + + @Override + public void gameStarted() { + this.listeners.forEach((l) -> l.gameStarted()); + } + + @Override + public void promotePawn(Coordinate pieceCoords) { + this.listeners.forEach((l) -> l.promotePawn(pieceCoords)); + } + + @Override + public void updateDisplay() { + this.listeners.forEach((l) -> l.updateDisplay()); + } + + + +} diff --git a/app/src/main/java/chess/controller/OutputSystem.java b/app/src/main/java/chess/controller/event/GameListener.java similarity index 83% rename from app/src/main/java/chess/controller/OutputSystem.java rename to app/src/main/java/chess/controller/event/GameListener.java index 38b310e..a8183c8 100644 --- a/app/src/main/java/chess/controller/OutputSystem.java +++ b/app/src/main/java/chess/controller/event/GameListener.java @@ -1,9 +1,9 @@ -package chess.controller; +package chess.controller.event; import chess.model.Color; import chess.model.Coordinate; -public interface OutputSystem { +public interface GameListener { void playerTurn(Color color); diff --git a/app/src/main/java/chess/view/consolerender/Console.java b/app/src/main/java/chess/view/consolerender/Console.java index d1bb525..5334c5d 100644 --- a/app/src/main/java/chess/view/consolerender/Console.java +++ b/app/src/main/java/chess/view/consolerender/Console.java @@ -2,11 +2,11 @@ package chess.view.consolerender; import chess.controller.Command; import chess.controller.CommandExecutor; -import chess.controller.OutputSystem; import chess.controller.commands.GetPieceAtCommand; import chess.controller.commands.MoveCommand; import chess.controller.commands.PromoteCommand; import chess.controller.commands.SurrenderCommand; +import chess.controller.event.GameListener; import chess.model.Color; import chess.model.Coordinate; import chess.model.Move; @@ -14,7 +14,7 @@ import chess.model.Piece; import java.util.Scanner; -public class Console implements OutputSystem { +public class Console implements GameListener { private final Scanner scanner = new Scanner(System.in); private final CommandExecutor commandExecutor; private final ConsolePieceName consolePieceName = new ConsolePieceName(); diff --git a/app/src/main/java/chess/view/simplerender/Window.java b/app/src/main/java/chess/view/simplerender/Window.java index a6aedf3..edb34f1 100644 --- a/app/src/main/java/chess/view/simplerender/Window.java +++ b/app/src/main/java/chess/view/simplerender/Window.java @@ -19,7 +19,6 @@ import javax.swing.SwingUtilities; import chess.controller.Command; import chess.controller.Command.CommandResult; import chess.controller.CommandExecutor; -import chess.controller.OutputSystem; import chess.controller.commands.CastlingCommand; import chess.controller.commands.GetAllowedMovesPieceCommand; import chess.controller.commands.GetPieceAtCommand; @@ -27,12 +26,13 @@ import chess.controller.commands.GetPlayerMovesCommand; import chess.controller.commands.MoveCommand; import chess.controller.commands.PromoteCommand; import chess.controller.commands.PromoteCommand.PromoteType; +import chess.controller.event.GameListener; import chess.controller.commands.UndoCommand; import chess.model.Coordinate; import chess.model.Move; import chess.model.Piece; -public class Window extends JFrame implements OutputSystem { +public class Window extends JFrame implements GameListener { private final CommandExecutor commandExecutor;