Merge branch 'main' into tests-fix
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
package it.polimi.ingsw.gc14;
|
||||||
|
import it.polimi.ingsw.gc14.Controller.ClientController;
|
||||||
|
import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
|
||||||
|
import it.polimi.ingsw.gc14.View.IView;
|
||||||
|
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class ClientLauncherTUI {
|
||||||
|
public void main() throws InterruptedException {
|
||||||
|
ClientController controller = new ClientController();
|
||||||
|
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
|
||||||
|
System.out.println("Selezionare nome utente: ");
|
||||||
|
String username = scanner.next();
|
||||||
|
System.out.println(username);
|
||||||
|
|
||||||
|
System.out.println("Selezionare numero di giocatori desiderato: ");
|
||||||
|
int proposedNumPlayers = scanner.nextInt();
|
||||||
|
System.out.println(proposedNumPlayers);
|
||||||
|
|
||||||
|
System.out.println("Selezionare RMI[0] o TCP[1]: ");
|
||||||
|
int networkType = scanner.nextInt();
|
||||||
|
System.out.println(networkType);
|
||||||
|
|
||||||
|
scanner.close();
|
||||||
|
|
||||||
|
if (networkType == 0) {
|
||||||
|
RMIClient client = new RMIClient("localhost", 1099);
|
||||||
|
if (client.connect(username, proposedNumPlayers, controller)) {
|
||||||
|
System.out.println("Succesfully connected to RMI server\n\n");
|
||||||
|
} else {
|
||||||
|
System.out.println("RMI connection refused\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
System.out.flush();
|
||||||
|
if (controller.localModel!=null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.sleep(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Model set\n\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else if (networkType == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@ import it.polimi.ingsw.gc14.View.IView;
|
|||||||
|
|
||||||
public class ClientController {
|
public class ClientController {
|
||||||
|
|
||||||
private Game localModel;
|
public Game localModel;
|
||||||
public GameController localController;
|
public GameController localController;
|
||||||
public final IView view;
|
public IView view=null;
|
||||||
|
|
||||||
public ClientController(IView view,Game localModel) {
|
public ClientController(IView view,Game localModel) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
@@ -16,12 +16,18 @@ public class ClientController {
|
|||||||
this.localController = new GameController(localModel);
|
this.localController = new GameController(localModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClientController() {
|
||||||
|
this.localController = new GameController(localModel);
|
||||||
|
}
|
||||||
|
|
||||||
public void setModel(Game model) {
|
public void setModel(Game model) {
|
||||||
this.localModel = model;
|
this.localModel = model;
|
||||||
localController.setModel(model);
|
localController.setModel(model);
|
||||||
localModel.addObserver((Observer) view); // registra la view come observer
|
// localModel.addObserver((Observer) view); // registra la view come observer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void onError(String message) {
|
public void onError(String message) {
|
||||||
view.showError(message);
|
view.showError(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package it.polimi.ingsw.gc14;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class LimitedList<T> extends ArrayList<T> {
|
||||||
|
private int limit;
|
||||||
|
private Runnable action;
|
||||||
|
|
||||||
|
public LimitedList(int limit, Runnable action) {
|
||||||
|
this.limit = limit;
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(T element) {
|
||||||
|
boolean result = super.add(element);
|
||||||
|
if (size() >= limit) {
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimit(int num) {
|
||||||
|
this.limit=num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLimit(){return limit;}
|
||||||
|
|
||||||
|
public void setAction(Runnable action) {
|
||||||
|
this.action=action;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,8 @@ package it.polimi.ingsw.gc14.Model.Cards.Building.Effects;
|
|||||||
|
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
|
import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character;
|
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
||||||
import it.polimi.ingsw.gc14.Model.Player;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* During the Sustenance Event, you have a discount of 1 food token on the total you
|
* During the Sustenance Event, you have a discount of 1 food token on the total you
|
||||||
@@ -47,4 +44,8 @@ public class Building1 extends BuildingCard {
|
|||||||
return new Building1(getEra(),getPrice(),getPrestigeValue(),getIcon());
|
return new Building1(getEra(),getPrice(),getPrestigeValue(),getIcon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " Icon: " + this.icon.toString().charAt(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
|||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
|
|
||||||
public class Building11 extends BuildingCard {
|
public class Building11 extends BuildingCard {
|
||||||
|
|
||||||
private CharacterType icon ;
|
private CharacterType icon ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,6 +15,7 @@ public class Building11 extends BuildingCard {
|
|||||||
* @return the CharacterType associated with this building card effect.
|
* @return the CharacterType associated with this building card effect.
|
||||||
*/
|
*/
|
||||||
public CharacterType getIcon() {return icon;}
|
public CharacterType getIcon() {return icon;}
|
||||||
|
|
||||||
private int PrestigeMul;
|
private int PrestigeMul;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,4 +67,9 @@ public class Building11 extends BuildingCard {
|
|||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
player.addPrestige(player.getNType(getIcon()) * this.getPrestigeMul());
|
player.addPrestige(player.getNType(getIcon()) * this.getPrestigeMul());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " Icon: " + this.icon.toString().charAt(0) + " MP: " + this.PrestigeMul;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -182,6 +182,6 @@ public class BuildingCard extends PlayableCard implements Cloneable , BuildingEf
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Era:"+String.valueOf(getEra())+" Price:"+String.valueOf(getPrice())+" Prestige:"+String.valueOf(getPrestigeValue());
|
return "⎕:" + " ID:" + String.valueOf(getEffectId())+ " $:"+String.valueOf(getPrice())+" PV:"+String.valueOf(getPrestigeValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,13 @@ public abstract class Character extends TribeCard implements Cloneable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString()+" "+type.toString();
|
return super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toStringBoard()
|
||||||
|
{
|
||||||
|
return super.toStringBoard()+" "+getType().toString()+" ";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -86,7 +86,15 @@ public class Builder extends Character
|
|||||||
* @return the string representation of this Builder card.
|
* @return the string representation of this Builder card.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() { return super.toString()+" Reduction Value: " + String.valueOf(reductionValue) + "\n Prestige Value: " + String.valueOf(prestigeValue); }
|
public String toString() {
|
||||||
|
return super.toString() + " RV:" + String.valueOf(reductionValue) + " PV:" + String.valueOf(prestigeValue);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toStringBoard()
|
||||||
|
{
|
||||||
|
return super.toStringBoard()+" "+ " RV:" + String.valueOf(reductionValue) + " PV:" + String.valueOf(prestigeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a copy of this Builder card.
|
* Creates and returns a copy of this Builder card.
|
||||||
|
|||||||
@@ -47,8 +47,21 @@ public class Hunter extends Character {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + "Icon: " + String.valueOf(icon);
|
String toPrint = super.toString();
|
||||||
|
if(this.icon){
|
||||||
|
toPrint += " I";
|
||||||
|
}
|
||||||
|
return toPrint;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
String toPrint = super.toStringBoard();
|
||||||
|
if(this.icon){
|
||||||
|
toPrint += " I";
|
||||||
|
}
|
||||||
|
return toPrint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a copy of this Hunter card.
|
* Creates and returns a copy of this Hunter card.
|
||||||
|
|||||||
@@ -52,7 +52,11 @@ public class Inventor extends Character {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " Symbol:" + String.valueOf(icon);
|
return super.toString() + " I_ID:" + String.valueOf(icon);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
return super.toStringBoard() + " I_ID:" + String.valueOf(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,8 +49,13 @@ public class Shaman extends Character {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + "Icon: " + String.valueOf(icon);
|
return super.toString() + " *:" + String.valueOf(icon);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
return super.toStringBoard() + " *:" + String.valueOf(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a copy of this Shaman card.
|
* Creates and returns a copy of this Shaman card.
|
||||||
|
|||||||
@@ -62,7 +62,11 @@ public abstract class EventCard extends TribeCard {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString()+", "+type.toString();
|
return super.toString()+" "+type.toString();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
return super.toString()+" "+type.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -85,4 +85,9 @@ public class CavePaintings extends EventCard {
|
|||||||
{
|
{
|
||||||
return new CavePaintings(getEra(), NLower, NPrestigeRem, NPrestigeMul) ;
|
return new CavePaintings(getEra(), NLower, NPrestigeRem, NPrestigeMul) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
return super.toString()+" 0-"+(NLower-1)+":"+NPrestigeRem+" "+NLower+"+:"+NPrestigeMul;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,5 +70,9 @@ public class Hunt extends EventCard {
|
|||||||
public EventCard clone() {
|
public EventCard clone() {
|
||||||
return new Hunt(getEra(), prestigeMultiplier);
|
return new Hunt(getEra(), prestigeMultiplier);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
return super.toString()+" 1F+"+prestigeMultiplier+"PP"+" X N Hunter";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -96,6 +96,9 @@ public class ShamanicRitual extends EventCard {
|
|||||||
public EventCard clone() {
|
public EventCard clone() {
|
||||||
return new ShamanicRitual(getEra(), prestigeToAdd, prestigeToRemove);
|
return new ShamanicRitual(getEra(), prestigeToAdd, prestigeToRemove);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
return super.toString()+" *>:"+prestigeToAdd+" *<:"+prestigeToRemove;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,4 +89,9 @@ public class Sustenance extends EventCard {
|
|||||||
public EventCard clone() {
|
public EventCard clone() {
|
||||||
return new Sustenance(getEra(), PrestigeDebt);
|
return new Sustenance(getEra(), PrestigeDebt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toStringBoard() {
|
||||||
|
return super.toString()+" -1F/-"+PrestigeDebt+"PP";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ import java.io.Serializable;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import it.polimi.ingsw.gc14.Network.Observer;
|
import it.polimi.ingsw.gc14.Network.Observer;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.BorderStyle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the main game model.
|
* Represents the main game model.
|
||||||
* A Game object stores the players, the current state of the match,
|
* A Game object stores the players, the current state of the match,
|
||||||
@@ -36,6 +39,15 @@ public class Game implements Serializable {
|
|||||||
o.update(this);
|
o.update(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of players participating in the game.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<Player> getPlayers() {
|
||||||
|
return playersList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current number of players.
|
* The current number of players.
|
||||||
*/
|
*/
|
||||||
@@ -746,4 +758,90 @@ public class Game implements Serializable {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
var table = new AsciiTable(BorderStyle.UNICODE, slotMap.size());
|
||||||
|
List<String> stringUp=new ArrayList<>();
|
||||||
|
List<String> stringEmpty=new ArrayList<>();
|
||||||
|
List<String> stringDown=new ArrayList<>();
|
||||||
|
for(Map.Entry<Slot,Player> entry:slotMap.entrySet())
|
||||||
|
{
|
||||||
|
stringEmpty.add(" ");
|
||||||
|
stringDown.add(entry.getKey().toStringTUI());
|
||||||
|
if(entry.getValue()!=null)
|
||||||
|
stringUp.add(entry.getValue().getUserName());
|
||||||
|
else
|
||||||
|
stringUp.add(" ");
|
||||||
|
}
|
||||||
|
table.addRow(stringUp);
|
||||||
|
table.addRow(stringEmpty);
|
||||||
|
table.addRow(stringDown);
|
||||||
|
|
||||||
|
List<String>lines=List.of(orderLogicCard.toString().split("\n"));
|
||||||
|
List<String> lines2=new ArrayList<>();
|
||||||
|
lines2.add("OFFER TRACK");
|
||||||
|
lines2.addAll(List.of(table.build().split("\n")));
|
||||||
|
|
||||||
|
String boardToString=AsciiTable.sideBySide(lines,lines2,1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var table2 = new AsciiTable(BorderStyle.UNICODE, Math.max(getUpperListTribeCards().size(),getLowerListTribeCards().size()));
|
||||||
|
List<String> stringUp2=new ArrayList<>();
|
||||||
|
List<String> stringDown2=new ArrayList<>();
|
||||||
|
for(int i=0;i<Math.max(getUpperListTribeCards().size(),getLowerListTribeCards().size());i++)
|
||||||
|
{
|
||||||
|
if(i<getUpperListTribeCards().size())
|
||||||
|
{
|
||||||
|
stringUp2.add(getUpperListTribeCards().get(i).toStringBoard());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stringUp2.add("");
|
||||||
|
}
|
||||||
|
if(i<getLowerListTribeCards().size())
|
||||||
|
{
|
||||||
|
stringDown2.add(getLowerListTribeCards().get(i).toStringBoard());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stringDown2.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table2.addRow(stringUp2);
|
||||||
|
table2.addRow(stringDown2);
|
||||||
|
|
||||||
|
var table3 = new AsciiTable(BorderStyle.UNICODE, Math.max(getUpperListBuilding().size(),getLowerListBuilding().size()));
|
||||||
|
List<String> stringUp3=new ArrayList<>();
|
||||||
|
List<String> stringDown3=new ArrayList<>();
|
||||||
|
for(int i=0;i<Math.max(getUpperListBuilding().size(),getLowerListBuilding().size());i++)
|
||||||
|
{
|
||||||
|
if(i<getUpperListBuilding().size())
|
||||||
|
{
|
||||||
|
stringUp3.add(getUpperListBuilding().get(i).toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stringUp3.add("-");
|
||||||
|
}
|
||||||
|
if(i<getLowerListBuilding().size())
|
||||||
|
{
|
||||||
|
stringDown3.add(getLowerListBuilding().get(i).toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stringDown3.add("-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table3.addRow(stringUp3);
|
||||||
|
table3.addRow(stringDown3);
|
||||||
|
|
||||||
|
String PlayerToString ="";
|
||||||
|
for(Player p:playersList)
|
||||||
|
{
|
||||||
|
PlayerToString+=p.toString()+"\n";
|
||||||
|
}
|
||||||
|
return PlayerToString+"\n"+ boardToString +"UPPERList\\LOWERList\n"+table2.build() + "\nBUILDING\n"+table3.build() + "\n";
|
||||||
|
//return s.toString()+"\n"++"\nOFFER TRACK\n"+ table.build()+"\n" ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,9 +111,9 @@ public class Board implements Serializable {
|
|||||||
ArrayList<BuildingCard> buildingDeck = new ArrayList<>(DecksCreator.loadBuildingDeckByEra(1));
|
ArrayList<BuildingCard> buildingDeck = new ArrayList<>(DecksCreator.loadBuildingDeckByEra(1));
|
||||||
Collections.shuffle(buildingDeck);
|
Collections.shuffle(buildingDeck);
|
||||||
if(nTotem==2)
|
if(nTotem==2)
|
||||||
upperListBuilding= buildingDeck.subList(0,1);
|
upperListBuilding = new ArrayList<>(buildingDeck.subList(0,1));
|
||||||
else
|
else
|
||||||
upperListBuilding= buildingDeck.subList(0,2);
|
upperListBuilding = new ArrayList<>(buildingDeck.subList(0,2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
package it.polimi.ingsw.gc14.Model;
|
package it.polimi.ingsw.gc14.Model;
|
||||||
|
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
||||||
|
import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.BorderStyle;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* The queue of players associated with this order logic card.
|
||||||
*/
|
*/
|
||||||
private Queue<Player> players;
|
protected Queue<Player> players;
|
||||||
|
protected List<OrderPlayer> playerList;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an order logic card with the specified list of players.
|
* Creates an order logic card with the specified list of players.
|
||||||
@@ -26,6 +27,8 @@ public abstract class OrderLogicCard implements Serializable {
|
|||||||
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);
|
||||||
|
|
||||||
|
this.playerList=new ArrayList<>(players.stream().map(x->new OrderPlayer(x,false)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +39,15 @@ public abstract class OrderLogicCard implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public void push(Player player){
|
public void push(Player player){
|
||||||
effect(player,players.size());
|
effect(player,players.size());
|
||||||
|
if(players.size()==0)
|
||||||
|
{
|
||||||
|
playerList=new ArrayList<>();
|
||||||
|
|
||||||
|
}
|
||||||
|
playerList.add(new OrderPlayer(player,false));
|
||||||
players.add(player);
|
players.add(player);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,6 +56,13 @@ public abstract class OrderLogicCard implements Serializable {
|
|||||||
* @return the first player in the queue, or {@code null} if the queue is empty.
|
* @return the first player in the queue, or {@code null} if the queue is empty.
|
||||||
*/
|
*/
|
||||||
public Player pull(){
|
public Player pull(){
|
||||||
|
for(OrderPlayer p:playerList){
|
||||||
|
if(p.played==false)
|
||||||
|
{
|
||||||
|
p.played=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return players.poll();
|
return players.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,4 +97,17 @@ public abstract class OrderLogicCard implements Serializable {
|
|||||||
for(BuildingCard b : player.buildingCards.stream().filter(x->x.getEffectId()==3).toList())
|
for(BuildingCard b : player.buildingCards.stream().filter(x->x.getEffectId()==3).toList())
|
||||||
player.addFood(1);
|
player.addFood(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int getPosition(String username)
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
for (Player p : players) {
|
||||||
|
if (p.getUserName().equals(username))
|
||||||
|
return pos;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ package it.polimi.ingsw.gc14.Model.Orders;
|
|||||||
|
|
||||||
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.BorderStyle;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
public class Order2 extends OrderLogicCard {
|
public class Order2 extends OrderLogicCard {
|
||||||
|
|
||||||
@@ -49,4 +52,35 @@ public class Order2 extends OrderLogicCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
|
||||||
|
var table = new AsciiTable(BorderStyle.UNICODE, 2);
|
||||||
|
List<String> stringUp=new ArrayList<>();
|
||||||
|
List<String> stringDown=new ArrayList<>();
|
||||||
|
for(int i=0;i<2;i++)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
playerList.get(i);
|
||||||
|
stringUp.add(i+". "+playerList.get(i).player.getUserName());
|
||||||
|
if(playerList.get(i).played)
|
||||||
|
stringDown.add(" Placed");
|
||||||
|
else
|
||||||
|
stringDown.add(" Not Placed");
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException e) {
|
||||||
|
stringUp.add("");
|
||||||
|
stringDown.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table.addRow(stringUp);
|
||||||
|
table.addRow(stringDown);
|
||||||
|
|
||||||
|
List<String> stringList=new ArrayList<>();
|
||||||
|
stringList.add("+1 Food");
|
||||||
|
stringList.add("-1 Food / -2 PP");
|
||||||
|
table.addRow(stringList);
|
||||||
|
return "TURN ORDER\n" + table.build() + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ package it.polimi.ingsw.gc14.Model.Orders;
|
|||||||
|
|
||||||
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.BorderStyle;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
public class Order3 extends OrderLogicCard {
|
public class Order3 extends OrderLogicCard {
|
||||||
@@ -49,4 +52,40 @@ public class Order3 extends OrderLogicCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
|
||||||
|
var table = new AsciiTable(BorderStyle.UNICODE, 3);
|
||||||
|
|
||||||
|
List<String> stringUp=new ArrayList<>();
|
||||||
|
List<String> stringDown=new ArrayList<>();
|
||||||
|
for(int i=0;i<3;i++)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
playerList.get(i);
|
||||||
|
stringUp.add(i+". "+playerList.get(i).player.getUserName());
|
||||||
|
if(playerList.get(i).played)
|
||||||
|
stringDown.add(" Placed");
|
||||||
|
else
|
||||||
|
stringDown.add(" Not Placed");
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException e) {
|
||||||
|
stringUp.add("");
|
||||||
|
stringDown.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table.addRow(stringUp);
|
||||||
|
table.addRow(stringDown);
|
||||||
|
|
||||||
|
List<String> stringList=new ArrayList<>();
|
||||||
|
|
||||||
|
stringList.add("+2 Food");
|
||||||
|
stringList.add("--");
|
||||||
|
stringList.add("-1 Food / -2 PP");
|
||||||
|
table.addRow(stringList);
|
||||||
|
|
||||||
|
|
||||||
|
return "TURN ORDER\n" + table.build() + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,11 @@ package it.polimi.ingsw.gc14.Model.Orders;
|
|||||||
|
|
||||||
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.BorderStyle;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
public class Order4 extends OrderLogicCard {
|
public class Order4 extends OrderLogicCard {
|
||||||
@@ -57,4 +60,37 @@ public class Order4 extends OrderLogicCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
|
||||||
|
var table = new AsciiTable(BorderStyle.UNICODE, 4);
|
||||||
|
List<String> stringUp=new ArrayList<>();
|
||||||
|
List<String> stringDown=new ArrayList<>();
|
||||||
|
for(int i=0;i<4;i++)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
playerList.get(i);
|
||||||
|
stringUp.add(i+". "+playerList.get(i).player.getUserName());
|
||||||
|
if(playerList.get(i).played)
|
||||||
|
stringDown.add(" Placed");
|
||||||
|
else
|
||||||
|
stringDown.add(" Not Placed");
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException e) {
|
||||||
|
stringUp.add("");
|
||||||
|
stringDown.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table.addRow(stringUp);
|
||||||
|
table.addRow(stringDown);
|
||||||
|
|
||||||
|
List<String> stringList=new ArrayList<>();
|
||||||
|
stringList.add("+2 Food");
|
||||||
|
stringList.add("+1 Food");
|
||||||
|
stringList.add("--");
|
||||||
|
stringList.add("-1 Food / -2 PP");
|
||||||
|
table.addRow(stringList);
|
||||||
|
return "TURN ORDER\n" + table.build() + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,11 @@ package it.polimi.ingsw.gc14.Model.Orders;
|
|||||||
|
|
||||||
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
import it.polimi.ingsw.gc14.Model.OrderLogicCard;
|
||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.BorderStyle;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
public class Order5 extends OrderLogicCard {
|
public class Order5 extends OrderLogicCard {
|
||||||
@@ -58,4 +61,38 @@ public class Order5 extends OrderLogicCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
|
||||||
|
var table = new AsciiTable(BorderStyle.UNICODE, 5);
|
||||||
|
List<String> stringUp=new ArrayList<>();
|
||||||
|
List<String> stringDown=new ArrayList<>();
|
||||||
|
for(int i=0;i<5;i++)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
playerList.get(i);
|
||||||
|
stringUp.add(i+". "+playerList.get(i).player.getUserName());
|
||||||
|
if(playerList.get(i).played)
|
||||||
|
stringDown.add(" Placed");
|
||||||
|
else
|
||||||
|
stringDown.add(" Not Placed");
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException e) {
|
||||||
|
stringUp.add("");
|
||||||
|
stringDown.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
table.addRow(stringUp);
|
||||||
|
table.addRow(stringDown);
|
||||||
|
|
||||||
|
List<String> stringList=new ArrayList<>();
|
||||||
|
stringList.add("+3 Food");
|
||||||
|
stringList.add("+1 Food");
|
||||||
|
stringList.add("--");
|
||||||
|
stringList.add("--");
|
||||||
|
stringList.add("-1 Food / -2 PP");
|
||||||
|
table.addRow(stringList);
|
||||||
|
return "TURN ORDER\n" + table.build() + "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package it.polimi.ingsw.gc14.Model.Orders;
|
||||||
|
|
||||||
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 class OrderPlayer{
|
||||||
|
public Player player;
|
||||||
|
public boolean played;
|
||||||
|
public OrderPlayer(Player player,boolean played){
|
||||||
|
this.player=player;
|
||||||
|
this.played=played;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return player.getUserName()+" "+played;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,10 @@ public abstract class PlayableCard implements Serializable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Era:"+String.valueOf(Era);
|
return "⎕:";
|
||||||
|
}
|
||||||
|
public String toStringBoard()
|
||||||
|
{
|
||||||
|
return "⎕:";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ package it.polimi.ingsw.gc14.Model;
|
|||||||
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.*;
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.*;
|
||||||
|
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static it.polimi.ingsw.gc14.View.TUI.BorderStyle.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Player class; contains all identifiers and methods needed.
|
* Default Player class; contains all identifiers and methods needed.
|
||||||
@@ -224,21 +228,91 @@ public class Player implements Serializable {
|
|||||||
// endregion constructors
|
// endregion constructors
|
||||||
|
|
||||||
// region Functions
|
// region Functions
|
||||||
// TODO tostring usr + food + prestige \n tab foreach(characters.cards + spazio)
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String toPrint = "";
|
int Last = 6;
|
||||||
toPrint = this.getUserName()
|
|
||||||
+ ":\n\tFood: " + this.getFoodValue()
|
var table = new AsciiTable(UNICODE, 1);
|
||||||
+ "\n\tPrestige: " + this.getPrestigeValue()
|
|
||||||
+ "\n\tArtists: " + this.artists.toString()
|
table.addHeader(this.getUserName());
|
||||||
+ "\n\tBuilders: " + this.builders.toString()
|
table.addRow("RESOURCES:");
|
||||||
+ "\n\tGatherers: " + this.gatherers.toString()
|
table.addRow("Food: " + this.getFoodValue());
|
||||||
+ "\n\tShamans: " + this.shamans.toString()
|
table.addSeparator();
|
||||||
+ "\n\tHunters: " + this.hunters.toString()
|
table.addRow("Prestige: " + this.getPrestigeValue());
|
||||||
+ "\n\tBuildings: "
|
|
||||||
+ this.buildingCards.toString();
|
if(!this.hunters.isEmpty()){
|
||||||
return toPrint;
|
Last = 6;
|
||||||
|
}
|
||||||
|
else if(!this.inventors.isEmpty()){
|
||||||
|
Last = 5;
|
||||||
|
}
|
||||||
|
else if(!this.shamans.isEmpty()){
|
||||||
|
Last = 4;
|
||||||
|
}
|
||||||
|
else if(!this.gatherers.isEmpty()){
|
||||||
|
Last = 3;
|
||||||
|
}
|
||||||
|
else if(!this.builders.isEmpty()){
|
||||||
|
Last = 2;
|
||||||
|
}
|
||||||
|
else if(!this.artists.isEmpty()){
|
||||||
|
Last = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Last = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Last == 0){
|
||||||
|
table.addSeparator();
|
||||||
|
}
|
||||||
|
table.addRow("CHARACTERS:");
|
||||||
|
if(!this.artists.isEmpty()){
|
||||||
|
if(Last == 1){
|
||||||
|
table.addSeparator();
|
||||||
|
}
|
||||||
|
table.addRow("Artists: " + this.artists.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.builders.isEmpty()){
|
||||||
|
if(Last == 2){
|
||||||
|
table.addSeparator();
|
||||||
|
}
|
||||||
|
table.addRow("Builders: " + this.builders.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.gatherers.isEmpty()){
|
||||||
|
if(Last == 3){
|
||||||
|
table.addSeparator();
|
||||||
|
}
|
||||||
|
table.addRow("Gatherers: " + this.gatherers.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.shamans.isEmpty()){
|
||||||
|
if(Last == 4){
|
||||||
|
table.addSeparator();
|
||||||
|
}
|
||||||
|
table.addRow("Shamans: " + this.shamans.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.inventors.isEmpty()){
|
||||||
|
if(Last == 5){
|
||||||
|
table.addSeparator();
|
||||||
|
}
|
||||||
|
table.addRow("Inventors: " + this.inventors.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!this.hunters.isEmpty()){
|
||||||
|
table.addSeparator();
|
||||||
|
table.addRow("Hunters: " + this.hunters.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
table.addRow("BUILDING CARDS:");
|
||||||
|
if(!this.buildingCards.isEmpty()){
|
||||||
|
table.addRow("Buildings: " + this.buildingCards.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return table.build();
|
||||||
}
|
}
|
||||||
// endregion functions
|
// endregion functions
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,25 @@ public class Slot implements Serializable {
|
|||||||
*/
|
*/
|
||||||
@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()+"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String toStringTUI()
|
||||||
|
{
|
||||||
|
StringBuilder s = new StringBuilder();
|
||||||
|
s.append(this.getSlotId()+" ");
|
||||||
|
for(int i=0;i<this.getNUpper();i++)
|
||||||
|
{
|
||||||
|
s.append("↑");
|
||||||
|
}
|
||||||
|
for(int i=0;i<this.getNLower();i++)
|
||||||
|
{
|
||||||
|
s.append("↓");
|
||||||
|
}
|
||||||
|
if(getFood()!=0)
|
||||||
|
s.append("+"+getFood()+" Food");
|
||||||
|
return s.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// End Constructors
|
// End Constructors
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package it.polimi.ingsw.gc14.Network;
|
package it.polimi.ingsw.gc14.Network;
|
||||||
|
|
||||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||||
import javafx.event.Event;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@@ -12,9 +11,23 @@ public abstract class NetworkEvent implements Serializable {
|
|||||||
}
|
}
|
||||||
protected EventType eventType;
|
protected EventType eventType;
|
||||||
public EventType getEventType() {return eventType;}
|
public EventType getEventType() {return eventType;}
|
||||||
protected NetworkEvent(String username, EventType eventType) {
|
protected boolean isError;
|
||||||
|
public boolean getIsError() {return isError;}
|
||||||
|
public void setIsError(boolean isError) {this.isError = isError;}
|
||||||
|
|
||||||
|
protected NetworkEvent(String username, EventType eventType, boolean isError) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.eventType = eventType;
|
this.eventType = eventType;
|
||||||
|
this.isError = isError;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if(isError) {
|
||||||
|
return ("ERROR: action " + eventType.toString());
|
||||||
|
} else {
|
||||||
|
return ("ACTION: action " + eventType.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean apply(GameController gameController);
|
public abstract boolean apply(GameController gameController);
|
||||||
|
|||||||
@@ -8,8 +8,13 @@ import it.polimi.ingsw.gc14.View.IView;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public class AddPlayer extends NetworkEvent implements Serializable {
|
public class AddPlayer extends NetworkEvent implements Serializable {
|
||||||
public AddPlayer(String username) {
|
private int proposedNPlayer;
|
||||||
super(username, EventType.ADD_PLAYER);
|
public int getProposedNPlayer() {
|
||||||
|
return proposedNPlayer;
|
||||||
|
}
|
||||||
|
public AddPlayer(String username, int proposedNPlayer) {
|
||||||
|
super(username, EventType.ADD_PLAYER, false);
|
||||||
|
this.proposedNPlayer = proposedNPlayer;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(GameController gameController)
|
public boolean apply(GameController gameController)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class DrawLowerBuildingCard extends NetworkEvent implements Serializable
|
|||||||
private int pos;
|
private int pos;
|
||||||
|
|
||||||
public DrawLowerBuildingCard(String username, int pos){
|
public DrawLowerBuildingCard(String username, int pos){
|
||||||
super(username, EventType.DRAW_LOWER_BUILD);
|
super(username, EventType.DRAW_LOWER_BUILD, false);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class DrawLowerTribeCard extends NetworkEvent implements Serializable{
|
|||||||
private int pos;
|
private int pos;
|
||||||
|
|
||||||
public DrawLowerTribeCard(String username, int pos){
|
public DrawLowerTribeCard(String username, int pos){
|
||||||
super(username, EventType.DRAW_LOWER_TRIBE);
|
super(username, EventType.DRAW_LOWER_TRIBE, false);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class DrawUpperBuildingCard extends NetworkEvent implements Serializable
|
|||||||
private int pos;
|
private int pos;
|
||||||
|
|
||||||
public DrawUpperBuildingCard(String username, int pos){
|
public DrawUpperBuildingCard(String username, int pos){
|
||||||
super(username, EventType.DRAW_UPPER_BUILD);
|
super(username, EventType.DRAW_UPPER_BUILD, false);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class DrawUpperTribeCard extends NetworkEvent implements Serializable{
|
|||||||
private int pos;
|
private int pos;
|
||||||
|
|
||||||
public DrawUpperTribeCard(String username, int pos){
|
public DrawUpperTribeCard(String username, int pos){
|
||||||
super(username, EventType.DRAW_UPPER_TRIBE);
|
super(username, EventType.DRAW_UPPER_TRIBE, false);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ public class PickOptionalBuildingCard extends NetworkEvent implements Serializa
|
|||||||
private int pos;
|
private int pos;
|
||||||
|
|
||||||
public PickOptionalBuildingCard(String username, int pos){
|
public PickOptionalBuildingCard(String username, int pos){
|
||||||
super(username, EventType.PICK_OPTIONAL_BUILD);
|
super(username, EventType.PICK_OPTIONAL_BUILD, false);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class PickOptionalTribeCard extends NetworkEvent implements Serializable
|
|||||||
private int pos;
|
private int pos;
|
||||||
|
|
||||||
public PickOptionalTribeCard(String username, int pos){
|
public PickOptionalTribeCard(String username, int pos){
|
||||||
super(username, EventType.PICK_OPTIONAL_TRIBE);
|
super(username, EventType.PICK_OPTIONAL_TRIBE, false);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class SlotChoice extends NetworkEvent implements Serializable {
|
|||||||
private int pos;
|
private int pos;
|
||||||
|
|
||||||
public SlotChoice(String username, int pos) {
|
public SlotChoice(String username, int pos) {
|
||||||
super(username, EventType.SLOT_CHOICE);
|
super(username, EventType.SLOT_CHOICE, false);
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,31 +5,57 @@ import it.polimi.ingsw.gc14.Model.Game;
|
|||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
|
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import java.rmi.server.UnicastRemoteObject;
|
import java.rmi.server.UnicastRemoteObject;
|
||||||
|
|
||||||
public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCallback {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RMI client callback implementation of {@link IClientCallback}.
|
||||||
|
* Receives notifications from the server and updates the client game model.
|
||||||
|
*/
|
||||||
|
public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCallback, Serializable {
|
||||||
|
|
||||||
|
/** The client controller used to apply events and update the model */
|
||||||
private final ClientController clientController;
|
private final ClientController clientController;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
* @param clientController the client controller
|
||||||
|
* @throws RemoteException if any RMI error occurs
|
||||||
|
*/
|
||||||
public ClientCallbackImpl(ClientController clientController) throws RemoteException {
|
public ClientCallbackImpl(ClientController clientController) throws RemoteException {
|
||||||
this.clientController = clientController;
|
this.clientController = clientController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the server when the game is initialized.
|
||||||
|
* Sets the client game model in the {@link ClientController}.
|
||||||
|
* @param model the initialized {@link Game} model
|
||||||
|
* @throws RemoteException if any RMI error occurs
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onGameInit(Game model) throws RemoteException {
|
public void onGameInit(Game model) throws RemoteException {
|
||||||
clientController.setModel(model); // setta il model
|
clientController.setModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the server when an action has been accepted.
|
||||||
|
* If the event contains an error, it is printed to the console.
|
||||||
|
* Otherwise, the event is applied to the local model.
|
||||||
|
* @param event the {@link NetworkEvent} sent by the server
|
||||||
|
* @throws RemoteException if any RMI error occurs
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onAction(NetworkEvent event) throws RemoteException {
|
public void onAction(NetworkEvent event) throws RemoteException {
|
||||||
event.apply(clientController.localController); // delega tutto al controller
|
if(event.getIsError()) {
|
||||||
//clientController.view.update(); TODO
|
System.out.println(event.toString());
|
||||||
|
} else {
|
||||||
|
event.apply(clientController.localController);
|
||||||
|
//clientController.view.update(); TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(String message) throws RemoteException {
|
|
||||||
clientController.onError(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,55 @@
|
|||||||
package it.polimi.ingsw.gc14.Network.RMI.Client;
|
package it.polimi.ingsw.gc14.Network.RMI.Client;
|
||||||
|
import java.rmi.RemoteException;
|
||||||
import java.rmi.registry.LocateRegistry;
|
import java.rmi.registry.LocateRegistry;
|
||||||
import java.rmi.registry.Registry;
|
import java.rmi.registry.Registry;
|
||||||
|
|
||||||
import it.polimi.ingsw.gc14.Controller.ClientController;
|
import it.polimi.ingsw.gc14.Controller.ClientController;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
|
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
|
||||||
import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer;
|
import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer;
|
||||||
|
|
||||||
public class RMIClient {
|
/**
|
||||||
|
* Client RMI. Uses the methods exposed by the server RMI.
|
||||||
|
*/
|
||||||
|
public class RMIClient {
|
||||||
|
|
||||||
|
/** The host address of the RMI server */
|
||||||
private final String host;
|
private final String host;
|
||||||
|
|
||||||
|
/** The port of the RMI server */
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
|
/** The remote stub used to call methods on the server */
|
||||||
private IGameServer stub;
|
private IGameServer stub;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
* @param host the host address of the RMI server
|
||||||
|
* @param port the port of the RMI server
|
||||||
|
*/
|
||||||
public RMIClient(String host, int port) {
|
public RMIClient(String host, int port) {
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean connect(String username,ClientController clientController) {
|
/**
|
||||||
// 1. Connettiti al registry
|
* Connects to the RMI server and attempts to join the game.
|
||||||
|
* Looks up the RMI registry to retrieve the {@link IGameServer} stub.
|
||||||
|
* Then, creates a {@link ClientCallbackImpl} and calls {@link RMIServer#joinGame(String, int, IClientCallback)}.
|
||||||
|
* @param username the player's username
|
||||||
|
* @param preferredInt the desired number of players
|
||||||
|
* @param clientController the client controller used to create the callback
|
||||||
|
* @return true if the player successfully joined the game, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean connect(String username,int preferredInt, ClientController clientController) {
|
||||||
try {
|
try {
|
||||||
Registry registry = LocateRegistry.getRegistry(host, port);
|
Registry registry = LocateRegistry.getRegistry(host, port);
|
||||||
|
|
||||||
// 2. Prendi lo stub del server
|
|
||||||
this.stub = (IGameServer) registry.lookup("RMIGameServer");
|
this.stub = (IGameServer) registry.lookup("RMIGameServer");
|
||||||
|
|
||||||
// 3. Crea il callback e registralo
|
|
||||||
ClientCallbackImpl callback = new ClientCallbackImpl(clientController);
|
ClientCallbackImpl callback = new ClientCallbackImpl(clientController);
|
||||||
|
|
||||||
if (!stub.joinGame(username, callback))
|
return stub.joinGame(username, preferredInt, callback);
|
||||||
{
|
|
||||||
stub = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -46,8 +58,12 @@ public class RMIClient {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
public void doEvent(NetworkEvent event) throws Exception {
|
* Sends a {@link NetworkEvent} to the server.
|
||||||
|
* @param event the event to send
|
||||||
|
* @throws RemoteException if any RMI error occurs
|
||||||
|
*/
|
||||||
|
public void doEvent(NetworkEvent event) throws RemoteException {
|
||||||
stub.doEvent(event);
|
stub.doEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package it.polimi.ingsw.gc14.Network.RMI.Common;
|
|||||||
import it.polimi.ingsw.gc14.Model.Game;
|
import it.polimi.ingsw.gc14.Model.Game;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.rmi.*;
|
import java.rmi.*;
|
||||||
|
|
||||||
public interface IClientCallback extends Remote {
|
public interface IClientCallback extends Remote, Serializable {
|
||||||
void onGameInit(Game model) throws RemoteException;
|
void onGameInit(Game model) throws RemoteException;
|
||||||
void onAction(NetworkEvent action) throws RemoteException;
|
void onAction(NetworkEvent action) throws RemoteException;
|
||||||
void onError(String message) throws RemoteException;
|
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ import java.rmi.*;
|
|||||||
|
|
||||||
public interface IGameServer extends Remote {
|
public interface IGameServer extends Remote {
|
||||||
|
|
||||||
boolean joinGame(String username, IClientCallback callback) throws RemoteException;
|
boolean joinGame(String username,int preferredInt, IClientCallback callback) throws RemoteException;
|
||||||
boolean doEvent(NetworkEvent event) throws RemoteException;
|
boolean doEvent(NetworkEvent event) throws RemoteException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package it.polimi.ingsw.gc14.Network.RMI.Server;
|
package it.polimi.ingsw.gc14.Network.RMI.Server;
|
||||||
|
|
||||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||||
|
import it.polimi.ingsw.gc14.LimitedList;
|
||||||
import it.polimi.ingsw.gc14.Model.Game;
|
import it.polimi.ingsw.gc14.Model.Game;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
|
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
|
||||||
@@ -14,77 +15,135 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
import java.rmi.*;
|
import java.rmi.*;
|
||||||
|
|
||||||
public class RMIServer implements IGameServer {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server RMI. Exposes a method to join the game and one to execute an event.
|
||||||
|
*/
|
||||||
|
public class RMIServer extends UnicastRemoteObject implements IGameServer {
|
||||||
|
|
||||||
|
/** Server game's controller */
|
||||||
private GameController controller;
|
private GameController controller;
|
||||||
|
|
||||||
|
/** Server game's model */
|
||||||
|
private Game model;
|
||||||
|
|
||||||
|
/** RMI registry */
|
||||||
private Registry registry;
|
private Registry registry;
|
||||||
|
|
||||||
|
/** RMI port */
|
||||||
private int nPort;
|
private int nPort;
|
||||||
|
|
||||||
|
/** Map containing the associations between a player's username and its callback */
|
||||||
private final Map<String, IClientCallback> clients = new ConcurrentHashMap<>();
|
private final Map<String, IClientCallback> clients = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/** Queue containing the events to be applied to the game model */
|
||||||
BlockingQueue<NetworkEvent> actionQueue;
|
BlockingQueue<NetworkEvent> actionQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List containing the usernames of joined players.
|
||||||
|
* {@link LimitedList}'s limit defines at which size the list calls its action. The limit can be set using {@link LimitedList#setLimit(int)}.
|
||||||
|
*/
|
||||||
|
private LimitedList<String> playerList;
|
||||||
|
|
||||||
// Costruttore
|
|
||||||
public RMIServer(GameController controller, int nPort, BlockingQueue<NetworkEvent> actionQueue) throws RemoteException {
|
/**
|
||||||
|
* Class constructor that initializes the attributes.
|
||||||
|
* @param controller The game controller
|
||||||
|
* @param nPort The RMI port
|
||||||
|
* @param actionQueue The action queue
|
||||||
|
* @param playerList The player's usernames list
|
||||||
|
* @throws RemoteException if an RMI error occurs
|
||||||
|
*/
|
||||||
|
public RMIServer(GameController controller, int nPort, BlockingQueue<NetworkEvent> actionQueue,LimitedList<String> playerList) throws RemoteException {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.nPort = nPort;
|
this.nPort = nPort;
|
||||||
this.actionQueue = actionQueue;
|
this.actionQueue = actionQueue;
|
||||||
|
this.playerList = playerList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// RMI's exposed methods
|
||||||
|
/**
|
||||||
// Metodi esposti RMI
|
* Allows a player to join the game.
|
||||||
public void setController (GameController controller) {
|
* If the desired number of player is invalid, the request is rejected.
|
||||||
this.controller = controller;
|
* If this is the first player, a new game model is created and passed to the controller. Additionally, the playerList's limit is set.
|
||||||
}
|
* Then, if the controller successfully adds the player, the username is added to {@link #playerList} and {@link #clients}.
|
||||||
|
* @param username The player's name
|
||||||
|
* @param preferredInt The desired number of players
|
||||||
|
* @param callback The client's callback interface
|
||||||
|
* @return true if the player successfully joined the game, false otherwise
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean joinGame(String username, IClientCallback callback) {
|
public boolean joinGame(String username, int preferredInt, IClientCallback callback) {
|
||||||
if(controller.addPlayer(username))
|
if (preferredInt<2 || preferredInt>5) {
|
||||||
{
|
return false;
|
||||||
clients.put(username, callback);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
synchronized (controller) {
|
||||||
|
if(playerList.isEmpty()){
|
||||||
|
model = new Game(preferredInt);
|
||||||
|
controller.setModel(model);
|
||||||
|
playerList.setLimit(preferredInt);
|
||||||
|
}
|
||||||
|
if (controller.addPlayer(username)) {
|
||||||
|
clients.put(username, callback);
|
||||||
|
playerList.add(username);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push an action in actionQueue.
|
||||||
|
* @param action The desired actio
|
||||||
|
* @return true if the action was successfully added, false otherwise
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean doEvent(NetworkEvent event) throws RemoteException {
|
public boolean doEvent(NetworkEvent action) {
|
||||||
return actionQueue.offer(event);
|
return actionQueue.offer(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// RMI's internal methods
|
||||||
|
/**
|
||||||
// Metodi interni del server
|
* Sends an action to all RMI clients.
|
||||||
|
* @param action The desired action
|
||||||
|
*/
|
||||||
public void notifyAll(NetworkEvent action) throws RemoteException {
|
public void notifyAll(NetworkEvent action) throws RemoteException {
|
||||||
for (IClientCallback cb : clients.values()) {
|
for (IClientCallback cb : clients.values()) {
|
||||||
cb.onAction(action);
|
cb.onAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a game model to all RMI clients.
|
||||||
|
* @param model The desired model
|
||||||
|
*/
|
||||||
public void notifyAll(Game model) throws RemoteException {
|
public void notifyAll(Game model) throws RemoteException {
|
||||||
for (IClientCallback cb : clients.values()) {
|
for (IClientCallback cb : clients.values()) {
|
||||||
cb.onGameInit(model);
|
cb.onGameInit(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void notifyError(String username, String message) throws RemoteException {
|
|
||||||
IClientCallback cb = clients.get(username);
|
|
||||||
if (cb != null) cb.onError(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Metodi per avviare server RMI
|
// Metodi per avviare server RMI
|
||||||
|
/**
|
||||||
|
* Starts the RMI server.
|
||||||
|
* @return true if the server starts successfully, false otherwise
|
||||||
|
*/
|
||||||
public boolean start() {
|
public boolean start() {
|
||||||
try {
|
try {
|
||||||
registry = LocateRegistry.createRegistry(nPort);
|
registry = LocateRegistry.createRegistry(nPort);
|
||||||
registry.rebind("RMIGameServer", this);
|
registry.rebind("RMIGameServer", this);
|
||||||
System.out.println("RMI Server avviato sulla porta "+nPort);
|
System.out.println("RMI Server started on port: "+nPort);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
@@ -92,6 +151,12 @@ public class RMIServer implements IGameServer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the RMI server.
|
||||||
|
* @return true if the server stops successfully, false otherwise
|
||||||
|
*/
|
||||||
public boolean stop() {
|
public boolean stop() {
|
||||||
try {
|
try {
|
||||||
registry.unbind("RMIGameServer");
|
registry.unbind("RMIGameServer");
|
||||||
|
|||||||
@@ -1,70 +1,118 @@
|
|||||||
package it.polimi.ingsw.gc14.Network.TCP.Client;
|
package it.polimi.ingsw.gc14.Network.TCP.Client;
|
||||||
|
|
||||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||||
|
import it.polimi.ingsw.gc14.Model.Game;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvents.AddPlayer;
|
import it.polimi.ingsw.gc14.Network.NetworkEvents.AddPlayer;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
|
||||||
public class TCPClient implements Serializable{
|
/**
|
||||||
Socket communicationSocket = null;
|
* Client TCP. Sends and receives messages with the TCP server.
|
||||||
|
*/
|
||||||
|
public class TCPClient {
|
||||||
|
|
||||||
|
/** Socket TCP */
|
||||||
|
Socket communicationSocket;
|
||||||
|
|
||||||
|
/** Input stream used receive objects from the server */
|
||||||
ObjectInputStream socketReceive;
|
ObjectInputStream socketReceive;
|
||||||
|
|
||||||
|
/** Output stream used to send objects to the server */
|
||||||
ObjectOutputStream socketSend;
|
ObjectOutputStream socketSend;
|
||||||
|
|
||||||
|
/** Client game's controller */
|
||||||
GameController controller;
|
GameController controller;
|
||||||
|
|
||||||
|
/** IP address of the server to connect to */
|
||||||
String hostname;
|
String hostname;
|
||||||
|
|
||||||
|
/** TCP port */
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
public TCPClient(GameController controller, String hostname, int port){
|
|
||||||
|
/**
|
||||||
|
* Class constructor that initializes the attributes.
|
||||||
|
* @param controller The game controller
|
||||||
|
* @param hostname The IP address of the server
|
||||||
|
* @param port The TCP port of the server
|
||||||
|
*/
|
||||||
|
public TCPClient(GameController controller, String hostname, int port) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean start(String user){
|
|
||||||
try{
|
/**
|
||||||
|
* Starts the TCP connection with the server.
|
||||||
|
* Sends an {@link AddPlayer} event, if the server responds with {@code -1}, the connection is refused and the method returns {@code false}.
|
||||||
|
* Otherwise, a listener thread is started.
|
||||||
|
* @param user The username of the player
|
||||||
|
* @param proposedNPlayers The desired number of players for the game
|
||||||
|
* @return true if the connection is successful, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean start(String user, int proposedNPlayers) {
|
||||||
|
try {
|
||||||
communicationSocket = new Socket(hostname, port);
|
communicationSocket = new Socket(hostname, port);
|
||||||
socketSend = new ObjectOutputStream(communicationSocket.getOutputStream());
|
socketSend = new ObjectOutputStream(communicationSocket.getOutputStream());
|
||||||
socketReceive = new ObjectInputStream(communicationSocket.getInputStream());
|
socketReceive = new ObjectInputStream(communicationSocket.getInputStream());
|
||||||
|
|
||||||
socketSend.writeObject(new AddPlayer(user));
|
sendEvent(new AddPlayer(user, proposedNPlayers));
|
||||||
if(communicationSocket.getInputStream().read() == -1){
|
if (communicationSocket.getInputStream().read() == -1) {
|
||||||
|
System.out.println("Could not connect to server");
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
else{
|
Thread listener = new Thread(() -> receiveMessage());
|
||||||
Thread listener = new Thread(() -> ReceiveMessage());
|
|
||||||
listener.start();
|
listener.start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch(Exception e){
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReceiveMessage(){
|
|
||||||
while(true){
|
/**
|
||||||
try{
|
* Listens continuously for incoming objects from the server.
|
||||||
((NetworkEvent)(socketReceive.readObject())).apply(controller);
|
* - If the received object is a {@link NetworkEvent} flagged as an error, it is printed.
|
||||||
}
|
* - If the received object is a valid {@link NetworkEvent}, it is applied to the game controller.
|
||||||
catch(IOException e){
|
* - If the received object is a {@link Game} model, the controller's model is set.
|
||||||
|
*/
|
||||||
|
private void receiveMessage() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Object read = socketReceive.readObject();
|
||||||
|
if (read instanceof NetworkEvent event) { //TODO: avoid instanceof
|
||||||
|
if (event.getIsError()) {
|
||||||
|
System.out.println(event);
|
||||||
|
} else {
|
||||||
|
event.apply(controller);
|
||||||
|
//clientController.view.update(); TODO
|
||||||
|
}
|
||||||
|
} else if (read instanceof Game model) {
|
||||||
|
controller.setModel(model);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
} catch (ClassNotFoundException e) {
|
||||||
catch(ClassNotFoundException e){
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendEvent(NetworkEvent event){
|
|
||||||
try{
|
/**
|
||||||
|
* Sends a {@link NetworkEvent} to the server.
|
||||||
|
* @param event The NetworkEvent to send.
|
||||||
|
*/
|
||||||
|
private void sendEvent(NetworkEvent event) {
|
||||||
|
try {
|
||||||
socketSend.writeObject(event);
|
socketSend.writeObject(event);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
@@ -1,76 +1,105 @@
|
|||||||
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.Model.Game;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
import it.polimi.ingsw.gc14.Network.EventType;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the TCP connection with a single client.
|
||||||
|
* Each instance runs on a dedicated thread and is responsible for receiving {@link NetworkEvent} from its client and adding them
|
||||||
|
* to the {@link #actionQueue}.
|
||||||
|
* It is also responsible to send events and game model updates back to the client.
|
||||||
|
*/
|
||||||
public class ClientHandler implements Runnable {
|
public class ClientHandler implements Runnable {
|
||||||
|
|
||||||
|
/** The TCP socket */
|
||||||
private Socket clientSocket;
|
private Socket clientSocket;
|
||||||
private TCPServer server;
|
|
||||||
public ObjectInputStream in = null;
|
/** Input stream used to receive objects from the client */
|
||||||
public ObjectOutputStream out = null;
|
public ObjectInputStream in;
|
||||||
|
|
||||||
|
/** Output stream used to send objects to the client */
|
||||||
|
public ObjectOutputStream out;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared list of all client handlers.
|
||||||
|
* This handler removes itself from the list when disconnected.
|
||||||
|
*/
|
||||||
List<ClientHandler> clientHandlers;
|
List<ClientHandler> clientHandlers;
|
||||||
GameController gameController;
|
|
||||||
private EventType eventType;
|
|
||||||
|
|
||||||
public Socket getClientSocket() {
|
/** Queue containing the events to be applied to the game model */
|
||||||
return clientSocket;
|
BlockingQueue<NetworkEvent> actionQueue;
|
||||||
}
|
|
||||||
|
|
||||||
public ClientHandler(Socket clientSocket, List<ClientHandler> clientHandlers, GameController gameController) {
|
|
||||||
|
/**
|
||||||
|
* Class constructor that initializes the attributes.
|
||||||
|
* @param clientSocket The socket representing the client's TCP connection
|
||||||
|
* @param clientHandlers The shared list of all active client handlers
|
||||||
|
* @param actionQueue The queue containing incoming events
|
||||||
|
*/
|
||||||
|
public ClientHandler(Socket clientSocket, List<ClientHandler> clientHandlers, BlockingQueue<NetworkEvent> actionQueue) {
|
||||||
this.clientSocket = clientSocket;
|
this.clientSocket = clientSocket;
|
||||||
this.clientHandlers = clientHandlers;
|
this.clientHandlers = clientHandlers;
|
||||||
this.gameController = gameController;
|
this.actionQueue = actionQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for incoming {@link NetworkEvent}s from the client and adds them to the {@link #actionQueue}.
|
||||||
|
* Upon disconnection, this handler removes itself from {@link #clientHandlers}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run(){
|
public void run() {
|
||||||
clientLoop();
|
try {
|
||||||
}
|
in = new ObjectInputStream(clientSocket.getInputStream());
|
||||||
|
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
||||||
private void clientLoop(){
|
while (true) {
|
||||||
try{
|
NetworkEvent event = (NetworkEvent) in.readObject();
|
||||||
NetworkEvent input = null;
|
if (!actionQueue.add(event)) {
|
||||||
synchronized(in){
|
System.out.println("Error inserting action into queue");
|
||||||
in = new ObjectInputStream(clientSocket.getInputStream());
|
}
|
||||||
}
|
}
|
||||||
while(true){
|
} catch (IOException e) {
|
||||||
try{
|
clientHandlers.remove(this);
|
||||||
input = (NetworkEvent) (in.readObject());
|
|
||||||
if(input.apply(gameController)){
|
|
||||||
server.broadcastUpdate(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(java.io.IOException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyEvent(NetworkEvent event){
|
|
||||||
synchronized(out){
|
/**
|
||||||
try{
|
* Sends a {@link NetworkEvent} to the client.
|
||||||
|
* @param event The network event to send to the client.
|
||||||
|
*/
|
||||||
|
public void notifyEvent(NetworkEvent event) {
|
||||||
|
synchronized (out) {
|
||||||
|
try {
|
||||||
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
||||||
out.writeObject(gameController.getModel());
|
out.writeObject(event);
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch(IOException e){
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the current game model to this client.
|
||||||
|
* @param game The current state of the game to send to the client.
|
||||||
|
*/
|
||||||
|
public void notifyModel(Game game) {
|
||||||
|
synchronized (out) {
|
||||||
|
try {
|
||||||
|
out = new ObjectOutputStream(clientSocket.getOutputStream());
|
||||||
|
out.writeObject(game);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
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.LimitedList;
|
||||||
|
import it.polimi.ingsw.gc14.Model.Game;
|
||||||
|
import it.polimi.ingsw.gc14.Network.EventType;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
|
import it.polimi.ingsw.gc14.Network.NetworkEvents.AddPlayer;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
@@ -9,86 +13,139 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server TCP. Accepts connections and manages all client handlers.
|
||||||
|
*/
|
||||||
public class TCPServer {
|
public class TCPServer {
|
||||||
int port = -1;
|
|
||||||
int ConnectedPlayers = 0;
|
/** TCP port */
|
||||||
ServerSocket serverTCP = null;
|
int port;
|
||||||
GameController gameController;
|
|
||||||
|
/** Number of currently connected clients */
|
||||||
|
int ConnectedPlayers;
|
||||||
|
|
||||||
|
/** Socket TCP */
|
||||||
|
ServerSocket socketTCP;
|
||||||
|
|
||||||
|
/** Server game's controller */
|
||||||
|
GameController controller;
|
||||||
|
|
||||||
|
/** Queue containing the events to be applied to the game model */
|
||||||
BlockingQueue<NetworkEvent> actionQueue;
|
BlockingQueue<NetworkEvent> actionQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List containing the usernames of joined players.
|
||||||
|
* {@link LimitedList}'s limit defines at which size the list calls its action. The limit can be set using {@link LimitedList#setLimit(int)}.
|
||||||
|
*/
|
||||||
|
private LimitedList<String> playerList;
|
||||||
|
|
||||||
|
/** List containing all client's handlers */
|
||||||
private List<ClientHandler> clientHandlers;
|
private List<ClientHandler> clientHandlers;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
private int getConnectedPlayers(){
|
* Class constructor that initializes the attributes.
|
||||||
return ConnectedPlayers;
|
* @param controller The game controller
|
||||||
|
* @param port The TCP port
|
||||||
|
* @param actionQueue The action queue
|
||||||
|
* @param playerList The player's usernames list
|
||||||
|
*/
|
||||||
|
public TCPServer(GameController controller, int port, BlockingQueue<NetworkEvent> actionQueue, LimitedList<String> playerList){
|
||||||
|
this.port = port;
|
||||||
|
this.ConnectedPlayers = 0;
|
||||||
|
this.socketTCP = null;
|
||||||
|
this.controller = controller;
|
||||||
|
this.actionQueue = actionQueue;
|
||||||
|
this.playerList = playerList;
|
||||||
|
this.clientHandlers = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the TCP server.
|
||||||
|
* If the first event is not AddPlayer, the request is rejected.
|
||||||
|
* If the desired number of player is invalid, the request is rejected.
|
||||||
|
*
|
||||||
|
* If this is the first player to connect, a new game model is created and passed to the controller. Additionally, the playerList's limit is set.
|
||||||
|
* If the controller successfully adds the player, the username is added to {@link #playerList} and the handler is added to {@link #clientHandlers}.
|
||||||
|
*
|
||||||
|
* If any error occurs, the server sends -1 back to the client. Otherwise, it sends 1.
|
||||||
|
*/
|
||||||
public void start(){
|
public void start(){
|
||||||
clientHandlers = new ArrayList<>();
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
serverTCP = new ServerSocket(port);
|
socketTCP = new ServerSocket(port);
|
||||||
}
|
}
|
||||||
catch (IOException e){
|
catch (IOException e){
|
||||||
System.out.println("Could not listen on port: " + port);
|
System.out.println("Could not start the server TCP on port: " + port);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.out.println("Listening on port: " + port);
|
System.out.println("Server TCP started on port: " + port);
|
||||||
|
Socket clientSocket;
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
Socket clientSocket = null;
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
clientSocket = serverTCP.accept();
|
clientSocket = socketTCP.accept();
|
||||||
if(!gameController.addPlayer(clientSocket.getInputStream().toString()) || ConnectedPlayers > gameController.getModel().getNPlayers()){
|
ObjectInputStream clientSocketObj = new ObjectInputStream(clientSocket.getInputStream());
|
||||||
|
NetworkEvent event = (NetworkEvent) clientSocketObj.readObject();
|
||||||
|
|
||||||
|
if(!(event.getEventType() == EventType.ADD_PLAYER)){
|
||||||
clientSocket.getOutputStream().write((int)(-1));
|
clientSocket.getOutputStream().write((int)(-1));
|
||||||
clientSocket.close();
|
clientSocket.close();
|
||||||
System.out.println("Invalid parameters. Connection terminated.\n");
|
System.out.println("Invalid parameters. Connection terminated.\n");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
clientSocket.getOutputStream().write((int)(1));
|
AddPlayer eventAddPlayer = (AddPlayer) event;
|
||||||
}
|
if (eventAddPlayer.getProposedNPlayer() < 2 || eventAddPlayer.getProposedNPlayer() > 5) {
|
||||||
// gestione di ADD_PLAYER
|
clientSocket.getOutputStream().write((int) (-1));
|
||||||
}
|
clientSocket.close();
|
||||||
catch (IOException e){
|
System.out.println("Invalid parameters. Connection terminated.\n");
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
synchronized (controller) {
|
||||||
|
if (playerList.isEmpty()){
|
||||||
|
Game model = new Game(eventAddPlayer.getProposedNPlayer());
|
||||||
|
controller.setModel(model);
|
||||||
|
playerList.setLimit(eventAddPlayer.getProposedNPlayer());
|
||||||
|
}
|
||||||
|
if (controller.addPlayer(eventAddPlayer.getUsername())) {
|
||||||
|
playerList.add(eventAddPlayer.getUsername());
|
||||||
|
clientSocket.getOutputStream().write((int) (1));
|
||||||
|
|
||||||
System.out.println("Accepted player: " + gameController.getModel().getPlayerByUsername(clientSocket.getInetAddress().toString()));
|
System.out.println("Accepted player: " + eventAddPlayer.getUsername());
|
||||||
|
ClientHandler clientHandler = new ClientHandler(clientSocket, clientHandlers, actionQueue);
|
||||||
|
clientHandlers.add(clientHandler);
|
||||||
|
ConnectedPlayers++;
|
||||||
|
|
||||||
ConnectedPlayers++;
|
Thread t = new Thread(clientHandler);
|
||||||
ClientHandler clientHandler = new ClientHandler(clientSocket, clientHandlers, gameController);
|
t.start();
|
||||||
clientHandlers.add(clientHandler);
|
} else {
|
||||||
|
clientSocket.getOutputStream().write((int) (-1));
|
||||||
//Sending model to clients
|
clientSocket.close();
|
||||||
if(ConnectedPlayers == gameController.getModel().getNPlayers()){
|
System.out.println("Player could not be added. Connection terminated.\n");
|
||||||
for (ClientHandler handler : clientHandlers) {
|
|
||||||
try {
|
|
||||||
synchronized(handler.out){
|
|
||||||
ObjectOutputStream socketTx = new ObjectOutputStream(handler.getClientSocket().getOutputStream());
|
|
||||||
socketTx.writeObject(gameController.getModel());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(IOException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(IOException e){
|
||||||
Thread t = new Thread(clientHandler);
|
e.printStackTrace();
|
||||||
t.start();
|
}
|
||||||
|
catch(ClassNotFoundException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TCPServer(GameController gameController, int port, BlockingQueue<NetworkEvent> actionQueue){
|
|
||||||
this.port = port;
|
|
||||||
this.gameController = gameController;
|
|
||||||
this.actionQueue = actionQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void broadcastUpdate(NetworkEvent event){
|
/** Sends an action to all TCP clients */
|
||||||
|
public void notifyAll(NetworkEvent event){
|
||||||
clientHandlers.forEach((x) -> x.notifyEvent(event));
|
clientHandlers.forEach((x) -> x.notifyEvent(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Sends a game model to all TCP clients */
|
||||||
|
public void notifyAll(Game model){
|
||||||
|
clientHandlers.forEach((x) -> x.notifyModel(model));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package it.polimi.ingsw.gc14;
|
|||||||
import it.polimi.ingsw.gc14.Controller.GameController;
|
import it.polimi.ingsw.gc14.Controller.GameController;
|
||||||
import it.polimi.ingsw.gc14.Model.Game;
|
import it.polimi.ingsw.gc14.Model.Game;
|
||||||
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
import it.polimi.ingsw.gc14.Network.NetworkEvent;
|
||||||
|
import it.polimi.ingsw.gc14.Network.NetworkEvents.AddPlayer;
|
||||||
import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer;
|
import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer;
|
||||||
import it.polimi.ingsw.gc14.Network.TCP.Server.TCPServer;
|
import it.polimi.ingsw.gc14.Network.TCP.Server.TCPServer;
|
||||||
|
|
||||||
@@ -11,14 +12,58 @@ import java.rmi.RemoteException;
|
|||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main server launcher that handles both TCP and RMI connections.
|
||||||
|
* The workflow is divided into two parts: game creation and game execution.
|
||||||
|
*
|
||||||
|
* The process flow for game creation is as follows:
|
||||||
|
* - The first client (TCP/RMI) requests to join the game by providing a username and the desired number of players
|
||||||
|
* - The TCP/RMI server checks {@link #playerList} and, if it is empty, sets the number of players according to the first user's request using {@link LimitedList#setLimit(int)}
|
||||||
|
* - The TCP/RMI server creates the {@link Game} with the requested number of players and adds the player to {@link #playerList}
|
||||||
|
* - Other players request to join the game (their requested number of players is ignored)
|
||||||
|
* - When the number of players in {@link #playerList} reaches the {@link LimitedList}'s limit, the list calls {@link #run()}
|
||||||
|
* - All players are notified of the {@link Game}
|
||||||
|
*
|
||||||
|
* The process flow for game execution is as follows:
|
||||||
|
* - The TCP/RMI server receives a {@link NetworkEvent} from a client and adds it to the {@link #actionQueue}
|
||||||
|
* - The {@link #run()} method repeatedly calls {@link #doFirstEvent()}, which takes the first event in the {@link #actionQueue} and tries to apply it
|
||||||
|
* - If the event cannot be successfully applied to the model, its {@code isError} flag is set to {@code true}
|
||||||
|
* - All players are notified of the event
|
||||||
|
*/
|
||||||
public class ServerLauncher {
|
public class ServerLauncher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue containinetworkTypeng the events to be applied to the game model.
|
||||||
|
* Thread safe by design.
|
||||||
|
*/
|
||||||
BlockingQueue<NetworkEvent> actionQueue;
|
BlockingQueue<NetworkEvent> actionQueue;
|
||||||
|
|
||||||
|
/** Game controller. Used to apply events */
|
||||||
GameController gameController;
|
GameController gameController;
|
||||||
|
|
||||||
|
/** Server RMI. Handles RMI clients */
|
||||||
RMIServer serverRMI;
|
RMIServer serverRMI;
|
||||||
|
|
||||||
|
/** Server TCP. Handles TCP clients */
|
||||||
TCPServer serverTCP;
|
TCPServer serverTCP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List containing the usernames of joined players.
|
||||||
|
* {@link LimitedList}'s limit defines at which size the list calls its action
|
||||||
|
* Both the limit and the action can be set using {@link LimitedList#setLimit(int)} and {@link LimitedList#setAction(Runnable)}
|
||||||
|
* The limit is set by the first player joining the game. The action consists in calling {@link #run()}
|
||||||
|
*/
|
||||||
|
static LimitedList<String> playerList;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor that initializes the attributes.
|
||||||
|
* @param actionQueue The queue containing the events
|
||||||
|
* @param gameController The game controller
|
||||||
|
* @param serverRMI The server RMI
|
||||||
|
* @param serverTCP The server TCP
|
||||||
|
*/
|
||||||
public ServerLauncher(BlockingQueue<NetworkEvent> actionQueue, GameController gameController, RMIServer serverRMI, TCPServer serverTCP) {
|
public ServerLauncher(BlockingQueue<NetworkEvent> actionQueue, GameController gameController, RMIServer serverRMI, TCPServer serverTCP) {
|
||||||
this.actionQueue = actionQueue;
|
this.actionQueue = actionQueue;
|
||||||
this.serverRMI = serverRMI;
|
this.serverRMI = serverRMI;
|
||||||
@@ -26,35 +71,74 @@ public class ServerLauncher {
|
|||||||
this.serverTCP = serverTCP;
|
this.serverTCP = serverTCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes the first event in the actionQueue and attempts to apply it to the game controller.
|
||||||
|
* If the event cannot be applied, its isError flag is set to true; otherwise, it is set to false.
|
||||||
|
* All clients (both TCP and RMI) are notified of the event
|
||||||
|
* @return the outcome of applying the event to the controller
|
||||||
|
* @throws InterruptedException if an error occurs while accessing the actionQueue
|
||||||
|
* @throws RemoteException if an RMI error occurs
|
||||||
|
*/
|
||||||
public boolean doFirstEvent() throws InterruptedException, RemoteException {
|
public boolean doFirstEvent() throws InterruptedException, RemoteException {
|
||||||
NetworkEvent event = actionQueue.take();
|
NetworkEvent event = actionQueue.take();
|
||||||
if(event.apply(gameController)) {
|
event.setIsError(!event.apply(gameController));
|
||||||
serverRMI.notifyAll(event);
|
|
||||||
serverTCP.broadcastUpdate(event);
|
serverRMI.notifyAll(event);
|
||||||
return true;
|
serverTCP.notifyAll(event);
|
||||||
} else {
|
|
||||||
serverRMI.notifyError(event.getUsername(), "Mossa non valida"); // TODO Converrebbe mettere in network event un booleano che dice se è stato accettato e fare una notifyAll anche per errori
|
return !event.getIsError();
|
||||||
//serverTCP // TODO non esiste un notify error (guarda sopra)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void main() throws RemoteException {
|
/**
|
||||||
|
* The first method executed when the server program is launched.
|
||||||
|
* It creates all the objects needed: playerList, actionQueue, gameController, serverRMI, serverTCP, launcher.
|
||||||
|
* Then sets the playerList's action to execute launcher.run() and starts the TCP/RMI servers.
|
||||||
|
* Note: the model is initialized and set in the controller in TCP/RMI servers when the first user decides the number of players.
|
||||||
|
*
|
||||||
|
* @throws InterruptedException if this exception is issued by run method
|
||||||
|
* @throws RemoteException if this exception is issued by run method
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws InterruptedException, RemoteException {
|
||||||
|
playerList = new LimitedList<>(5, ()->{});
|
||||||
BlockingQueue<NetworkEvent> actionQueue = new LinkedBlockingQueue<>();
|
BlockingQueue<NetworkEvent> actionQueue = new LinkedBlockingQueue<>();
|
||||||
Game model = new Game();
|
GameController gameController = new GameController();
|
||||||
GameController gameController = new GameController(model);
|
RMIServer serverRMI = new RMIServer(gameController, 1099, actionQueue, playerList);
|
||||||
RMIServer serverRMI = new RMIServer(gameController, 1099, actionQueue);
|
TCPServer serverTCP = new TCPServer(gameController, 8080, actionQueue, playerList);
|
||||||
TCPServer serverTCP = new TCPServer(gameController, 8080, actionQueue);
|
ServerLauncher launcher = new ServerLauncher(actionQueue, gameController, serverRMI, serverTCP);
|
||||||
|
|
||||||
|
playerList.setAction(()->{
|
||||||
|
new Thread(()->{
|
||||||
|
try {
|
||||||
|
launcher.run();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
});
|
||||||
|
|
||||||
serverRMI.start();
|
serverRMI.start();
|
||||||
new Thread (()->{serverTCP.start();}).start();
|
new Thread(()->{serverTCP.start();}).start();
|
||||||
|
|
||||||
ServerLauncher launcher = new ServerLauncher(actionQueue, gameController, serverRMI, serverTCP);
|
|
||||||
launcher.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
|
||||||
|
/**
|
||||||
|
* Creates and executes the game.
|
||||||
|
* Game creation: TCP/RMI servers send the game model to all players.
|
||||||
|
* Game execution: repeatedly calls doFirstEvent() to process the events in the actionQueue.
|
||||||
|
* @throws InterruptedException if the TCP server thread is interrupted
|
||||||
|
* @throws RemoteException if an RMI error occurs
|
||||||
|
*/
|
||||||
|
public void run() throws InterruptedException, RemoteException {
|
||||||
|
// Game creation
|
||||||
|
System.out.println("\n\nNotifying model");
|
||||||
|
serverRMI.notifyAll(gameController.getModel());
|
||||||
|
serverTCP.notifyAll(gameController.getModel());
|
||||||
|
|
||||||
|
// Game execution
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
this.doFirstEvent();
|
this.doFirstEvent();
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package it.polimi.ingsw.gc14.View.TUI;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
// Helper generale per costruire tabelle ASCII
|
||||||
|
public class AsciiTable {
|
||||||
|
private final BorderStyle s;
|
||||||
|
private final int cols;
|
||||||
|
private final List<List<String>> rows = new ArrayList<>();
|
||||||
|
private final List<Integer> separators = new ArrayList<>();
|
||||||
|
|
||||||
|
public AsciiTable(BorderStyle s, int cols) {
|
||||||
|
this.s = s; this.cols = cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRow(String... cells) { rows.add(Arrays.asList(cells)); }
|
||||||
|
public void addRow(List<String> cells) { rows.add(cells); }
|
||||||
|
public void addHeader(String... cells) { rows.add(0, Arrays.asList(cells)); separators.add(0); }
|
||||||
|
public void addSeparator() { separators.add(rows.size()); }
|
||||||
|
|
||||||
|
public String build() {
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
int maxWidth = rows.stream().mapToInt(x->x.stream().mapToInt(y->y.length()).max().getAsInt()).max().getAsInt()+1;
|
||||||
|
sb.append(hline(s.tl(), s.mt(), s.tr(),maxWidth)).append('\n');
|
||||||
|
|
||||||
|
for (int i = 0; i < rows.size(); i++) {
|
||||||
|
sb.append(s.v());
|
||||||
|
for (String cell : rows.get(i))
|
||||||
|
sb.append(rpad(" " + cell, maxWidth)).append(s.v());
|
||||||
|
sb.append('\n');
|
||||||
|
if (separators.contains(i) && i < rows.size() - 1)
|
||||||
|
sb.append(hline(s.sl(), s.sx(), s.sr(),maxWidth)).append('\n');
|
||||||
|
}
|
||||||
|
sb.append(hline(s.bl(), s.mb(), s.br(), maxWidth));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String hline(String l, String m, String r,int maxWidth) {
|
||||||
|
var sb = new StringBuilder(l);
|
||||||
|
for (int i = 0; i < cols; i++) {
|
||||||
|
sb.append(s.h().repeat(maxWidth));
|
||||||
|
if (i < cols - 1) sb.append(m);
|
||||||
|
}
|
||||||
|
return sb.append(r).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String rpad(String s, int w) {
|
||||||
|
if (s.length() >= w) return s.substring(0, w);
|
||||||
|
return s + " ".repeat(w - s.length());
|
||||||
|
}
|
||||||
|
public static String sideBySide(List<String> left, List<String> right, int gap) {
|
||||||
|
int leftWidth = left.stream().mapToInt(String::length).max().orElse(0);
|
||||||
|
int maxHeight = Math.max(left.size(), right.size());
|
||||||
|
String padding = " ".repeat(gap);
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < maxHeight; i++) {
|
||||||
|
String l = i < left.size()
|
||||||
|
? left.get(i)
|
||||||
|
: " ".repeat(leftWidth);
|
||||||
|
|
||||||
|
// padda la riga sinistra se è più corta delle altre
|
||||||
|
l = rpad(l, leftWidth);
|
||||||
|
|
||||||
|
String r = i < right.size() ? right.get(i) : "";
|
||||||
|
sb.append(l).append(padding).append(r).append('\n');
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package it.polimi.ingsw.gc14.View.TUI;
|
||||||
|
|
||||||
|
public enum BorderStyle {
|
||||||
|
UNICODE("╔","╗","╚","╝","═","║","╠","╣","╦","╩","╬","├","┤","─","┼"),
|
||||||
|
ASCII ("+","+","+","+","-","|","+","+","+","+","+","+","+","-","+"),
|
||||||
|
ROUNDED("╭","╮","╰","╯","─","│","├","┤","┬","┴","┼","├","┤","─","┼");
|
||||||
|
|
||||||
|
private final String tl,tr,bl,br,h,v,ml,mr,mt,mb,x,sl,sr,sh,sx;
|
||||||
|
|
||||||
|
BorderStyle(String tl,String tr,String bl,String br,
|
||||||
|
String h, String v, String ml,String mr,
|
||||||
|
String mt,String mb,String x,
|
||||||
|
String sl,String sr,String sh,String sx) {
|
||||||
|
this.tl = tl; this.tr = tr;
|
||||||
|
this.bl = bl; this.br = br;
|
||||||
|
this.h = h; this.v = v;
|
||||||
|
this.ml = ml; this.mr = mr;
|
||||||
|
this.mt = mt; this.mb = mb;
|
||||||
|
this.x = x;
|
||||||
|
this.sl = sl; this.sr = sr;
|
||||||
|
this.sh = sh; this.sx = sx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String tl() { return tl; }
|
||||||
|
public String tr() { return tr; }
|
||||||
|
public String bl() { return bl; }
|
||||||
|
public String br() { return br; }
|
||||||
|
public String h() { return h; }
|
||||||
|
public String v() { return v; }
|
||||||
|
public String ml() { return ml; }
|
||||||
|
public String mr() { return mr; }
|
||||||
|
public String mt() { return mt; }
|
||||||
|
public String mb() { return mb; }
|
||||||
|
public String x() { return x; }
|
||||||
|
public String sl() { return sl; }
|
||||||
|
public String sr() { return sr; }
|
||||||
|
public String sh() { return sh; }
|
||||||
|
public String sx() { return sx; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
//package it.polimi.ingsw.gc14.View.TUI;
|
||||||
|
//import it.polimi.ingsw.gc14.Model.Game;
|
||||||
|
//
|
||||||
|
//public class TUI {
|
||||||
|
//
|
||||||
|
// // ── dati di stato ───────────────────────────────────────────
|
||||||
|
// private BorderStyle style = BorderStyle.UNICODE;
|
||||||
|
// private Game model;
|
||||||
|
// // ── punto di ingresso ───────────────────────────────────────
|
||||||
|
// public String render() {
|
||||||
|
// var sb = new StringBuilder();
|
||||||
|
// sb.append(renderHeader());
|
||||||
|
// sb.append(renderTurnOrder());
|
||||||
|
// sb.append(renderOfferTrack());
|
||||||
|
// sb.append(renderCardRows());
|
||||||
|
// sb.append(renderTableaux());
|
||||||
|
// sb.append(renderFooter());
|
||||||
|
// return sb.toString();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // ── sezioni ─────────────────────────────────────────────────
|
||||||
|
// private String renderTurnOrder() {
|
||||||
|
// var table = new AsciiTable(style, 4, 10); // 4 colonne, largh 10
|
||||||
|
// table.addRow(model.getPlayers().stream()
|
||||||
|
// .map(p -> + ". " + p.getUserName())
|
||||||
|
// .toList());
|
||||||
|
// table.addRow(state.getPlayers().stream()
|
||||||
|
// .map(p -> p.getTotemPosition() != null
|
||||||
|
// ? "totem: " + p.getTotemPosition()
|
||||||
|
// : "(da piaz)")
|
||||||
|
// .toList());
|
||||||
|
// return " TURN ORDER\n" + table.build() + "\n";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String renderOfferTrack() {
|
||||||
|
// var table = new AsciiTable(style, 5, 14);
|
||||||
|
// table.addRow(state.getOfferTiles().stream()
|
||||||
|
// .map(t -> t.getId() + ": " + t.getLabel()).toList());
|
||||||
|
// table.addRow(state.getOfferTiles().stream()
|
||||||
|
// .map(OfferTile::getRowsLabel).toList());
|
||||||
|
// table.addRow(state.getOfferTiles().stream()
|
||||||
|
// .map(t -> state.getTotemOnTile(t.getId())).toList());
|
||||||
|
// return " OFFER TRACK\n" + table.build() + "\n";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String renderCardRows() {
|
||||||
|
// int cols = state.getTopRow().size();
|
||||||
|
// var table = new AsciiTable(style, cols, 13);
|
||||||
|
// table.addRow(state.getTopRow().stream()
|
||||||
|
// .map(c -> "[" + c.getTypeLabel() + "]").toList());
|
||||||
|
// table.addRow(state.getTopRow().stream()
|
||||||
|
// .map(Card::getName).toList());
|
||||||
|
// table.addSeparator();
|
||||||
|
// table.addRow(state.getBotRow().stream()
|
||||||
|
// .map(c -> "[" + c.getTypeLabel() + "]").toList());
|
||||||
|
// table.addRow(state.getBotRow().stream()
|
||||||
|
// .map(Card::getName).toList());
|
||||||
|
// return " CARTE IN GIOCO\n" + prefix("TOP ", "BOT ", table.build()) + "\n";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String renderTableaux() {
|
||||||
|
// var sb = new StringBuilder(" TABLEAU GIOCATORI\n\n");
|
||||||
|
// for (Player p : state.getPlayers()) {
|
||||||
|
// String marker = p.isActive() ? ">>>" : " ";
|
||||||
|
// sb.append(String.format(" %s %s%s Food:%d PP:%d%n",
|
||||||
|
// marker, p.getName(),
|
||||||
|
// p.isActive() ? " [TUO TURNO]" : "",
|
||||||
|
// p.getFood(), p.getPP()));
|
||||||
|
// sb.append(renderPlayerTableau(p));
|
||||||
|
// sb.append("\n");
|
||||||
|
// }
|
||||||
|
// return sb.toString();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String renderPlayerTableau(Player p) {
|
||||||
|
// var table = new AsciiTable(style, 3, 14);
|
||||||
|
// table.addHeader("PERSONAGGI", "EDIFICI", "RISORSE");
|
||||||
|
// int rows = Math.max(p.getChars().size(),
|
||||||
|
// Math.max(p.getBuildings().size(), 3));
|
||||||
|
// for (int i = 0; i < rows; i++) {
|
||||||
|
// String ch = i < p.getChars().size() ? p.getChars().get(i) : "";
|
||||||
|
// String bd = i < p.getBuildings().size() ? p.getBuildings().get(i) : "";
|
||||||
|
// String rs = switch (i) {
|
||||||
|
// case 0 -> "Food: " + "O".repeat(p.getFood());
|
||||||
|
// case 1 -> "PP: " + p.getPP();
|
||||||
|
// case 2 -> "Chars:" + p.getChars().size() + " Edif:" + p.getBuildings().size();
|
||||||
|
// default -> "";
|
||||||
|
// };
|
||||||
|
// table.addRow(ch, bd, rs);
|
||||||
|
// }
|
||||||
|
// return " " + table.build().replace("\n", "\n ");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -8,7 +8,14 @@ module it.polimi.ingsw.gc14 {
|
|||||||
|
|
||||||
opens it.polimi.ingsw.gc14 to javafx.fxml, com.google.gson;
|
opens it.polimi.ingsw.gc14 to javafx.fxml, com.google.gson;
|
||||||
opens it.polimi.ingsw.gc14.Model to com.google.gson;
|
opens it.polimi.ingsw.gc14.Model to com.google.gson;
|
||||||
|
opens it.polimi.ingsw.gc14.Model.GamePackage to com.google.gson;
|
||||||
|
|
||||||
exports it.polimi.ingsw.gc14;
|
exports it.polimi.ingsw.gc14;
|
||||||
opens it.polimi.ingsw.gc14.Model.GamePackage to com.google.gson;
|
|
||||||
|
// RMI
|
||||||
|
exports it.polimi.ingsw.gc14.Network.RMI.Common to java.rmi;
|
||||||
|
exports it.polimi.ingsw.gc14.Network.RMI.Server to java.rmi;
|
||||||
|
exports it.polimi.ingsw.gc14.Network.RMI.Client to java.rmi;
|
||||||
|
exports it.polimi.ingsw.gc14.Network to java.rmi;
|
||||||
|
exports it.polimi.ingsw.gc14.Model to java.rmi, com.google.gson;
|
||||||
}
|
}
|
||||||
@@ -143,8 +143,4 @@ class Building0Test {
|
|||||||
b0.buy(p1);
|
b0.buy(p1);
|
||||||
assertFalse(b0.buy(p2));
|
assertFalse(b0.buy(p2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+22
-1
@@ -3,7 +3,6 @@ package it.polimi.ingsw.gc14.Model.Cards.Building.Effects;
|
|||||||
import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
|
import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Artist;
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Artist;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Hunter;
|
|
||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -109,4 +108,26 @@ class Building11Test {
|
|||||||
b4.applyEffect(p5);
|
b4.applyEffect(p5);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("toString")
|
||||||
|
void testToString(){
|
||||||
|
Building11 b11 = new Building11(1,2,3, CharacterType.INVENTOR, 1);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: INVENTOR", b11.toString());
|
||||||
|
|
||||||
|
b11 = new Building11(1,2,3, CharacterType.BUILDER, 1);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: BUILDER", b11.toString());
|
||||||
|
|
||||||
|
b11 = new Building11(1,2,3, CharacterType.GATHERER, 1);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: GATHERER", b11.toString());
|
||||||
|
|
||||||
|
b11 = new Building11(1,2,3, CharacterType.ARTIST, 1);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: ARTIST", b11.toString());
|
||||||
|
|
||||||
|
b11 = new Building11(1,2,3, CharacterType.SHAMAN, 1);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: SHAMAN", b11.toString());
|
||||||
|
|
||||||
|
b11 = new Building11(1,2,3, CharacterType.HUNTER, 1);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: HUNTER", b11.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -66,4 +66,26 @@ class Building1Test {
|
|||||||
assertEquals(Prestige, bClone.getPrestigeValue());
|
assertEquals(Prestige, bClone.getPrestigeValue());
|
||||||
assertEquals(ct, b0.getIcon());
|
assertEquals(ct, b0.getIcon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("toString")
|
||||||
|
void testToString(){
|
||||||
|
Building1 b1 = new Building1(1,2,3, CharacterType.INVENTOR);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: INVENTOR", b1.toString());
|
||||||
|
|
||||||
|
b1 = new Building1(1,2,3, CharacterType.BUILDER);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: BUILDER", b1.toString());
|
||||||
|
|
||||||
|
b1 = new Building1(1,2,3, CharacterType.GATHERER);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: GATHERER", b1.toString());
|
||||||
|
|
||||||
|
b1 = new Building1(1,2,3, CharacterType.ARTIST);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: ARTIST", b1.toString());
|
||||||
|
|
||||||
|
b1 = new Building1(1,2,3, CharacterType.SHAMAN);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: SHAMAN", b1.toString());
|
||||||
|
|
||||||
|
b1 = new Building1(1,2,3, CharacterType.HUNTER);
|
||||||
|
assertEquals("Era:1 Price:2 Prestige:3 Icon: HUNTER", b1.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -347,6 +347,7 @@ class GameTest {
|
|||||||
|
|
||||||
assertNotEquals(thirdPlayer, game.getCurrentState().getCurrentPlayer());
|
assertNotEquals(thirdPlayer, game.getCurrentState().getCurrentPlayer());
|
||||||
|
|
||||||
|
System.out.println(game);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,5 +806,23 @@ class GameTest {
|
|||||||
|
|
||||||
assertFalse(game.PickOptionalBuildingCard(current, 0));
|
assertFalse(game.PickOptionalBuildingCard(current, 0));
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
void toStringModel()
|
||||||
|
{
|
||||||
|
Game game=new Game(3);
|
||||||
|
Player p1=new Player("p1");
|
||||||
|
Player p2=new Player("p2");
|
||||||
|
Player p3=new Player("p3");
|
||||||
|
|
||||||
|
assertTrue(game.addPlayer(p1));
|
||||||
|
assertTrue(game.addPlayer(p2));
|
||||||
|
assertTrue(game.addPlayer(p3));
|
||||||
|
|
||||||
|
Queue<Player>players=new LinkedList<>();
|
||||||
|
for(int i=0;i<3;i++) {
|
||||||
|
players.add( game.getCurrentState().getCurrentPlayer());
|
||||||
|
assertTrue(game.SlotChoiceByIndex(game.getCurrentState().getCurrentPlayer(), i));
|
||||||
|
}
|
||||||
|
System.out.println(game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,10 @@ import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
|||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.lang.reflect.Field;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class Order2Test {
|
class Order2Test {
|
||||||
@@ -154,4 +155,16 @@ class Order2Test {
|
|||||||
assertEquals(p1, order.getFirst());
|
assertEquals(p1, order.getFirst());
|
||||||
assertEquals(p1, order.getFirst());
|
assertEquals(p1, order.getFirst());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
void toStringTest() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Player p1 = new Player("wPIshEUhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
|
Player p2 = new Player("L*Ncw1rjjrF2xn%H@4P1iC@&NNIooQQk");
|
||||||
|
Order2 order = new Order2(new ArrayList<>(Arrays.asList(p1, p2)));
|
||||||
|
order.pull();
|
||||||
|
order.pull();
|
||||||
|
order.push(p2);
|
||||||
|
order.push(p1);
|
||||||
|
order.pull().getUserName();
|
||||||
|
System.out.println(order);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,10 @@ import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
|||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.lang.reflect.Field;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class Order3Test {
|
class Order3Test {
|
||||||
@@ -180,5 +181,30 @@ class Order3Test {
|
|||||||
assertEquals(p1, order.getFirst());
|
assertEquals(p1, order.getFirst());
|
||||||
assertEquals(p1, order.getFirst());
|
assertEquals(p1, order.getFirst());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
void toStringTest() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Player p1 = new Player("wPIshEUhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
|
Player p2 = new Player("L*Ncw1rjjrF2xn%H@4P1iC@&NNIooQQk");
|
||||||
|
Player p3 = new Player("L*Ncw1ryyrF2xn%H@4P1iC@&NNIooQQk");
|
||||||
|
Order3 order = new Order3(new ArrayList<>(Arrays.asList(p1, p2,p3)));
|
||||||
|
Field field = Order3.class.getSuperclass().getDeclaredField("playerList");
|
||||||
|
field.setAccessible(true);
|
||||||
|
List<OrderPlayer> values =(ArrayList<OrderPlayer>)field.get(order);
|
||||||
|
|
||||||
|
String userPulled=order.pull().getUserName();
|
||||||
|
userPulled=order.pull().getUserName();
|
||||||
|
userPulled=order.pull().getUserName();
|
||||||
|
|
||||||
|
System.out.println(values);
|
||||||
|
order.push(p1);
|
||||||
|
order.push(p2);
|
||||||
|
values =(ArrayList<OrderPlayer>)field.get(order);
|
||||||
|
System.out.println(order);
|
||||||
|
// assertEquals("TURN ORDER\n" +
|
||||||
|
// "╔════════════════════════════════════╦════════════════════════════════════╦════════════════════════════════════╗\n" +
|
||||||
|
// "║ 0. ║ 1. "+values.get(1).getUserName() +"║ 2. "+values.get(2).getUserName()+"║\n" +
|
||||||
|
// "║ +2 Food ║ -- ║ -1 Food / -2 Prestige ║\n"+
|
||||||
|
// "╚════════════════════════════════════╩════════════════════════════════════╩════════════════════════════════════╝\n", order.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
|||||||
import it.polimi.ingsw.gc14.Model.Player;
|
import it.polimi.ingsw.gc14.Model.Player;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.lang.reflect.Field;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class Order4Test {
|
class Order4Test {
|
||||||
@@ -272,22 +273,14 @@ class Order4Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getFirst() {
|
void toStringTest() throws NoSuchFieldException, IllegalAccessException {
|
||||||
Player p1 = new Player("p1");
|
Player p1 = new Player("wPIshNQhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
Player p2 = new Player("p2");
|
Player p2 = new Player("L*Ncw1rjjrF2xn%H@4P1iC@&NNIooQQk");
|
||||||
Player p3 = new Player("p3");
|
Player p3 = new Player("wPIshEUhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
Player p4 = new Player("p4");
|
Player p4 = new Player("wPIshOThiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
Order4 order = new Order4(new ArrayList<>(Arrays.asList(p1, p2, p3, p4)));
|
Order4 order = new Order4(new ArrayList<>(Arrays.asList(p1, p2,p3,p4)));
|
||||||
|
String userPulled=order.pull().getUserName();
|
||||||
|
System.out.println(order);
|
||||||
|
|
||||||
order.pull();
|
|
||||||
order.pull();
|
|
||||||
order.pull();
|
|
||||||
order.pull();
|
|
||||||
assertNull(order.getFirst());
|
|
||||||
|
|
||||||
order.push(p1);
|
|
||||||
|
|
||||||
assertEquals(p1, order.getFirst());
|
|
||||||
assertEquals(p1, order.getFirst());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,12 @@ import it.polimi.ingsw.gc14.Model.Player;
|
|||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
@@ -361,6 +367,23 @@ class Order5Test {
|
|||||||
assertEquals(p1, order.getFirst());
|
assertEquals(p1, order.getFirst());
|
||||||
assertEquals(p1, order.getFirst());
|
assertEquals(p1, order.getFirst());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
void toStringTest() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Player p1 = new Player("wPIshUEhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
|
Player p2 = new Player("L*Ncw1rjjrF2xn%H@4P1iC@&NNIooQQk");
|
||||||
|
Player p3 = new Player("wPIshOUhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
|
Player p4 = new Player("wPIshNUhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
|
Player p5 = new Player("wPIshKUhiOpRRnIBFfM89s2$@q$9FGbz");
|
||||||
|
Order5 order = new Order5(new ArrayList<>(Arrays.asList(p1, p2,p3,p4,p5)));
|
||||||
|
order.pull();
|
||||||
|
order.pull();
|
||||||
|
order.pull();
|
||||||
|
order.pull();
|
||||||
|
order.pull();
|
||||||
|
order.push(p1);
|
||||||
|
System.out.println(order);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package it.polimi.ingsw.gc14.Model;
|
package it.polimi.ingsw.gc14.Model;
|
||||||
|
|
||||||
|
import it.polimi.ingsw.gc14.Model.Cards.Building.Effects.*;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
import it.polimi.ingsw.gc14.Model.Cards.BuildingCard;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
|
||||||
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.*;
|
import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.*;
|
||||||
@@ -200,17 +201,44 @@ class PlayerTest {
|
|||||||
p.addPrestige(15);
|
p.addPrestige(15);
|
||||||
p.addFood(7);
|
p.addFood(7);
|
||||||
p.artists.add(new Artist(1));
|
p.artists.add(new Artist(1));
|
||||||
|
p.artists.add(new Artist(1));
|
||||||
|
p.artists.add(new Artist(1));
|
||||||
|
p.artists.add(new Artist(1));
|
||||||
|
p.artists.add(new Artist(1));
|
||||||
|
p.artists.add(new Artist(1));
|
||||||
p.artists.add(new Artist(2));
|
p.artists.add(new Artist(2));
|
||||||
|
p.builders.add(new Builder(2, 5, 1));
|
||||||
|
p.gatherers.add(new Gatherer(1, 3));
|
||||||
|
p.shamans.add(new Shaman(2, 3, 3));
|
||||||
|
p.shamans.add(new Shaman(2, 3, 4));
|
||||||
|
p.inventors.add(new Inventor(3, 1));
|
||||||
|
p.hunters.add(new Hunter(3, true));
|
||||||
|
p.hunters.add(new Hunter(2, false));
|
||||||
|
|
||||||
p.buildingCards.add(new BuildingCard(2, 1,2, 5));
|
p.buildingCards.add(new BuildingCard(2, 1,2, 5));
|
||||||
p.buildingCards.add(new BuildingCard(2, 2,3, 6));
|
p.buildingCards.add(new BuildingCard(2, 2,3, 6));
|
||||||
assertEquals("test_usr:"+ "\n\t" +
|
p.buildingCards.add(new Building1(2, 5, 5, CharacterType.INVENTOR));
|
||||||
"Food: 7" + "\n\t" +
|
p.buildingCards.add(new Building1(2, 5, 5, CharacterType.SHAMAN));
|
||||||
"Prestige: 15" + "\n\t" +
|
p.buildingCards.add(new Building11(1, 5, 7, CharacterType.ARTIST , 3));
|
||||||
"Artists: [Era:1 ARTIST, Era:2 ARTIST]" + "\n\t" + "Builders: []" + "\n\t" +
|
//System.out.println(p.toString());
|
||||||
"Gatherers: []" + "\n\t" +
|
assertEquals(""+
|
||||||
"Shamans: []" + "\n\t" +
|
"╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n" +
|
||||||
"Hunters: []" + "\n\t" +
|
"║ test_usr ║\n" +
|
||||||
"Buildings: [Era:1 Price:2 Prestige:5, Era:2 Price:3 Prestige:6]",
|
"├═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════┤\n" +
|
||||||
p.toString());
|
"║ RESOURCES: ║\n" +
|
||||||
|
"║ Food: 7 ║\n" +
|
||||||
|
"║ Prestige: 15 ║\n" +
|
||||||
|
"├═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════┤\n" +
|
||||||
|
"║ CHARACTERS: ║\n" +
|
||||||
|
"║ Artists: [⎕:, ⎕:, ⎕:, ⎕:, ⎕:, ⎕:, ⎕:] ║\n" +
|
||||||
|
"║ Builders: [⎕: RV:5 PV:1] ║\n" +
|
||||||
|
"║ Gatherers: [⎕:] ║\n" +
|
||||||
|
"║ Shamans: [⎕: *:3, ⎕: *:3] ║\n" +
|
||||||
|
"║ Inventors: [⎕: I_ID:1] ║\n" +
|
||||||
|
"║ Hunters: [⎕: I, ⎕:] ║\n" +
|
||||||
|
"├═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════┤\n" +
|
||||||
|
"║ BUILDING CARDS: ║\n" +
|
||||||
|
"║ Buildings: [⎕: ID:2 $:2 PV:5, ⎕: ID:2 $:3 PV:6, ⎕: ID:1 $:5 PV:5 Icon: I, ⎕: ID:1 $:5 PV:5 Icon: S, ⎕: ID:11 $:5 PV:7 Icon: A MP: 3]║\n" +
|
||||||
|
"╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝", p.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,8 @@ class SlotTest {
|
|||||||
assertEquals(0, s.getNLower());
|
assertEquals(0, s.getNLower());
|
||||||
assertEquals(0, s.getNUpper());
|
assertEquals(0, s.getNUpper());
|
||||||
assertEquals(5, s.getNMinPlayer());
|
assertEquals(5, s.getNMinPlayer());
|
||||||
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\nNMinPlayer: "+s.getNMinPlayer()+"\n", s.toString());
|
System.out.println(s);
|
||||||
|
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\n", s.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -59,7 +60,8 @@ class SlotTest {
|
|||||||
assertEquals(1, s.getNLower());
|
assertEquals(1, s.getNLower());
|
||||||
assertEquals(0, s.getNUpper());
|
assertEquals(0, s.getNUpper());
|
||||||
assertEquals(0, s.getNMinPlayer());
|
assertEquals(0, s.getNMinPlayer());
|
||||||
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\nNMinPlayer: "+s.getNMinPlayer()+"\n", s.toString());
|
System.out.println(s);
|
||||||
|
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\n", s.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -72,8 +74,8 @@ class SlotTest {
|
|||||||
assertEquals(0, s.getNLower());
|
assertEquals(0, s.getNLower());
|
||||||
assertEquals(1, s.getNUpper());
|
assertEquals(1, s.getNUpper());
|
||||||
assertEquals(0, s.getNMinPlayer());
|
assertEquals(0, s.getNMinPlayer());
|
||||||
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\nNMinPlayer: "+s.getNMinPlayer()+"\n", s.toString());
|
System.out.println(s);
|
||||||
}
|
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\n", s.toString()); }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void SlotIdD() {
|
void SlotIdD() {
|
||||||
@@ -85,7 +87,8 @@ class SlotTest {
|
|||||||
assertEquals(2, s.getNLower());
|
assertEquals(2, s.getNLower());
|
||||||
assertEquals(0, s.getNUpper());
|
assertEquals(0, s.getNUpper());
|
||||||
assertEquals(3, s.getNMinPlayer());
|
assertEquals(3, s.getNMinPlayer());
|
||||||
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\nNMinPlayer: "+s.getNMinPlayer()+"\n", s.toString());
|
System.out.println(s);
|
||||||
|
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\n", s.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -98,7 +101,8 @@ class SlotTest {
|
|||||||
assertEquals(1, s.getNLower());
|
assertEquals(1, s.getNLower());
|
||||||
assertEquals(1, s.getNUpper());
|
assertEquals(1, s.getNUpper());
|
||||||
assertEquals(0, s.getNMinPlayer());
|
assertEquals(0, s.getNMinPlayer());
|
||||||
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\nNMinPlayer: "+s.getNMinPlayer()+"\n", s.toString());
|
System.out.println(s);
|
||||||
|
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\n", s.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -111,7 +115,8 @@ class SlotTest {
|
|||||||
assertEquals(0, s.getNLower());
|
assertEquals(0, s.getNLower());
|
||||||
assertEquals(2, s.getNUpper());
|
assertEquals(2, s.getNUpper());
|
||||||
assertEquals(0, s.getNMinPlayer());
|
assertEquals(0, s.getNMinPlayer());
|
||||||
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\nNMinPlayer: "+s.getNMinPlayer()+"\n", s.toString());
|
System.out.println(s);
|
||||||
|
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\n", s.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -124,6 +129,7 @@ class SlotTest {
|
|||||||
assertEquals(1, s.getNLower());
|
assertEquals(1, s.getNLower());
|
||||||
assertEquals(2, s.getNUpper());
|
assertEquals(2, s.getNUpper());
|
||||||
assertEquals(4, s.getNMinPlayer());
|
assertEquals(4, s.getNMinPlayer());
|
||||||
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\nNMinPlayer: "+s.getNMinPlayer()+"\n", s.toString());
|
System.out.println(s);
|
||||||
|
assertEquals("SlotID: "+slotID+"\nNUpper: "+s.getNUpper()+"\nNLower: "+s.getNLower()+"\nFood: "+s.getFood()+"\n", s.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user