Merge pull request #35 from rubenpirreram/main

Merge Main in RMI
This commit is contained in:
rubenpirreram
2026-04-19 17:17:56 +02:00
committed by GitHub
17 changed files with 774 additions and 33 deletions
@@ -7,26 +7,76 @@ import it.polimi.ingsw.gc14.Model.Player;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
public class BuildingCard extends PlayableCard implements Cloneable , BuildingEffect, Serializable { public class BuildingCard extends PlayableCard implements Cloneable , BuildingEffect, Serializable {
/**
* The price of this building card.
*/
private int price; private int price;
/**
* Returns the price of this building card.
*
* @return the price of this building card.
*/
public int getPrice() { public int getPrice() {
return price; return price;
} }
/**
* Indicates whether this building card has already been bought.
*/
private boolean bought; private boolean bought;
/**
* The type of effect associated with this building card.
*/
protected EffectType effectType; protected EffectType effectType;
/**
* The identifier of the effect associated with this building card.
*/
protected int effectId; protected int effectId;
/**
* The prestige value of this building card.
*/
private int prestigeValue; private int prestigeValue;
/**
* Returns the prestige value of this building card.
*
* @return the prestige value of this building card.
*/
public int getPrestigeValue() { public int getPrestigeValue() {
return prestigeValue; return prestigeValue;
} }
/**
* Returns the identifier of the effect associated with this building card.
*
* @return the effect identifier of this building card.
*/
public int getEffectId() { public int getEffectId() {
return effectId; return effectId;
} }
/**
* Returns the type of effect associated with this building card.
*
* @return the effect type of this building card.
*/
public EffectType getEffectType() { public EffectType getEffectType() {
return effectType; return effectType;
} }
/**
* Creates a building card with the specified era, price, and prestige value.
*
* @param era the era of the building card.
* @param price the price of the building card.
* @param prestigeValue the prestige value of the building card.
* @throws IllegalArgumentException if {@code price <= 0} or {@code prestigeValue < 0}
*/
protected BuildingCard(int era,int price,int prestigeValue) throws IllegalArgumentException{ protected BuildingCard(int era,int price,int prestigeValue) throws IllegalArgumentException{
super(era); super(era);
if (price > 0) { if (price > 0) {
@@ -42,6 +92,20 @@ public class BuildingCard extends PlayableCard implements Cloneable , BuildingEf
bought = false; bought = false;
} }
/**
* Creates a building card with the specified effect identifier, era, price,
* and prestige value.
* The effect type is determined from the given effect identifier.
*
* @param effectId the identifier of the effect associated with the building card.
* @param era the era of the building card.
* @param price the price of the building card.
* @param prestigeValue the prestige value of the building card.
* @throws IllegalArgumentException if the effect identifier is not valid,
* if {@code price <= 0}, or if {@code prestigeValue < 0}
*/
public BuildingCard(int effectId ,int era,int price,int prestigeValue) throws IllegalArgumentException{ public BuildingCard(int effectId ,int era,int price,int prestigeValue) throws IllegalArgumentException{
this.effectId = effectId; this.effectId = effectId;
switch (effectId){ switch (effectId){
@@ -73,12 +137,28 @@ public class BuildingCard extends PlayableCard implements Cloneable , BuildingEf
this(era,price,prestigeValue); this(era,price,prestigeValue);
} }
/**
* Creates and returns a copy of this building card.
*
* @return a clone of this building card.
*/
@Override @Override
public BuildingCard clone() public BuildingCard clone()
{ {
return new BuildingCard(effectId,getEra(),getPrice(),getPrestigeValue()); return new BuildingCard(effectId,getEra(),getPrice(),getPrestigeValue());
} }
/**
* Attempts to buy this building card for the specified player.
* The purchase succeeds only if the card has not already been bought
* and the player can pay its price in Food.
* If the purchase succeeds, the card is added to the player's building cards
* and marked as bought.
*
* @param player the player attempting to buy the building card.
* @return {@code true} if the building card is successfully bought,
* {@code false} otherwise.
*/
public boolean buy(Player player) { public boolean buy(Player player) {
if( bought || !player.removeFood(getPrice())) if( bought || !player.removeFood(getPrice()))
return false; return false;
@@ -86,8 +166,20 @@ public class BuildingCard extends PlayableCard implements Cloneable , BuildingEf
bought=true; bought=true;
return true; return true;
} }
/**
* Applies the effect of this building card to the specified player.
*
* @param player the player to whom the effect is applied.
*/
@Override
public void applyEffect(Player player){}; public void applyEffect(Player player){};
/**
* Returns the string representation of this building card.
*
* @return the string representation of this building card.
*/
@Override @Override
public String toString() { public String toString() {
return "Era:"+String.valueOf(getEra())+" Price:"+String.valueOf(getPrice())+" Prestige:"+String.valueOf(getPrestigeValue()); return "Era:"+String.valueOf(getEra())+" Price:"+String.valueOf(getPrice())+" Prestige:"+String.valueOf(getPrestigeValue());
@@ -2,27 +2,74 @@ package it.polimi.ingsw.gc14.Model.Cards;
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character;
import it.polimi.ingsw.gc14.Model.PlayableCard; import it.polimi.ingsw.gc14.Model.PlayableCard;
import java.io.Serializable; import java.io.Serializable;
/**
* Abstract base class for all tribe cards.
* A TribeCard is a {@link PlayableCard} that may either be an event card
* or a non-event card, and may optionally specify a minimum number of players.
*/
public abstract class TribeCard extends PlayableCard implements Serializable { public abstract class TribeCard extends PlayableCard implements Serializable {
/**
* Indicates whether this tribe card is an event card.
*/
private boolean isEventCard; private boolean isEventCard;
/**
* Returns whether this tribe card is an event card.
*
* @return {@code true} if this card is an event card, {@code false} otherwise.
*/
public boolean IsEventCard() { public boolean IsEventCard() {
return isEventCard; return isEventCard;
} }
/**
* The minimum number of players required for this tribe card.
*/
private int nMin=0; private int nMin=0;
/**
* Returns the minimum number of players required for this tribe card.
*
* @return the minimum number of players required for this tribe card.
*/
public int getNMin() { public int getNMin() {
return nMin; return nMin;
} }
/**
* Creates a tribe card with the specified era and event-card flag.
* The minimum number of players is set to 0.
*
* @param Era the era of the tribe card.
* @param isEventCard whether the card is an event card.
*/
public TribeCard(int Era,boolean isEventCard) { public TribeCard(int Era,boolean isEventCard) {
this(Era,isEventCard,0); this(Era,isEventCard,0);
} }
/**
* Creates a tribe card with the specified era, event-card flag,
* and minimum number of players.
*
* @param Era the era of the tribe card.
* @param isEventCard whether the card is an event card.
* @param nMin the minimum number of players required for the card.
*/
public TribeCard(int Era,boolean isEventCard,int nMin) { public TribeCard(int Era,boolean isEventCard,int nMin) {
super(Era); super(Era);
this.nMin=nMin; this.nMin=nMin;
this.isEventCard=isEventCard; this.isEventCard=isEventCard;
} }
/**
* Creates and returns a copy of this tribe card.
*
* @return a clone of this tribe card.
*/
@Override @Override
public abstract TribeCard clone(); public abstract TribeCard clone();
} }
@@ -3,29 +3,75 @@ package it.polimi.ingsw.gc14.Model.Cards.TribeCards;
import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard;
import it.polimi.ingsw.gc14.Model.Player; import it.polimi.ingsw.gc14.Model.Player;
/**
* Abstract base class for all character cards.
* A Character is a {@link TribeCard} that is not an event card and is associated.
* with a specific {@link CharacterType}.
*/
public abstract class Character extends TribeCard implements Cloneable { public abstract class Character extends TribeCard implements Cloneable {
/**
* The specific type of this character card.
*/
private CharacterType type; private CharacterType type;
/**
* Returns the type of this character card.
*
* @return the type of this character card.
*/
public CharacterType getType() { public CharacterType getType() {
return type; return type;
} }
/**
* Creates a character card with the specified era and character type.
*
* @param Era the era of the character card.
* @param type the type of the character card.
*/
public Character(int Era, CharacterType type){ public Character(int Era, CharacterType type){
super(Era,false ); super(Era,false );
this.type = type; this.type = type;
} }
/**
* Creates a character card with the specified era, character type,
* and minimum number of players.
*
* @param Era the era of the character card.
* @param type the type of the character card.
* @param nMin the minimum number of players required for the card.
*/
public Character(int Era, CharacterType type,int nMin){ public Character(int Era, CharacterType type,int nMin){
super(Era,false ,nMin); super(Era,false ,nMin);
this.type = type; this.type = type;
} }
/**
* Returns the string representation of this character card.
* The returned string includes the string representation of the superclass
* and the string representation of the character type.
*
* @return the string representation of this character card.
*/
@Override @Override
public String toString() { public String toString() {
return super.toString()+" "+type.toString(); return super.toString()+" "+type.toString();
} }
/**
* Creates and returns a copy of this character card.
*
* @return a clone of this character card.
*/
@Override @Override
public abstract Character clone(); public abstract Character clone();
/**
* Inserts this character card into the appropriate collection of the specified player.
*
* @param player the player who receives the character card.
*/
public abstract void insert(Player player); public abstract void insert(Player player);
} }
@@ -6,13 +6,37 @@ import it.polimi.ingsw.gc14.Model.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.lang.reflect.Array; import java.lang.reflect.Array;
/**
* Abstract base class for all event cards.
* An EventCard is a {@link TribeCard} marked as an event card and associated.
* with a specific {@link EventType}.
*/
public abstract class EventCard extends TribeCard { public abstract class EventCard extends TribeCard {
// Getters // Getters
/**
* The specific type of this event card.
*/
private EventType type; private EventType type;
/**
* Returns the type of this event card.
*
* @return the type of this event card.
*/
public EventType getType() { return type; } public EventType getType() { return type; }
// End getters // End getters
// Constructors // Constructors
/**
* Creates an event card with the specified era and event type.
*
* @param Era the era of the event card.
* @param type the type of the event card.
*/
public EventCard(int Era, EventType type) { public EventCard(int Era, EventType type) {
super(Era,true); super(Era,true);
this.type = type; this.type = type;
@@ -20,15 +44,34 @@ public abstract class EventCard extends TribeCard {
// End Constructors // End Constructors
// Function // Function
/**
* Creates and returns a copy of this event card.
*
* @return a clone of this event card.
*/
@Override @Override
public abstract TribeCard clone(); public abstract TribeCard clone();
/**
* Returns the string representation of this event card.
* The returned string includes the string representation of the superclass
* and the string representation of the event type.
*
* @return the string representation of this event card.
*/
@Override @Override
public String toString() { public String toString() {
return super.toString()+" "+type.toString(); return super.toString()+" "+type.toString();
} }
/**
* Activates the effect of this event card on the specified list of players.
*
* @param playerList the list of players affected by the event.
*/
public abstract void activateEvent (ArrayList <Player> playerList); public abstract void activateEvent (ArrayList <Player> playerList);
// End Functions // End Functions
} }
@@ -3,42 +3,110 @@ package it.polimi.ingsw.gc14.Model.GamePackage;
import it.polimi.ingsw.gc14.Model.Player; import it.polimi.ingsw.gc14.Model.Player;
import it.polimi.ingsw.gc14.Model.Slot; import it.polimi.ingsw.gc14.Model.Slot;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
import java.io.Serializable; import java.io.Serializable;
/**
* Represents the current state of the game.
* A CurrentState object stores the current player, slot, era, round,
* remaining upper and lower cards, and the current game stage.
*/
public class CurrentState implements Serializable { public class CurrentState implements Serializable {
// region Getters // region Getters
/**
* The current player associated with the game state.
*/
private Player player; private Player player;
/**
* Returns the current player.
*
* @return the current player.
*/
public Player getCurrentPlayer(){ public Player getCurrentPlayer(){
return player; return player;
} }
/**
* The current slot associated with the game state.
*/
private Slot slot; private Slot slot;
/**
* Returns the current slot.
*
* @return the current slot.
*/
public Slot getSlot(){ public Slot getSlot(){
return slot; return slot;
} }
/**
* The current era of the game.
*/
private int Era; private int Era;
/**
* Returns the current era of the game.
*
* @return the current era of the game.
*/
public int getEra(){ public int getEra(){
return Era; return Era;
} }
/**
* The current round of the game.
*/
private int round; private int round;
/**
* Returns the current round of the game.
*
* @return the current round of the game.
*/
public int getRound(){ public int getRound(){
return round; return round;
} }
/**
* The number of upper cards currently available.
*/
private int NUpper; private int NUpper;
/**
* Returns the number of upper cards currently available.
*
* @return the number of upper cards currently available.
*/
public int getNUpper(){ public int getNUpper(){
return NUpper; return NUpper;
} }
/**
* The number of lower cards currently available.
*/
private int NLower; private int NLower;
/**
* Returns the number of lower cards currently available.
*
* @return the number of lower cards currently available.
*/
public int getNLower(){ public int getNLower(){
return NLower; return NLower;
} }
/**
* The current stage of the game.
*/
private GameStages GameStage; private GameStages GameStage;
/**
* Returns the current stage of the game.
*
* @return the current stage of the game.
*/
public GameStages getGameStage(){ public GameStages getGameStage(){
return GameStage; return GameStage;
} }
@@ -46,28 +114,52 @@ public class CurrentState implements Serializable {
// endregion getters // endregion getters
// region Setters // region Setters
/**
* Increments the current era by 1.
*/
public void EraUpdate(){ public void EraUpdate(){
Era++; Era++;
} }
/**
* Increments the current round by 1.
*/
public void RoundUpdate(){ public void RoundUpdate(){
round++; round++;
} }
/**
* Decrements the number of upper cards by 1.
*/
public void UpperDrawn(){ public void UpperDrawn(){
NUpper--; NUpper--;
} }
/**
* Decrements the number of lower cards by 1.
*/
public void LowerDrawn(){ public void LowerDrawn(){
NLower--; NLower--;
} }
/**
* Updates the current game stage.
*
* @param GameStage the new game stage.
*/
public void GameStageUpdate(GameStages GameStage){ public void GameStageUpdate(GameStages GameStage){
this.GameStage = GameStage; this.GameStage = GameStage;
} }
// endregion setters // endregion setters
// region Constructors // region Constructors
/**
* Creates a new CurrentState object with default initial values.
* The initial player and slot are {@code null}, the era and round are set to 1,
* the number of upper and lower cards is set to 0, and the game stage is set to {@code WAITING}.
*/
public CurrentState(){ public CurrentState(){
this.player = null; this.player = null;
this.slot = null; this.slot = null;
@@ -80,6 +172,15 @@ public class CurrentState implements Serializable {
// endregion constructors // endregion constructors
// region Functions // region Functions
/**
* Updates the current player and slot.
* If the specified slot is {@code null}, the numbers of upper and lower cards are both set to 0.
* Otherwise, the numbers of upper and lower cards are updated using the values of the specified slot.
*
* @param player the new current player.
* @param slot the new current slot.
*/
public void PlayerUpdate(Player player, Slot slot){ public void PlayerUpdate(Player player, Slot slot){
this.player = player; this.player = player;
this.slot = slot; this.slot = slot;
@@ -5,25 +5,75 @@ import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
/**
* Abstract base class for all order logic cards.
* An OrderLogicCard manages a queue of players and defines the effects
* applied when players are pushed back into the queue.
*/
public abstract class OrderLogicCard implements Serializable { public abstract class OrderLogicCard implements Serializable {
/**
* The queue of players associated with this order logic card.
*/
private Queue<Player> players; private Queue<Player> players;
/**
* Creates an order logic card with the specified list of players.
* The input list is shuffled before being inserted into the queue.
*
* @param players the list of players associated with this order logic card.
*/
public OrderLogicCard(ArrayList<Player> players) { public OrderLogicCard(ArrayList<Player> players) {
Collections.shuffle(players); Collections.shuffle(players);
this.players = new LinkedList<>(players); this.players = new LinkedList<>(players);
} }
/**
* Applies the effect associated with the current queue position of the player
* and then adds the player to the end of the queue.
*
* @param player the player to be pushed into the queue.
*/
public void push(Player player){ public void push(Player player){
effect(player,players.size()); effect(player,players.size());
players.add(player); players.add(player);
} }
/**
* Removes and returns the first player in the queue.
*
* @return the first player in the queue, or {@code null} if the queue is empty.
*/
public Player pull(){ public Player pull(){
return players.poll(); return players.poll();
} }
/**
* Returns the first player in the queue without removing it.
*
* @return the first player in the queue, or {@code null} if the queue is empty.
*/
public Player getFirst() public Player getFirst()
{ {
return players.peek(); return players.peek();
} }
/**
* Applies the effect associated with the specified player and queue position.
*
* @param player the player to whom the effect is applied.
* @param index the queue position index associated with the effect.
* @throws IndexOutOfBoundsException if the specified index is not valid.
*/
protected abstract void effect(Player player, int index) throws IndexOutOfBoundsException; protected abstract void effect(Player player, int index) throws IndexOutOfBoundsException;
/**
* Applies the building-related effect to the specified player.
* For each building card owned by the player with effect id equal to 3,
* the player gains 1 Food.
*
* @param player the player to whom the building effect is applied.
*/
protected void buildingEffect(Player player) protected void buildingEffect(Player player)
{ {
for(BuildingCard b : player.buildingCards.stream().filter(x->x.getEffectId()==3).toList()) for(BuildingCard b : player.buildingCards.stream().filter(x->x.getEffectId()==3).toList())
@@ -1,12 +1,33 @@
package it.polimi.ingsw.gc14.Model; package it.polimi.ingsw.gc14.Model;
import java.io.Serializable; import java.io.Serializable;
/**
* Abstract base class for all playable cards.
* A PlayableCard is characterized by an era value.
*/
public abstract class PlayableCard implements Serializable { public abstract class PlayableCard implements Serializable {
/**
* The era associated with this playable card.
*/
private int Era; private int Era;
/**
* Returns the era of this playable card.
*
* @return the era of this playable card.
*/
public int getEra(){ public int getEra(){
return Era; return Era;
} }
/**
* Creates a playable card with the specified era.
*
* @param Era the era of the playable card.
* @throws IllegalArgumentException if {@code Era <= 0} or {@code Era >= 4}.
*/
public PlayableCard (int Era) throws IllegalArgumentException{ public PlayableCard (int Era) throws IllegalArgumentException{
if (Era>0 && Era<4) { if (Era>0 && Era<4) {
this.Era = Era; this.Era = Era;
@@ -15,6 +36,11 @@ public abstract class PlayableCard implements Serializable {
} }
} }
/**
* Returns the string representation of this playable card.
*
* @return the string representation of this playable card.
*/
@Override @Override
public String toString() { public String toString() {
return "Era:"+String.valueOf(Era); return "Era:"+String.valueOf(Era);
@@ -1,28 +1,80 @@
package it.polimi.ingsw.gc14.Model; package it.polimi.ingsw.gc14.Model;
import java.io.Serializable; import java.io.Serializable;
/**
* Represents a slot with a specific identifier and associated values
* for upper cards, lower cards, food, and minimum number of players.
* The slot configuration depends on the specified slot identifier.
*/
public class Slot implements Serializable { public class Slot implements Serializable {
// Getters // Getters
/**
* The identifier of this slot.
*/
private char slotId; private char slotId;
/**
* Returns the identifier of this slot.
*
* @return the identifier of this slot.
*/
public char getSlotId() { public char getSlotId() {
return slotId; return slotId;
} }
/**
* The number of upper cards associated with this slot.
*/
private int NUpper; private int NUpper;
/**
* Returns the number of upper cards associated with this slot.
*
* @return the number of upper cards associated with this slot.
*/
public int getNUpper(){ public int getNUpper(){
return NUpper; return NUpper;
} }
/**
* The minimum number of players required for this slot.
*/
private int nMinPlayer; private int nMinPlayer;
/**
* Returns the minimum number of players required for this slot.
*
* @return the minimum number of players required for this slot.
*/
public int getNMinPlayer() public int getNMinPlayer()
{ {
return nMinPlayer; return nMinPlayer;
} }
/**
* The number of lower cards associated with this slot.
*/
private int NLower; private int NLower;
/**
* Returns the number of lower cards associated with this slot.
*
* @return the number of lower cards associated with this slot.
*/
public int getNLower(){ public int getNLower(){
return NLower; return NLower;
} }
/**
* The amount of Food associated with this slot.
*/
private int Food; private int Food;
/**
* Returns the amount of Food associated with this slot.
*
* @return the amount of Food associated with this slot.
*/
public int getFood(){ public int getFood(){
return Food; return Food;
} }
@@ -30,7 +82,17 @@ public class Slot implements Serializable {
// Setters // Setters
// End setters // End setters
// Constructors // Constructors
/**
* Creates a slot with the specified identifier.
* The slot values for Food, NLower, NUpper, and minimum number of players
* are determined by the given slot identifier.
*
* @param slotId the identifier of the slot.
* @throws IllegalArgumentException if the specified slot identifier is not valid.
*/
public Slot(char slotId) throws IllegalArgumentException public Slot(char slotId) throws IllegalArgumentException
{ {
this.slotId = slotId; this.slotId = slotId;
@@ -80,6 +142,14 @@ public class Slot implements Serializable {
} }
} }
/**
* Returns the string representation of this slot.
* The returned string includes the slot identifier, number of upper cards,
* number of lower cards, food value, and minimum number of players.
*
* @return the string representation of this slot.
*/
@Override @Override
public String toString() { public String toString() {
return ("SlotID: "+this.getSlotId()+"\nNUpper: "+this.getNUpper()+"\nNLower: "+this.getNLower()+"\nFood: "+this.getFood()+"\nNMinPlayer: "+this.getNMinPlayer()+"\n"); return ("SlotID: "+this.getSlotId()+"\nNUpper: "+this.getNUpper()+"\nNLower: "+this.getNLower()+"\nFood: "+this.getFood()+"\nNMinPlayer: "+this.getNMinPlayer()+"\n");
@@ -0,0 +1,29 @@
package it.polimi.ingsw.gc14.Network.TCP.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import it.polimi.ingsw.gc14.View.IView;
import java.io.Serializable;
public class DrawLowerBuildingCard extends NetworkEvent implements Serializable{
private String username;
private EventType eventType;
private int pos;
public DrawLowerBuildingCard(String username, int pos){
this.username = username;
this.eventType = EventType.DRAW_LOWER_BUILD;
this.pos = pos;
}
@Override
public boolean apply(GameController gameController){
return gameController.drawLowerBuildingCard(username, pos);
}
public String apply(IView gameController){
return gameController.toString();
}
}
@@ -0,0 +1,29 @@
package it.polimi.ingsw.gc14.Network.TCP.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import it.polimi.ingsw.gc14.View.IView;
import java.io.Serializable;
public class DrawLowerTribeCard extends NetworkEvent implements Serializable{
private String username;
private EventType eventType;
private int pos;
public DrawLowerTribeCard(String username, int pos){
this.username = username;
this.eventType = EventType.DRAW_LOWER_TRIBE;
this.pos = pos;
}
@Override
public boolean apply(GameController gameController){
return gameController.drawLowerTribeCard(username, pos);
}
public String apply(IView gameController){
return gameController.toString();
}
}
@@ -0,0 +1,29 @@
package it.polimi.ingsw.gc14.Network.TCP.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import it.polimi.ingsw.gc14.View.IView;
import java.io.Serializable;
public class DrawUpperBuildingCard extends NetworkEvent implements Serializable{
private String username;
private EventType eventType;
private int pos;
public DrawUpperBuildingCard(String username, int pos){
this.username = username;
this.eventType = EventType.DRAW_UPPER_BUILD;
this.pos = pos;
}
@Override
public boolean apply(GameController gameController){
return gameController.drawUpperBuildingCard(username, pos);
}
public String apply(IView gameController){
return gameController.toString();
}
}
@@ -0,0 +1,29 @@
package it.polimi.ingsw.gc14.Network.TCP.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import it.polimi.ingsw.gc14.View.IView;
import java.io.Serializable;
public class DrawUpperTribeCard extends NetworkEvent implements Serializable{
private String username;
private EventType eventType;
private int pos;
public DrawUpperTribeCard(String username, int pos){
this.username = username;
this.eventType = EventType.DRAW_UPPER_TRIBE;
this.pos = pos;
}
@Override
public boolean apply(GameController gameController){
return gameController.drawUpperTribeCard(username, pos);
}
public String apply(IView gameController){
return gameController.toString();
}
}
@@ -0,0 +1,29 @@
package it.polimi.ingsw.gc14.Network.TCP.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import it.polimi.ingsw.gc14.View.IView;
import java.io.Serializable;
public class PickOptionalBuildingCard extends NetworkEvent implements Serializable{
private String username;
private EventType eventType;
private int pos;
public PickOptionalBuildingCard(String username, int pos){
this.username = username;
this.eventType = EventType.PICK_OPTIONAL_BUILD;
this.pos = pos;
}
@Override
public boolean apply(GameController gameController){
return gameController.pickOptionalBuildingCard(username, pos);
}
public String apply(IView gameController){
return gameController.toString();
}
}
@@ -0,0 +1,29 @@
package it.polimi.ingsw.gc14.Network.TCP.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import it.polimi.ingsw.gc14.View.IView;
import java.io.Serializable;
public class PickOptionalTribeCard extends NetworkEvent implements Serializable{
private String username;
private EventType eventType;
private int pos;
public PickOptionalTribeCard(String username, int pos){
this.username = username;
this.eventType = EventType.PICK_OPTIONAL_TRIBE;
this.pos = pos;
}
@Override
public boolean apply(GameController gameController){
return gameController.pickOptionalTribeCard(username, pos);
}
public String apply(IView gameController){
return gameController.toString();
}
}
@@ -0,0 +1,29 @@
package it.polimi.ingsw.gc14.Network.TCP.NetworkEvents;
import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import it.polimi.ingsw.gc14.View.IView;
import java.io.Serializable;
public class SlotChoice extends NetworkEvent implements Serializable{
private String username;
private EventType eventType;
private int pos;
public SlotChoice(String username, int pos){
this.username = username;
this.eventType = EventType.SLOT_CHOICE;
this.pos = pos;
}
@Override
public boolean apply(GameController gameController){
return gameController.slotChoice(username, pos);
}
public String apply(IView gameController){
return gameController.toString();
}
}
@@ -1,6 +1,8 @@
package it.polimi.ingsw.gc14.Network.TCP.Server; package it.polimi.ingsw.gc14.Network.TCP.Server;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.EventType;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
@@ -8,42 +10,67 @@ import java.util.List;
public class ClientHandler implements Runnable { public class ClientHandler implements Runnable {
private Socket clientSocket; private Socket clientSocket;
BufferedReader in = null; private TCPServer server;
PrintWriter out = null; public ObjectInputStream in = null;
public ObjectOutputStream out = null;
List<ClientHandler> clientHandlers; List<ClientHandler> clientHandlers;
GameController gameController; GameController gameController;
private EventType eventType;
public Socket getClientSocket() {
return clientSocket;
}
public ClientHandler(Socket clientSocket, List<ClientHandler> clientHandlers, GameController gameController) { public ClientHandler(Socket clientSocket, List<ClientHandler> clientHandlers, GameController gameController) {
this.clientSocket = clientSocket; this.clientSocket = clientSocket;
this.clientHandlers = clientHandlers; this.clientHandlers = clientHandlers;
this.gameController = gameController; this.gameController = gameController;
} }
@Override @Override
public void run(){ public void run(){
clientLoop(); clientLoop();
} }
private void clientLoop(){ private void clientLoop(){
try{ try{
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); NetworkEvent input = null;
synchronized (out) { synchronized(in){
out = new PrintWriter(clientSocket.getOutputStream(), true); in = new ObjectInputStream(clientSocket.getInputStream());
} }
} catch (IOException e) { while(true){
try{
input = (NetworkEvent)(in.readObject());
if(input.apply(gameController)){
server.broadcastUpdate(input);
}
}
catch(java.io.IOException e){
e.printStackTrace(); e.printStackTrace();
} }
String s = ""; catch (ClassNotFoundException e){
try{ throw new RuntimeException(e);
while ((s = in.readLine()) != null) { }
System.out.println(s);
out.println(s.toUpperCase());
} }
} }
catch (IOException e) { catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private void notifyEvent(Object event) {
public void notifyEvent(NetworkEvent event){
synchronized(out){ synchronized(out){
out.println(event.toString()); try{
out = new ObjectOutputStream(clientSocket.getOutputStream());
out.writeObject(gameController.getModel());
}
catch(IOException e){
e.printStackTrace();
} }
} }
} }
}
@@ -1,19 +1,27 @@
package it.polimi.ingsw.gc14.Network.TCP.Server; package it.polimi.ingsw.gc14.Network.TCP.Server;
import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Controller.GameController;
import it.polimi.ingsw.gc14.Network.TCP.NetworkEvent;
import java.io.IOException; import java.io.*;
import java.net.*; import java.net.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class TCPServer { public class TCPServer {
int port = -1; int port = -1;
int ConnectedPlayers = 0;
ServerSocket serverTCP = null; ServerSocket serverTCP = null;
GameController gameController; GameController gameController;
private List<ClientHandler> clientHandlers; private List<ClientHandler> clientHandlers;
private int getConnectedPlayers(){
return ConnectedPlayers;
}
public void start(String args[]){ public void start(String args[]){
clientHandlers = new ArrayList<>(); clientHandlers = new ArrayList<>();
@@ -25,20 +33,44 @@ public class TCPServer {
e.printStackTrace(); e.printStackTrace();
return; return;
} }
System.out.println("Listening on port " + port); System.out.println("Listening on port: " + port);
while(true){ while(true){
Socket clientSocket = null; Socket clientSocket = null;
try{ try{
clientSocket = serverTCP.accept(); clientSocket = serverTCP.accept();
} catch (IOException e) { if(!gameController.addPlayer(clientSocket.getInputStream().toString()) || ConnectedPlayers > gameController.getModel().getNPlayers()){
clientSocket.close();
System.out.println("Invalid parameters. Connection terminated.\n");
}
// gestione di ADD_PLAYER
}
catch (IOException e){
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Accepted"); System.out.println("Accepted player: " + gameController.getModel().getPlayerByUsername(clientSocket.getInetAddress().toString()));
ClientHandler clientHandler = new ClientHandler(clientSocket, clientHandlers, this.gameController);
ConnectedPlayers++;
ClientHandler clientHandler = new ClientHandler(clientSocket, clientHandlers, gameController);
clientHandlers.add(clientHandler); clientHandlers.add(clientHandler);
//Sending model to clients
if(ConnectedPlayers == gameController.getModel().getNPlayers()){
for (ClientHandler handler : clientHandlers) {
try {
synchronized(handler.out){
ObjectOutputStream socketTx = new ObjectOutputStream(handler.getClientSocket().getOutputStream());
socketTx.writeObject(gameController.getModel());
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
Thread t = new Thread(clientHandler); Thread t = new Thread(clientHandler);
t.start(); t.start();
} }
@@ -48,4 +80,8 @@ public class TCPServer {
this.port = port; this.port = port;
this.gameController = gameController; this.gameController = gameController;
} }
public void broadcastUpdate(NetworkEvent event){
clientHandlers.forEach((x) -> x.notifyEvent(event));
}
} }