mirror of
https://athene2.informatik.unibw-muenchen.de/progproj/gruppen-ht24/Gruppe-02.git
synced 2024-11-25 03:29:44 +01:00
Merge branch 'main' into 'Testhandbuch'
# Conflicts: # Projekte/monopoly/model/src/test/java/pp/monopoly/Testhandbuch.java
This commit is contained in:
commit
2496ad812a
@ -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'");
|
||||
}
|
||||
}
|
||||
|
@ -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<Void>{
|
||||
private final int id;
|
||||
private String name;
|
||||
private ColorRGBA color;
|
||||
private PlayerColor color;
|
||||
private int accountBalance = 0;
|
||||
private Figure figure;
|
||||
private List<PropertyField> 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<PropertyField> 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) {
|
||||
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) {
|
||||
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<Void>{
|
||||
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) {
|
||||
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<Integer> 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<Integer> 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 'visit'");
|
||||
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'");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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<Player> players = new LinkedList<>();
|
||||
private Set<Player> 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<Player> 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");
|
||||
}
|
||||
}
|
@ -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<Player> players = new ArrayList<>(2);
|
||||
private final Set<Player> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,22 @@
|
||||
package pp.monopoly.message.server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DiceResult extends ServerMessage{
|
||||
|
||||
private List<Integer> rollResult;
|
||||
|
||||
public DiceResult(List<Integer> rollResult) {
|
||||
this.rollResult = rollResult;
|
||||
}
|
||||
|
||||
public List<Integer> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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'");
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<PropertyField> 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<PropertyField> 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<PropertyField> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public int getAccountBalance() {
|
||||
return accountBalance;
|
||||
}
|
||||
|
||||
public int getJailCards() {
|
||||
return jailCards;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<PropertyField> offeredProperties,
|
||||
int offeredJailCards, int requestedAmount, List<PropertyField> 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<PropertyField> offeredProperties,
|
||||
int offeredJailCards, int requestedAmount, List<PropertyField> 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<PropertyField> offeredProperties, int offeredJailCards,
|
||||
Player receiver, int requestedAmount, List<PropertyField> 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());
|
||||
}
|
||||
}
|
@ -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<Field> createBoard() {
|
||||
private List<Field> board;
|
||||
|
||||
/**
|
||||
* Constructs a BoardManager
|
||||
*/
|
||||
public BoardManager() {
|
||||
board = createBoard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Monopoly GameBoard
|
||||
* @return the List of Fields in correct Order
|
||||
*/
|
||||
private static List<Field> createBoard() {
|
||||
ArrayList<Field> 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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -16,4 +16,8 @@ abstract class Field {
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -9,7 +9,7 @@ public class GateField extends PropertyField{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calcRent() {
|
||||
public int calcRent() {
|
||||
return rent;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -380,8 +380,6 @@ public class Testhandbuch {
|
||||
game.sendToJail(player);
|
||||
assertEquals(PlayerState.InJail, player.getState());
|
||||
}
|
||||
// T035
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,7 +120,7 @@ public class MonopolyServer implements MessageListener<HostedConnection>, 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
|
||||
|
Loading…
Reference in New Issue
Block a user