From f379a6b638509558786db67df6202b85d7fa64d4 Mon Sep 17 00:00:00 2001 From: Daniel Grigencha Date: Sun, 17 Nov 2024 20:17:19 +0100 Subject: [PATCH 1/2] added more logic for the server state diagram --- .../src/main/java/pp.mdga/game/Game.java | 83 ++++++++++++++++++- .../main/java/pp.mdga/server/Animation.java | 14 ++++ .../server/ChoosePieceStateMachine.java | 4 +- .../pp.mdga/server/DetermineStartPlayer.java | 35 ++++++++ .../main/java/pp.mdga/server/FirstRoll.java | 24 ++++++ .../main/java/pp.mdga/server/GameState.java | 7 +- .../main/java/pp.mdga/server/Interrupt.java | 9 ++ .../src/main/java/pp.mdga/server/NoPiece.java | 48 +++++++++++ .../src/main/java/pp.mdga/server/NoTurn.java | 7 ++ .../java/pp.mdga/server/PlayPowerCard.java | 7 ++ .../main/java/pp.mdga/server/PowerCard.java | 47 +++++++++++ .../java/pp.mdga/server/RollDiceMachine.java | 4 +- .../main/java/pp.mdga/server/SecondRoll.java | 18 ++++ .../main/java/pp.mdga/server/SelectPiece.java | 14 ++++ .../main/java/pp.mdga/server/ServerState.java | 7 +- .../pp.mdga/server/ServerStateMachine.java | 10 ++- .../main/java/pp.mdga/server/StartPiece.java | 13 +++ .../main/java/pp.mdga/server/ThirdRoll.java | 18 ++++ .../src/main/java/pp.mdga/server/Turn.java | 2 + .../java/pp.mdga/server/TurnStateMachine.java | 4 +- .../java/pp.mdga/server/WaitingPiece.java | 15 ++++ 21 files changed, 374 insertions(+), 16 deletions(-) create mode 100644 Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java create mode 100644 Projekte/mdga/model/src/main/java/pp.mdga/server/PlayPowerCard.java diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java b/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java index 23f135e9..65b37f6d 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java @@ -22,8 +22,12 @@ public class Game { private Map playerConnectionID; private ArrayList observers = new ArrayList<>(); + private Player startPlayer; private Boolean gameHasStarted = false; private Boolean playerHasDisconnected = false; + private Boolean gameIsInterrupted = false; + private Boolean allRanked = false; + private Boolean movablePieces = false; private static final int AMOUNT_OF_TURBO_CARDS = 16; private static final int AMOUNT_OF_SHIELD_AND_SWAP_CARDS = 12; @@ -309,6 +313,44 @@ public Boolean playerHasDisconnected() { return playerHasDisconnected; } + /** + * This method sets the game interruption state. + * + * @param gameIsInterrupted the new game interruption state + */ + public void setGameIsInterrupted(Boolean gameIsInterrupted) { + this.gameIsInterrupted = gameIsInterrupted; + if (!gameIsInterrupted) notifyObservers(); + } + + /** + * This method returns whether the game is interrupted. + * + * @return true if the game is interrupted, false otherwise + */ + public Boolean gameIsInterrupted() { + return gameIsInterrupted; + } + + /** + * This method returns whether the game is interrupted. + * + * @return true if the game is interrupted, false otherwise + */ + public Boolean getMovablePieces() { + return movablePieces; + } + + /** + * This method sets the game interruption state. + * + * @param movablePieces the new game interruption state + */ + public void setMovablePieces(Boolean movablePieces) { + this.movablePieces = movablePieces; + if (!movablePieces) notifyObservers(); + } + /** * This method sets the player has disconnected. * @@ -316,9 +358,44 @@ public Boolean playerHasDisconnected() { */ public void setPlayerHasDisconnected(Boolean playerHasDisconnected) { this.playerHasDisconnected = playerHasDisconnected; - if (playerHasDisconnected) { - notifyObservers(); - } + if (playerHasDisconnected) notifyObservers(); + } + + /** + * This method returns whether all players have ranked. + * + * @return true if all players have ranked, false otherwise + */ + public Boolean allRanked() { + return allRanked; + } + + /** + * This method sets whether all players have ranked. + * + * @param allRanked the new all ranked state + */ + public void setAllRanked(Boolean allRanked) { + this.allRanked = allRanked; + if (allRanked) notifyObservers(); + } + + /** + * This method returns the start player. + * + * @return the start player + */ + public Player getStartPlayer() { + return startPlayer; + } + + /** + * This method sets the start player. + * + * @param startPlayer the new start player + */ + public void setStartPlayer(Player startPlayer) { + this.startPlayer = startPlayer; } /** diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java new file mode 100644 index 00000000..c7a71f92 --- /dev/null +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java @@ -0,0 +1,14 @@ +package pp.mdga.server; + +import pp.mdga.message.client.AnimationEnd; + +public class Animation extends ServerState { + public Animation(ServerState parent, ServerGameLogic logic) { + super(parent, logic); + } + + @Override + public void receivedAnimationEnd(AnimationEnd msg) { + parent.gotoState(new Turn(parent, logic)); + } +} diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ChoosePieceStateMachine.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ChoosePieceStateMachine.java index 89dbefeb..2558e028 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ChoosePieceStateMachine.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ChoosePieceStateMachine.java @@ -6,7 +6,7 @@ public ChoosePieceStateMachine(ServerState parent, ServerGameLogic logic) { } @Override - public ServerState initialState() { - return null; + public NoPiece initialState() { + return new NoPiece(this, logic); } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java index 6160701f..aaf401e4 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java @@ -1,7 +1,42 @@ package pp.mdga.server; +import pp.mdga.game.Player; +import pp.mdga.message.client.RequestDice; +import pp.mdga.message.server.DiceNow; +import pp.mdga.message.server.RankingRollAgain; + public class DetermineStartPlayer extends ServerState { public DetermineStartPlayer(ServerState parent, ServerGameLogic logic) { super(parent, logic); + logic.getGame().addObserver(this); } + + @Override + public void receivedRequestDice(RequestDice msg) { + // todo: implement + } + + // todo: msg?, sent to everyone? + @Override + public void sentRankingResponse() { + // todo: implemtent + } + + @Override + public void update() { + if (logic.getGame().allRanked()) { + if (logic.getGame().getStartPlayer() == null) { + // todo: send it to everyone? or player with the same dice value? save the players with the same value? + logic.send(new Player(1), new RankingRollAgain()); + } else { + // todo: set start player + Player startPlayer = new Player(1); + logic.getGame().setStartPlayer(startPlayer); + logic.send(startPlayer, new DiceNow()); + parent.gotoState(new Animation(parent, logic)); + logic.getGame().removeObserver(this); + } + } + } + } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java index daa811dd..7787a229 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java @@ -1,7 +1,31 @@ package pp.mdga.server; +import pp.mdga.game.Player; +import pp.mdga.message.client.RequestDice; +import pp.mdga.message.server.Dice; +import pp.mdga.message.server.DiceAgain; + public class FirstRoll extends ServerState { public FirstRoll(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + @Override + public void receivedRequestDice(RequestDice msg) { + // todo: implement player.hasMovablePieces() + if (player.hasMovablePieces()) { + // todo: goto ChoosePiece + } else { + // todo: implement roll + if (roll == 6) { + // todo: send to everyone? or one player? + logic.send(new Player(1), new Dice()); + // todo: goto ChoosePiece + } else { + // todo: send to everyone? or one player? + logic.send(new Player(1), new DiceAgain()); + parent.gotoState(new SecondRoll(parent, logic)); + } + } + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java index 53ee5901..f94b3bb2 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java @@ -34,8 +34,8 @@ public void receivedNoPowerCard(NoPowerCard msg) { } @Override - public void receivedPowerCardChoice(SelectCard msg) { - gameStateMachine.receivedPowerCardChoice(msg); + public void receivedSelectCard(SelectCard msg) { + gameStateMachine.receivedSelectCard(msg); } @Override @@ -68,7 +68,8 @@ public void sentRankingResponse() { @Override public void update() { if (logic.getGame().playerHasDisconnected()) { - parent.gotoState(new Ceremony(parent, logic)); + parent.gotoState(new Interrupt(parent, logic)); + // todo: change to interrupt, save the last state of gamestatemachine, change from interrupt to gamestate has to restore the last state logic.getGame().removeObserver(this); } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java index 0f9e0fdc..ae67c4c8 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java @@ -3,5 +3,14 @@ public class Interrupt extends ServerState { public Interrupt(ServerState parent, ServerGameLogic logic) { super(parent, logic); + logic.getGame().addObserver(this); + } + + @Override + public void update() { + if (!logic.getGame().gameIsInterrupted()) { + parent.gotoState(new GameState(parent, logic)); + logic.getGame().removeObserver(this); + } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java index 9b2cbb48..59a80020 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java @@ -1,7 +1,55 @@ package pp.mdga.server; +import pp.mdga.game.Player; +import pp.mdga.message.server.WaitPiece; + public class NoPiece extends ServerState { public NoPiece(ServerState parent, ServerGameLogic logic) { super(parent, logic); + entry(); + } + + @Override + public void entry() { + if (hasTurbo() || turbo == 0) { + if (roll == 6 && + logic.getGame().getBoard().getPlayerData().getWaitingArea().hasPieces() && + logic.getGame().getBoard().getNodes().getStartNode(Color).isOccupied()) { + parent.gotoState(new WaitingPiece(parent, logic)); + } else { + parent.gotoState(new NoTurn(parent, logic)); + } + } else { + validateHasPieces(); + } + } + + private void validateHasPieces() { + if (logic.getGame().getBoard().getPlayerData().getWaitingArea().hasPieces()) { + if (logic.getGame().getBoard().getNodes().getStartNode(Color).isOccupied()) { + if (roll == 6) { + logic.send(new Player(1), new WaitPiece()); + } else { + validateMove(); + } + } else { + if (logic.getGame().getBoard().getNodes().getStartNode(Color).getPiece().canMove()) { + logic.send(new Player(1), new WaitPiece()); + parent.gotoState(new StartPiece(parent, logic)); + } else { + validateMove(); + } + } + } else { + validateMove(); + } + } + + private void validateMove() { + if (player.canMove()) { + parent.gotoState(new NoTurn(parent, logic)); + } else { + logic.send(new Player(1), new SelectPiece()); + } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java index 9986437b..810e4966 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java @@ -1,7 +1,14 @@ package pp.mdga.server; +import pp.mdga.message.server.EndOfTurn; + public class NoTurn extends ServerState { public NoTurn(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + @Override + public void sentEndOfTurn(EndOfTurn msg) { + // todo: goto end of turn + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/PlayPowerCard.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/PlayPowerCard.java new file mode 100644 index 00000000..cc7cf7b0 --- /dev/null +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/PlayPowerCard.java @@ -0,0 +1,7 @@ +package pp.mdga.server; + +public class PlayPowerCard extends ServerState { + public PlayPowerCard(ServerState parent, ServerGameLogic logic) { + super(parent, logic); + } +} diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java index fef94ce2..5bc0c495 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java @@ -1,7 +1,54 @@ package pp.mdga.server; +import pp.mdga.game.Player; +import pp.mdga.message.client.NoPowerCard; +import pp.mdga.message.client.SelectCard; +import pp.mdga.message.client.SelectedPieces; +import pp.mdga.message.server.DiceNow; +import pp.mdga.message.server.PossibleCard; + public class PowerCard extends ServerState { public PowerCard(ServerState parent, ServerGameLogic logic) { super(parent, logic); + logic.getGame().addObserver(this); + } + + @Override + public void receivedNoPowerCard(NoPowerCard msg) { + // todo: send to everyone? or one player? + // todo: right msg? + logic.send(new Player(1), new DiceNow()); + parent.gotoState(new RollDice(parent, logic)); + } + + @Override + public void receivedSelectCard(SelectCard msg) { + // todo: send to everyone? or one player? + logic.send(new Player(1), new PossibleCard()); + } + + @Override + public void receivedSelectedPieces(SelectedPieces msg) { + if (verifySelectedPieces()) { + // todo: send to everyone? or one player? + // todo: msg PowerCardAnimation? + logic.send(new Player(1), new PowerCardAnimation()); + parent.gotoState(new PlayPowerCard(parent, logic)); + } + } + + @Override + public void sentPossibleCard(PossibleCard msg) { + // todo: implement + } + + @Override + public void update() { + if (!logic.getGame().getMovablePieces()) { + // todo: send to everyone? or one player? + // todo: right msg? + logic.send(new Player(1), new DiceNow()); + parent.gotoState(new RollDice(parent, logic)); + } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/RollDiceMachine.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/RollDiceMachine.java index 49117d0c..bc788947 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/RollDiceMachine.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/RollDiceMachine.java @@ -6,7 +6,7 @@ public RollDiceMachine(ServerState parent, ServerGameLogic logic) { } @Override - public ServerState initialState() { - return null; + public FirstRoll initialState() { + return new FirstRoll(this, logic); } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java index 63b98b9a..a225df40 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java @@ -1,7 +1,25 @@ package pp.mdga.server; +import pp.mdga.game.Player; +import pp.mdga.message.client.RequestDice; +import pp.mdga.message.server.Dice; +import pp.mdga.message.server.DiceAgain; + public class SecondRoll extends ServerState { public SecondRoll(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + @Override + public void receivedRequestDice(RequestDice msg) { + if (roll == 6) { + // todo: send to everyone? or one player? + logic.send(new Player(1), new Dice()); + // todo: goto ChoosePiece + } else { + // todo: send to everyone? or one player? + logic.send(new Player(1), new DiceAgain()); + parent.gotoState(new ThirdRoll(parent, logic)); + } + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java index f3e21d28..a61bfc27 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java @@ -1,7 +1,21 @@ package pp.mdga.server; +import pp.mdga.game.Piece; +import pp.mdga.game.Player; +import pp.mdga.message.server.StartPiece; + public class SelectPiece extends ServerState { public SelectPiece(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + @Override + public void receivedConfirmPiece(Piece p) { + if (verifyPiece(p)) { + logic.send(new Player(1), new Animation()); + // todo: goto state + } else { + logic.send(new Player(1), new StartPiece()); + } + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java index ee022302..8cb15d59 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java @@ -2,6 +2,7 @@ import pp.mdga.game.Piece; import pp.mdga.message.client.*; +import pp.mdga.message.server.EndOfTurn; import pp.mdga.message.server.PossibleCard; import java.lang.System.Logger; @@ -28,8 +29,6 @@ public void receivedNoPowerCard(NoPowerCard msg) { /* do nothing */ } public void receivedNotReady(LobbyNotReady msg) { /* do nothing */ } - public void receivedPowerCardChoice(SelectCard msg) { /* do nothing */ } - public void receivedReady(LobbyReady msg) { /* do nothing */ } public void receivedRequestDice(RequestDice msg) { /* do nothing */ } @@ -37,12 +36,16 @@ public void receivedRequestDice(RequestDice msg) { /* do nothing */ } // todo msg? public void receivedRollRankingDice() { /* do nothing */ } + public void receivedSelectCard(SelectCard msg) { /* do nothing */ } + public void receivedSelectTSK(SelectTSK msg) { /* do nothing */ } public void receivedSelectedPieces(SelectedPieces msg) { /* do nothing */ } public void receivedStartGame(ClientStartGame msg) { /* do nothing */ } + public void sentEndOfTurn(EndOfTurn msg) { /* do nothing */ } + public void sentPossibleCard(PossibleCard msg) { /* do nothing */ } // todo msg?, sent to everyone? diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java index f97d54f2..329da544 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java @@ -2,6 +2,7 @@ import pp.mdga.game.Piece; import pp.mdga.message.client.*; +import pp.mdga.message.server.EndOfTurn; import pp.mdga.message.server.PossibleCard; public abstract class ServerStateMachine extends ServerState { @@ -61,8 +62,8 @@ public void receivedNotReady(LobbyNotReady msg) { } @Override - public void receivedPowerCardChoice(SelectCard msg) { - state.receivedPowerCardChoice(msg); + public void receivedSelectCard(SelectCard msg) { + state.receivedSelectCard(msg); } @Override @@ -96,6 +97,11 @@ public void receivedStartGame(ClientStartGame msg) { state.receivedStartGame(msg); } + @Override + public void sentEndOfTurn(EndOfTurn msg) { + state.sentEndOfTurn(msg); + } + @Override public void sentPossibleCard(PossibleCard msg) { state.sentPossibleCard(msg); diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java index 24e23b60..0e8d8461 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java @@ -1,7 +1,20 @@ package pp.mdga.server; +import pp.mdga.game.Piece; +import pp.mdga.game.Player; + public class StartPiece extends ServerState { public StartPiece(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + @Override + public void receivedConfirmPiece(Piece p) { + if (verifyPiece(p)) { + logic.send(new Player(1), new Animation()); + // todo: goto state + } else { + logic.send(new Player(1), new pp.mdga.message.server.StartPiece()); + } + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java index 5f5245d1..496ef8a5 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java @@ -1,7 +1,25 @@ package pp.mdga.server; +import pp.mdga.game.Player; +import pp.mdga.message.client.RequestDice; +import pp.mdga.message.server.Dice; +import pp.mdga.message.server.DiceAgain; + public class ThirdRoll extends ServerState { public ThirdRoll(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + @Override + public void receivedRequestDice(RequestDice msg) { + if (roll == 6) { + // todo: send to everyone? or one player? + logic.send(new Player(1), new Dice()); + // todo: goto ChoosePiece + } else { + // todo: send to everyone? or one player? + logic.send(new Player(1), new DiceAgain()); + // todo: goto End from Turn + } + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java index ce1447a6..21ec15c7 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java @@ -6,4 +6,6 @@ public class Turn extends ServerState { public Turn(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + // todo: when TurnStateMachine is in the end state, and then? } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/TurnStateMachine.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/TurnStateMachine.java index b54f2e07..a5974332 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/TurnStateMachine.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/TurnStateMachine.java @@ -6,7 +6,7 @@ public TurnStateMachine(ServerState parent, ServerGameLogic logic) { } @Override - public ServerState initialState() { - return null; + public PowerCard initialState() { + return new PowerCard(this, logic); } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java index dcc28f3c..b5f39d38 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java @@ -1,7 +1,22 @@ package pp.mdga.server; +import pp.mdga.game.Piece; +import pp.mdga.game.Player; +import pp.mdga.message.client.AnimationEnd; +import pp.mdga.message.server.StartPiece; + public class WaitingPiece extends ServerState { public WaitingPiece(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + + @Override + public void receivedConfirmPiece(Piece p) { + if (verifyPiece(p)) { + logic.send(new Player(1), new Animation()); + // todo: goto state + } else { + logic.send(new Player(1), new StartPiece()); + } + } } -- 2.43.0 From 89232901a76d988f0822021166204e73cb9709f4 Mon Sep 17 00:00:00 2001 From: Daniel Grigencha Date: Fri, 22 Nov 2024 09:37:49 +0100 Subject: [PATCH 2/2] added more logic for the server state diagram --- .../src/main/java/pp.mdga/game/Game.java | 1 - .../main/java/pp.mdga/server/Animation.java | 4 +- .../pp.mdga/server/DetermineStartPlayer.java | 30 +-- .../main/java/pp.mdga/server/FirstRoll.java | 33 ++- .../main/java/pp.mdga/server/GameState.java | 55 +++-- .../java/pp.mdga/server/GameStateMachine.java | 16 +- .../main/java/pp.mdga/server/Interrupt.java | 12 +- .../src/main/java/pp.mdga/server/Lobby.java | 62 ++++-- .../src/main/java/pp.mdga/server/NoPiece.java | 68 +++--- .../src/main/java/pp.mdga/server/NoTurn.java | 2 +- .../main/java/pp.mdga/server/PowerCard.java | 22 +- .../main/java/pp.mdga/server/SecondRoll.java | 20 +- .../main/java/pp.mdga/server/SelectPiece.java | 15 +- .../java/pp.mdga/server/ServerAutomaton.java | 14 ++ .../java/pp.mdga/server/ServerGameLogic.java | 1 - .../main/java/pp.mdga/server/ServerState.java | 203 ++++++++++++++---- .../pp.mdga/server/ServerStateMachine.java | 186 ++++++++++++---- .../main/java/pp.mdga/server/StartPiece.java | 15 +- .../main/java/pp.mdga/server/ThirdRoll.java | 20 +- .../src/main/java/pp.mdga/server/Turn.java | 25 +++ .../java/pp.mdga/server/WaitingPiece.java | 17 +- 21 files changed, 570 insertions(+), 251 deletions(-) diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java b/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java index 65b37f6d..4e09869b 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/game/Game.java @@ -301,7 +301,6 @@ public Boolean getGameHasStarted() { */ public void setGameHasStarted(Boolean gameHasStarted) { this.gameHasStarted = gameHasStarted; - if (gameHasStarted) notifyObservers(); } /** diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java index c7a71f92..74d95b65 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/Animation.java @@ -1,6 +1,7 @@ package pp.mdga.server; import pp.mdga.message.client.AnimationEnd; +import pp.mdga.message.server.DiceNow; public class Animation extends ServerState { public Animation(ServerState parent, ServerGameLogic logic) { @@ -8,7 +9,8 @@ public Animation(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedAnimationEnd(AnimationEnd msg) { + public void receivedAnimationEnd(AnimationEnd msg, int from) { + logic.send(logic.getGame().getStartPlayer(), new DiceNow()); parent.gotoState(new Turn(parent, logic)); } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java index aaf401e4..0ff4b48e 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/DetermineStartPlayer.java @@ -2,41 +2,43 @@ import pp.mdga.game.Player; import pp.mdga.message.client.RequestDice; -import pp.mdga.message.server.DiceNow; -import pp.mdga.message.server.RankingRollAgain; +import pp.mdga.message.server.*; + +import java.util.ArrayList; +import java.util.List; public class DetermineStartPlayer extends ServerState { + private final List player = new ArrayList<>(); + public DetermineStartPlayer(ServerState parent, ServerGameLogic logic) { super(parent, logic); logic.getGame().addObserver(this); } @Override - public void receivedRequestDice(RequestDice msg) { - // todo: implement - } + public void receivedRequestDice(RequestDice msg, int from) { + logic.send(); - // todo: msg?, sent to everyone? - @Override - public void sentRankingResponse() { - // todo: implemtent + broadcastUpdate(new Dice()); } @Override public void update() { - if (logic.getGame().allRanked()) { - if (logic.getGame().getStartPlayer() == null) { - // todo: send it to everyone? or player with the same dice value? save the players with the same value? - logic.send(new Player(1), new RankingRollAgain()); + if (Boolean.TRUE.equals(logic.getGame().allRanked())) { + broadcastUpdate(new RankingResponce()); + if (logic.getGame().getOrder().isEmpty()) { + // todo: save the players with the same value? + broadcastUpdate(new RankingRollAgain()); + broadcastUpdate(new EndOfTurn()); } else { // todo: set start player Player startPlayer = new Player(1); logic.getGame().setStartPlayer(startPlayer); logic.send(startPlayer, new DiceNow()); + broadcastUpdate(new EndOfTurn()); parent.gotoState(new Animation(parent, logic)); logic.getGame().removeObserver(this); } } } - } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java index 7787a229..3c687bf7 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/FirstRoll.java @@ -1,9 +1,6 @@ package pp.mdga.server; -import pp.mdga.game.Player; import pp.mdga.message.client.RequestDice; -import pp.mdga.message.server.Dice; -import pp.mdga.message.server.DiceAgain; public class FirstRoll extends ServerState { public FirstRoll(ServerState parent, ServerGameLogic logic) { @@ -11,21 +8,21 @@ public FirstRoll(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedRequestDice(RequestDice msg) { + public void receivedRequestDice(RequestDice msg, int from) { // todo: implement player.hasMovablePieces() - if (player.hasMovablePieces()) { - // todo: goto ChoosePiece - } else { - // todo: implement roll - if (roll == 6) { - // todo: send to everyone? or one player? - logic.send(new Player(1), new Dice()); - // todo: goto ChoosePiece - } else { - // todo: send to everyone? or one player? - logic.send(new Player(1), new DiceAgain()); - parent.gotoState(new SecondRoll(parent, logic)); - } - } +// if (player.hasMovablePieces()) { +// // todo: goto ChoosePiece +// } else { +// // todo: implement roll +// if (roll == 6) { +// // todo: send to everyone? or one player? +// logic.send(new Player(1), new Dice()); +// // todo: goto ChoosePiece +// } else { +// // todo: send to everyone? or one player? +// logic.send(new Player(1), new DiceAgain()); +// parent.gotoState(new SecondRoll(parent, logic)); +// } +// } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java index f94b3bb2..dab977c8 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/GameState.java @@ -1,8 +1,9 @@ package pp.mdga.server; -import pp.mdga.game.Piece; import pp.mdga.message.client.*; +import pp.mdga.message.server.PauseGame; import pp.mdga.message.server.PossibleCard; +import pp.mdga.message.server.RankingResponce; public class GameState extends ServerState { private final GameStateMachine gameStateMachine = new GameStateMachine(this, logic); @@ -18,58 +19,50 @@ public void entry() { } @Override - public void receivedAnimationEnd(AnimationEnd msg) { - gameStateMachine.receivedAnimationEnd(msg); - } - - // todo piece? - @Override - public void receivedConfirmPiece(Piece piece) { - gameStateMachine.receivedConfirmPiece(piece); + public void exit() { + parent.gotoState(new Ceremony(parent, logic)); } @Override - public void receivedNoPowerCard(NoPowerCard msg) { - gameStateMachine.receivedNoPowerCard(msg); + public void receivedAnimationEnd(AnimationEnd msg, int from) { + gameStateMachine.receivedAnimationEnd(msg, from); } @Override - public void receivedSelectCard(SelectCard msg) { - gameStateMachine.receivedSelectCard(msg); + public void receivedNoPowerCard(NoPowerCard msg, int from) { + gameStateMachine.receivedNoPowerCard(msg, from); } @Override - public void receivedRequestDice(RequestDice msg) { - gameStateMachine.receivedRequestDice(msg); - } - - // todo msg? - @Override - public void receivedRollRankingDice() { - gameStateMachine.receivedRollRankingDice(); + public void receivedSelectCard(SelectCard msg, int from) { + gameStateMachine.receivedSelectCard(msg, from); } @Override - public void receivedSelectedPieces(SelectedPieces msg) { - gameStateMachine.receivedSelectedPieces(msg); + public void receivedRequestDice(RequestDice msg, int from) { + gameStateMachine.receivedRequestDice(msg, from); } @Override - public void sentPossibleCard(PossibleCard msg) { - gameStateMachine.sentPossibleCard(msg); + public void receivedSelectedPieces(SelectedPieces msg, int from) { + gameStateMachine.receivedSelectedPieces(msg, from); } - // todo msg?, sent to everyone? @Override - public void sentRankingResponse() { - gameStateMachine.sentRankingResponse(); + public void sentPossibleCard(PossibleCard msg, int from) { + gameStateMachine.sentPossibleCard(msg, from); + } + + @Override + public void sentRankingResponse(RankingResponce msg, int from) { + gameStateMachine.sentRankingResponse(msg, from); } @Override public void update() { - if (logic.getGame().playerHasDisconnected()) { - parent.gotoState(new Interrupt(parent, logic)); - // todo: change to interrupt, save the last state of gamestatemachine, change from interrupt to gamestate has to restore the last state + if (Boolean.TRUE.equals(logic.getGame().playerHasDisconnected())) { + broadcastUpdate(new PauseGame()); + parent.gotoState(new Interrupt(parent, logic, this)); logic.getGame().removeObserver(this); } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/GameStateMachine.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/GameStateMachine.java index b01981de..2e14808b 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/GameStateMachine.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/GameStateMachine.java @@ -1,10 +1,24 @@ package pp.mdga.server; -public class GameStateMachine extends ServerStateMachine{ +/** + * The GameStateMachine class represents the state machine for the game state. + */ +public class GameStateMachine extends ServerStateMachine { + /** + * Constructs a new GameStateMachine with the specified parent state and game logic. + * + * @param parent the parent state + * @param logic the server game logic + */ public GameStateMachine(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + /** + * Returns the initial state of the state machine, which is DetermineStartPlayer. + * + * @return the initial state + */ @Override public DetermineStartPlayer initialState() { return new DetermineStartPlayer(this, logic); diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java index ae67c4c8..ca59ca86 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/Interrupt.java @@ -1,15 +1,21 @@ package pp.mdga.server; +import pp.mdga.message.server.ResumeGame; + public class Interrupt extends ServerState { - public Interrupt(ServerState parent, ServerGameLogic logic) { + private final GameState lastState; + + public Interrupt(ServerState parent, ServerGameLogic logic, GameState lastState) { super(parent, logic); + this.lastState = lastState; logic.getGame().addObserver(this); } @Override public void update() { - if (!logic.getGame().gameIsInterrupted()) { - parent.gotoState(new GameState(parent, logic)); + if (Boolean.FALSE.equals(logic.getGame().gameIsInterrupted())) { + broadcastUpdate(new ResumeGame()); + parent.gotoState(lastState); logic.getGame().removeObserver(this); } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/Lobby.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/Lobby.java index b3bb2330..a612f0f2 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/Lobby.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/Lobby.java @@ -1,52 +1,74 @@ package pp.mdga.server; import pp.mdga.message.client.*; -import pp.mdga.message.server.ServerMessage; +import pp.mdga.message.server.ServerStartGame; import pp.mdga.message.server.UpdateReady; import pp.mdga.message.server.UpdateTSK; +/** + * Represents the lobby state of the server. + */ public class Lobby extends ServerState { + /** + * Constructs a new Lobby state. + * + * @param parent the parent state + * @param logic the server game logic + */ public Lobby(ServerState parent, ServerGameLogic logic) { super(parent, logic); - logic.getGame().addObserver(this); } + /** + * Handles the DeselectTSK message. + * + * @param msg the DeselectTSK message + */ @Override - public void receivedDeselectTSK(DeselectTSK msg) { + public void receivedDeselectTSK(DeselectTSK msg, int from) { broadcastUpdate(new UpdateTSK()); } + /** + * Handles the LobbyNotReady message. + * + * @param msg the LobbyNotReady message + */ @Override - public void receivedNotReady(LobbyNotReady msg) { + public void receivedNotReady(LobbyNotReady msg, int from) { broadcastUpdate(new UpdateReady()); } + /** + * Handles the LobbyReady message. + * + * @param msg the LobbyReady message + */ @Override - public void receivedReady(LobbyReady msg) { + public void receivedReady(LobbyReady msg, int from) { broadcastUpdate(new UpdateReady()); } + /** + * Handles the SelectTSK message. + * + * @param msg the SelectTSK message + */ @Override - public void receivedSelectTSK(SelectTSK msg) { + public void receivedSelectTSK(SelectTSK msg, int from) { broadcastUpdate(new UpdateTSK()); } - private void broadcastUpdate(ServerMessage updateMessage) { - for (var entry : logic.getGame().getPlayers().entrySet()) { - logic.send(entry.getValue(), updateMessage); - } - } - + /** + * Handles the ClientStartGame message. + * + * @param msg the ClientStartGame message + */ @Override - public void receivedStartGame(ClientStartGame msg) { - // todo: implement?? - } - - @Override - public void update() { - if (logic.getGame().getGameHasStarted()) { + public void receivedStartGame(ClientStartGame msg, int from) { + if (Boolean.TRUE.equals(logic.getGame().allRanked())) { + broadcastUpdate(new ServerStartGame()); parent.gotoState(new GameState(parent, logic)); - logic.getGame().removeObserver(this); } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java index 59a80020..6326bfb1 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoPiece.java @@ -11,45 +11,45 @@ public NoPiece(ServerState parent, ServerGameLogic logic) { @Override public void entry() { - if (hasTurbo() || turbo == 0) { - if (roll == 6 && - logic.getGame().getBoard().getPlayerData().getWaitingArea().hasPieces() && - logic.getGame().getBoard().getNodes().getStartNode(Color).isOccupied()) { - parent.gotoState(new WaitingPiece(parent, logic)); - } else { - parent.gotoState(new NoTurn(parent, logic)); - } - } else { - validateHasPieces(); - } +// if (hasTurbo() || turbo == 0) { +// if (roll == 6 && +// logic.getGame().getBoard().getPlayerData().getWaitingArea().hasPieces() && +// logic.getGame().getBoard().getNodes().getStartNode(Color).isOccupied()) { +// parent.gotoState(new WaitingPiece(parent, logic)); +// } else { +// parent.gotoState(new NoTurn(parent, logic)); +// } +// } else { +// validateHasPieces(); +// } } private void validateHasPieces() { - if (logic.getGame().getBoard().getPlayerData().getWaitingArea().hasPieces()) { - if (logic.getGame().getBoard().getNodes().getStartNode(Color).isOccupied()) { - if (roll == 6) { - logic.send(new Player(1), new WaitPiece()); - } else { - validateMove(); - } - } else { - if (logic.getGame().getBoard().getNodes().getStartNode(Color).getPiece().canMove()) { - logic.send(new Player(1), new WaitPiece()); - parent.gotoState(new StartPiece(parent, logic)); - } else { - validateMove(); - } - } - } else { - validateMove(); - } +// if (logic.getGame().getBoard().getPlayerData().getWaitingArea().hasPieces()) { +// if (logic.getGame().getBoard().getNodes().getStartNode(Color).isOccupied()) { +// if (roll == 6) { +// logic.send(new Player(1), new WaitPiece()); +// } else { +// validateMove(); +// } +// } else { +// if (logic.getGame().getBoard().getNodes().getStartNode(Color).getPiece().canMove()) { +// logic.send(new Player(1), new WaitPiece()); +// parent.gotoState(new StartPiece(parent, logic)); +// } else { +// validateMove(); +// } +// } +// } else { +// validateMove(); +// } } private void validateMove() { - if (player.canMove()) { - parent.gotoState(new NoTurn(parent, logic)); - } else { - logic.send(new Player(1), new SelectPiece()); - } +// if (player.canMove()) { +// parent.gotoState(new NoTurn(parent, logic)); +// } else { +// logic.send(new Player(1), new SelectPiece()); +// } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java index 810e4966..388f50bf 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/NoTurn.java @@ -8,7 +8,7 @@ public NoTurn(ServerState parent, ServerGameLogic logic) { } @Override - public void sentEndOfTurn(EndOfTurn msg) { + public void sentEndOfTurn(EndOfTurn msg, int from) { // todo: goto end of turn } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java index 5bc0c495..a66f0104 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/PowerCard.java @@ -14,7 +14,7 @@ public PowerCard(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedNoPowerCard(NoPowerCard msg) { + public void receivedNoPowerCard(NoPowerCard msg, int from) { // todo: send to everyone? or one player? // todo: right msg? logic.send(new Player(1), new DiceNow()); @@ -22,29 +22,29 @@ public void receivedNoPowerCard(NoPowerCard msg) { } @Override - public void receivedSelectCard(SelectCard msg) { + public void receivedSelectCard(SelectCard msg, int from) { // todo: send to everyone? or one player? logic.send(new Player(1), new PossibleCard()); } @Override - public void receivedSelectedPieces(SelectedPieces msg) { - if (verifySelectedPieces()) { - // todo: send to everyone? or one player? - // todo: msg PowerCardAnimation? - logic.send(new Player(1), new PowerCardAnimation()); - parent.gotoState(new PlayPowerCard(parent, logic)); - } + public void receivedSelectedPieces(SelectedPieces msg, int from) { +// if (verifySelectedPieces()) { +// // todo: send to everyone? or one player? +// // todo: msg PowerCardAnimation? +// logic.send(new Player(1), new PowerCardAnimation()); +// parent.gotoState(new PlayPowerCard(parent, logic)); +// } } @Override - public void sentPossibleCard(PossibleCard msg) { + public void sentPossibleCard(PossibleCard msg, int from) { // todo: implement } @Override public void update() { - if (!logic.getGame().getMovablePieces()) { + if (!super.getMoveablePieces(logic.getGame().getActiveColor()).isEmpty()) { // todo: send to everyone? or one player? // todo: right msg? logic.send(new Player(1), new DiceNow()); diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java index a225df40..d149236b 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/SecondRoll.java @@ -11,15 +11,15 @@ public SecondRoll(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedRequestDice(RequestDice msg) { - if (roll == 6) { - // todo: send to everyone? or one player? - logic.send(new Player(1), new Dice()); - // todo: goto ChoosePiece - } else { - // todo: send to everyone? or one player? - logic.send(new Player(1), new DiceAgain()); - parent.gotoState(new ThirdRoll(parent, logic)); - } + public void receivedRequestDice(RequestDice msg, int from) { +// if (roll == 6) { +// // todo: send to everyone? or one player? +// logic.send(new Player(1), new Dice()); +// // todo: goto ChoosePiece +// } else { +// // todo: send to everyone? or one player? +// logic.send(new Player(1), new DiceAgain()); +// parent.gotoState(new ThirdRoll(parent, logic)); +// } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java index a61bfc27..9cd71e6a 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/SelectPiece.java @@ -2,6 +2,7 @@ import pp.mdga.game.Piece; import pp.mdga.game.Player; +import pp.mdga.message.client.RequestMove; import pp.mdga.message.server.StartPiece; public class SelectPiece extends ServerState { @@ -10,12 +11,12 @@ public SelectPiece(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedConfirmPiece(Piece p) { - if (verifyPiece(p)) { - logic.send(new Player(1), new Animation()); - // todo: goto state - } else { - logic.send(new Player(1), new StartPiece()); - } + public void receivedRequestMove(RequestMove msg, int from) { +// if (verifyPiece(p)) { +// logic.send(new Player(1), new Animation()); +// // todo: goto state +// } else { +// logic.send(new Player(1), new StartPiece()); +// } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerAutomaton.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerAutomaton.java index 4d8bbd31..14061e81 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerAutomaton.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerAutomaton.java @@ -1,11 +1,25 @@ package pp.mdga.server; +/** + * The ServerAutomaton class represents the top-level state machine for the server. + * It initializes the state machine and sets the initial state to Lobby. + */ public class ServerAutomaton extends ServerStateMachine { + /** + * Constructs a new ServerAutomaton with the specified game logic. + * + * @param logic the server game logic + */ public ServerAutomaton(ServerGameLogic logic) { super(null, logic); entry(); } + /** + * Returns the initial state of the state machine, which is Lobby. + * + * @return the initial state + */ @Override public Lobby initialState() { return new Lobby(this, logic); diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerGameLogic.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerGameLogic.java index c278a929..2dbb77f5 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerGameLogic.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerGameLogic.java @@ -125,7 +125,6 @@ public Game getGame() { return game; } - // todo: remove public ServerState getState() { return state; } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java index 311c7809..90c08897 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerState.java @@ -8,64 +8,175 @@ import pp.mdga.message.client.*; import pp.mdga.message.server.EndOfTurn; import pp.mdga.message.server.PossibleCard; +import pp.mdga.message.server.RankingResponce; +import pp.mdga.message.server.ServerMessage; + import java.lang.System.Logger; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +/** + * Abstract class representing a state in the server's state machine. + * Implements the Observer pattern to observe changes in the game state. + */ public abstract class ServerState implements Observer { + /** + * Logger for logging messages within the application. + */ protected static final Logger LOGGER = System.getLogger(ServerState.class.getName()); + + /** + * The parent state of the current state. + */ protected ServerState parent; + + /** + * The game logic associated with the server state. + */ protected ServerGameLogic logic; - public ServerState(ServerState parent, ServerGameLogic logic) { + /** + * Constructs a new ServerState with the specified parent state and game logic. + * + * @param parent the parent state of the current state + * @param logic the game logic associated with the server state + */ + protected ServerState(ServerState parent, ServerGameLogic logic) { this.parent = parent; this.logic = logic; } + /** + * This method is called when the state is entered. + */ public void entry() { /* do nothing */ } - public void receivedAnimationEnd(AnimationEnd msg) { /* do nothing */ } + /** + * This method is called when the state is exited. + */ + public void exit() { /* do nothing */ } - // todo piece? - public void receivedConfirmPiece(Piece piece) { /* do nothing */ } + /** + * This method is called when an animation ends. + * + * @param msg the animation end message + */ + public void receivedAnimationEnd(AnimationEnd msg, int from) { /* do nothing */ } - public void receivedDeselectTSK(DeselectTSK msg) { /* do nothing */ } + /** + * This method is called when a TSK is deselected. + * + * @param msg the deselect TSK message + */ + public void receivedDeselectTSK(DeselectTSK msg, int from) { /* do nothing */ } - public void receivedNoPowerCard(NoPowerCard msg) { /* do nothing */ } + /** + * This method is called when a NoPowerCard message is received. + * + * @param msg the NoPowerCard message + */ + public void receivedNoPowerCard(NoPowerCard msg, int from) { /* do nothing */ } - public void receivedNotReady(LobbyNotReady msg) { /* do nothing */ } + /** + * This method is called when a LobbyNotReady message is received. + * + * @param msg the LobbyNotReady message + */ + public void receivedNotReady(LobbyNotReady msg, int from) { /* do nothing */ } - public void receivedReady(LobbyReady msg) { /* do nothing */ } + /** + * This method is called when a LobbyReady message is received. + * + * @param msg the LobbyReady message + */ + public void receivedReady(LobbyReady msg, int from) { /* do nothing */ } - public void receivedRequestDice(RequestDice msg) { /* do nothing */ } + /** + * This method is called when a RequestDice message is received. + * + * @param msg the RequestDice message + */ + public void receivedRequestDice(RequestDice msg, int from) { /* do nothing */ } - // todo msg? - public void receivedRollRankingDice() { /* do nothing */ } + /** + * This method is called when a RequestMove message is received. + * + * @param msg the RequestMove message + */ + public void receivedRequestMove(RequestMove msg, int from) { /* do nothing */ } - public void receivedSelectCard(SelectCard msg) { /* do nothing */ } + /** + * This method is called when a SelectCard message is received. + * + * @param msg the SelectCard message + */ + public void receivedSelectCard(SelectCard msg, int from) { /* do nothing */ } - public void receivedSelectTSK(SelectTSK msg) { /* do nothing */ } + /** + * This method is called when a SelectTSK message is received. + * + * @param msg the SelectTSK message + */ + public void receivedSelectTSK(SelectTSK msg, int from) { /* do nothing */ } - public void receivedSelectedPieces(SelectedPieces msg) { /* do nothing */ } + /** + * This method is called when a SelectedPieces message is received. + * + * @param msg the SelectedPieces message + */ + public void receivedSelectedPieces(SelectedPieces msg, int from) { /* do nothing */ } - public void receivedStartGame(ClientStartGame msg) { /* do nothing */ } + /** + * This method is called when a StartGame message is received. + * + * @param msg the StartGame message + */ + public void receivedStartGame(ClientStartGame msg, int from) { /* do nothing */ } - public void sentEndOfTurn(EndOfTurn msg) { /* do nothing */ } + /** + * This method is called when an EndOfTurn message is sent. + * + * @param msg the EndOfTurn message + */ + public void sentEndOfTurn(EndOfTurn msg, int from) { /* do nothing */ } - public void sentPossibleCard(PossibleCard msg) { /* do nothing */ } + /** + * This method is called when a PossibleCard message is sent. + * + * @param msg the PossibleCard message + */ + public void sentPossibleCard(PossibleCard msg, int from) { /* do nothing */ } - // todo msg?, sent to everyone? - public void sentRankingResponse() { /* do nothing */ } + /** + * This method is called when a RankingResponce message is sent. + * + * @param msg the RankingResponce message + */ + public void sentRankingResponse(RankingResponce msg, int from) { /* do nothing */ } + /** + * This method transitions to a new state. + * + * @param state the new state to transition to + * @throws IllegalStateException if called outside a state machine + */ public void gotoState(ServerState state) { throw new IllegalStateException("not in a statemachine"); } + /** + * Returns the parent state of the current state. + * + * @return the parent state + */ public ServerState getParent() { return parent; } + /** + * This method is called when the observed object is changed. + * It is part of the Observer pattern implementation. + */ public void update() { /* do nothing */ } /** @@ -73,7 +184,7 @@ public void update() { /* do nothing */ } * * @return the steps a piece can move */ - private int calculateSteps(){ + private int calculateSteps() { return logic.getGame().getDiceEyes() * logic.getGame().getDiceModifier(); } @@ -84,14 +195,15 @@ private int calculateSteps(){ * @return true if the piece can be moved, false otherwise */ protected boolean tryMove(Piece piece) { - if (piece.getState() == PieceState.HOME){ - return tryHomeMove(piece, calculateSteps()); + int steps = calculateSteps(); + if (piece.getState() == PieceState.HOME) { + return tryHomeMove(piece, steps); } else { - int homeMoves = getHomeMoves(piece, calculateSteps()); - if (homeMoves > 0){ + int homeMoves = getHomeMoves(piece, steps); + if (homeMoves > 0) { return tryHomeMove(piece, homeMoves); } else { - return tryInfieldMove(piece, calculateSteps()); + return tryInfieldMove(piece, steps); } } } @@ -108,12 +220,12 @@ protected int getHomeMoves(Piece piece, int steps) { Color col = piece.getColor(); int startIndex = logic.getGame().getBoard().getPlayerData().get(col).getStartNodeIndex(); int moveIndex = startIndex + steps; - if (moveIndex > logic.getGame().getBoard().getInfield().length){ + if (moveIndex > logic.getGame().getBoard().getInfield().length) { moveIndex %= logic.getGame().getBoard().getInfield().length; - if(moveIndex >= startIndex){ + if (moveIndex >= startIndex) { return moveIndex - startIndex + 1; } - } else if (figureIndex < startIndex && moveIndex >= startIndex){ + } else if (figureIndex < startIndex && moveIndex >= startIndex) { return moveIndex - startIndex + 1; } return 0; @@ -126,11 +238,11 @@ protected int getHomeMoves(Piece piece, int steps) { * @param steps the steps the piece would move * @return true if the piece can move in the infield, false otherwise */ - protected boolean tryInfieldMove(Piece piece, int steps){ + protected boolean tryInfieldMove(Piece piece, int steps) { int figureIndex = logic.getGame().getBoard().getInfieldIndexOfPiece(piece); int moveIndex = (figureIndex + steps) % logic.getGame().getBoard().getInfield().length; Piece occupant = logic.getGame().getBoard().getInfield()[moveIndex].getOccupant(); - if(occupant != null){ + if (occupant != null) { return occupant.getColor() != piece.getColor(); } return true; @@ -143,22 +255,23 @@ protected boolean tryInfieldMove(Piece piece, int steps){ * @param steps the steps the piece would move * @return true if the piece can move into the home area, false otherwise */ - protected boolean tryHomeMove(Piece piece, int steps){ + protected boolean tryHomeMove(Piece piece, int steps) { Color col = piece.getColor(); PlayerData playerData = logic.getGame().getBoard().getPlayerData().get(col); Node[] homeNodes = playerData.getHomeNodes(); int index; - if (playerData.homeIncludes(piece)){ + if (playerData.homeIncludes(piece)) { index = playerData.getIndexInHome(piece); } else { index = 0; } - if(index + steps >= homeNodes.length){ + + if (index + steps >= homeNodes.length) { return false; } else { - for(int i = index; i <= index + steps; i++){ - if(homeNodes[i].getOccupant() != null){ + for (int i = index; i <= index + steps; i++) { + if (homeNodes[i].getOccupant() != null) { return false; } } @@ -176,7 +289,7 @@ protected List getMoveablePieces(Color color) { ArrayList moveablePieces = new ArrayList<>(); ArrayList pieces = new ArrayList<>(); for (Piece piece : logic.getGame().getBoard().getPlayerData().get(color).getPieces()) { - if(piece.getState() == PieceState.ACTIVE || piece.getState() == PieceState.HOME){ + if (piece.getState() == PieceState.ACTIVE || piece.getState() == PieceState.HOME) { pieces.add(piece); } } @@ -188,6 +301,22 @@ protected List getMoveablePieces(Color color) { return moveablePieces; } + /** + * Broadcasts an update message to all players. + * + * @param updateMessage the update message to be sent + */ + protected void broadcastUpdate(ServerMessage updateMessage) { + for (var entry : logic.getGame().getPlayers().entrySet()) { + logic.send(entry.getValue(), updateMessage); + } + } + + /** + * Returns a string representation of the object. + * + * @return the simple name of the class + */ @Override public String toString() { return getClass().getSimpleName(); diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java index 329da544..a55c0ef0 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ServerStateMachine.java @@ -1,26 +1,50 @@ package pp.mdga.server; -import pp.mdga.game.Piece; import pp.mdga.message.client.*; import pp.mdga.message.server.EndOfTurn; import pp.mdga.message.server.PossibleCard; +import pp.mdga.message.server.RankingResponce; +/** + * Abstract class representing a state machine for the server. + * It manages the transitions between different states and delegates + * the handling of messages to the current state. + */ public abstract class ServerStateMachine extends ServerState { - + /** + * The current state of the state machine. + */ private ServerState state; - public ServerStateMachine(ServerState parent, ServerGameLogic logic) { + /** + * Constructs a new instance of ServerStateMachine. + * + * @param parent the parent state + * @param logic the server game logic + */ + protected ServerStateMachine(ServerState parent, ServerGameLogic logic) { super(parent, logic); } + /** + * Creates the initial state of a state machine. + */ public abstract ServerState initialState(); + /** + * Transitions to a new state. + * + * @param newState the new state to transition to + */ @Override public void gotoState(ServerState newState) { LOGGER.log(System.Logger.Level.DEBUG, "{0}: {1} --> {2}", this, state, newState); enter(newState); } + /** + * This method is called when the state is entered. + */ @Override public void entry() { final ServerState newState = initialState(); @@ -28,6 +52,12 @@ public void entry() { enter(newState); } + /** + * Enters a new state. + * + * @param newState the new state to enter + * @throws IllegalArgumentException if the new state does not belong to this state machine + */ private void enter(ServerState newState) { if (newState.parent != this) throw new IllegalArgumentException("Wrong state: " + newState + " belongs to " + newState.parent + " instead of " + this); @@ -35,86 +65,170 @@ private void enter(ServerState newState) { state.entry(); } + /** + * This method is called when the state is exited. + */ @Override - public void receivedAnimationEnd(AnimationEnd msg) { - state.receivedAnimationEnd(msg); + public void exit() { + state.exit(); } - // todo piece? + /** + * This method is called when an animation ends. + * + * @param msg the animation end message + */ @Override - public void receivedConfirmPiece(Piece piece) { - state.receivedConfirmPiece(piece); + public void receivedAnimationEnd(AnimationEnd msg, int from) { + state.receivedAnimationEnd(msg, from); } + /** + * This method is called when a TSK is deselected. + * + * @param msg the deselect TSK message + */ @Override - public void receivedDeselectTSK(DeselectTSK msg) { - state.receivedDeselectTSK(msg); + public void receivedDeselectTSK(DeselectTSK msg, int from) { + state.receivedDeselectTSK(msg, from); } + /** + * This method is called when a NoPowerCard message is received. + * + * @param msg the NoPowerCard message + */ @Override - public void receivedNoPowerCard(NoPowerCard msg) { - state.receivedNoPowerCard(msg); + public void receivedNoPowerCard(NoPowerCard msg, int from) { + state.receivedNoPowerCard(msg, from); } + /** + * This method is called when a LobbyNotReady message is received. + * + * @param msg the LobbyNotReady message + */ @Override - public void receivedNotReady(LobbyNotReady msg) { - state.receivedNotReady(msg); + public void receivedNotReady(LobbyNotReady msg, int from) { + state.receivedNotReady(msg, from); } + /** + * This method is called when a LobbyReady message is received. + * + * @param msg the LobbyReady message + */ @Override - public void receivedSelectCard(SelectCard msg) { - state.receivedSelectCard(msg); + public void receivedReady(LobbyReady msg, int from) { + state.receivedReady(msg, from); } + /** + * This method is called when a RequestDice message is received. + * + * @param msg the RequestDice message + */ @Override - public void receivedReady(LobbyReady msg) { - state.receivedReady(msg); + public void receivedRequestDice(RequestDice msg, int from) { + state.receivedRequestDice(msg, from); } + /** + * This method is called when a RequestMove message is received. + * + * @param msg the RequestMove message + */ @Override - public void receivedRequestDice(RequestDice msg) { - state.receivedRequestDice(msg); + public void receivedRequestMove(RequestMove msg, int from) { + state.receivedRequestMove(msg, from); } - // todo msg? + /** + * This method is called when a SelectCard message is received. + * + * @param msg the SelectCard message + */ @Override - public void receivedRollRankingDice() { - state.receivedRollRankingDice(); + public void receivedSelectCard(SelectCard msg, int from) { + state.receivedSelectCard(msg, from); } + /** + * This method is called when a SelectTSK message is received. + * + * @param msg the SelectTSK message + */ @Override - public void receivedSelectTSK(SelectTSK msg) { - state.receivedSelectTSK(msg); + public void receivedSelectTSK(SelectTSK msg, int from) { + state.receivedSelectTSK(msg, from); } + /** + * This method is called when a SelectedPieces message is received. + * + * @param msg the SelectedPieces message + */ @Override - public void receivedSelectedPieces(SelectedPieces msg) { - state.receivedSelectedPieces(msg); + public void receivedSelectedPieces(SelectedPieces msg, int from) { + state.receivedSelectedPieces(msg, from); } + /** + * This method is called when a StartGame message is received. + * + * @param msg the StartGame message + */ @Override - public void receivedStartGame(ClientStartGame msg) { - state.receivedStartGame(msg); + public void receivedStartGame(ClientStartGame msg, int from) { + state.receivedStartGame(msg, from); } + /** + * This method is called when an EndOfTurn message is sent. + * + * @param msg the EndOfTurn message + */ @Override - public void sentEndOfTurn(EndOfTurn msg) { - state.sentEndOfTurn(msg); + public void sentEndOfTurn(EndOfTurn msg, int from) { + state.sentEndOfTurn(msg, from); } + /** + * This method is called when a PossibleCard message is sent. + * + * @param msg the PossibleCard message + */ @Override - public void sentPossibleCard(PossibleCard msg) { - state.sentPossibleCard(msg); + public void sentPossibleCard(PossibleCard msg, int from) { + state.sentPossibleCard(msg, from); } - // todo msg?, sent to everyone? + /** + * This method is called when a RankingResponce message is sent. + * + * @param msg the RankingResponce message + */ @Override - public void sentRankingResponse() { - state.sentRankingResponse(); + public void sentRankingResponse(RankingResponce msg, int from) { + state.sentRankingResponse(msg, from); } + /** + * Returns a string representation of the object, including the current state. + * + * @return the string representation of the object + */ @Override public String toString() { return super.toString() + "(in " + state + ")"; } + + /** + * Returns the current state. + * + * @return the current state + */ + public ServerState getState() { + return state; + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java index 0e8d8461..f18641a2 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/StartPiece.java @@ -2,6 +2,7 @@ import pp.mdga.game.Piece; import pp.mdga.game.Player; +import pp.mdga.message.client.RequestMove; public class StartPiece extends ServerState { public StartPiece(ServerState parent, ServerGameLogic logic) { @@ -9,12 +10,12 @@ public StartPiece(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedConfirmPiece(Piece p) { - if (verifyPiece(p)) { - logic.send(new Player(1), new Animation()); - // todo: goto state - } else { - logic.send(new Player(1), new pp.mdga.message.server.StartPiece()); - } + public void receivedRequestMove(RequestMove msg, int from) { +// if (verifyPiece(p)) { +// logic.send(new Player(1), new Animation()); +// // todo: goto state +// } else { +// logic.send(new Player(1), new pp.mdga.message.server.StartPiece()); +// } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java index 496ef8a5..ebe9fd77 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/ThirdRoll.java @@ -11,15 +11,15 @@ public ThirdRoll(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedRequestDice(RequestDice msg) { - if (roll == 6) { - // todo: send to everyone? or one player? - logic.send(new Player(1), new Dice()); - // todo: goto ChoosePiece - } else { - // todo: send to everyone? or one player? - logic.send(new Player(1), new DiceAgain()); - // todo: goto End from Turn - } + public void receivedRequestDice(RequestDice msg, int from) { +// if (roll == 6) { +// // todo: send to everyone? or one player? +// logic.send(new Player(1), new Dice()); +// // todo: goto ChoosePiece +// } else { +// // todo: send to everyone? or one player? +// logic.send(new Player(1), new DiceAgain()); +// // todo: goto End from Turn +// } } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java index 21ec15c7..d2eacc7b 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/Turn.java @@ -1,5 +1,11 @@ package pp.mdga.server; +import pp.mdga.client.Spectator; +import pp.mdga.game.Player; +import pp.mdga.message.server.ActivePlayer; +import pp.mdga.message.server.Ceremony; +import pp.mdga.message.server.EndOfTurn; + public class Turn extends ServerState { private final TurnStateMachine turnStateMachine = new TurnStateMachine(this, logic); @@ -8,4 +14,23 @@ public Turn(ServerState parent, ServerGameLogic logic) { } // todo: when TurnStateMachine is in the end state, and then? + @Override + public void exit() { + Player player = logic.getGame().getStartPlayer(); + +// if (player.isFinished()) { +// logic.send(player, new Spectator()); +// } else { +// logic.send(player, new EndOfTurn()); +// } + + if (logic.getGame().getPlayers().size() == 1) { + broadcastUpdate(new Ceremony()); + this.getParent().getParent().exit(); + } else { + // todo: next player + broadcastUpdate(new ActivePlayer()); + parent.gotoState(new Animation(parent, logic)); + } + } } diff --git a/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java b/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java index b5f39d38..a284a451 100644 --- a/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java +++ b/Projekte/mdga/model/src/main/java/pp.mdga/server/WaitingPiece.java @@ -2,7 +2,8 @@ import pp.mdga.game.Piece; import pp.mdga.game.Player; -import pp.mdga.message.client.AnimationEnd; +import pp.mdga.message.client.RequestDice; +import pp.mdga.message.client.RequestMove; import pp.mdga.message.server.StartPiece; public class WaitingPiece extends ServerState { @@ -11,12 +12,12 @@ public WaitingPiece(ServerState parent, ServerGameLogic logic) { } @Override - public void receivedConfirmPiece(Piece p) { - if (verifyPiece(p)) { - logic.send(new Player(1), new Animation()); - // todo: goto state - } else { - logic.send(new Player(1), new StartPiece()); - } + public void receivedRequestMove(RequestMove msg, int from) { +// if (verifyPiece(p)) { +// logic.send(new Player(1), new Animation()); +// // todo: goto state +// } else { +// logic.send(new Player(1), new StartPiece()); +// } } } -- 2.43.0