diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java index d3a34a8..84f4ae4 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -169,8 +169,9 @@ public class Game implements Serializable { * @throws IllegalArgumentException if {@code nPlayers < 0} or {@code nPlayers > 5}. */ public Game(int nPlayers) throws IllegalArgumentException{ - if(nPlayers < 0||nPlayers > 5) + if(nPlayers !=0 && (nPlayers < 2 || nPlayers > 5)) { throw new IllegalArgumentException(); + } this.nPlayers = nPlayers; board=new Board(nPlayers); slotMap = new LinkedHashMap<>(); @@ -312,10 +313,9 @@ public class Game implements Serializable { tempCard.insert(player); board.removeUpperTribeCard(tempCard); currentState.UpperDrawn(); - if(currentState.getNUpper() ==0 && currentState.getNLower() ==0) + if((currentState.getNLower() ==0 ||( getLowerListTribeCards().size()==0 && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||( getUpperListTribeCards().size()==0 && getUpperListBuilding().size()==0))) nextPlayerSetup(); return true; - } /** @@ -354,7 +354,7 @@ public class Game implements Serializable { tempCard.insert(player); board.removeLowerTribeCard(tempCard); currentState.LowerDrawn(); - if(currentState.getNLower() ==0 && currentState.getNUpper() ==0) + if((currentState.getNLower() ==0 ||( getLowerListTribeCards().size()==0 && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||( getUpperListTribeCards().size()==0 && getUpperListBuilding().size()==0))) nextPlayerSetup(); return true; @@ -393,7 +393,7 @@ public class Game implements Serializable { } else return false; - if(currentState.getNLower() ==0 && currentState.getNUpper() ==0) + if((currentState.getNLower() ==0 ||( getLowerListTribeCards().size()==0 && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||( getUpperListTribeCards().size()==0 && getUpperListBuilding().size()==0))) nextPlayerSetup(); return true; @@ -418,7 +418,7 @@ public class Game implements Serializable { { return false; } - + if(!player.equals(currentState.getCurrentPlayer())) { return false; @@ -433,7 +433,7 @@ public class Game implements Serializable { } else return false; - if(currentState.getNLower() ==0 && currentState.getNUpper() ==0) + if((currentState.getNLower() ==0 ||( getLowerListTribeCards().size()==0 && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||( getUpperListTribeCards().size()==0 && getUpperListBuilding().size()==0))) nextPlayerSetup(); return true; @@ -509,8 +509,8 @@ public class Game implements Serializable { else { return false; } - nextPlayerSetup(); OptionalCardQueue.removeIf(x->x.equals(player)); + nextPlayerSetup(); return true; } @@ -566,10 +566,16 @@ public class Game implements Serializable { return; } currentState.GameStageUpdate(GameStages.RESOLVING_ACTIONS); - for (Map.Entry s : slotMap.entrySet()) { - if (s.getValue()!=null) { - currentState.PlayerUpdate(s.getValue(), s.getKey()); - return; + for (Slot s : slotMap.keySet()) { + if (slotMap.get(s) != null) { + currentState.PlayerUpdate(slotMap.get(s), s); + if(!((currentState.getNLower() ==0 ||( getLowerListTribeCards().size()==0 && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||( getUpperListTribeCards().size()==0 && getUpperListBuilding().size()==0)))) + break; + else + { + orderLogicCard.push(currentState.getCurrentPlayer()); + slotMap.put(currentState.getSlot(), null); + } } } return; @@ -581,7 +587,15 @@ public class Game implements Serializable { for (Slot s : slotMap.keySet()) { if (slotMap.get(s) != null) { currentState.PlayerUpdate(slotMap.get(s), s); - break; + if((currentState.getNLower() ==0 ||( getLowerListTribeCards().size()==0 && getLowerListBuilding().size()==0)) && ((currentState.getNUpper() ==0)||( getUpperListTribeCards().size()==0 && getUpperListBuilding().size()==0))) { + orderLogicCard.push(currentState.getCurrentPlayer()); + + slotMap.put(currentState.getSlot(), null); + } + else + { + break; + } } } if(slotMap.values().stream().allMatch(v -> v == null)) @@ -600,31 +614,51 @@ public class Game implements Serializable { { OptionalCardQueue.add(e.getKey()); } - currentState.PlayerUpdate(OptionalCardQueue.remove(), null); - if(currentState.getCurrentPlayer()==null) - { - currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); - if(currentState.getRound()<10) - { - nextRound(); - } - else - { - EventResolution(); - currentState.GameStageUpdate(GameStages.ENDING); - endGame(); - } + Player optionalPlayer = OptionalCardQueue.poll(); + if (optionalPlayer != null) { + currentState.PlayerUpdate(optionalPlayer, null); return; } - } - } - if(GameStages.OPTIONAL_CARD_EFFECT==currentState.getGameStage()) { - currentState.PlayerUpdate(OptionalCardQueue.remove(), null); - if(currentState.getCurrentPlayer()==null) - { + currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); + + if (currentState.getRound() < 10) { + nextRound(); + currentState.PlayerUpdate(orderLogicCard.pull(), null); + currentState.GameStageUpdate(GameStages.SLOT_CHOICE); + } else { + EventResolution(); + currentState.GameStageUpdate(GameStages.ENDING); + endGame(); + } + + return; + } } + + if (GameStages.OPTIONAL_CARD_EFFECT == currentState.getGameStage()) { + Player optionalPlayer = OptionalCardQueue.poll(); + + if (optionalPlayer != null) { + currentState.PlayerUpdate(optionalPlayer, null); + return; + } + + currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); + + if (currentState.getRound() < 10) { + nextRound(); + currentState.PlayerUpdate(orderLogicCard.pull(), null); + currentState.GameStageUpdate(GameStages.SLOT_CHOICE); + } else { + EventResolution(); + currentState.GameStageUpdate(GameStages.ENDING); + endGame(); + } + + return; + } } @@ -669,9 +703,13 @@ public class Game implements Serializable { { currentState.GameStageUpdate(GameStages.ENDING); endGame(); + return; } - if(currentState.getEra()!= board.nextRound()) + + if(currentState.getEra()!= board.nextRound()) { currentState.EraUpdate(); + } + currentState.RoundUpdate(); } @@ -695,11 +733,28 @@ public class Game implements Serializable { * @param nPlayers the new configured number of players. * @return {@code true} if the number of players is updated, {@code false} otherwise. */ - public boolean setNPlayer(int nPlayers) - { - if(this.nPlayers!=0) + public boolean setNPlayer(int nPlayers) { + if (this.nPlayers != 0) { return false; - this.nPlayers=nPlayers; + } + + if (nPlayers < 2 || nPlayers > 5) { + return false; + } + + this.nPlayers = nPlayers; + + board = new Board(nPlayers); + + slotMap = new LinkedHashMap<>(); + for (Slot s : board.getSlotList()) { + slotMap.put(s, null); + } + + currentState = new CurrentState(); + playersList = new ArrayList<>(); + OptionalCardQueue = new LinkedList<>(); + return true; } @@ -771,19 +826,10 @@ public class Game implements Serializable { BuildTableLower.addRow(getLowerListBuilding().get(i).toString()); } } - - - //offerTrack.addRow(stringUpperListTribe); stringUpperListTribe.forEach(x->TribeTableUpper.addRow(x)); stringLowerListTribe.forEach(x->TribeTableLower.addRow(x)); - offerTrack.addRow(stringUpOffer); offerTrack.addRow(stringDownOffer); - //offerTrack.addRow(stringLowerListTribe); - - - - return orderLogicCard.toString()+"\n"+ AsciiTable.sideBySide(Arrays.stream((TribeTableUpper.build().split("\n"))).toList(), Arrays.stream(BuildTableUpper.build().split("\n")).toList(),2)+"\n"+offerTrack.build()+"\n"+AsciiTable.sideBySide(List.of(TribeTableLower.build().split("\n")), Arrays.stream(BuildTableLower.build().split("\n")).toList(),2); - //return s.toString()+"\n"++"\nOFFER TRACK\n"+ table.build()+"\n" ; + return "CURRENT STATE\n"+getCurrentState()+"\n"+orderLogicCard.toString()+"\n"+ AsciiTable.sideBySide(Arrays.stream((TribeTableUpper.build().split("\n"))).toList(), Arrays.stream(BuildTableUpper.build().split("\n")).toList(),2)+"\n"+offerTrack.build()+"\n"+AsciiTable.sideBySide(List.of(TribeTableLower.build().split("\n")), Arrays.stream(BuildTableLower.build().split("\n")).toList(),2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java index b2489b8..f464e02 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java @@ -3,7 +3,12 @@ package it.polimi.ingsw.gc14.Model.GamePackage; import it.polimi.ingsw.gc14.Model.Player; import it.polimi.ingsw.gc14.Model.Slot; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; +import it.polimi.ingsw.gc14.View.TUI.AsciiTable; +import it.polimi.ingsw.gc14.View.TUI.BorderStyle; + import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; /** * Represents the current state of the game. @@ -194,5 +199,27 @@ public class CurrentState implements Serializable { } } + @Override + public String toString(){ + var table= new AsciiTable(BorderStyle.UNICODE,6); + Listheader= new ArrayList<>(); + header.add("Player"); + header.add("NUpper"); + header.add("NLower"); + header.add("Round"); + header.add("Era"); + header.add("GameStage"); + table.addRow(header); + table.addSeparator(); + Listvalues= new ArrayList<>(); + values.add(player.getUserName()); + values.add(Integer.toString(NUpper)); + values.add(Integer.toString(NLower)); + values.add(Integer.toString(round)); + values.add(Integer.toString(Era)); + values.add(GameStage.toString()); + table.addRow(values); + return table.build(); + } // endregion functions } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order3.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order3.java index fb4c71a..1d434ea 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order3.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order3.java @@ -47,7 +47,7 @@ public class Order3 extends OrderLogicCard { return; } if(index==2){ - if(player.removeFood(1)){ + if(!player.removeFood(1)){ player.removePrestige(2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order4.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order4.java index 966f15a..608bcb6 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order4.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order4.java @@ -55,7 +55,7 @@ public class Order4 extends OrderLogicCard { return; } if(index==3){ - if(player.removeFood(1)){ + if(!player.removeFood(1)){ player.removePrestige(2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order5.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order5.java index 468c626..b75602d 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order5.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order5.java @@ -56,7 +56,7 @@ public class Order5 extends OrderLogicCard { return; } if(index==4){ - if(player.removeFood(1)){ + if(!player.removeFood(1)){ player.removePrestige(2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java index a71487a..6170dd5 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java @@ -1,9 +1,8 @@ package it.polimi.ingsw.gc14.View.TUI; import it.polimi.ingsw.gc14.Model.Game; -import it.polimi.ingsw.gc14.Network.Observer; import it.polimi.ingsw.gc14.View.IView; -public class TUI implements IView, Observer { +public class TUI implements IView { // ── dati di stato ─────────────────────────────────────────── private BorderStyle style = BorderStyle.UNICODE; diff --git a/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java b/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java index 19a845e..aa89a2a 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java @@ -1,5 +1,6 @@ package it.polimi.ingsw.gc14.Controller; +import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; @@ -14,6 +15,114 @@ import static org.junit.jupiter.api.Assertions.*; class GameControllerTest { + private Game createStartedGame() { + Game game = new Game(3); + GameController controller = new GameController(game); + assertEquals( controller.getModel(),game); + controller = new GameController(); + controller.setModel(game); + assertEquals( controller.getModel(),game); + assertTrue(controller.addPlayer("Giorgio")); + assertTrue(controller.addPlayer("Marco")); + assertTrue(controller.addPlayer("Luca")); + + return game; + } + + private Queue completeSlotChoice(Game game, GameController controller) { + Queue order = new LinkedList<>(); + + for (int i = 0; i < 3; i++) { + Player current = game.getCurrentState().getCurrentPlayer(); + order.add(current); + + assertTrue(controller.slotChoice(current.getUserName(), i)); + } + + assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + + return order; + } + + private int firstNonEventIndex(List cards) { + for (int i = 0; i < cards.size(); i++) { + if (!cards.get(i).IsEventCard()) { + return i; + } + } + + fail("No non-event tribe card available."); + return -1; + } + + private int firstEventIndexOrMinusOne(List cards) { + for (int i = 0; i < cards.size(); i++) { + if (cards.get(i).IsEventCard()) { + return i; + } + } + + return -1; + } + + private int firstNonEventIndexOrMinusOne(List cards) { + for (int i = 0; i < cards.size(); i++) { + if (!cards.get(i).IsEventCard()) { + return i; + } + } + + return -1; + } + + private void giveOptionalEffectToAllPlayers(Game game) { + Player first = game.getPlayerByUsername("Giorgio"); + Player second = game.getPlayerByUsername("Marco"); + Player third = game.getPlayerByUsername("Luca"); + + assertNotNull(first); + assertNotNull(second); + assertNotNull(third); + + first.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + second.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + third.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + } + + private void resolveActionsUntilOptionalCardEffect(Game game, GameController controller) { + int guard = 0; + + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS && guard < 20) { + guard++; + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + if (game.getCurrentState().getNLower() > 0) { + int index = firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()); + + if (index == -1) { + fail("No non-event lower tribe card available."); + } + + assertTrue(controller.drawLowerTribeCard(current.getUserName(), index)); + } else if (game.getCurrentState().getNUpper() > 0) { + int index = firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()); + + if (index == -1) { + fail("No non-event upper tribe card available."); + } + + assertTrue(controller.drawUpperTribeCard(current.getUserName(), index)); + } else { + fail("Current player has no remaining upper or lower draws."); + } + } + + assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + } + + @Test void addPlayer() { Game game = new Game(3); @@ -47,23 +156,15 @@ class GameControllerTest { @Test void slotChoice() { - Game game = new Game(3); + Game game = createStartedGame(); GameController controller = new GameController(game); - assertTrue(controller.addPlayer("Giorgio")); - assertTrue(controller.addPlayer("Marco")); - assertTrue(controller.addPlayer("Luca")); - String cur = game.getCurrentState().getCurrentPlayer().getUserName(); String other = cur.equals("Giorgio") ? "Marco" : "Giorgio"; + assertFalse(controller.slotChoice(other, 0)); - Queue order = new LinkedList<>(); - for (int i = 0; i < 3; i++) { - Player p = game.getCurrentState().getCurrentPlayer(); - order.add(p); - assertTrue(controller.slotChoice(p.getUserName(), i)); - } + Queue order = completeSlotChoice(game, controller); assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); assertEquals(order.poll(), game.getCurrentState().getCurrentPlayer()); @@ -71,66 +172,43 @@ class GameControllerTest { @Test void drawLowerTribeCard() { - Game game = new Game(3); + Game game = createStartedGame(); GameController controller = new GameController(game); - assertTrue(controller.addPlayer("Giorgio")); - assertTrue(controller.addPlayer("Marco")); - assertTrue(controller.addPlayer("Luca")); - - Queue order = new LinkedList<>(); - for (int i = 0; i < 3; i++) { - Player p = game.getCurrentState().getCurrentPlayer(); - order.add(p); - assertTrue(controller.slotChoice(p.getUserName(), i)); - } + Queue order = completeSlotChoice(game, controller); Player first = order.poll(); assertEquals(first, game.getCurrentState().getCurrentPlayer()); List cards = game.getLowerListTribeCards(); - int idx = cards.indexOf( - cards.stream() - .filter(c -> !c.IsEventCard()) - .findFirst() - .orElseThrow() - ); + int idx = firstNonEventIndex(cards); Player wrongPlayer = order.peek(); assertNotNull(wrongPlayer); + assertFalse(controller.drawLowerTribeCard(wrongPlayer.getUserName(), idx)); + int before = first.getTotCharacters(); + assertTrue(controller.drawLowerTribeCard(first.getUserName(), idx)); + assertEquals(before + 1, first.getTotCharacters()); } @Test void drawUpperTribeCard() { - Game game = new Game(3); + Game game = createStartedGame(); GameController controller = new GameController(game); - assertTrue(controller.addPlayer("Giorgio")); - assertTrue(controller.addPlayer("Marco")); - assertTrue(controller.addPlayer("Luca")); - - for (int i = 0; i < 3; i++) { - Player p = game.getCurrentState().getCurrentPlayer(); - assertTrue(controller.slotChoice(p.getUserName(), i)); - } - - assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + completeSlotChoice(game, controller); while (game.getCurrentState().getNUpper() == 0) { assertTrue(game.getCurrentState().getNLower() > 0); Player current = game.getCurrentState().getCurrentPlayer(); + List lower = game.getLowerListTribeCards(); - int lowerIdx = lower.indexOf( - lower.stream() - .filter(c -> !c.IsEventCard()) - .findFirst() - .orElseThrow() - ); + int lowerIdx = firstNonEventIndex(lower); assertTrue(controller.drawLowerTribeCard(current.getUserName(), lowerIdx)); } @@ -139,12 +217,7 @@ class GameControllerTest { int beforeTot = current.getTotCharacters(); List upper = game.getUpperListTribeCards(); - int upperIdx = upper.indexOf( - upper.stream() - .filter(c -> !c.IsEventCard()) - .findFirst() - .orElseThrow() - ); + int upperIdx = firstNonEventIndex(upper); assertTrue(controller.drawUpperTribeCard(current.getUserName(), upperIdx)); assertEquals(beforeTot + 1, current.getTotCharacters()); @@ -152,31 +225,18 @@ class GameControllerTest { @Test void drawUpperBuildingCard() { - Game game = new Game(3); + Game game = createStartedGame(); GameController controller = new GameController(game); - assertTrue(controller.addPlayer("Giacomo")); - assertTrue(controller.addPlayer("Marco")); - assertTrue(controller.addPlayer("Luca")); - - for (int i = 0; i < 3; i++) { - Player p = game.getCurrentState().getCurrentPlayer(); - assertTrue(controller.slotChoice(p.getUserName(), i)); - } - - assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + completeSlotChoice(game, controller); while (game.getCurrentState().getNUpper() == 0) { assertTrue(game.getCurrentState().getNLower() > 0); Player current = game.getCurrentState().getCurrentPlayer(); + List lower = game.getLowerListTribeCards(); - int lowerIdx = lower.indexOf( - lower.stream() - .filter(c -> !c.IsEventCard()) - .findFirst() - .orElseThrow() - ); + int lowerIdx = firstNonEventIndex(lower); assertTrue(controller.drawLowerTribeCard(current.getUserName(), lowerIdx)); } @@ -186,43 +246,214 @@ class GameControllerTest { assertFalse(controller.drawUpperBuildingCard(current.getUserName(), 0)); current.addFood(100); + int foodBefore = current.getFoodValue(); + int buildingsBefore = current.buildingCards.size(); + assertTrue(controller.drawUpperBuildingCard(current.getUserName(), 0)); + + assertTrue(current.getFoodValue() < foodBefore); + assertEquals(buildingsBefore + 1, current.buildingCards.size()); } - @Test - void drawLowerBuildingCard() { - Game game = new Game(3); - GameController controller = new GameController(game); + @Test + void drawingByIndexThroughController() { + Game game = new Game(3); + GameController controller = new GameController(game); - assertTrue(controller.addPlayer("Giacomo")); - assertTrue(controller.addPlayer("Marco")); - assertTrue(controller.addPlayer("Luca")); + assertTrue(controller.addPlayer("p1")); + assertTrue(controller.addPlayer("p2")); + assertFalse(controller.addPlayer("p2")); + assertTrue(controller.addPlayer("p3")); - for (int i = 0; i < 3; i++) { - Player p = game.getCurrentState().getCurrentPlayer(); - assertTrue(controller.slotChoice(p.getUserName(), i)); + Queue players = new LinkedList<>(); + + for (int i = 0; i < 3; i++) { + Player current = game.getCurrentState().getCurrentPlayer(); + players.add(current); + + assertTrue(controller.slotChoice(current.getUserName(), i)); + } + + assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + + Player tempPlayer = players.poll(); + assertNotNull(tempPlayer); + assertEquals(tempPlayer, game.getCurrentState().getCurrentPlayer()); + + List cards = game.getLowerListTribeCards(); + int index = firstNonEventIndex(cards); + + assertTrue(controller.drawLowerTribeCard(tempPlayer.getUserName(), index)); + + tempPlayer = players.poll(); + assertNotNull(tempPlayer); + assertEquals(tempPlayer, game.getCurrentState().getCurrentPlayer()); + + while (game.getCurrentState().getNUpper() > 1) { + cards = game.getUpperListTribeCards(); + + index = firstNonEventIndexOrMinusOne(cards); + + if (index == -1) { + break; } - String cur = game.getCurrentState().getCurrentPlayer().getUserName(); - assertFalse(controller.drawLowerBuildingCard(cur, 0)); + int before = tempPlayer.getTotCharacters(); + + assertTrue(controller.drawUpperTribeCard(tempPlayer.getUserName(), index)); + + assertEquals(before + 1, tempPlayer.getTotCharacters()); + } + + cards = game.getUpperListTribeCards(); + + int eventIndex = firstEventIndexOrMinusOne(cards); + + if (eventIndex != -1) { + assertFalse(controller.drawUpperTribeCard(tempPlayer.getUserName(), eventIndex)); + } + + tempPlayer.addFood(100); + + assertFalse(controller.drawUpperBuildingCard(tempPlayer.getUserName(), 999)); + + if (!game.getUpperListBuilding().isEmpty() && game.getCurrentState().getNUpper() > 0) { + assertTrue(controller.drawUpperBuildingCard(tempPlayer.getUserName(), 0)); + } + + cards = game.getUpperListTribeCards(); + + int nonEventIndex = firstNonEventIndexOrMinusOne(cards); + + if (nonEventIndex != -1) { + assertFalse(controller.drawUpperTribeCard(tempPlayer.getUserName(), nonEventIndex)); + } } - @Test - void pickOptionalCards() { - Game game = new Game(3); - GameController controller = new GameController(game); + @Test + void drawLowerBuildingCardShouldReturnFalseForUnavailableLowerBuildingCard() { + Game game = createStartedGame(); + GameController controller = new GameController(game); - assertTrue(controller.addPlayer("Giacomo")); - assertTrue(controller.addPlayer("Marco")); - assertTrue(controller.addPlayer("Luca")); + completeSlotChoice(game, controller); - for (int i = 0; i < 3; i++) { - Player p = game.getCurrentState().getCurrentPlayer(); - assertTrue(controller.slotChoice(p.getUserName(), i)); - } + Player current = game.getCurrentState().getCurrentPlayer(); - String cur = game.getCurrentState().getCurrentPlayer().getUserName(); - assertFalse(controller.pickOptionalTribeCard(cur, 0)); - assertFalse(controller.pickOptionalBuildingCard(cur, 0)); + assertFalse(controller.drawLowerBuildingCard(current.getUserName(), 0)); + } + + @Test + void pickOptionalCardsShouldReturnFalseOutsideOptionalCardEffectState() { + Game game = createStartedGame(); + GameController controller = new GameController(game); + + completeSlotChoice(game, controller); + + assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + + String cur = game.getCurrentState().getCurrentPlayer().getUserName(); + + assertFalse(controller.pickOptionalTribeCard(cur, 0)); + assertFalse(controller.pickOptionalBuildingCard(cur, 0)); + } + + @Test + void pickOptionalTribeCardShouldWorkDuringOptionalCardEffectState() { + Game game = createStartedGame(); + GameController controller = new GameController(game); + + giveOptionalEffectToAllPlayers(game); + + completeSlotChoice(game, controller); + resolveActionsUntilOptionalCardEffect(game, controller); + + Player optionalPlayer = game.getCurrentState().getCurrentPlayer(); + assertNotNull(optionalPlayer); + + assertTrue(optionalPlayer.buildingCards.stream() + .anyMatch(building -> building.getEffectId() == 12)); + + List upperCards = game.getUpperListTribeCards(); + int index = firstNonEventIndex(upperCards); + + int charactersBefore = optionalPlayer.getTotCharacters(); + + assertTrue(controller.pickOptionalTribeCard(optionalPlayer.getUserName(), index)); + + assertEquals(charactersBefore + 1, optionalPlayer.getTotCharacters()); + } + + @Test + void pickOptionalBuildingCardShouldWorkDuringOptionalCardEffectState() { + Game game = createStartedGame(); + GameController controller = new GameController(game); + + giveOptionalEffectToAllPlayers(game); + + completeSlotChoice(game, controller); + resolveActionsUntilOptionalCardEffect(game, controller); + + Player optionalPlayer = game.getCurrentState().getCurrentPlayer(); + assertNotNull(optionalPlayer); + + assertTrue(optionalPlayer.buildingCards.stream() + .anyMatch(building -> building.getEffectId() == 12)); + + assertFalse(game.getUpperListBuilding().isEmpty()); + + optionalPlayer.addFood(100); + + int foodBefore = optionalPlayer.getFoodValue(); + int buildingsBefore = optionalPlayer.buildingCards.size(); + + assertTrue(controller.pickOptionalBuildingCard(optionalPlayer.getUserName(), 0)); + + assertTrue(optionalPlayer.getFoodValue() < foodBefore); + assertEquals(buildingsBefore + 1, optionalPlayer.buildingCards.size()); + } + + @Test + void addPlayerShouldRejectDuplicateUsername() { + Game game = new Game(3); + GameController controller = new GameController(game); + + assertTrue(controller.addPlayer("Giorgio")); + assertFalse(controller.addPlayer("Giorgio")); + } + + @Test + void drawingMethodsShouldReturnFalseForInvalidIndexes() { + Game game = createStartedGame(); + GameController controller = new GameController(game); + + completeSlotChoice(game, controller); + + Player current = game.getCurrentState().getCurrentPlayer(); + String username = current.getUserName(); + + assertFalse(controller.drawLowerTribeCard(username, -1)); + assertFalse(controller.drawLowerTribeCard(username, 999)); + + assertFalse(controller.drawUpperTribeCard(username, -1)); + assertFalse(controller.drawUpperTribeCard(username, 999)); + + assertFalse(controller.drawLowerBuildingCard(username, -1)); + assertFalse(controller.drawLowerBuildingCard(username, 999)); + + assertFalse(controller.drawUpperBuildingCard(username, -1)); + assertFalse(controller.drawUpperBuildingCard(username, 999)); + } + + @Test + void slotChoiceShouldReturnFalseForAlreadyOccupiedSlot() { + Game game = createStartedGame(); + GameController controller = new GameController(game); + + Player first = game.getCurrentState().getCurrentPlayer(); + assertTrue(controller.slotChoice(first.getUserName(), 0)); + + Player second = game.getCurrentState().getCurrentPlayer(); + + assertFalse(controller.slotChoice(second.getUserName(), 0)); } } diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java index 0d6087b..959dd13 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -5,187 +5,381 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; -import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; -import org.junit.platform.commons.annotation.Testable; +import org.junit.jupiter.api.Timeout; import java.io.IOException; import java.util.*; +import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; +@Timeout(value = 10, unit = TimeUnit.SECONDS) class GameTest { - @Test void Game() - { - int nPlayers = 3; - Game game=new Game(nPlayers); - assertEquals(nPlayers,game.getNPlayers()); - assertEquals(GameStages.WAITING,game.getCurrentState().getGameStage()); - assertThrows(IllegalArgumentException.class,()->new Game(6)); - game=new Game(); + + private Queue completeSlotChoice(Game game) { + Queue order = new LinkedList<>(); + + for (int i = 0; i < game.getNPlayers(); i++) { + Player current = game.getCurrentState().getCurrentPlayer(); + order.add(current); + + assertTrue(game.SlotChoiceByIndex(current, i)); + } + + assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + + return order; + } + + private int firstNonEventIndex(List cards) { + for (int i = 0; i < cards.size(); i++) { + if (!cards.get(i).IsEventCard()) { + return i; + } + } + + fail("No non-event tribe card available."); + return -1; + } + + private int firstNonEventIndexOrMinusOne(List cards) { + for (int i = 0; i < cards.size(); i++) { + if (!cards.get(i).IsEventCard()) { + return i; + } + } + + return -1; + } + + private void giveOptionalEffectToAllPlayers(Player... players) { + for (Player player : players) { + player.buildingCards.add(new BuildingCard(12, 1, 1, 1)); + } + } + + private void resolveAllMandatoryActions(Game game) { + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS) { + resolveOneMandatoryAction(game); + } + } + + private void resolveOneMandatoryAction(Game game) { + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + if (game.getCurrentState().getNLower() > 0 && hasDrawableLower(game)) { + int index = firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()); + + if (index != -1) { + assertTrue(game.DrawLowerTribeCardByIndex(current, index)); + } else { + current.addFood(100); + assertTrue(game.DrawLowerBuildingCardByIndex(current, 0)); + } + + } else if (game.getCurrentState().getNUpper() > 0 && hasDrawableUpper(game)) { + int index = firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()); + + if (index != -1) { + assertTrue(game.DrawUpperTribeCardByIndex(current, index)); + } else { + current.addFood(100); + assertTrue(game.DrawUpperBuildingCardByIndex(current, 0)); + } + + } else { + fail( + "Current player has no drawable cards, although the game is still resolving actions.\n" + + "Current player: " + current + "\n" + + "Round: " + game.getCurrentState().getRound() + "\n" + + "Stage: " + game.getCurrentState().getGameStage() + "\n" + + "Slot: " + (game.getCurrentState().getSlot() == null + ? "null" + : game.getCurrentState().getSlot().getSlotId()) + "\n" + + "NLower: " + game.getCurrentState().getNLower() + "\n" + + "NUpper: " + game.getCurrentState().getNUpper() + "\n" + + "Lower tribe size: " + game.getLowerListTribeCards().size() + "\n" + + "Upper tribe size: " + game.getUpperListTribeCards().size() + "\n" + + "Lower building size: " + game.getLowerListBuilding().size() + "\n" + + "Upper building size: " + game.getUpperListBuilding().size() + "\n" + + "First lower non-event: " + firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()) + "\n" + + "First upper non-event: " + firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()) + ); + } + } + + private void resolveActionsUntilOptionalCardEffect(Game game) { + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS) { + resolveOneMandatoryAction(game); + } + + assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + } + + private void resolveOptionalPhaseIfPresent(Game game) { + while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT) { + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertTrue(game.NoOptionalCard(current)); + } + } + + private void playOneFullRound(Game game) { + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + + completeSlotChoice(game); + + assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + + resolveAllMandatoryActions(game); + + resolveOptionalPhaseIfPresent(game); + } + + private boolean hasDrawableLower(Game game) { + return firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()) != -1 + || !game.getLowerListBuilding().isEmpty(); + } + + private boolean hasDrawableUpper(Game game) { + return firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()) != -1 + || !game.getUpperListBuilding().isEmpty(); + } + + @Test + void constructorShouldInitializeGameCorrectly() { + int nPlayers = 3; + Game game = new Game(nPlayers); + + assertEquals(nPlayers, game.getNPlayers()); + assertEquals(GameStages.WAITING, game.getCurrentState().getGameStage()); + + assertThrows(IllegalArgumentException.class, () -> new Game(6)); + assertThrows(IllegalArgumentException.class, () -> new Game(-1)); + + game = new Game(); + assertFalse(game.addPlayer(new Player("p1"))); - game.setNPlayer(nPlayers); + + + assertTrue(game.setNPlayer(nPlayers)); assertTrue(game.addPlayer(new Player("p1"))); - assertEquals(nPlayers,game.getNPlayers()); - assertEquals(GameStages.WAITING,game.getCurrentState().getGameStage()); + + assertEquals(nPlayers, game.getNPlayers()); + assertEquals(GameStages.WAITING, game.getCurrentState().getGameStage()); } @Test void getUpperListTribeCards() { int nPlayers = 3; - Game game=new Game(nPlayers); - assertEquals(nPlayers+4 ,game.getUpperListTribeCards().size()); + Game game = new Game(nPlayers); + assertEquals(nPlayers + 4, game.getUpperListTribeCards().size()); } + @Test void getUpperListBuildingCards() { int nPlayers = 3; - Game game=new Game(nPlayers); - assertEquals(2 ,game.getUpperListBuilding().size()); + Game game = new Game(nPlayers); + assertEquals(2, game.getUpperListBuilding().size()); } @Test void getLowerListBuildingCards() { int nPlayers = 3; - Game game=new Game(nPlayers); - assertEquals(0 ,game.getLowerListBuilding().size()); + Game game = new Game(nPlayers); + assertEquals(0, game.getLowerListBuilding().size()); } @Test void getLowerListTribeCards() { int nPlayers = 3; - Game game=new Game(nPlayers); - assertEquals(nPlayers+1 ,game.getLowerListTribeCards().size()); + Game game = new Game(nPlayers); + assertEquals(nPlayers + 1, game.getLowerListTribeCards().size()); } @Test - void getPlayerByIndex() { + void getPlayerByUsernameShouldReturnPlayerOrNull() { + Game game = new Game(3); + + Player p1 = new Player("p1"); + + assertTrue(game.addPlayer(p1)); + + assertEquals(p1, game.getPlayerByUsername("p1")); + assertNull(game.getPlayerByUsername("ghost")); } @Test - void getNPlayers() { + void setNPlayerShouldWorkOnlyIfGameWasCreatedWithZeroPlayers() { + Game game = new Game(); + assertTrue(game.setNPlayer(3)); + assertEquals(3, game.getNPlayers()); + + assertFalse(game.setNPlayer(4)); } @Test - void addPlayer() { - Game game=new Game(3); - Player p1=new Player("p1"); - Player p2=new Player("p2"); - Player p3=new Player("p3"); - Player p4=new Player("p3"); + void addPlayerShouldRejectDuplicatesAndStartSlotChoiceWhenFull() { + Game game = new Game(3); + Player p1 = new Player("p1"); + Player p2 = new Player("p2"); + Player p3 = new Player("p3"); + Player p4 = new Player("p4"); assertTrue(game.addPlayer(p1)); assertTrue(game.addPlayer(p2)); assertFalse(game.addPlayer(p2)); assertTrue(game.addPlayer(p3)); - assertEquals(GameStages.SLOT_CHOICE,game.getCurrentState().getGameStage()); + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertFalse(game.addPlayer(p4)); - - } @Test - void init() { + void shouldRejectInvalidSlotChoices() { + Game game = new Game(3); - } + Player p1 = new Player("p1"); + Player p2 = new Player("p2"); + Player p3 = new Player("p3"); - @Test - void slotChoiceByIndex() { + assertTrue(game.addPlayer(p1)); + assertTrue(game.addPlayer(p2)); + assertTrue(game.addPlayer(p3)); + + Player current = game.getCurrentState().getCurrentPlayer(); + + assertFalse(game.SlotChoiceByIndex(current, -1)); + assertFalse(game.SlotChoiceByIndex(current, 999)); + + Player wrongPlayer = current.equals(p1) ? p2 : p1; + assertFalse(game.SlotChoiceByIndex(wrongPlayer, 0)); + + assertTrue(game.SlotChoiceByIndex(current, 0)); + + Player next = game.getCurrentState().getCurrentPlayer(); + assertFalse(game.SlotChoiceByIndex(next, 0)); } @Test void drawingByIndex() { - Game game=new Game(3); - Player p1=new Player("p1"); - Player p2=new Player("p2"); - Player p3=new Player("p3"); - Player p4=new Player("p3"); + 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)); assertFalse(game.addPlayer(p2)); assertTrue(game.addPlayer(p3)); - Queueplayers=new LinkedList<>(); - for(int i=0;i<3;i++) { - players.add( game.getCurrentState().getCurrentPlayer()); + Queue players = new LinkedList<>(); + for (int i = 0; i < 3; i++) { + players.add(game.getCurrentState().getCurrentPlayer()); assertTrue(game.SlotChoiceByIndex(game.getCurrentState().getCurrentPlayer(), i)); } Player temp_player; - System.out.println(game); - temp_player=players.poll(); - assertEquals(temp_player,game.getCurrentState().getCurrentPlayer()); + + temp_player = players.poll(); + assertEquals(temp_player, game.getCurrentState().getCurrentPlayer()); int index; - List cards=game.getLowerListTribeCards(); + List cards = game.getLowerListTribeCards(); - index=cards.indexOf(cards.stream().filter(x->!x.IsEventCard()).findFirst().get()); - assertTrue(game.DrawLowerTribeCardByIndex(temp_player,index)); + index = firstNonEventIndex(cards); + assertTrue(game.DrawLowerTribeCardByIndex(temp_player, index)); - temp_player=players.poll(); - assertEquals(temp_player,game.getCurrentState().getCurrentPlayer()); - int nCards=game.getUpperListTribeCards().size(); - int countCards=0; - HashMapnCardsByType=new HashMap(); - Arrays.stream(CharacterType.values()).forEach(type->nCardsByType.put(type,0)); - while(game.getCurrentState().getNUpper()>1) { - cards=game.getUpperListTribeCards(); - TribeCard temp_card=cards.stream().filter(x->!x.IsEventCard()).findFirst().get(); - index=cards.indexOf(temp_card); - assertEquals(nCards-countCards,game.getUpperListTribeCards().size()-countCards); - drawTribeTest(nCardsByType,nCards,countCards,temp_card,temp_player,game); - assertTrue(game.DrawUpperTribeCardByIndex(temp_player,index)); + temp_player = players.poll(); + assertEquals(temp_player, game.getCurrentState().getCurrentPlayer()); + + int nCards = game.getUpperListTribeCards().size(); + int countCards = 0; + HashMap nCardsByType = new HashMap(); + Arrays.stream(CharacterType.values()).forEach(type -> nCardsByType.put(type, 0)); + while (game.getCurrentState().getNUpper() > 1) { + cards = game.getUpperListTribeCards(); + index = firstNonEventIndexOrMinusOne(cards); + + if (index == -1) { + break; + } + + TribeCard temp_card = cards.get(index); + assertEquals(nCards - countCards, game.getUpperListTribeCards().size()); + assertTrue(game.DrawUpperTribeCardByIndex(temp_player, index)); + drawTribeTest(nCardsByType, temp_card, temp_player); countCards++; } - cards=game.getUpperListTribeCards(); - try { - index = cards.indexOf(cards.stream().filter(TribeCard::IsEventCard).findFirst().get()); - assertFalse(game.DrawUpperTribeCardByIndex(temp_player, index)); - }catch (Exception e) { + cards = game.getUpperListTribeCards(); + int eventIndex = firstEventIndexOrMinusOne(cards); + if (eventIndex != -1) { + assertFalse(game.DrawUpperTribeCardByIndex(temp_player, eventIndex)); } - //index=cards.indexOf(cards.stream().filter(x->!x.IsEventCard()).findFirst().get()); - //assertTrue(game.DrawUpperTribeCardByIndex(temp_player,index)); - List buildings=game.getUpperListBuilding(); - temp_player.addFood(10); - index=0; - assertTrue(game.DrawUpperBuildingCardByIndex(temp_player,index)); - index=cards.indexOf(cards.stream().filter(x->!x.IsEventCard()).findFirst().get()); - assertFalse(game.DrawUpperTribeCardByIndex(temp_player,index)); + + temp_player.addFood(100); + + assertFalse(game.getUpperListBuilding().isEmpty()); + + index = 0; + assertTrue(game.DrawUpperBuildingCardByIndex(temp_player, index)); + + int remainingTribeIndex = firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()); + if (remainingTribeIndex != -1) { + assertFalse(game.DrawUpperTribeCardByIndex(temp_player, remainingTribeIndex)); + } + + Player thirdPlayer = players.poll(); + assertNotNull(thirdPlayer); + assertEquals(thirdPlayer, game.getCurrentState().getCurrentPlayer()); + + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS + && thirdPlayer.equals(game.getCurrentState().getCurrentPlayer())) { + resolveOneMandatoryAction(game); + } + + assertNotEquals(thirdPlayer, game.getCurrentState().getCurrentPlayer()); System.out.println(game); } - private void drawTribeTest(HashMapnCardsByType,int nCards,int countCards,TribeCard temp_card,Player temp_player,Game game) { - switch (((Character)temp_card).getType()) { - case CharacterType.ARTIST: - assertEquals( nCardsByType.get(((Character)temp_card).getType())+1,temp_player.artists.size()); - nCardsByType.merge(((Character)temp_card).getType(),1,Integer::sum); + private void drawTribeTest(HashMap nCardsByType, + TribeCard temp_card, + Player temp_player) { + + switch (((Character) temp_card).getType()) { + case ARTIST: + assertEquals(nCardsByType.get(((Character) temp_card).getType()) + 1, temp_player.artists.size()); + nCardsByType.merge(((Character) temp_card).getType(), 1, Integer::sum); break; - case CharacterType.INVENTOR: - assertEquals( nCardsByType.get(((Character)temp_card).getType())+1,temp_player.inventors.size()); - nCardsByType.merge(((Character)temp_card).getType(),1,Integer::sum); + case INVENTOR: + assertEquals(nCardsByType.get(((Character) temp_card).getType()) + 1, temp_player.inventors.size()); + nCardsByType.merge(((Character) temp_card).getType(), 1, Integer::sum); break; - case CharacterType.HUNTER: - assertEquals( nCardsByType.get(((Character)temp_card).getType())+1,temp_player.hunters.size()); - nCardsByType.merge(((Character)temp_card).getType(),1,Integer::sum); + case HUNTER: + assertEquals(nCardsByType.get(((Character) temp_card).getType()) + 1, temp_player.hunters.size()); + nCardsByType.merge(((Character) temp_card).getType(), 1, Integer::sum); break; - case CharacterType.SHAMAN: - assertEquals( nCardsByType.get(((Character)temp_card).getType())+1,temp_player.shamans.size()); - nCardsByType.merge(((Character)temp_card).getType(),1,Integer::sum); + case SHAMAN: + assertEquals(nCardsByType.get(((Character) temp_card).getType()) + 1, temp_player.shamans.size()); + nCardsByType.merge(((Character) temp_card).getType(), 1, Integer::sum); break; - case CharacterType.BUILDER: - assertEquals( nCardsByType.get(((Character)temp_card).getType())+1,temp_player.builders.size()); - nCardsByType.merge(((Character)temp_card).getType(),1,Integer::sum); + case BUILDER: + assertEquals(nCardsByType.get(((Character) temp_card).getType()) + 1, temp_player.builders.size()); + nCardsByType.merge(((Character) temp_card).getType(), 1, Integer::sum); break; - case CharacterType.GATHERER: - assertEquals( nCardsByType.get(((Character)temp_card).getType())+1,temp_player.gatherers.size()); - nCardsByType.merge(((Character)temp_card).getType(),1,Integer::sum); + case GATHERER: + assertEquals(nCardsByType.get(((Character) temp_card).getType()) + 1, temp_player.gatherers.size()); + nCardsByType.merge(((Character) temp_card).getType(), 1, Integer::sum); break; } @@ -193,12 +387,425 @@ class GameTest { @Test void pickOptionalTribeCard() { + 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)); + + giveOptionalEffectToAllPlayers(p1, p2, p3); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + int index = firstNonEventIndex(game.getUpperListTribeCards()); + + int charactersBefore = current.getTotCharacters(); + + assertTrue(game.PickOptionalTribeCardByIndex(current, index)); + + assertEquals(charactersBefore + 1, current.getTotCharacters()); } + @Test void pickOptionalBuildingCard() { + 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)); + + giveOptionalEffectToAllPlayers(p1, p2, p3); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertFalse(game.getUpperListBuilding().isEmpty()); + + current.addFood(100); + + int foodBefore = current.getFoodValue(); + int buildingsBefore = current.buildingCards.size(); + + assertTrue(game.PickOptionalBuildingCard(current, 0)); + + assertTrue(current.getFoodValue() < foodBefore); + assertEquals(buildingsBefore + 1, current.buildingCards.size()); } + @Test void noOptionalCard() { + 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)); + + giveOptionalEffectToAllPlayers(p1, p2, p3); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertTrue(game.NoOptionalCard(current)); + + assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + assertNotEquals(current, game.getCurrentState().getCurrentPlayer()); + } + + private List addPlayers(Game game, int nPlayers, String prefix) { + List players = new ArrayList<>(); + + for (int i = 1; i <= nPlayers; i++) { + Player player = new Player(prefix + i); + players.add(player); + assertTrue(game.addPlayer(player)); + } + + return players; + } + + private int firstEventIndexOrMinusOne(List cards) { + for (int i = 0; i < cards.size(); i++) { + if (cards.get(i).IsEventCard()) { + return i; + } + } + + return -1; + } + + @Test + void getCurrentPlayerNumberShouldTrackAddedPlayers() { + Game game = new Game(3); + + assertEquals(0, game.getCurrentPlayerNumber()); + + assertTrue(game.addPlayer(new Player("a"))); + assertEquals(1, game.getCurrentPlayerNumber()); + + assertTrue(game.addPlayer(new Player("b"))); + assertEquals(2, game.getCurrentPlayerNumber()); + + assertTrue(game.addPlayer(new Player("c"))); + assertEquals(3, game.getCurrentPlayerNumber()); + } + + + @Test + void slotChoiceByIndexShouldReturnFalseOutsideSlotChoiceStage() { + Game game = new Game(3); + + addPlayers(game, 3, "slot_out_"); + + completeSlotChoice(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertFalse(game.SlotChoiceByIndex(current, 0)); + } + + @Test + void shouldRejectInvalidDrawRequests() { + 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)); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertFalse(game.DrawLowerTribeCardByIndex(current, 0)); + assertFalse(game.DrawUpperTribeCardByIndex(current, 0)); + assertFalse(game.DrawUpperBuildingCardByIndex(current, 0)); + assertFalse(game.DrawLowerBuildingCardByIndex(current, 0)); + + completeSlotChoice(game); + + current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + Player wrongPlayer = current.equals(p1) ? p2 : p1; + + assertFalse(game.DrawLowerTribeCardByIndex(current, -1)); + assertFalse(game.DrawLowerTribeCardByIndex(current, 999)); + + assertFalse(game.DrawUpperTribeCardByIndex(current, -1)); + assertFalse(game.DrawUpperTribeCardByIndex(current, 999)); + + assertFalse(game.DrawUpperBuildingCardByIndex(current, -1)); + assertFalse(game.DrawUpperBuildingCardByIndex(current, 999)); + + assertFalse(game.DrawLowerBuildingCardByIndex(current, -1)); + assertFalse(game.DrawLowerBuildingCardByIndex(current, 999)); + + int lowerIndex = firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()); + if (lowerIndex != -1) { + assertFalse(game.DrawLowerTribeCardByIndex(wrongPlayer, lowerIndex)); + } + + int upperIndex = firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()); + if (upperIndex != -1) { + assertFalse(game.DrawUpperTribeCardByIndex(wrongPlayer, upperIndex)); + } + + if (!game.getUpperListBuilding().isEmpty()) { + assertFalse(game.DrawUpperBuildingCardByIndex(wrongPlayer, 0)); + } + } + + + @Test + void optionalMethodsShouldReturnFalseOutsideOptionalState() { + Game game = new Game(3); + + addPlayers(game, 3, "optional_out_"); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertFalse(game.PickOptionalTribeCardByIndex(current, 0)); + assertFalse(game.PickOptionalBuildingCard(current, 0)); + assertFalse(game.NoOptionalCard(current)); + } + + @Test + void optionalMethodsShouldRejectWrongPlayerAndInvalidIndexes() { + Game game = new Game(3); + + List players = addPlayers(game, 3, "optional_invalid_"); + + giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + Player wrongPlayer = current.equals(players.get(0)) ? players.get(1) : players.get(0); + + assertFalse(game.PickOptionalTribeCardByIndex(wrongPlayer, 0)); + assertFalse(game.PickOptionalBuildingCard(wrongPlayer, 0)); + assertFalse(game.NoOptionalCard(wrongPlayer)); + + assertFalse(game.PickOptionalTribeCardByIndex(current, -1)); + assertFalse(game.PickOptionalTribeCardByIndex(current, 999)); + + assertFalse(game.PickOptionalBuildingCard(current, -1)); + assertFalse(game.PickOptionalBuildingCard(current, 999)); + + } + + @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) + void shouldNotCrashWhenNoPlayerHasOptionalEffect() { + Game game = new Game(3); + + addPlayers(game, 3, "no_optional_"); + + completeSlotChoice(game); + + assertDoesNotThrow(() -> resolveAllMandatoryActions(game)); + + assertNotEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + } + + + @Test + void constructorShouldRejectOnePlayerGame() { + assertThrows(IllegalArgumentException.class, () -> new Game(1)); + } + + @Test + void setNPlayerShouldAllowCompleteGameSetup() { + Game game = new Game(); + + assertTrue(game.setNPlayer(3)); + + assertTrue(game.addPlayer(new Player("p1"))); + assertTrue(game.addPlayer(new Player("p2"))); + assertTrue(game.addPlayer(new Player("p3"))); + + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertTrue(game.SlotChoiceByIndex(current, 0)); + } + + @Test + @Timeout(value = 20, unit = TimeUnit.SECONDS) + void shouldCompleteFullGameThroughRealFlow() { + for (int nPlayers : new int[]{2, 3, 4, 5}) { + Game game = new Game(nPlayers); + + for (int i = 1; i <= nPlayers; i++) { + assertTrue(game.addPlayer(new Player("p" + nPlayers + "_" + i))); + } + + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(1, game.getCurrentState().getRound()); + assertNotNull(game.getCurrentState().getCurrentPlayer()); + + for (int expectedRound = 1; expectedRound < 10; expectedRound++) { + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(expectedRound, game.getCurrentState().getRound()); + + playOneFullRound(game); + + assertEquals( + GameStages.SLOT_CHOICE, + game.getCurrentState().getGameStage(), + "After round " + expectedRound + ", the game should return to SLOT_CHOICE." + ); + + assertEquals( + expectedRound + 1, + game.getCurrentState().getRound(), + "The round should increase after completing round " + expectedRound + "." + ); + + assertNotNull(game.getCurrentState().getCurrentPlayer()); + } + + assertEquals(10, game.getCurrentState().getRound()); + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + + playOneFullRound(game); + + assertEquals( + GameStages.ENDED, + game.getCurrentState().getGameStage(), + "The game should end after completing round 10 with " + nPlayers + " players." + ); + + assertEquals( + 10, + game.getCurrentState().getRound(), + "The game should end at round 10 with " + nPlayers + " players." + ); + } + } + + @Test + void setNPlayerShouldRejectInvalidPlayerCounts() { + assertFalse(new Game().setNPlayer(-1)); + assertFalse(new Game().setNPlayer(1)); + assertFalse(new Game().setNPlayer(6)); + } + + @Test + void addPlayerShouldRejectDifferentPlayerWithSameUsername() { + Game game = new Game(3); + + assertTrue(game.addPlayer(new Player("same_name"))); + assertFalse(game.addPlayer(new Player("same_name"))); + } + + @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) + void roundShouldAdvanceAfterOnlyOptionalPlayerSkipsOptionalCard() { + Game game = new Game(3); + + List players = addPlayers(game, 3, "single_optional_"); + + players.get(0).buildingCards.add(new BuildingCard(12, 1, 1, 1)); + + int roundBefore = game.getCurrentState().getRound(); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertTrue(game.NoOptionalCard(current)); + + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(roundBefore + 1, game.getCurrentState().getRound()); + assertNotNull(game.getCurrentState().getCurrentPlayer()); + } + + @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) + void roundShouldAdvanceAfterAllOptionalPlayersSkipOptionalCard() { + 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)); + + giveOptionalEffectToAllPlayers(p1, p2, p3); + + int roundBefore = game.getCurrentState().getRound(); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + resolveOptionalPhaseIfPresent(game); + + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(roundBefore + 1, game.getCurrentState().getRound()); + assertNotNull(game.getCurrentState().getCurrentPlayer()); + } + + @Test + void pickOptionalBuildingCardShouldReturnFalseIfPlayerCannotPay() { + Game game = new Game(3); + List players = addPlayers(game, 3, "no_food_"); + + giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + while (current.getFoodValue() > 0) { + assertTrue(current.removeFood(1)); + } + + assertEquals(0, current.getFoodValue()); + + assertFalse( + game.getUpperListBuilding().isEmpty(), + "There must be at least one upper building card to test that the player cannot buy it." + ); + + assertFalse(game.PickOptionalBuildingCard(current, 0)); } @Test void toStringModel() throws IOException, InterruptedException { @@ -221,8 +828,6 @@ class GameTest { assertTrue(game.SlotChoiceByIndex(game.getCurrentState().getCurrentPlayer(), i)); } - System.out.println(game.BoardStamp()); - String os = System.getProperty("os.name").toLowerCase(); - System.out.println(game.PlayersStamp()); + System.out.println(game.toString()); } } \ No newline at end of file diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order3Test.java b/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order3Test.java index 34c2e3e..3e24680 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order3Test.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order3Test.java @@ -69,7 +69,7 @@ class Order3Test { } @Test - void thirdReturnPaysFoodAndLosesPrestige() { + void thirdReturnPaysFoodWithoutLosingPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -90,33 +90,7 @@ class Order3Test { order.push(thirdToAct); assertEquals(0, thirdToAct.getFoodValue()); - assertEquals(-2, thirdToAct.getPrestigeValue()); - } - - @Test - void thirdReturnWithoutFoodNoEffect() { - Player p1 = new Player("p1"); - Player p2 = new Player("p2"); - Player p3 = new Player("p3"); - ArrayList players = new ArrayList<>(); - players.add(p1); - players.add(p2); - players.add(p3); - Order3 order = new Order3(players); - - Player firstToAct = order.pull(); - Player secondToAct = order.pull(); - Player thirdToAct = order.pull(); - - int initialFood = thirdToAct.getFoodValue(); - int initialPrestige = thirdToAct.getPrestigeValue(); - - order.push(firstToAct); - order.push(secondToAct); - order.push(thirdToAct); - - assertEquals(initialFood, thirdToAct.getFoodValue()); - assertEquals(initialPrestige, thirdToAct.getPrestigeValue()); + assertEquals(0, thirdToAct.getPrestigeValue()); } @Test diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order4Test.java b/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order4Test.java index c562f60..78e731f 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order4Test.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order4Test.java @@ -102,7 +102,7 @@ class Order4Test { } @Test - void fourthReturnPaysFoodAndLosesPrestige() { + void fourthReturnPaysFoodWithoutLosingPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -127,11 +127,11 @@ class Order4Test { order.push(fourthToAct); assertEquals(0, fourthToAct.getFoodValue()); - assertEquals(-2, fourthToAct.getPrestigeValue()); + assertEquals(0, fourthToAct.getPrestigeValue()); } @Test - void fourthReturnWithoutFoodNoEffect() { + void fourthReturnWithoutFoodLosesPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -157,7 +157,7 @@ class Order4Test { order.push(fourthToAct); assertEquals(initialFood, fourthToAct.getFoodValue()); - assertEquals(initialPrestige, fourthToAct.getPrestigeValue()); + assertEquals(initialPrestige - 2, fourthToAct.getPrestigeValue()); } @Test diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order5Test.java b/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order5Test.java index 0dceb69..9e838fb 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order5Test.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/Orders/Order5Test.java @@ -12,7 +12,9 @@ import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.NoSuchElementException; + import static org.junit.jupiter.api.Assertions.*; class Order5Test { @@ -149,7 +151,7 @@ class Order5Test { } @Test - void fifthReturnPaysFoodAndLosesPrestige() { + void fifthReturnPaysFoodWithoutLosingPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -178,11 +180,11 @@ class Order5Test { order.push(fifthToAct); assertEquals(0, fifthToAct.getFoodValue()); - assertEquals(-2, fifthToAct.getPrestigeValue()); + assertEquals(0, fifthToAct.getPrestigeValue()); } @Test - void fifthReturnWithoutFoodNoEffect() { + void fifthReturnWithoutFoodLosesPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -212,7 +214,7 @@ class Order5Test { order.push(fifthToAct); assertEquals(initialFood, fifthToAct.getFoodValue()); - assertEquals(initialPrestige, fifthToAct.getPrestigeValue()); + assertEquals(initialPrestige - 2, fifthToAct.getPrestigeValue()); } @Test