Merge branch 'development' into 'dev/test'
Merge Test to Development See merge request progproj/gruppen-ht24/Gruppe-01!8
This commit is contained in:
		@@ -22,8 +22,12 @@ public class Game {
 | 
			
		||||
    private Map<Color, Integer> playerConnectionID;
 | 
			
		||||
 | 
			
		||||
    private ArrayList<Observer> 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;
 | 
			
		||||
@@ -297,7 +301,6 @@ public Boolean getGameHasStarted() {
 | 
			
		||||
     */
 | 
			
		||||
    public void setGameHasStarted(Boolean gameHasStarted) {
 | 
			
		||||
        this.gameHasStarted = gameHasStarted;
 | 
			
		||||
        if (gameHasStarted) notifyObservers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -309,6 +312,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 +357,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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
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) {
 | 
			
		||||
        super(parent, logic);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void receivedAnimationEnd(AnimationEnd msg, int from) {
 | 
			
		||||
        logic.send(logic.getGame().getStartPlayer(), new DiceNow());
 | 
			
		||||
        parent.gotoState(new Turn(parent, logic));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,7 +6,7 @@ public ChoosePieceStateMachine(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ServerState initialState() {
 | 
			
		||||
        return null;
 | 
			
		||||
    public NoPiece initialState() {
 | 
			
		||||
        return new NoPiece(this, logic);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,44 @@
 | 
			
		||||
package pp.mdga.server;
 | 
			
		||||
 | 
			
		||||
import pp.mdga.game.Player;
 | 
			
		||||
import pp.mdga.message.client.RequestDice;
 | 
			
		||||
import pp.mdga.message.server.*;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class DetermineStartPlayer extends ServerState {
 | 
			
		||||
    private final List<Player> player = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    public DetermineStartPlayer(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
        super(parent, logic);
 | 
			
		||||
        logic.getGame().addObserver(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void receivedRequestDice(RequestDice msg, int from) {
 | 
			
		||||
        logic.send();
 | 
			
		||||
 | 
			
		||||
        broadcastUpdate(new Dice());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void update() {
 | 
			
		||||
        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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,28 @@
 | 
			
		||||
package pp.mdga.server;
 | 
			
		||||
 | 
			
		||||
import pp.mdga.message.client.RequestDice;
 | 
			
		||||
 | 
			
		||||
public class FirstRoll extends ServerState {
 | 
			
		||||
    public FirstRoll(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
        super(parent, logic);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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));
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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,57 +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 receivedPowerCardChoice(SelectCard msg) {
 | 
			
		||||
        gameStateMachine.receivedPowerCardChoice(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 Ceremony(parent, logic));
 | 
			
		||||
        if (Boolean.TRUE.equals(logic.getGame().playerHasDisconnected())) {
 | 
			
		||||
            broadcastUpdate(new PauseGame());
 | 
			
		||||
            parent.gotoState(new Interrupt(parent, logic, this));
 | 
			
		||||
            logic.getGame().removeObserver(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,22 @@
 | 
			
		||||
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 (Boolean.FALSE.equals(logic.getGame().gameIsInterrupted())) {
 | 
			
		||||
            broadcastUpdate(new ResumeGame());
 | 
			
		||||
            parent.gotoState(lastState);
 | 
			
		||||
            logic.getGame().removeObserver(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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, int from) {
 | 
			
		||||
        // todo: goto end of turn
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
package pp.mdga.server;
 | 
			
		||||
 | 
			
		||||
public class PlayPowerCard extends ServerState {
 | 
			
		||||
    public PlayPowerCard(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
        super(parent, logic);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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, int from) {
 | 
			
		||||
        // 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, int from) {
 | 
			
		||||
        // todo: send to everyone? or one player?
 | 
			
		||||
        logic.send(new Player(1), new PossibleCard());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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, int from) {
 | 
			
		||||
        // todo: implement
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void update() {
 | 
			
		||||
        if (!super.getMoveablePieces(logic.getGame().getActiveColor()).isEmpty()) {
 | 
			
		||||
            // todo: send to everyone? or one player?
 | 
			
		||||
            // todo: right msg?
 | 
			
		||||
            logic.send(new Player(1), new DiceNow());
 | 
			
		||||
            parent.gotoState(new RollDice(parent, logic));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ public RollDiceMachine(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ServerState initialState() {
 | 
			
		||||
        return null;
 | 
			
		||||
    public FirstRoll initialState() {
 | 
			
		||||
        return new FirstRoll(this, logic);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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, 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));
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,22 @@
 | 
			
		||||
package pp.mdga.server;
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
    public SelectPiece(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
        super(parent, logic);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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());
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,6 @@ public Game getGame() {
 | 
			
		||||
        return game;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // todo: remove
 | 
			
		||||
    public ServerState getState() {
 | 
			
		||||
        return state;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,63 +6,177 @@
 | 
			
		||||
import pp.mdga.game.PieceState;
 | 
			
		||||
import pp.mdga.game.PlayerData;
 | 
			
		||||
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 receivedPowerCardChoice(SelectCard 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 receivedReady(LobbyReady 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 */ }
 | 
			
		||||
 | 
			
		||||
    public void receivedRequestDice(RequestDice msg) { /* 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 */ }
 | 
			
		||||
 | 
			
		||||
    // todo msg?
 | 
			
		||||
    public void receivedRollRankingDice() { /* 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 sentPossibleCard(PossibleCard 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 */ }
 | 
			
		||||
 | 
			
		||||
    // todo msg?, sent to everyone?
 | 
			
		||||
    public void sentRankingResponse() { /* 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 */ }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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 */ }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -70,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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -81,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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -105,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;
 | 
			
		||||
@@ -123,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;
 | 
			
		||||
@@ -140,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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -173,7 +289,7 @@ protected List<Piece> getMoveablePieces(Color color) {
 | 
			
		||||
        ArrayList<Piece> moveablePieces = new ArrayList<>();
 | 
			
		||||
        ArrayList<Piece> 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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -185,6 +301,22 @@ protected List<Piece> 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();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +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();
 | 
			
		||||
@@ -27,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);
 | 
			
		||||
@@ -34,81 +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 receivedPowerCardChoice(SelectCard msg) {
 | 
			
		||||
        state.receivedPowerCardChoice(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 sentPossibleCard(PossibleCard msg) {
 | 
			
		||||
        state.sentPossibleCard(msg);
 | 
			
		||||
    public void sentEndOfTurn(EndOfTurn msg, int from) {
 | 
			
		||||
        state.sentEndOfTurn(msg, from);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // todo msg?, sent to everyone?
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is called when a PossibleCard message is sent.
 | 
			
		||||
     *
 | 
			
		||||
     * @param msg the PossibleCard message
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void sentRankingResponse() {
 | 
			
		||||
        state.sentRankingResponse();
 | 
			
		||||
    public void sentPossibleCard(PossibleCard msg, int from) {
 | 
			
		||||
        state.sentPossibleCard(msg, from);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method is called when a RankingResponce message is sent.
 | 
			
		||||
     *
 | 
			
		||||
     * @param msg the RankingResponce message
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,21 @@
 | 
			
		||||
package pp.mdga.server;
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
        super(parent, logic);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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());
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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, 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
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,36 @@
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
    public Turn(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
        super(parent, 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));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ public TurnStateMachine(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ServerState initialState() {
 | 
			
		||||
        return null;
 | 
			
		||||
    public PowerCard initialState() {
 | 
			
		||||
        return new PowerCard(this, logic);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,23 @@
 | 
			
		||||
package pp.mdga.server;
 | 
			
		||||
 | 
			
		||||
import pp.mdga.game.Piece;
 | 
			
		||||
import pp.mdga.game.Player;
 | 
			
		||||
import pp.mdga.message.client.RequestDice;
 | 
			
		||||
import pp.mdga.message.client.RequestMove;
 | 
			
		||||
import pp.mdga.message.server.StartPiece;
 | 
			
		||||
 | 
			
		||||
public class WaitingPiece extends ServerState {
 | 
			
		||||
    public WaitingPiece(ServerState parent, ServerGameLogic logic) {
 | 
			
		||||
        super(parent, logic);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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());
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user