From 7d0a0123e08f8e22c338d192c4ae6bbcf05758b7 Mon Sep 17 00:00:00 2001 From: Johannes Schmelz Date: Sun, 1 Dec 2024 18:17:46 +0100 Subject: [PATCH] server side logic for propertyAdmin --- .../java/pp/monopoly/client/gui/Toolbar.java | 2 +- .../java/pp/monopoly/game/server/Player.java | 13 +++- .../monopoly/game/server/ServerGameLogic.java | 37 ++++++++++ .../message/client/AlterProperty.java | 36 ++++++++++ .../message/client/ClientInterpreter.java | 8 +++ .../monopoly/model/fields/BoardManager.java | 69 +++++++++++++++++++ .../model/fields/BuildingProperty.java | 37 +++------- .../pp/monopoly/server/MonopolyServer.java | 2 + 8 files changed, 172 insertions(+), 32 deletions(-) create mode 100644 Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/AlterProperty.java diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java index 9f89bba..ce8d707 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java @@ -174,7 +174,7 @@ public class Toolbar extends Dialog implements GameEventListener { propertyMenuButton.setFontSize(30); propertyMenuButton.addClickCommands(s -> ifTopDialog(() -> { app.getGameLogic().playSound(Sound.BUTTON); - new PropertyOverviewMenu(app).open(); + new BuildingAdminMenu(app).open(); })); return propertyMenuButton; } 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 1b8a4f7..766df27 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 @@ -15,7 +15,6 @@ import java.util.Set; import com.jme3.network.serializing.Serializable; -import pp.monopoly.game.client.WaitForTurnState; import pp.monopoly.message.server.BuyPropertyRequest; import pp.monopoly.message.server.DiceResult; import pp.monopoly.message.server.EventDrawCard; @@ -149,7 +148,10 @@ public class Player implements FieldVisitor{ if (state instanceof ActiveState) state = new WaitForTurnState(); return true; } - else return false; + else { + bankrupt(); + return false; + } } boolean canFinishTurn() { @@ -496,7 +498,12 @@ public class Player implements FieldVisitor{ return state.rollDice(); } - + private void bankrupt() { + for (PropertyField field : getPropertyFields()) { + field.setOwner(null); + } + } + /** * A interface representing the PlayerStates */ 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 6891a17..4193f37 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,8 +6,11 @@ import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; +import java.util.stream.Collector; +import java.util.stream.Collectors; import pp.monopoly.MonopolyConfig; +import pp.monopoly.message.client.AlterProperty; import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.ClientInterpreter; import pp.monopoly.message.client.EndTurn; @@ -28,6 +31,7 @@ import pp.monopoly.model.Rotation; import pp.monopoly.model.TradeHandler; import pp.monopoly.model.card.DeckHelper; import pp.monopoly.model.fields.BoardManager; +import pp.monopoly.model.fields.BuildingProperty; import pp.monopoly.model.fields.PropertyField; /** @@ -364,4 +368,37 @@ public class ServerGameLogic implements ClientInterpreter { public DeckHelper getDeckHelper() { return deckHelper; } + + @Override + public void received(AlterProperty msg, int from) { + Player sender = playerHandler.getPlayerById(from); + + if (msg.getKeyword().equals("TakeMortage")) { + for (PropertyField field : sender.getPropertyFields()) { + field.setMortgaged(true); + sender.earnMoney(field.getHypo()); + } + } else if (msg.getKeyword().equals("RepayMortage")) { + for (PropertyField field : sender.getPropertyFields()) { + if(sender.getAccountBalance() >= field.getHypo()) { + field.setMortgaged(false); + sender.pay(field.getHypo()); + } + } + } else if(msg.getKeyword().equals("BuyHouse")) { + for (BuildingProperty field : sender.getPropertyFields().stream().filter(p -> p instanceof BuildingProperty).map(p -> (BuildingProperty) p).collect(Collectors.toList())) { + if (boardManager.canBuild(field) && sender.getAccountBalance() >= field.getHousePrice()) { + field.build(); + sender.pay(field.getHousePrice()); + } + } + } else if(msg.getKeyword().equals("SellHouse")) { + for (BuildingProperty field : sender.getPropertyFields().stream().filter(p -> p instanceof BuildingProperty).map(p -> (BuildingProperty) p).collect(Collectors.toList())) { + if (boardManager.canSell(field)) { + field.sell(); + sender.earnMoney(field.getHousePrice()); + } + } + } + } } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/AlterProperty.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/AlterProperty.java new file mode 100644 index 0000000..1330e8d --- /dev/null +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/AlterProperty.java @@ -0,0 +1,36 @@ +package pp.monopoly.message.client; + +import java.util.Set; + +import com.jme3.network.serializing.Serializable; + +@Serializable +public class AlterProperty extends ClientMessage{ + + private String keyword; + private Set properties; + + private AlterProperty() {} + + public AlterProperty(String keyword) { + this.keyword = keyword; + } + + @Override + public void accept(ClientInterpreter interpreter, int from) { + interpreter.received(this, from); + } + + public String getKeyword() { + return keyword; + } + + public void setProperties(Set properties) { + this.properties = properties; + } + + public Set getProperties() { + return properties; + } + +} diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ClientInterpreter.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ClientInterpreter.java index 9b266a5..9f68460 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ClientInterpreter.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/client/ClientInterpreter.java @@ -66,4 +66,12 @@ public interface ClientInterpreter { * @param from the connection ID from which the message was received */ void received(ViewAssetsRequest msg, int from); + + /** + * Processes a received AlterProperty. + * + * @param msg the AlterProperty to be processed + * @param from the connection ID from which the message was received + */ + void received(AlterProperty msg, int from); } diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java index 1db88e7..7fbbd26 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java @@ -3,6 +3,8 @@ package pp.monopoly.model.fields; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; +import java.util.stream.Collector; +import java.util.stream.Collectors; import com.jme3.network.serializing.Serializable; @@ -112,4 +114,71 @@ public class BoardManager { } return properties; } + + public boolean canBuild(BuildingProperty field) { + if (field == null) { + return false; // Null check for safety + } + + // Get the color group of the property + FieldColor groupColor = field.getColor(); + + // Get all properties of the same color group + List groupProperties = board.stream() + .filter(f -> f instanceof BuildingProperty) + .map(f -> (BuildingProperty) f) + .filter(bp -> bp.getColor() == groupColor) + .collect(Collectors.toList()); + + // Check if the player owns all properties in the color group + if (!groupProperties.stream().allMatch(bp -> bp.getOwner() != null && bp.getOwner().equals(field.getOwner()))) { + return false; // The player must own all properties in the color group + } + + // Ensure balanced building: Check if building levels are balanced within the group + int currentHouses = field.getHouses(); + return groupProperties.stream() + .allMatch(bp -> bp.getHouses() >= currentHouses); + } + + /** + * Checks if a House can be sold on the given Property + * @param field the Property to check + * @return true if a house can be sold on the property, false otherwise + */ + public boolean canSell(BuildingProperty field) { + if (field == null) { + return false; // Null check for safety + } + + // Get the color group of the property + FieldColor groupColor = field.getColor(); + + // Get all properties of the same color group + List groupProperties = board.stream() + .filter(f -> f instanceof BuildingProperty) + .map(f -> (BuildingProperty) f) + .filter(bp -> bp.getColor() == groupColor) + .collect(Collectors.toList()); + + // Check if the property has houses or a hotel to sell + if (field.getHouses() == 0 && field.getHotel() == 0) { + return false; // No houses or hotels to sell + } + + // Ensure balanced selling: You cannot sell houses unevenly in the group + int currentHouses = field.getHouses(); + int currentHotel = field.getHotel(); + + // If there is a hotel, selling is allowed only if all other properties have max houses + if (currentHotel > 0) { + return groupProperties.stream() + .allMatch(bp -> bp.getHouses() == 4 || bp.equals(field)); + } + + // If there are houses, check that selling does not unbalance the group + return groupProperties.stream() + .allMatch(bp -> bp.getHouses() <= currentHouses); + } + } 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 1048e2b..3fc9839 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 @@ -11,7 +11,6 @@ import pp.monopoly.game.server.Player; public class BuildingProperty extends PropertyField { private int houses; - private boolean hotel = false; private final int housePrice; private final FieldColor color; private final int rentFactor1 = 5; @@ -34,41 +33,31 @@ public class BuildingProperty extends PropertyField { @Override public int calcRent() { - if (hotel) { - return (int) Math.round(rent*rentFactorHotel/10)*10; - } switch (houses) { case 1: - return (int) Math.round(rent*rentFactor1/10)*10; + return (int) Math.round(rent*rentFactor1/10)*10; case 2: - return (int) Math.round(rent*rentFactor2/10)*10; + return (int) Math.round(rent*rentFactor2/10)*10; case 3: - return (int) Math.round(rent*rentFactor3/10)*10; + return (int) Math.round(rent*rentFactor3/10)*10; case 4: return (int) Math.round(rent*rentFactor4/10)*10; - + case 5: + return (int) Math.round(rent*rentFactorHotel/10)*10; default: return rent; } } - public boolean buildHouse() { - if (houses < 4) { + public boolean build() { + if (houses < 5) { houses++; return true; } return false; } - - public boolean buildHotel() { - if (hotel) { - return false; - } - hotel = true; - return true; - } - public boolean removeHouse() { + public boolean sell() { if (houses == 0) { return false; } @@ -76,14 +65,6 @@ public class BuildingProperty extends PropertyField { return true; } - public boolean removeHotel() { - if (!hotel) { - return false; - } - hotel = false; - return true; - } - @Override public void accept(Player player) { player.visit(this); @@ -113,6 +94,6 @@ public class BuildingProperty extends PropertyField { } public int getHotel() { - return hotel ? 1:0; + return (houses == 5)? 1:0; } } 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 f1b2ddf..2fa1a50 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 @@ -29,6 +29,7 @@ import pp.monopoly.game.server.Player; import pp.monopoly.game.server.PlayerHandler; import pp.monopoly.game.server.ServerGameLogic; import pp.monopoly.game.server.ServerSender; +import pp.monopoly.message.client.AlterProperty; import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.ClientMessage; import pp.monopoly.message.client.EndTurn; @@ -174,6 +175,7 @@ public class MonopolyServer implements MessageListener, Connec Serializer.registerClass(TradeHandler.class); Serializer.registerClass(NotificationMessage.class); Serializer.registerClass(JailEvent.class); + Serializer.registerClass(AlterProperty.class); } private void registerListeners() {