diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java index d805f6c..67e291c 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java @@ -17,6 +17,7 @@ import pp.monopoly.message.server.JailEvent; import pp.monopoly.message.server.PlayerStatusUpdate; import pp.monopoly.message.server.ServerInterpreter; import pp.monopoly.message.server.TimeOutWarning; +import pp.monopoly.message.server.TradeReply; import pp.monopoly.message.server.TradeRequest; import pp.monopoly.message.server.UpdatePlayerAssets; import pp.monopoly.message.server.ViewAssetsResponse; @@ -230,12 +231,6 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker { throw new UnsupportedOperationException("Unimplemented method 'received'"); } - @Override - public void received(TradeRequest msg) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); - } - @Override public void received(UpdatePlayerAssets msg) { // TODO Auto-generated method stub @@ -247,4 +242,16 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker { // TODO Auto-generated method stub throw new UnsupportedOperationException("Unimplemented method 'received'"); } + + @Override + public void received(TradeReply msg) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'received'"); + } + + @Override + public void received(TradeRequest msg) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'received'"); + } } 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 1802f4b..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 @@ -8,11 +8,12 @@ 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; +import pp.monopoly.model.card.DeckHelper; import pp.monopoly.model.fields.BuildingProperty; import pp.monopoly.model.fields.EventField; import pp.monopoly.model.fields.FineField; @@ -28,48 +29,177 @@ import pp.monopoly.model.fields.WacheField; * Class representing a player */ 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 final PlayerHandler handler; + private PlayerState state = new LobbyState(); - Player(String name, ColorRGBA color) { + /** + * 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; + } + + /** + * 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; + } + + /** + * Set the name of the Player + * @param name the new name + */ + void setName(String name) { + this.name = name; + } + + /** + * Set the PlayerColor + * @param color the color to be set to + */ + void setColor(PlayerColor color) { this.color = color; - figure = new Figure(); } + /** + * 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 += steps; + 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){ + 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); + } } - public void payRent(int amount) { + /** + * 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"); @@ -77,57 +207,281 @@ 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(); + } + @Override public Void visit(BuildingProperty field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + int rent = field.calcRent(); + + field.getOwner().earnMoney(rent); + pay(rent); + return null; } @Override public Void visit(FoodField field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + int factor = 4; + if (field.getOwner().getNumProp(field) == 2) { + factor = 10; + } + field.getOwner().earnMoney(rollResult.calcTotal()*factor); + pay(rollResult.calcTotal()*factor); + return null; } @Override public Void visit(GateField field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + int rent = field.calcRent() * field.getOwner().getNumProp(field); + + field.getOwner().earnMoney(rent); + pay(rent); + return null; } @Override public Void visit(GulagField field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + state = new JailState(); + return null; } @Override public Void visit(TestStreckeField field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + earnMoney(field.collectMoney()); + return null; } @Override public Void visit(EventField field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + DeckHelper.drawCard(); + return null; } @Override public Void visit(WacheField field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + movePos(10); + 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; } @Override public Void visit(FineField field) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + int amount = field.getFine(); + pay(amount); + TestStreckeField res =(TestStreckeField) handler.getLogic().getBoardManager().getFieldAtIndex(20); + res.addMoney(amount); + 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) { + if (propertyField.getClass() == field.getClass()) { + count++; + } + } + + return count; + } + + /** + * Inner class for dice functionality in the game. + * Rolls random dice values. + */ + private class Dice { + private static Random random = new Random(); + + /** + * Rolls a single die and returns a random value from 1 to 6. + * + * @return the result of a dice roll (1 to 6) + */ + private static int rollDice() { + return random.nextInt(6) + 1; + } + } + + /** + * Rolls two dice and returns a list with the results. + * + * @return a List of two integers representing the dice roll results + */ + DiceResult rollDice() { + return state.rollDice(); + } + + /** + * 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(); + } + + + /** + * Class to represent the Active PlayerState + * This class is set when it is the Players turn to do actions + */ + private class ActiveState implements PlayerState { + + @Override + public DiceResult rollDice() { + List roll = List.of(Dice.rollDice(), Dice.rollDice()); + rollResult = new DiceResult(roll); + return rollResult; + } + + @Override + public void payBail() { + // do nothing + } + + @Override + public void useJailCard() { + // do nothings + } + } + + + /** + * A class to represent the Lobby PlayerState + * Set when in Lobby + */ + private class LobbyState implements PlayerState{ + + @Override + public DiceResult rollDice() { + //do nothing + return null; + } + + @Override + public void payBail() { + //do nothing + } + + @Override + public void useJailCard() { + // do nothing + } + + } + + + /** + * A class to represent the Jailed PlayerState + * Set when in Gulag + */ + private class JailState implements PlayerState { + + private int DoubletsCounter = 3; + + @Override + public DiceResult rollDice() { + List roll = List.of(Dice.rollDice(), Dice.rollDice()); + rollResult = new DiceResult(roll); + if (rollResult.isDoublets()) { + state = new ActiveState(); + } else if (DoubletsCounter == 0) { + + } else { + DoubletsCounter--; + } + return rollResult; + } + + @Override + public void payBail() { + pay(500); + state = new ActiveState(); + } + + @Override + public void useJailCard() { + getOutOfJailCard--; + state = new ActiveState(); + } + + } + + private class BankruptState implements PlayerState { + + @Override + public DiceResult rollDice() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'rollDice'"); + } + + @Override + public void payBail() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'payBail'"); + } + + @Override + public void useJailCard() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'useJailCard'"); + } + + } + + private class WaitForTurnState implements PlayerState { + + @Override + public DiceResult rollDice() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'rollDice'"); + } + + @Override + public void payBail() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'payBail'"); + } + + @Override + public void useJailCard() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method '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 new file mode 100644 index 0000000..a5cc850 --- /dev/null +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java @@ -0,0 +1,135 @@ +package pp.monopoly.game.server; + +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"); + } else { + if (ready) { + readyPlayers.add(player); + } else { + readyPlayers.remove(player); + } + } + } + + /** + * 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"); + } + players.add(player); + } + + /** + * Removes the specified Player from the Queue + * @param player the player to be removed + */ + void removePlayer(Player player) { + players.remove(player); + } + + /** + * 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 31b241b..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 @@ -1,31 +1,16 @@ -//////////////////////////////////////// -// Programming project code -// UniBw M, 2022, 2023, 2024 -// www.unibw.de/inf2 -// (c) Mark Minas (mark.minas@unibw.de) -//////////////////////////////////////// - package pp.monopoly.game.server; import pp.monopoly.MonopolyConfig; -import pp.monopoly.message.client.BuyPropertyRequest; -import pp.monopoly.message.client.ClientInterpreter; -import pp.monopoly.message.client.EndTurn; -import pp.monopoly.message.client.PlayerReady; -import pp.monopoly.message.client.RollDice; -import pp.monopoly.message.client.TradeOffer; -import pp.monopoly.message.client.TradeResponse; -import pp.monopoly.message.client.ViewAssetsRequest; +import pp.monopoly.message.client.*; import pp.monopoly.message.server.ServerMessage; - -import pp.monopoly.model.IntPoint; +import pp.monopoly.message.server.TradeReply; +import pp.monopoly.message.server.TradeRequest; +import pp.monopoly.message.server.ViewAssetsResponse; +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.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; /** * Controls the server-side game logic for Monopoly. @@ -35,14 +20,14 @@ public class ServerGameLogic implements ClientInterpreter { private static final Logger LOGGER = System.getLogger(ServerGameLogic.class.getName()); private final MonopolyConfig config; - private final List players = new ArrayList<>(2); - private final Set readyPlayers = new HashSet<>(); + private final PlayerHandler playerHandler = new PlayerHandler(this); private final ServerSender serverSender; - private Player activePlayer; - private ServerState state = ServerState.WAIT; + private ServerState state = ServerState.CREATEGAME; + private static final int MAX_PLAYERS = 6; + private BoardManager boardManager = new BoardManager(); /** - * Constructs a ServerGameLogic with the specified sender and configuration. + * Constructs a ServerGameLogic instance with the specified sender and configuration. * * @param serverSender the sender used to send messages to clients * @param config the game configuration @@ -53,122 +38,189 @@ public class ServerGameLogic implements ClientInterpreter { } /** - * Returns the state of the game. + * Retrieves the current state of the game. + * + * @return the current ServerState */ ServerState getState() { return state; } /** - * Sets the new state of the game and logs the state transition. + * Sets a new state for the game and logs the state transition. * - * @param newState the new state to set + * @param newState the new ServerState to transition to */ void setState(ServerState newState) { - LOGGER.log(Level.DEBUG, "state transition {0} --> {1}", state, newState); //NON-NLS + LOGGER.log(Level.DEBUG, "State transition {0} --> {1}", state, newState); state = newState; } /** - * Returns the opponent of the specified player. + * Sends a message to a specified player. * - * @param p the player - * @return the opponent of the player - */ - Player getOpponent(Player p) { - if (players.size() != 2) - throw new RuntimeException("trying to find opponent without having 2 players"); - final int index = players.indexOf(p); - if (index < 0) - throw new RuntimeException("Nonexistent player " + p); - return players.get(1 - index); - } - - /** - * Returns the player representing the client with the specified connection ID. - * - * @param id the ID of the client - * @return the player associated with the client ID, or null if not found - */ - public Player getPlayerById(int id) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method"); - } - - /** - * Sends a message to the specified player. - * - * @param player the player to send the message to - * @param msg the message to send + * @param player the Player to whom the message is sent + * @param msg the ServerMessage to send */ void send(Player player, ServerMessage msg) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method"); + if (player != null && msg != null) { + serverSender.send(player.getId(), msg); + LOGGER.log(Level.DEBUG, "Message sent to player {0}: {1}", player.getName(), msg.getClass().getSimpleName()); + } else { + LOGGER.log(Level.WARNING, "Attempted to send a null message or to a null player"); + } } /** - * Adds a new player to the game if there are less than two players. - * Transitions the state to SET_UP if two players are present. + * 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 id the connection ID of the new player - * @return the player added to the game, or null if the game is not in the right state + * @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(int id) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method"); + public Player addPlayer(Player player) { + if (state != ServerState.LOBBY) { + LOGGER.log(Level.WARNING, "Cannot add player; game is not in LOBBY state."); + return null; + } + + if (playerHandler.getPlayerCount() >= MAX_PLAYERS) { + LOGGER.log(Level.WARNING, "Cannot add player; maximum player limit reached."); + return null; + } + + playerHandler.addPlayer(player); + LOGGER.log(Level.DEBUG, "Player added: {0}", player.getId()); + + return player; } /** - * Marks the player as ready - * Transitions the state to PLAY if both players are ready. + * Handles a BuyPropertyRequest from a player, allowing the player to purchase a property + * if it is unowned and they have sufficient funds. * - * @param player the player who is ready + * @param msg the BuyPropertyRequest received from the player + * @param from the connection ID of the player who sent the request */ - void playerReady(Player player) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method"); - } - @Override public void received(BuyPropertyRequest msg, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); + Player player = playerHandler.getPlayerById(from); + if (player != null && state == ServerState.INGAME) { + PropertyField property = (PropertyField) boardManager.getFieldAtIndex(player.move(0)); // Assuming player position for property + + if (property.getOwner() == null && player.getAccountBalance() >= property.getPrice()) { + player.buyProperty(property); + property.setOwner(player); + player.earnMoney(-property.getPrice()); + LOGGER.log(Level.INFO, "Player {0} bought property {1}", player.getName(), property.getName()); + } else { + LOGGER.log(Level.WARNING, "Player {0} cannot buy property {1}", player.getName(), property.getName()); + } + } } + /** + * Handles an EndTurn request, ending the player's turn and advancing to the next player. + * + * @param msg the EndTurn message received from the player + * @param from the connection ID of the player who sent the request + */ @Override public void received(EndTurn msg, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); + Player player = playerHandler.getPlayerById(from); + if (player != null && state == ServerState.INGAME) { + LOGGER.log(Level.DEBUG, "Ending turn for player {0}", player.getName()); + playerHandler.nextPlayer(); + } } + /** + * Handles a PlayerReady message, marking the player as ready. + * + * @param msg the PlayerReady message received from the player + * @param from the connection ID of the player who sent the request + */ @Override public void received(PlayerReady msg, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); + Player player = playerHandler.getPlayerById(from); + if (player != null) { + player.setName(msg.getName()); + player.setColor(msg.getColor()); + player.setName(msg.getName()); + LOGGER.log(Level.DEBUG, "Player {0} is ready", player.getName()); + } } + /** + * Handles a RollDice message, rolling dice for the player and moving them on the board. + * + * @param msg the RollDice message received from the player + * @param from the connection ID of the player who sent the request + */ @Override public void received(RollDice msg, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); + Player player = playerHandler.getPlayerById(from); + if (player != null && state == ServerState.INGAME) { + send(player, player.rollDice()); + } } + /** + * Handles a TradeOffer message by forwarding the trade offer to the receiving player. + * + * @param msg the TradeOffer message received from the initiating player + * @param from the connection ID of the player who sent the offer + */ @Override public void received(TradeOffer msg, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); + 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(playerHandler.getPlayerById(msg.getReceiverId()), new TradeRequest(msg.getReceiverId(), msg.getTradeHandler())); + } } + /** + * Handles a TradeResponse message by forwarding the response back to the initiating player. + * + * @param msg the TradeResponse message received from the receiving player + * @param from the connection ID of the player who sent the response + */ @Override public void received(TradeResponse msg, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); + 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()); + send(initiator, new TradeReply(msg.getInitiatorId(), msg.getTradeHandler())); + } } + /** + * Handles a ViewAssetsRequest message, sending the player a response containing their assets. + * + * @param msg the ViewAssetsRequest message received from the player + * @param from the connection ID of the player who sent the request + */ @Override public void received(ViewAssetsRequest msg, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'received'"); + Player player = playerHandler.getPlayerById(from); + if (player != null) { + LOGGER.log(Level.DEBUG, "Processing ViewAssetsRequest for player {0}", player.getName()); + + send(player, new ViewAssetsResponse(player.getProperties(), player.getAccountBalance(), player.getNumJailCard())); + } } + /** + * Retrieves the board manager, which manages the game board. + * + * @return the BoardManager instance managing the game board + */ + public BoardManager getBoardManager() { + return boardManager; + } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerState.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerState.java index d6185d9..2ce67c8 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerState.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerState.java @@ -14,20 +14,20 @@ enum ServerState { /** * The server is waiting for clients to connect. */ - WAIT, + CREATEGAME, /** - * The server is waiting for clients to set up their maps. + * The server is waiting for clients to set up their status to ready */ - SET_UP, + LOBBY, /** * The battle of the game where players take turns */ - BATTLE, + INGAME, /** - * The game has ended because all the players went bankrott + * The game has ended because all the players went bankrupt */ - GAME_OVER + GAMEOVER } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/BuyPropertyRequest.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/BuyPropertyRequest.java index 8fd1f4f..12a6bc9 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/BuyPropertyRequest.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/BuyPropertyRequest.java @@ -1,11 +1,31 @@ package pp.monopoly.message.client; +/** + * Represents a request from a player to buy a property. + */ public class BuyPropertyRequest extends ClientMessage{ + private int propertyId; + + /** + * Constructs a BuyPropertyRequest with the specified property ID. + * + * @param propertyId the ID of the property to buy + */ + public BuyPropertyRequest(int propertyId) { + this.propertyId = propertyId; + } + + /** + * Gets the ID of the property to buy. + * + * @return the property ID + */ + public int getPropertyId() { + return propertyId; + } @Override public void accept(ClientInterpreter interpreter, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this, from); } - -} \ No newline at end of file +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/EndTurn.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/EndTurn.java index 8241f76..dae8120 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/EndTurn.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/EndTurn.java @@ -1,11 +1,12 @@ package pp.monopoly.message.client; - +/** + * Represents a message indicating the player wants to end their turn. + */ public class EndTurn extends ClientMessage{ @Override public void accept(ClientInterpreter interpreter, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this, from); } } \ No newline at end of file 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 9e22eb1..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,11 +1,52 @@ 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. + * + * @param isReady true if the player is ready, false otherwise + */ + public PlayerReady(boolean isReady) { + 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. + * + * @return true if ready, false otherwise + */ + public boolean isReady() { + return isReady; + } + @Override public void accept(ClientInterpreter interpreter, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this, from); } - -} \ No newline at end of file +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/RollDice.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/RollDice.java index 60129b2..9fb0b93 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/RollDice.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/RollDice.java @@ -1,11 +1,12 @@ package pp.monopoly.message.client; - +/** + * Represents a message requesting to roll the dice. + */ public class RollDice extends ClientMessage{ @Override public void accept(ClientInterpreter interpreter, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this, from); } } \ No newline at end of file diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeOffer.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeOffer.java index 4826e82..b614365 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeOffer.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeOffer.java @@ -1,11 +1,32 @@ package pp.monopoly.message.client; +import pp.monopoly.model.TradeHandler; + +/** + * Represents a trade Request message from one player to another. + */ public class TradeOffer extends ClientMessage{ + private int receiverId; + private TradeHandler tradehandler; + + + /** + * Constructs a TradeOffer with the specified details. + * + * @param receiverId the ID of the player receiving the Request + * @param tradehandler the tradehandler + */ + public TradeOffer(int receiverId, TradeHandler tradehandler) { + this.receiverId = receiverId; + this.tradehandler = tradehandler; + } + + public int getReceiverId() { return receiverId; } + public TradeHandler getTradeHandler() { return tradehandler; } @Override public void accept(ClientInterpreter interpreter, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this, from); } -} \ No newline at end of file +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeResponse.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeResponse.java index d8489ea..d317c6f 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeResponse.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/TradeResponse.java @@ -1,11 +1,32 @@ package pp.monopoly.message.client; +import pp.monopoly.model.TradeHandler; + +/** + * Represents a response to a trade offer. + */ public class TradeResponse extends ClientMessage{ + private int initiatorId; + private TradeHandler tradeHandler; + + /** + * Constructs a TradeResponse with the specified response details. + * + * @param initiatorId the ID of the player who initiated the trade + * @param accepted true if the offer is accepted, false if declined + */ + public TradeResponse(int initiatorId, TradeHandler tradeHandler) { + this.initiatorId = initiatorId; + this.tradeHandler = tradeHandler; + } + + public int getInitiatorId() { return initiatorId; } + public TradeHandler getTradeHandler() { + return tradeHandler; + } @Override public void accept(ClientInterpreter interpreter, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this, from); } - -} \ No newline at end of file +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ViewAssetsRequest.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ViewAssetsRequest.java index a6b8739..f78d778 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ViewAssetsRequest.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ViewAssetsRequest.java @@ -1,11 +1,12 @@ package pp.monopoly.message.client; - +/** + * Represents a request from a player to view their assets. + */ public class ViewAssetsRequest extends ClientMessage{ @Override public void accept(ClientInterpreter interpreter, int from) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this, from); } } \ No newline at end of file diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/DiceResult.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/DiceResult.java index 40b780e..65a8223 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/DiceResult.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/DiceResult.java @@ -1,11 +1,22 @@ package pp.monopoly.message.server; +import java.util.List; + public class DiceResult extends ServerMessage{ + private List rollResult; + + public DiceResult(List rollResult) { + this.rollResult = rollResult; + } + + public List getRollResult() { + return rollResult; + } + @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override @@ -14,4 +25,11 @@ public class DiceResult extends ServerMessage{ throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); } + public boolean isDoublets() { + return rollResult.get(0) == rollResult.get(1); + } + + public int calcTotal() { + return rollResult.get(0)+rollResult.get(1); + } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java index 90ef339..7ed4938 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java @@ -4,8 +4,7 @@ public class EventDrawCard extends ServerMessage{ @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java index 486fa88..9b2cff3 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java @@ -4,8 +4,7 @@ public class GameOver extends ServerMessage{ @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameStart.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameStart.java index 0855fef..bf39031 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameStart.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameStart.java @@ -4,8 +4,7 @@ public class GameStart extends ServerMessage{ @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java index 8c04ead..a802398 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java @@ -4,8 +4,7 @@ public class JailEvent extends ServerMessage{ @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java index 692a25d..8b51066 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java @@ -4,8 +4,7 @@ public class PlayerStatusUpdate extends ServerMessage{ @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java index d99cd42..3480d20 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java @@ -69,13 +69,6 @@ public interface ServerInterpreter { */ void received(TimeOutWarning msg); - /** - * Handles a TradeRequest message received from the server. - * - * @param msg the TradeRequest message received - */ - void received(TradeRequest msg); - /** * Handles a UpdatePlayerAssets message received from the server. * @@ -89,4 +82,18 @@ public interface ServerInterpreter { * @param msg the ViewAssetsResponse message received */ void received(ViewAssetsResponse msg); + + /** + * Handles a TradeReply message received from the server. + * + * @param msg the TradeReply message received + */ + void received(TradeReply msg); + + /** + * Handles a TradeRequest message received from the server. + * + * @param msg the TradeRequest message received + */ + void received(TradeRequest msg); } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java index 65e80c9..f9510a7 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java @@ -4,8 +4,7 @@ public class TimeOutWarning extends ServerMessage{ @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TradeReply.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TradeReply.java new file mode 100644 index 0000000..6535906 --- /dev/null +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TradeReply.java @@ -0,0 +1,39 @@ +package pp.monopoly.message.server; + +import pp.monopoly.model.TradeHandler; + +/** + * Represents a response to a trade offer. + */ +public class TradeReply extends ServerMessage{ + private int initiatorId; + private TradeHandler tradeHandler; + + /** + * Constructs a TradeResponse with the specified response details. + * + * @param initiatorId the ID of the player who initiated the trade + * @param accepted true if the offer is accepted, false if declined + */ + public TradeReply(int initiatorId, TradeHandler tradeHandler) { + this.initiatorId = initiatorId; + this.tradeHandler = tradeHandler; + } + + public int getInitiatorId() { return initiatorId; } + public TradeHandler getTradeHandler() { + return tradeHandler; + } + + @Override + public void accept(ServerInterpreter interpreter) { + interpreter.received(this); + } + + @Override + public String getInfoTextKey() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); + } + +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TradeRequest.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TradeRequest.java index cffd567..5320953 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TradeRequest.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TradeRequest.java @@ -1,11 +1,33 @@ package pp.monopoly.message.server; +import pp.monopoly.model.TradeHandler; + +/** + * Represents a trade Request message from one player to another. + */ public class TradeRequest extends ServerMessage{ + private int receiverId; + private TradeHandler tradehandler; + + + /** + * Constructs a TradeRequest with the specified details. + * + * @param receiverId the ID of the player receiving the Request + * @param tradehandler the tradehandler + */ + public TradeRequest(int receiverId, TradeHandler tradehandler) { + this.receiverId = receiverId; + this.tradehandler = tradehandler; + } + + public int getReceiverId() { return receiverId; } + public TradeHandler getTradeHandler() { return tradehandler; } + @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/UpdatePlayerAssets.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/UpdatePlayerAssets.java index 782f695..e37c78c 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/UpdatePlayerAssets.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/UpdatePlayerAssets.java @@ -4,8 +4,7 @@ public class UpdatePlayerAssets extends ServerMessage{ @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java index 7d29692..116366e 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java @@ -1,11 +1,32 @@ package pp.monopoly.message.server; +import java.util.List; + +import pp.monopoly.model.fields.PropertyField; +/** + * Represents a response containing the player's assets. + */ public class ViewAssetsResponse extends ServerMessage{ + private List properties; + private int accountBalance; + private int jailCards; + + /** + * Constructs a ViewAssetsResponse with the specified properties and account balance. + * + * @param properties a List of PropertyField objects representing the player's properties + * @param accountBalance the player's current account balance + */ + public ViewAssetsResponse(List properties, int accountBalance, int jailCards) { + this.properties = properties; + this.accountBalance = accountBalance; + this.jailCards = jailCards; + } + @Override public void accept(ServerInterpreter interpreter) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + interpreter.received(this); } @Override @@ -14,4 +35,16 @@ public class ViewAssetsResponse extends ServerMessage{ throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); } + public List getProperties() { + return properties; + } + + public int getAccountBalance() { + return accountBalance; + } + + public int getJailCards() { + return jailCards; + } + } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/TradeHandler.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/TradeHandler.java new file mode 100644 index 0000000..fc1f65f --- /dev/null +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/TradeHandler.java @@ -0,0 +1,183 @@ +package pp.monopoly.model; + +import pp.monopoly.game.server.Player; +import pp.monopoly.model.fields.PropertyField; + +import java.util.List; + +/** + * Helper class that handles the trade logic between two players. + * Manages trade initiation, validation, acceptance, and rejection involving multiple properties, money, and jail cards. + */ +public class TradeHandler { + + /** + * Initiates a trade offer between two players involving properties, money, and jail cards. + * + * @param sender the Player who is initiating the trade + * @param receiver the Player who is the target of the trade offer + * @param offeredAmount the amount of money the sender offers + * @param offeredProperties the list of properties the sender offers + * @param offeredJailCards the number of jail cards the sender offers + * @param requestedAmount the amount of money the sender requests from the receiver + * @param requestedProperties the list of properties the sender requests from the receiver + * @param requestedJailCards the number of jail cards the sender requests from the receiver + * @return true if the trade offer is valid and initiated, false otherwise + */ + public boolean initiateTrade(Player sender, Player receiver, int offeredAmount, List offeredProperties, + int offeredJailCards, int requestedAmount, List requestedProperties, int requestedJailCards) { + // Validate the trade offer + if (!validateTrade(sender, offeredAmount, offeredProperties, offeredJailCards, receiver, requestedAmount, requestedProperties, requestedJailCards)) { + System.out.println("Trade offer is invalid."); + return false; + } + + // Notify the receiver about the trade offer (this would be an actual message in a real implementation) + System.out.println("Trade offer initiated by " + sender.getName() + " to " + receiver.getName()); + return true; + } + + /** + * Accepts the trade offer and completes the trade between two players. + * + * @param sender the Player who initiated the trade + * @param receiver the Player who accepted the trade + * @param offeredAmount the amount of money to transfer from the sender to the receiver + * @param offeredProperties the list of properties to transfer from the sender to the receiver + * @param offeredJailCards the number of jail cards to transfer from the sender to the receiver + * @param requestedAmount the amount of money to transfer from the receiver to the sender + * @param requestedProperties the list of properties to transfer from the receiver to the sender + * @param requestedJailCards the number of jail cards to transfer from the receiver to the sender + */ + public void acceptTrade(Player sender, Player receiver, int offeredAmount, List offeredProperties, + int offeredJailCards, int requestedAmount, List requestedProperties, int requestedJailCards) { + // Transfer money + sender.earnMoney(-offeredAmount); // Deduct money from the sender + receiver.earnMoney(offeredAmount); // Add money to the receiver + + receiver.earnMoney(-requestedAmount); // Deduct money from the receiver + sender.earnMoney(requestedAmount); // Add money to the sender + + // Transfer ownership of the properties from sender to receiver + if (offeredProperties != null) { + for (PropertyField property : offeredProperties) { + transferProperty(sender, receiver, property); + } + } + + // Transfer ownership of the properties from receiver to sender + if (requestedProperties != null) { + for (PropertyField property : requestedProperties) { + transferProperty(receiver, sender, property); + } + } + + // Transfer jail cards + transferJailCards(sender, receiver, offeredJailCards); + transferJailCards(receiver, sender, requestedJailCards); + + System.out.println("Trade accepted. " + sender.getName() + " and " + receiver.getName() + " completed the trade."); + } + + /** + * Rejects the trade offer. + * + * @param receiver the Player who is rejecting the trade + */ + public void rejectTrade(Player receiver) { + System.out.println("Trade rejected by " + receiver.getName()); + } + + /** + * Validates a trade offer by checking if the sender and receiver own the properties involved, + * have sufficient funds for the money involved in the trade, and have enough jail cards. + * + * @param sender the Player initiating the trade + * @param offeredAmount the amount of money the sender is offering + * @param offeredProperties the list of properties the sender is offering + * @param offeredJailCards the number of jail cards the sender is offering + * @param receiver the Player receiving the trade offer + * @param requestedAmount the amount of money the sender is requesting + * @param requestedProperties the list of properties the sender is requesting from the receiver + * @param requestedJailCards the number of jail cards the sender is requesting from the receiver + * @return true if the trade offer is valid, false otherwise + */ + private boolean validateTrade(Player sender, int offeredAmount, List offeredProperties, int offeredJailCards, + Player receiver, int requestedAmount, List requestedProperties, int requestedJailCards) { + // Check if sender has enough money to offer + if (sender.getAccountBalance() < offeredAmount) { + System.out.println("Sender does not have enough balance to make this offer."); + return false; + } + + // Check if receiver has enough money to offer + if (receiver.getAccountBalance() < requestedAmount) { + System.out.println("Receiver does not have enough balance to fulfill requested amount."); + return false; + } + + // Check if sender owns all the offered properties + if (offeredProperties != null) { + for (PropertyField property : offeredProperties) { + if (!sender.getProperties().contains(property)) { + System.out.println("Sender does not own the property " + property.getName() + " being offered."); + return false; + } + } + } + + // Check if receiver owns all the requested properties + if (requestedProperties != null) { + for (PropertyField property : requestedProperties) { + if (!receiver.getProperties().contains(property)) { + System.out.println("Receiver does not own the property " + property.getName() + " requested."); + return false; + } + } + } + + // Check if sender has enough jail cards to offer + if (sender.getNumJailCard() < offeredJailCards) { + System.out.println("Sender does not have enough jail cards to offer."); + return false; + } + + // Check if receiver has enough jail cards to fulfill the request + if (receiver.getNumJailCard() < requestedJailCards) { + System.out.println("Receiver does not have enough jail cards to fulfill the request."); + return false; + } + + return true; + } + + /** + * Transfers a property from one player to another. + * + * @param from the Player transferring the property + * @param to the Player receiving the property + * @param property the PropertyField being transferred + */ + private void transferProperty(Player from, Player to, PropertyField property) { + from.sellProperty(property); + to.buyProperty(property); + property.setOwner(to); // Update the property's owner + + System.out.println("Property " + property.getName() + " transferred from " + from.getName() + " to " + to.getName()); + } + + /** + * Transfers jail cards between players. + * + * @param from the Player transferring jail cards + * @param to the Player receiving jail cards + * @param numCards the number of jail cards to transfer + */ + private void transferJailCards(Player from, Player to, int numCards) { + for (int i = 0; i < numCards; i++) { + from.removeJailCard(); + to.addJailCard(); + } + System.out.println("Transferred " + numCards + " jail card(s) from " + from.getName() + " to " + to.getName()); + } +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FieldFactory.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java similarity index 69% rename from Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FieldFactory.java rename to Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java index 306be20..cf0b74d 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FieldFactory.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java @@ -2,17 +2,34 @@ package pp.monopoly.model.fields; import java.util.ArrayList; import java.util.List; +import java.util.NoSuchElementException; -public class FieldFactory { +/** + * Simple Manager class responsible for managing the GameBoard of Monopoly + */ +public class BoardManager { - public static List createBoard() { + private List board; + + /** + * Constructs a BoardManager + */ + public BoardManager() { + board = createBoard(); + } + + /** + * Creates a Monopoly GameBoard + * @return the List of Fields in correct Order + */ + private static List createBoard() { ArrayList fields = new ArrayList<>(); fields.addLast(new GoField()); fields.addLast(new BuildingProperty("Gym", 1, 600, 20)); fields.addLast(new EventField("Hausfeier", 2)); fields.addLast(new BuildingProperty("Sportplatz", 3, 600, 40)); - fields.addLast(new FineField("Diszi", 4)); + fields.addLast(new FineField("Diszi", 4, 2000)); fields.addLast(new GateField("Südtor", 5)); fields.addLast(new BuildingProperty("Studium+", 6, 1000, 60)); fields.addLast(new EventField("Üvas", 7)); @@ -46,9 +63,29 @@ public class FieldFactory { fields.addLast(new GateField("Osttor", 35)); fields.addLast(new EventField("Üvas", 36)); fields.addLast(new BuildingProperty("2er", 37, 3500, 350)); - fields.addLast(new FineField("EZM", 38)); + fields.addLast(new FineField("EZM", 38, 1000)); fields.addLast(new BuildingProperty("20er", 39, 4000, 500)); return fields; } + + + /** + * Method to find the Field at specific index + * @param index the index for which to find the field + * @return the field at the index + */ + public Field getFieldAtIndex(int index) { + return board.get(index); + } + + /** + * Method to find the index of a Monopoly field + * @param field the Field to get the Index of + * @return the Index of the field + */ + public int getIndexOfField(Field field) { + if (board.contains(field)) return field.getId(); + else throw new NoSuchElementException(); + } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BuildingProperty.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BuildingProperty.java index 1e2dcc7..ae73cb8 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BuildingProperty.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BuildingProperty.java @@ -12,7 +12,7 @@ public class BuildingProperty extends PropertyField { } @Override - protected int calcRent() { + public int calcRent() { if (hotel) { return (int) Math.round(rent*70/10)*10; } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/Field.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/Field.java index 841142a..0baa044 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/Field.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/Field.java @@ -16,4 +16,8 @@ abstract class Field { public int getId() { return id; } + + public String getName() { + return name; + } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FineField.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FineField.java index 46cd71f..8429394 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FineField.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FineField.java @@ -4,14 +4,20 @@ import pp.monopoly.game.server.Player; public class FineField extends Field{ - FineField(String name, int id) { + private final int fine; + + FineField(String name, int id, int fine) { super(name, id); + this.fine = fine; + } + + public int getFine() { + return fine; } @Override public void accept(Player player) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'accept'"); + player.visit(this); } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FoodField.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FoodField.java index efa3eb4..a3f0abf 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FoodField.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/FoodField.java @@ -9,9 +9,8 @@ public class FoodField extends PropertyField { } @Override - protected int calcRent() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'calcRent'"); + public int calcRent() { + return 0; } @Override diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/GateField.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/GateField.java index 6e8440a..ce04a4c 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/GateField.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/GateField.java @@ -9,7 +9,7 @@ public class GateField extends PropertyField{ } @Override - protected int calcRent() { + public int calcRent() { return rent; } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/PropertyField.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/PropertyField.java index 118daa5..8f89831 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/PropertyField.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/PropertyField.java @@ -2,27 +2,91 @@ package pp.monopoly.model.fields; import pp.monopoly.game.server.Player; +/** + * Represents an abstract property field in the Monopoly game. + * Contains attributes related to ownership, price, rent, and mortgage status. + */ public abstract class PropertyField extends Field { private final int price; protected final int rent; private Player owner; - private boolean mortaged = false; + private boolean mortgaged = false; + /** + * Constructs a PropertyField with the specified name, ID, price, and rent. + * + * @param name the name of the property + * @param id the unique identifier for the property + * @param price the purchase price of the property + * @param rent the base rent for the property + */ protected PropertyField(String name, int id, int price, int rent) { super(name, id); this.price = price; this.rent = rent; } + /** + * Calculates the rent for this property. + * The calculation may depend on various factors specific to property type. + * + * @return the calculated rent for this property + */ + public abstract int calcRent(); - protected abstract int calcRent(); - + /** + * Gets the purchase price of the property. + * + * @return the price of the property + */ public int getPrice() { return price; } + /** + * Gets the mortgage value (hypothecary value) of the property. + * Typically, this is half of the property price. + * + * @return the mortgage value of the property + */ public int getHypo() { - return price/2; + return price / 2; + } + + /** + * Gets the owner of the property. + * + * @return the Player who owns the property, or null if the property is unowned + */ + public Player getOwner() { + return owner; + } + + /** + * Sets the owner of the property. + * + * @param player the Player who will own this property + */ + public void setOwner(Player player) { + owner = player; + } + + /** + * Checks if the property is currently mortgaged. + * + * @return true if the property is mortgaged, false otherwise + */ + public boolean isMortgaged() { + return mortgaged; + } + + /** + * Sets the mortgage status of the property. + * + * @param mortgaged true to mark the property as mortgaged, false to unmark it + */ + public void setMortgaged(boolean mortgaged) { + this.mortgaged = mortgaged; } } diff --git a/Projekte/monopoly/model/src/test/java/pp/monopoly/Testhandbuch.java b/Projekte/monopoly/model/src/test/java/pp/monopoly/Testhandbuch.java index fac44e3..caf2a99 100644 --- a/Projekte/monopoly/model/src/test/java/pp/monopoly/Testhandbuch.java +++ b/Projekte/monopoly/model/src/test/java/pp/monopoly/Testhandbuch.java @@ -380,8 +380,6 @@ public class Testhandbuch { game.sendToJail(player); assertEquals(PlayerState.InJail, player.getState()); } - // T035 - } diff --git a/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java b/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java index 73aaa17..ff77c8a 100644 --- a/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java +++ b/Projekte/monopoly/server/src/main/java/pp/monopoly/server/MonopolyServer.java @@ -120,7 +120,7 @@ public class MonopolyServer implements MessageListener, Connec @Override public void connectionAdded(Server server, HostedConnection hostedConnection) { LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS - logic.addPlayer(hostedConnection.getId()); + logic.addPlayer(new Player(hostedConnection.getId())); } @Override