From 1d69bcc8143b98ff95b4d25495c8a4120fb8f3a6 Mon Sep 17 00:00:00 2001 From: Johannes Schmelz Date: Sun, 17 Nov 2024 17:43:05 +0100 Subject: [PATCH] refactor and bug fixes --- .../java/pp/monopoly/game/server/Player.java | 138 ++++++++++++++++-- .../pp/monopoly/game/server/PlayerColor.java | 35 +++++ .../monopoly/game/server/PlayerHandler.java | 69 ++++++++- .../monopoly/game/server/ServerGameLogic.java | 66 +++------ .../monopoly/message/client/PlayerReady.java | 21 +++ 5 files changed, 262 insertions(+), 67 deletions(-) create mode 100644 Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerColor.java diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java index 56d6731..a8701cb 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/Player.java @@ -10,8 +10,6 @@ package pp.monopoly.game.server; import java.util.List; import java.util.Random; -import com.jme3.math.ColorRGBA; - import pp.monopoly.message.server.DiceResult; import pp.monopoly.model.FieldVisitor; import pp.monopoly.model.Figure; @@ -33,87 +31,175 @@ import pp.monopoly.model.fields.WacheField; public class Player implements FieldVisitor{ private final int id; private String name; - private ColorRGBA color; + private PlayerColor color; private int accountBalance = 0; private Figure figure; private List properties; private int getOutOfJailCard; private int fieldID; private DiceResult rollResult; - private PlayerHandler handler; + private final PlayerHandler handler; private PlayerState state = new LobbyState(); + /** + * Constructs a player with the speciefied params + * @param id the id of the player + * @param name the name of the player + * @param handler the PlayerHandler thispalyer is a part of + */ public Player(int id, String name, PlayerHandler handler) { this.name = name; this.id = id; this.handler = handler; } - public Player(int id) { + /** + * Constructs a player with the specified id + * @param id the id of the player + * @param handler the PlayerHandler this player is a part of + */ + public Player(int id, PlayerHandler handler) { this.id = id; + this.handler = handler; } - public void setName(String name) { + /** + * Set the name of the Player + * @param name the new name + */ + void setName(String name) { this.name = name; } - public void setColor(ColorRGBA color) { + /** + * Set the PlayerColor + * @param color the color to be set to + */ + void setColor(PlayerColor color) { this.color = color; } + /** + * Returns this players id + * @return th eid of this player + */ public int getId() { return id; } + /** + * Returns the current position of the player + * @return the current position of this player + */ public int getFieldID() { return fieldID; } + /** + * Moves by the specified amount of steps + * @param steps the number of steps to move + * @return the new position + */ public int move(int steps){ - return fieldID = (fieldID+steps)%40; + return movePos(fieldID+steps); } + /** + * Moves the player to the specified Position on the board + * @param position the position to move to + * @return the new position + */ public int movePos(int position){ - return fieldID = (fieldID+position)%40; + fieldID = fieldID+position; + if(fieldID >= 40) { + fieldID = fieldID%40; + earnMoney(2000); + } + return fieldID; } + /** + * Gets all the properties owned by this player + * @return List of all properties owned by this player + */ public List getProperties() { return properties; } - + /** + * Buy the speciefied property. + * Properties can olny be bought when they are not sold yet and you have enough money left to buy + * @param property to property to be bought + */ public void buyProperty(PropertyField property) { - properties.add(property); + if (property.getOwner() == null && accountBalance >= property.getPrice()) { + properties.add(property); + pay(property.getPrice()); + } } + /** + * Sell the property + * @param property the property to be sold + */ public void sellProperty(PropertyField property) { - properties.remove(property); + if (property.getOwner() == this) { + properties.remove(property); + property.setOwner(null); + } } + /** + * Gets this players current accountBalanece + * @return the amount of money currently owned by this player + */ public int getAccountBalance() { return accountBalance; } + /** + * Removed the speciefied amount of money to this players accountabalance + * @param amount the amount to be removed + */ public void pay(int amount) { accountBalance -= amount; } + /** + * Add the speciefied amount of money to this players accountabalance + * @param amount the amount to be added + */ public void earnMoney(int amount) { accountBalance += amount; } + /** + * Return the players name + * @return the name of this player + */ public String getName() { return name; } + /** + * Return the number of GEtOutOfJailCards owned by this player + * @return + */ public int getNumJailCard() { return getOutOfJailCard; } + /** + * Adds a GetOutOfJailCard + */ public void addJailCard() { getOutOfJailCard++; } + /** + * Removes a GetOutOfJailCard. + * Removes one single card per call, to a minimum of 0 cards + */ public void removeJailCard() { if (getOutOfJailCard ==0) { throw new IllegalStateException("Has no JailCard to remove"); @@ -121,10 +207,16 @@ public class Player implements FieldVisitor{ getOutOfJailCard--; } + /** + * Handles the logic of paying the jail bail + */ public void payBail() { state.payBail(); } + /** + * Handles the logic of using a GetOutOfJailCard + */ public void useJailCard() { state.useJailCard(); } @@ -160,7 +252,7 @@ public class Player implements FieldVisitor{ @Override public Void visit(GulagField field) { - //do nothing + state = new JailState(); return null; } @@ -179,13 +271,12 @@ public class Player implements FieldVisitor{ @Override public Void visit(WacheField field) { movePos(10); - state = new JailState(); return null; } @Override public Void visit(GoField field) { - accountBalance += 4000; + earnMoney(2000); GulagField res = (GulagField) handler.getLogic().getBoardManager().getFieldAtIndex(10); res.accept(this); return null; @@ -200,6 +291,11 @@ public class Player implements FieldVisitor{ return null; } + /** + * Return the number of Properties of the speciefied fild type + * @param field the type of field to search for + * @return the number of the fields owned with the specified type + */ public int getNumProp(PropertyField field) { int count = 0; for (PropertyField propertyField : properties) { @@ -241,8 +337,20 @@ public class Player implements FieldVisitor{ * A interface representing the PlayerStates */ private interface PlayerState { + /** + * Handles the logic for rolling Dice + * @return the {@link DiceResult} of this the DiceRoll + */ DiceResult rollDice(); + + /** + * Handles the logic for paying the Jail Bail + */ void payBail(); + + /** + * Handles the action of using a GetOutOfJail Card + */ void useJailCard(); } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerColor.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerColor.java new file mode 100644 index 0000000..4895b3f --- /dev/null +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerColor.java @@ -0,0 +1,35 @@ +package pp.monopoly.game.server; + +import com.jme3.math.ColorRGBA; + +/** + * Enum representing six distinct colors for players in the game. + */ +public enum PlayerColor { + GREEN_LIGHT(new ColorRGBA(0 / 255f, 204 / 255f, 0 / 255f, 1)), // Hex: 00cc00 + RED(new ColorRGBA(255 / 255f, 0 / 255f, 0 / 255f, 1)), // Hex: ff0000 + BLUE(new ColorRGBA(0 / 255f, 0 / 255f, 204 / 255f, 1)), // Hex: 0000cc + PINK(new ColorRGBA(255 / 255f, 77 / 255f, 166 / 255f, 1)), // Hex: ff4da6 + GREEN_DARK(new ColorRGBA(0 / 255f, 102 / 255f, 0 / 255f, 1)), // Hex: 006600 + YELLOW(new ColorRGBA(255 / 255f, 255 / 255f, 0 / 255f, 1)); // Hex: ffff00 + + private final ColorRGBA color; + + /** + * Constructs a PlayerColor with the specified ColorRGBA value. + * + * @param color the ColorRGBA value associated with the player color + */ + PlayerColor(ColorRGBA color) { + this.color = color; + } + + /** + * Gets the ColorRGBA value of the player color. + * + * @return the ColorRGBA value + */ + public ColorRGBA getColor() { + return color; + } +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java index 3c484cf..a5cc850 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java @@ -4,36 +4,66 @@ import java.util.LinkedList; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.NoSuchElementException; import java.util.Set; - +/** + * A class for helping with player actions and managing thier turns + */ public class PlayerHandler { private List players = new LinkedList<>(); private Set readyPlayers = new HashSet<>(); private ServerGameLogic logic; + /** + * Contructs a PlayerHandler + * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of + */ PlayerHandler(ServerGameLogic logic) { this.logic = logic; } + /** + * Contructs a PlayerHandler + * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of + * @param p1 a Player to be added + */ PlayerHandler(ServerGameLogic logic, Player p1) { this(logic); players.add(p1); } + /** + * Contructs a PlayerHandler + * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of + * @param players a Collection of Players to be added + */ PlayerHandler(ServerGameLogic logic, Collection players) { this(logic); players.addAll(players); } + /** + * Return the number of players + * @return number of players in the game + */ public int getPlayerCount() { return players.size(); } + /** + * Chechs if all players are ready to start the game + * @return {@code true} if all players are ready, otherwise {@code false} + */ public boolean allPlayersReady() { if (readyPlayers.size() == players.size()) return true; return false; } + /** + * Sets a players Ready status + * @param player the player to alter + * @param ready the new Status + */ void setPlayerReady(Player player, boolean ready) { if (!players.contains(player)) { throw new IllegalArgumentException("Player does not belong to this PlayerHandler"); @@ -46,6 +76,10 @@ public class PlayerHandler { } } + /** + * Adds a player to the Queue + * @param player the player to be added to the queue + */ void addPlayer(Player player) { if (players.contains(player)) { throw new IllegalArgumentException("Player already registered"); @@ -53,20 +87,49 @@ public class PlayerHandler { players.add(player); } + /** + * Removes the specified Player from the Queue + * @param player the player to be removed + */ void removePlayer(Player player) { players.remove(player); } - Player getPlayerAtIndex(int i) { - return players.get(i); + /** + * Gets Player based on their id in the Queue + * @param index the index of the queue + * @return the Player at the required index + */ + Player getPlayerAtIndex(int index) { + return players.get(index); } + /** + * Completes a player turn and return the next player + * @return the next players who is active + */ Player nextPlayer() { players.addLast(players.removeFirst()); return players.getFirst(); } + /** + * Returns the {@link ServerGameLogic} of this PlayerHandler + * @return the {@link ServerGameLogic} of this PlayerHandler + */ ServerGameLogic getLogic() { return logic; } + + /** + * Gets a player based on their id + * @param id the id to be searched for + * @return the player with the required id + */ + Player getPlayerById(int id) { + for (Player player : players) { + if (player.getId() == id) return player; + } + throw new NoSuchElementException("Player mit id "+id+" existiert nicht"); + } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java index 53a741d..cfcd7c3 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java @@ -6,14 +6,11 @@ import pp.monopoly.message.server.ServerMessage; import pp.monopoly.message.server.TradeReply; import pp.monopoly.message.server.TradeRequest; import pp.monopoly.message.server.ViewAssetsResponse; -import pp.monopoly.message.server.DiceResult; import pp.monopoly.model.fields.BoardManager; import pp.monopoly.model.fields.PropertyField; import java.lang.System.Logger; import java.lang.System.Logger.Level; -import java.util.List; -import java.util.Random; /** * Controls the server-side game logic for Monopoly. @@ -59,16 +56,6 @@ public class ServerGameLogic implements ClientInterpreter { state = newState; } - /** - * Retrieves the player associated with the specified connection ID. - * - * @param id the connection ID of the client - * @return the Player associated with the given ID, or null if not found - */ - public Player getPlayerById(int id) { - return playerHandler.getPlayerAtIndex(id); - } - /** * Sends a message to a specified player. * @@ -85,15 +72,15 @@ public class ServerGameLogic implements ClientInterpreter { } /** - * Adds a new player to the game if the game is in the CREATEGAME state and the maximum + * Adds a new player to the game if the game is in the LOBBY state and the maximum * player limit has not been reached. * * @param player the Player to add to the game * @return the added Player, or null if the player could not be added */ public Player addPlayer(Player player) { - if (state != ServerState.CREATEGAME) { - LOGGER.log(Level.WARNING, "Cannot add player; game is not in CREATEGAME state."); + if (state != ServerState.LOBBY) { + LOGGER.log(Level.WARNING, "Cannot add player; game is not in LOBBY state."); return null; } @@ -103,32 +90,11 @@ public class ServerGameLogic implements ClientInterpreter { } playerHandler.addPlayer(player); - LOGGER.log(Level.DEBUG, "Player added: {0}", player.getName()); - - if (playerHandler.getPlayerCount() == MAX_PLAYERS) { - LOGGER.log(Level.INFO, "Maximum number of players reached. Starting game."); - setState(ServerState.INGAME); - } + LOGGER.log(Level.DEBUG, "Player added: {0}", player.getId()); return player; } - /** - * Marks a player as ready and transitions the game state to PLAY if all players are ready. - * - * @param player the Player to mark as ready - * @param status true if the player is ready, false otherwise - */ - void playerReady(Player player, boolean status) { - playerHandler.setPlayerReady(player, status); - LOGGER.log(Level.DEBUG, "Player {0} is now ready: {1}", player.getName(), status); - - if (playerHandler.allPlayersReady() && playerHandler.getPlayerCount() > 1) { - setState(ServerState.INGAME); - LOGGER.log(Level.INFO, "All players are ready. Transitioning game state to PLAY."); - } - } - /** * Handles a BuyPropertyRequest from a player, allowing the player to purchase a property * if it is unowned and they have sufficient funds. @@ -138,7 +104,7 @@ public class ServerGameLogic implements ClientInterpreter { */ @Override public void received(BuyPropertyRequest msg, int from) { - Player player = getPlayerById(from); + Player player = playerHandler.getPlayerById(from); if (player != null && state == ServerState.INGAME) { PropertyField property = (PropertyField) boardManager.getFieldAtIndex(player.move(0)); // Assuming player position for property @@ -161,7 +127,7 @@ public class ServerGameLogic implements ClientInterpreter { */ @Override public void received(EndTurn msg, int from) { - Player player = getPlayerById(from); + Player player = playerHandler.getPlayerById(from); if (player != null && state == ServerState.INGAME) { LOGGER.log(Level.DEBUG, "Ending turn for player {0}", player.getName()); playerHandler.nextPlayer(); @@ -176,9 +142,11 @@ public class ServerGameLogic implements ClientInterpreter { */ @Override public void received(PlayerReady msg, int from) { - Player player = getPlayerById(from); + Player player = playerHandler.getPlayerById(from); if (player != null) { - playerReady(player, true); + player.setName(msg.getName()); + player.setColor(msg.getColor()); + player.setName(msg.getName()); LOGGER.log(Level.DEBUG, "Player {0} is ready", player.getName()); } } @@ -191,7 +159,7 @@ public class ServerGameLogic implements ClientInterpreter { */ @Override public void received(RollDice msg, int from) { - Player player = getPlayerById(from); + Player player = playerHandler.getPlayerById(from); if (player != null && state == ServerState.INGAME) { send(player, player.rollDice()); } @@ -205,12 +173,12 @@ public class ServerGameLogic implements ClientInterpreter { */ @Override public void received(TradeOffer msg, int from) { - Player sender = getPlayerById(from); - Player receiver = getPlayerById(msg.getReceiverId()); + Player sender = playerHandler.getPlayerById(from); + Player receiver = playerHandler.getPlayerById(msg.getReceiverId()); if (sender != null && receiver != null) { LOGGER.log(Level.INFO, "Player {0} offers a trade to player {1}", sender.getName(), receiver.getName()); - send(getPlayerById(msg.getReceiverId()), new TradeRequest(msg.getReceiverId(), msg.getTradeHandler())); + send(playerHandler.getPlayerById(msg.getReceiverId()), new TradeRequest(msg.getReceiverId(), msg.getTradeHandler())); } } @@ -222,8 +190,8 @@ public class ServerGameLogic implements ClientInterpreter { */ @Override public void received(TradeResponse msg, int from) { - Player responder = getPlayerById(from); - Player initiator = getPlayerById(msg.getInitiatorId()); + Player responder = playerHandler.getPlayerById(from); + Player initiator = playerHandler.getPlayerById(msg.getInitiatorId()); if (responder != null && initiator != null) { LOGGER.log(Level.INFO, "Player {0} responded to trade with player {1}", responder.getName(), initiator.getName()); @@ -239,7 +207,7 @@ public class ServerGameLogic implements ClientInterpreter { */ @Override public void received(ViewAssetsRequest msg, int from) { - Player player = getPlayerById(from); + Player player = playerHandler.getPlayerById(from); if (player != null) { LOGGER.log(Level.DEBUG, "Processing ViewAssetsRequest for player {0}", player.getName()); diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/PlayerReady.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/PlayerReady.java index 1d4a417..6324b9e 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/PlayerReady.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/PlayerReady.java @@ -1,10 +1,14 @@ package pp.monopoly.message.client; +import pp.monopoly.game.server.PlayerColor; + /** * Represents a message indicating the player is ready to play. */ public class PlayerReady extends ClientMessage{ private boolean isReady; + private String name; + private PlayerColor color; /** * Constructs a PlayerReady message. @@ -15,6 +19,22 @@ public class PlayerReady extends ClientMessage{ this.isReady = isReady; } + /** + * Getter for the Name + * @return the Name + */ + public String getName() { + return name; + } + + /** + * Getter for the Playercolor + * @return the Playercolor + */ + public PlayerColor getColor() { + return color; + } + /** * Checks if the player is ready. * @@ -24,6 +44,7 @@ public class PlayerReady extends ClientMessage{ return isReady; } + @Override public void accept(ClientInterpreter interpreter, int from) { interpreter.received(this, from);