server side logic for propertyAdmin

This commit is contained in:
Johannes Schmelz 2024-12-01 18:17:46 +01:00
parent 2f025e2e1a
commit 7d0a0123e0
8 changed files with 172 additions and 32 deletions

View File

@ -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;
}

View File

@ -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<Void>{
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<Void>{
return state.rollDice();
}
private void bankrupt() {
for (PropertyField field : getPropertyFields()) {
field.setOwner(null);
}
}
/**
* A interface representing the PlayerStates
*/

View File

@ -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());
}
}
}
}
}

View File

@ -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<Integer> 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<Integer> properties) {
this.properties = properties;
}
public Set<Integer> getProperties() {
return properties;
}
}

View File

@ -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);
}

View File

@ -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<BuildingProperty> 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<BuildingProperty> 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);
}
}

View File

@ -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;
}
}

View File

@ -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<HostedConnection>, Connec
Serializer.registerClass(TradeHandler.class);
Serializer.registerClass(NotificationMessage.class);
Serializer.registerClass(JailEvent.class);
Serializer.registerClass(AlterProperty.class);
}
private void registerListeners() {