trade logic complete

This commit is contained in:
Johannes Schmelz 2024-11-30 20:50:36 +01:00
parent a70295f1ff
commit 87309235bd
7 changed files with 140 additions and 165 deletions

View File

@ -9,6 +9,11 @@ import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.client.gui.TradeMenu;
import pp.monopoly.message.client.TradeResponse;
import pp.monopoly.message.server.TradeReply;
import pp.monopoly.model.TradeHandler;
import pp.monopoly.model.fields.PropertyField;
import pp.monopoly.notification.Sound;
/**
@ -18,11 +23,13 @@ public class ConfirmTrade extends Dialog {
private final MonopolyApp app;
private final Container confirmTradeContainer;
private final Container backgroundContainer;
private TradeHandler tradeHandler;
public ConfirmTrade(MonopolyApp app) {
super(app.getDialogManager());
this.app = app;
tradeHandler = app.getGameLogic().getTradeHandler();
// Create the background container
backgroundContainer = new Container();
@ -40,20 +47,32 @@ public class ConfirmTrade extends Dialog {
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
StringBuilder offeredProperties = new StringBuilder();
for (PropertyField field : tradeHandler.getOfferedProperties()) {
offeredProperties.append(field.getName());
offeredProperties.append(", ");
}
StringBuilder requestedProperties = new StringBuilder();
for (PropertyField field : tradeHandler.getRequestedProperties()) {
requestedProperties.append(field.getName());
requestedProperties.append(", ");
}
// Text, der auf der Karte steht
// Die Werte werden dem Handel entnommen (Iwas auch immer da dann ist)
Container propertyValuesContainer = confirmTradeContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label("„Spieler XXX möchte:", new ElementId("label-Text"))); //TODO hier überall die entsprechenden Variablen einfügen
propertyValuesContainer.addChild(new Label("„Spieler " + tradeHandler.getSender().getName() + " möchte:", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- XXX Gebäude", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- XXX EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- XXX Sonderkaten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + offeredProperties, new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedAmount() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedJailCards() +" Sonderkaten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("gegen:", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- XXX Gebäude", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- XXX EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- XXX Sonderkaten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- "+ requestedProperties, new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- "+ tradeHandler.getRequestedAmount() +" EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- "+ tradeHandler.getRequestedJailCards() +" Sonderkaten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("tauschen, willst du das Angebot annehmen?", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
@ -63,19 +82,24 @@ public class ConfirmTrade extends Dialog {
declineButton.setFontSize(32);
declineButton.addClickCommands(s -> ifTopDialog(() -> { //TODO Buttonfunktion prüfen
app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new TradeResponse(false, tradeHandler));
close();
}));
// Verhandeln-Button
Button negotiateButton = confirmTradeContainer.addChild(new Button("Verhandeln", new ElementId("button")));
negotiateButton.setFontSize(32);
negotiateButton.addClickCommands(s -> ifTopDialog( () -> { //TODO Buttonfunktion prüfen
negotiateButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
new TradeMenu(app, new TradeHandler(app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()))).open();
}));
// Confirm-Button
Button confirmButton = confirmTradeContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(s -> ifTopDialog( () -> { //TODO Buttonfunktion prüfen
confirmButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new TradeResponse(true, tradeHandler));
close();
}));
// Zentriere das Menü

View File

@ -22,6 +22,7 @@ import pp.monopoly.message.server.TradeRequest;
import pp.monopoly.message.server.ViewAssetsResponse;
import pp.monopoly.model.Board;
import pp.monopoly.model.IntPoint;
import pp.monopoly.model.TradeHandler;
import pp.monopoly.model.fields.BoardManager;
import pp.monopoly.notification.ClientStateEvent;
import pp.monopoly.notification.DiceRollEvent;
@ -61,6 +62,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
private BoardManager boardManager = new BoardManager();
private TradeHandler tradeHandler;
/**
* Constructs a ClientGameLogic with the specified sender object.
@ -113,6 +116,10 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
return board;
}
public TradeHandler getTradeHandler() {
return tradeHandler;
}
/**
* Moves the preview figure to the specified position.
*
@ -300,13 +307,11 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
*/
@Override
public void received(TradeReply msg) {
// if (msg.getTradeHandler().getStatus()) {
// playSound(Sound.TRADE_ACCEPTED);
// } else {
// playSound(Sound.TRADE_REJECTED);
// }
if (msg.isAccepted()) {
playSound(Sound.TRADE_ACCEPTED);
} else {
playSound(Sound.TRADE_REJECTED);
}
}
/**
@ -316,7 +321,7 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
*/
@Override
public void received(TradeRequest msg) {
System.out.println("Angebot angekommen");
tradeHandler = msg.getTradeHandler();
notifyListeners(new PopUpEvent("tradeRequest"));
}

View File

@ -8,10 +8,10 @@
package pp.monopoly.game.server;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import javax.swing.JInternalFrame;
import java.util.Set;
import com.jme3.network.serializing.Serializable;
@ -43,7 +43,7 @@ public class Player implements FieldVisitor<Void>{
private String name;
private int accountBalance = 15000;
private Figure figure;
private List<Integer> properties = new ArrayList<>();
private Set<Integer> properties = new HashSet<>();
private int getOutOfJailCard;
private int fieldID;
private DiceResult rollResult;
@ -189,7 +189,7 @@ public class Player implements FieldVisitor<Void>{
* @return List of all properties owned by this player
*/
public List<Integer> getProperties() {
return properties;
return new ArrayList<>(properties);
}
/**
@ -578,8 +578,17 @@ DiceResult rollDice() {
}
}
@Override
public String toString() {
return "Player{name=" + name + ", figure=" + figure + "}";
}
public void addProperty(Integer id) {
properties.add(id);
}
public void removeProperty(Integer id) {
properties.remove(id);
}
}

View File

@ -2,6 +2,10 @@ package pp.monopoly.game.server;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import pp.monopoly.MonopolyConfig;
import pp.monopoly.message.client.BuyPropertyResponse;
@ -21,6 +25,7 @@ import pp.monopoly.message.server.TradeRequest;
import pp.monopoly.message.server.ViewAssetsResponse;
import pp.monopoly.model.Figure;
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.PropertyField;
@ -248,15 +253,76 @@ public class ServerGameLogic implements ClientInterpreter {
*/
@Override
public void received(TradeResponse msg, int from) {
Player responder = playerHandler.getPlayerById(from);
Player initiator = playerHandler.getPlayerById(msg.getInitiatorId());
TradeHandler tradeHandler = msg.getTradeHandler();
Player receiver = playerHandler.getPlayerById(tradeHandler.getReceiver().getId());
Player sender = playerHandler.getPlayerById(tradeHandler.getSender().getId());
Set<PropertyField> offered = new HashSet<>();
for (PropertyField propertyField : tradeHandler.getOfferedProperties()) {
offered.add( (PropertyField) boardManager.getFieldAtIndex(propertyField.getId()));
}
Set<PropertyField> requested = new HashSet<>();
for (PropertyField propertyField : tradeHandler.getRequestedProperties()) {
requested.add( (PropertyField) boardManager.getFieldAtIndex(propertyField.getId()));
}
executeTrade(sender, receiver, offered, requested);
sender.earnMoney(tradeHandler.getRequestedAmount());
sender.pay(tradeHandler.getOfferedAmount());
receiver.earnMoney(tradeHandler.getOfferedAmount());
receiver.pay(tradeHandler.getRequestedAmount());
for (int i = 0; i < tradeHandler.getOfferedJailCards(); i++) {
sender.removeJailCard();
receiver.addJailCard();
}
for (int i = 0; i < tradeHandler.getRequestedAmount(); i++) {
sender.addJailCard();
receiver.removeJailCard();
}
updateAllPlayers();
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()));
if (receiver != null && sender != null) {
LOGGER.log(Level.INFO, "Player {0} responded to trade with player {1}", receiver.getName(), sender.getName());
send(sender, new TradeReply(msg.isAccepted(), msg.getTradeHandler()));
}
}
/**
* Executes the trade by transferring requested properties from the receiver
* to the sender and offered properties from the sender to the receiver.
*/
public void executeTrade(Player sender, Player receiver, Set<PropertyField> requestedProperties, Set<PropertyField> offeredProperties) {
// Transfer requested properties from receiver to sender
for (PropertyField field : requestedProperties) {
receiver.removeProperty(field.getId());
sender.addProperty(field.getId());
field.setOwner(sender); // Update ownership
System.out.printf("Property %s transferred from %s to %s.\n",
field.getName(), receiver.getName(), sender.getName());
}
// Transfer offered properties from sender to receiver
for (PropertyField field : offeredProperties) {
sender.removeProperty(field.getId());
receiver.addProperty(field.getId());
field.setOwner(receiver); // Update ownership
System.out.printf("Property %s transferred from %s to %s.\n",
field.getName(), sender.getName(), receiver.getName());
}
}
/**
* Handles a ViewAssetsRequest message, sending the player a response containing their assets.
*

View File

@ -9,7 +9,7 @@ import pp.monopoly.model.TradeHandler;
*/
@Serializable
public class TradeResponse extends ClientMessage{
private int initiatorId;
private boolean status;
private TradeHandler tradeHandler;
/**
@ -20,15 +20,15 @@ public class TradeResponse extends ClientMessage{
/**
* Constructs a TradeResponse with the specified response details.
*
* @param initiatorId the ID of the player who initiated the trade
* @param status 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;
public TradeResponse(boolean status, TradeHandler tradeHandler) {
this.status = status;
this.tradeHandler = tradeHandler;
}
public int getInitiatorId() { return initiatorId; }
public boolean isAccepted() { return status; }
public TradeHandler getTradeHandler() {
return tradeHandler;
}

View File

@ -9,7 +9,7 @@ import pp.monopoly.model.TradeHandler;
*/
@Serializable
public class TradeReply extends ServerMessage{
private int initiatorId;
private boolean status;
private TradeHandler tradeHandler;
/**
@ -20,15 +20,15 @@ public class TradeReply extends ServerMessage{
/**
* Constructs a TradeResponse with the specified response details.
*
* @param initiatorId the ID of the player who initiated the trade
* @param status 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;
public TradeReply(boolean status, TradeHandler tradeHandler) {
this.status = status;
this.tradeHandler = tradeHandler;
}
public int getInitiatorId() { return initiatorId; }
public boolean isAccepted() { return status; }
public TradeHandler getTradeHandler() {
return tradeHandler;
}

View File

@ -100,135 +100,6 @@ public class TradeHandler {
return sender;
}
/**
* Initiates the trade and validates its terms.
*
* @return true if the trade is valid and can proceed, false otherwise
*/
public boolean initiateTrade() {
if (!validateTrade()) {
return false;
}
return true;
}
/**
* Completes the trade by transferring money, properties, and jail cards.
*/
public void acceptTrade() {
// Transfer money
sender.earnMoney(-offeredAmount);
receiver.earnMoney(offeredAmount);
receiver.earnMoney(-requestedAmount);
sender.earnMoney(requestedAmount);
// Transfer properties
if (offeredProperties != null) {
for (PropertyField property : offeredProperties) {
transferProperty(sender, receiver, property);
}
}
if (requestedProperties != null) {
for (PropertyField property : requestedProperties) {
transferProperty(receiver, sender, property);
}
}
// Transfer jail cards
transferJailCards(sender, receiver, offeredJailCards);
transferJailCards(receiver, sender, requestedJailCards);
}
/**
* Rejects the trade.
*/
public void rejectTrade() {
}
/**
* Validates the trade offer by checking ownership, balances, and jail cards.
*
* @return true if the trade is valid, false otherwise
*/
private boolean validateTrade() {
// Validate sender's ability to offer money
if (sender.getAccountBalance() < offeredAmount) {
return false;
}
// Validate receiver's ability to fulfill the requested amount
if (receiver.getAccountBalance() < requestedAmount) {
return false;
}
// Validate property ownership
if (offeredProperties != null) {
for (PropertyField property : offeredProperties) {
if (!sender.getProperties().contains(property)) {
return false;
}
}
}
if (requestedProperties != null) {
for (PropertyField property : requestedProperties) {
if (!receiver.getProperties().contains(property)) {
return false;
}
}
}
// Validate jail cards
if (sender.getNumJailCard() < offeredJailCards) {
return false;
}
if (receiver.getNumJailCard() < requestedJailCards) {
return false;
}
return true;
}
/**
* Transfers a property between players.
*
* @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);
}
/**
* 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();
}
}
public void setOfferedAmount(int offeredAmount) {
this.offeredAmount = offeredAmount;
}