From 6d1e41bb44aa8ecf34716bf46d0b716d2b27cb07 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Fri, 24 Apr 2026 18:05:58 +0200 Subject: [PATCH 01/13] Fix: GameControllerTest --- .../gc14/Controller/GameControllerTest.java | 416 ++++++++++++++---- 1 file changed, 322 insertions(+), 94 deletions(-) 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..efef3d5 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,111 @@ import static org.junit.jupiter.api.Assertions.*; class GameControllerTest { + private Game createStartedGame() { + Game game = new Game(3); + GameController controller = new GameController(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 +153,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 +169,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 +214,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 +222,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 +243,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)); } } From 2bce00ca805dbb3038b5916f78fd3316f46069ee Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Fri, 24 Apr 2026 18:14:02 +0200 Subject: [PATCH 02/13] Fixed: GameControllerTest --- .../it/polimi/ingsw/gc14/Controller/GameControllerTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 efef3d5..aa89a2a 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Controller/GameControllerTest.java @@ -18,7 +18,10 @@ 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")); From aee1d3ad873d8fcd5772789d0cd50e3ab6bcabd6 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Fri, 24 Apr 2026 20:15:27 +0200 Subject: [PATCH 03/13] Fix: GameTest --- .../it/polimi/ingsw/gc14/Model/GameTest.java | 699 +++++++++++++++++- 1 file changed, 677 insertions(+), 22 deletions(-) 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 9dcb81a..228e64a 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -5,15 +5,116 @@ 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 java.util.*; import static org.junit.jupiter.api.Assertions.*; class GameTest { + + private Queue completeSlotChoice(Game game) { + Queue order = new LinkedList<>(); + + for (int i = 0; i < 3; 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 p1, Player p2, Player p3) { + p1.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + p2.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + p3.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + } + + private void resolveActionsUntilOptionalCardEffect(Game game) { + 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 lower non-event tribe card available."); + } + + assertTrue(game.DrawLowerTribeCardByIndex(current, index)); + } else if (game.getCurrentState().getNUpper() > 0) { + 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 remaining draws."); + } + } + + assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + } + + private static class FinalTestBuildingCard extends BuildingCard { + FinalTestBuildingCard() { + super(12, 1, 1, 0); + } + + @Override + public it.polimi.ingsw.gc14.Model.Cards.Building.EffectType getEffectType() { + return it.polimi.ingsw.gc14.Model.Cards.Building.EffectType.FINAL; + } + + @Override + public void applyEffect(Player player) { + player.addPrestige(10); + } + } + + private void setCurrentStateEra(Game game, int era) { + try { + java.lang.reflect.Field field = game.getCurrentState().getClass().getDeclaredField("Era"); + field.setAccessible(true); + field.set(game.getCurrentState(), era); + } catch (Exception e) { + fail("Failed to set CurrentState era: " + e.getMessage()); + } + } + @Test void Game() { int nPlayers = 3; @@ -22,6 +123,7 @@ class GameTest { 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); @@ -60,40 +162,69 @@ class GameTest { @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"); + 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 slotChoiceByIndexShouldRejectInvalidWrongAndOccupiedSlot() { + 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 @@ -102,7 +233,6 @@ class GameTest { Player p1=new Player("p1"); Player p2=new Player("p2"); Player p3=new Player("p3"); - Player p4=new Player("p3"); assertTrue(game.addPlayer(p1)); assertTrue(game.addPlayer(p2)); @@ -140,14 +270,15 @@ class GameTest { assertTrue(game.DrawUpperTribeCardByIndex(temp_player,index)); countCards++; } - cards=game.getUpperListTribeCards(); + cards = game.getUpperListTribeCards(); - index=cards.indexOf(cards.stream().filter(TribeCard::IsEventCard).findFirst().get()); - assertFalse(game.DrawUpperTribeCardByIndex(temp_player,index)); + 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); + temp_player.addFood(100); index=0; assertTrue(game.DrawUpperBuildingCardByIndex(temp_player,index)); index=cards.indexOf(cards.stream().filter(x->!x.IsEventCard()).findFirst().get()); @@ -188,11 +319,535 @@ 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; + } + + private it.polimi.ingsw.gc14.Model.GamePackage.Board getBoard(Game game) { + try { + java.lang.reflect.Field field = Game.class.getDeclaredField("board"); + field.setAccessible(true); + return (it.polimi.ingsw.gc14.Model.GamePackage.Board) field.get(game); + } catch (Exception e) { + fail("Failed to access board field: " + e.getMessage()); + return null; + } + } + + private void invokePrivateMethod(Game game, String methodName) { + try { + java.lang.reflect.Method method = Game.class.getDeclaredMethod(methodName); + method.setAccessible(true); + method.invoke(game); + } catch (Exception e) { + fail("Failed to invoke private method " + methodName + ": " + e.getMessage()); + } + } + + @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 drawMethodsShouldRejectWrongStateInvalidIndexesAndWrongPlayer() { + 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 drawUpperTribeCardShouldReturnFalseForEventCardIfPresent() { + Game game = new Game(3); + + addPlayers(game, 3, "event_"); + + completeSlotChoice(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + int eventIndex = firstEventIndexOrMinusOne(game.getUpperListTribeCards()); + + if (eventIndex != -1) { + assertFalse(game.DrawUpperTribeCardByIndex(current, eventIndex)); + } + } + + @Test + void drawLowerBuildingCardShouldWorkWhenLowerBuildingExists() { + Game game = new Game(3); + + addPlayers(game, 3, "lower_building_"); + completeSlotChoice(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + game.getCurrentState().PlayerUpdate(current, new Slot('D')); + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.lowerListBuilding.clear(); + board.lowerListBuilding.add(new BuildingCard(12, 1, 1, 0)); + + current.addFood(100); + + int foodBefore = current.getFoodValue(); + int buildingsBefore = current.buildingCards.size(); + + assertTrue(game.DrawLowerBuildingCardByIndex(current, 0)); + + assertTrue(current.getFoodValue() < foodBefore); + assertEquals(buildingsBefore + 1, current.buildingCards.size()); + assertEquals(1, game.getCurrentState().getNLower()); + } + + @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 optionalMethodsShouldRejectWrongPlayerInvalidIndexesAndEventCards() { + 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)); + + int eventIndex = firstEventIndexOrMinusOne(game.getUpperListTribeCards()); + + if (eventIndex != -1) { + assertFalse(game.PickOptionalTribeCardByIndex(current, eventIndex)); + } + } + + @Test + void pickOptionalBuildingCardShouldReturnFalseIfPlayerCannotPay() { + Game game = new Game(3); + + List players = addPlayers(game, 3, "optional_no_food_"); + + giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + if (!game.getUpperListBuilding().isEmpty()) { + assertFalse(game.PickOptionalBuildingCard(current, 0)); + } + } + + @Test + void eventResolutionShouldDoNothingOutsideResolvingEventStage() { + Game game = new Game(3); + + assertEquals(GameStages.WAITING, game.getCurrentState().getGameStage()); + + invokePrivateMethod(game, "EventResolution"); + + assertEquals(GameStages.WAITING, game.getCurrentState().getGameStage()); + } + + + @Test + void nextRoundShouldIncreaseRound() { + Game game = new Game(3); + + int roundBefore = game.getCurrentState().getRound(); + + invokePrivateMethod(game, "nextRound"); + + assertEquals(roundBefore + 1, game.getCurrentState().getRound()); + } + + @Test + void nextRoundAtRoundTenShouldEndGame() { + Game game = new Game(3); + + for (int i = 0; i < 9; i++) { + game.getCurrentState().RoundUpdate(); + } + + assertEquals(10, game.getCurrentState().getRound()); + + invokePrivateMethod(game, "nextRound"); + + assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); + } + + + @Test + void addObserverAndNotifyObserversShouldCallObserver() { + Game game = new Game(3); + + final boolean[] notified = {false}; + + game.addObserver(updatedGame -> { + assertSame(game, updatedGame); + notified[0] = true; + }); + + invokePrivateMethod(game, "notifyObservers"); + + assertTrue(notified[0]); + } + + @Test + void drawLowerTribeCardShouldReturnFalseWhenNoLowerDrawsAreAvailable() { + Game game = new Game(3); + + addPlayers(game, 3, "no_lower_"); + completeSlotChoice(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + game.getCurrentState().PlayerUpdate(current, new Slot('C')); + + int index = firstNonEventIndex(game.getLowerListTribeCards()); + + assertEquals(0, game.getCurrentState().getNLower()); + assertFalse(game.DrawLowerTribeCardByIndex(current, index)); + } + + @Test + void drawLowerTribeCardShouldReturnFalseForEventCard() { + Game game = new Game(3); + + addPlayers(game, 3, "lower_event_"); + completeSlotChoice(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + game.getCurrentState().PlayerUpdate(current, new Slot('B')); + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.lowerListTribe.add(0, + new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.Sustenance(1, 3)); + + assertTrue(board.lowerListTribe.get(0).IsEventCard()); + assertFalse(game.DrawLowerTribeCardByIndex(current, 0)); + } + + @Test + void drawUpperBuildingCardShouldReturnFalseWhenNoUpperDrawsAreAvailable() { + Game game = new Game(3); + + addPlayers(game, 3, "no_upper_building_"); + completeSlotChoice(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + game.getCurrentState().PlayerUpdate(current, new Slot('B')); + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.upperListBuilding.clear(); + board.upperListBuilding.add(new BuildingCard(12, 1, 1, 0)); + + current.addFood(100); + + assertEquals(0, game.getCurrentState().getNUpper()); + assertFalse(game.DrawUpperBuildingCardByIndex(current, 0)); + } + + @Test + void drawUpperBuildingCardShouldBuyBuildingAndDecreaseUpperDraws() { + Game game = new Game(3); + + addPlayers(game, 3, "upper_buy_true_"); + completeSlotChoice(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + game.getCurrentState().PlayerUpdate(current, new Slot('F')); + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.upperListBuilding.clear(); + board.upperListBuilding.add(new BuildingCard(12, 1, 1, 0)); + + current.addFood(100); + + int foodBefore = current.getFoodValue(); + int buildingsBefore = current.buildingCards.size(); + + assertTrue(game.DrawUpperBuildingCardByIndex(current, 0)); + + assertTrue(current.getFoodValue() < foodBefore); + assertEquals(buildingsBefore + 1, current.buildingCards.size()); + assertEquals(1, game.getCurrentState().getNUpper()); + } + + @Test + void eventResolutionShouldActivateNormalAndSustenanceEvents() { + Game game = new Game(3); + + addPlayers(game, 3, "events_"); + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.lowerListTribe.clear(); + + board.lowerListTribe.add( + new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.ShamanicRitual(1, 15, 7)); + + board.lowerListTribe.add( + new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.Sustenance(1, 3)); + + game.getCurrentState().GameStageUpdate(GameStages.RESOLVING_EVENT); + + invokePrivateMethod(game, "EventResolution"); + + assertEquals(GameStages.RESOLVING_EVENT, game.getCurrentState().getGameStage()); + } + + @Test + void nextRoundShouldUpdateEraWhenBoardEraDiffersFromCurrentStateEra() { + Game game = new Game(3); + + setCurrentStateEra(game, 0); + + assertEquals(0, game.getCurrentState().getEra()); + + invokePrivateMethod(game, "nextRound"); + + assertEquals(1, game.getCurrentState().getEra()); + } + + @Test + void endGameShouldApplyFinalBuildingEffectsAndSetEndedStage() { + Game game = new Game(3); + + Player player = new Player("final_player"); + assertTrue(game.addPlayer(player)); + + player.buildingCards.add(new FinalTestBuildingCard()); + + int prestigeBefore = player.getPrestigeValue(); + + invokePrivateMethod(game, "endGame"); + + assertEquals(prestigeBefore + 10, player.getPrestigeValue()); + assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); + } + } \ No newline at end of file From ee87efcc484941dd3deb0b81476945286cf10d4d Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Sat, 25 Apr 2026 17:10:49 +0200 Subject: [PATCH 04/13] Fix: GameTest --- .../it/polimi/ingsw/gc14/Model/GameTest.java | 448 ++++++++++++------ 1 file changed, 291 insertions(+), 157 deletions(-) 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 228e64a..6f6d5ec 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -1,5 +1,6 @@ package it.polimi.ingsw.gc14.Model; +import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; @@ -13,10 +14,11 @@ import static org.junit.jupiter.api.Assertions.*; class GameTest { + private Queue completeSlotChoice(Game game) { Queue order = new LinkedList<>(); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < game.getNPlayers(); i++) { Player current = game.getCurrentState().getCurrentPlayer(); order.add(current); @@ -49,61 +51,68 @@ class GameTest { return -1; } - private void giveOptionalEffectToAllPlayers(Player p1, Player p2, Player p3) { - p1.buildingCards.add(new BuildingCard(12, 1, 1, 0)); - p2.buildingCards.add(new BuildingCard(12, 1, 1, 0)); - p3.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + private void giveOptionalEffectToAllPlayers(Player... players) { + for (Player player : players) { + player.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + } + } + + private void resolveAllMandatoryActions(Game game) { + int guard = 0; + + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS && guard < 50) { + guard++; + resolveOneMandatoryAction(game); + } + + assertTrue(guard < 50, "Possible infinite loop while resolving mandatory actions."); + } + + private void resolveOneMandatoryAction(Game game) { + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + if (game.getCurrentState().getNLower() > 0) { + int index = firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()); + + if (index != -1) { + assertTrue(game.DrawLowerTribeCardByIndex(current, index)); + } else if (!game.getLowerListBuilding().isEmpty()) { + current.addFood(100); + assertTrue(game.DrawLowerBuildingCardByIndex(current, 0)); + } else { + fail("No valid lower card available."); + } + + } else if (game.getCurrentState().getNUpper() > 0) { + int index = firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()); + + if (index != -1) { + assertTrue(game.DrawUpperTribeCardByIndex(current, index)); + } else if (!game.getUpperListBuilding().isEmpty()) { + current.addFood(100); + assertTrue(game.DrawUpperBuildingCardByIndex(current, 0)); + } else { + fail("No valid upper card available."); + } + + } else { + fail("Current player has no remaining draws."); + } } private void resolveActionsUntilOptionalCardEffect(Game game) { int guard = 0; - while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS && guard < 20) { + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS && guard < 50) { guard++; - - Player current = game.getCurrentState().getCurrentPlayer(); - assertNotNull(current); - - if (game.getCurrentState().getNLower() > 0) { - int index = firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()); - - if (index == -1) { - fail("No lower non-event tribe card available."); - } - - assertTrue(game.DrawLowerTribeCardByIndex(current, index)); - } else if (game.getCurrentState().getNUpper() > 0) { - 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 remaining draws."); - } + resolveOneMandatoryAction(game); } + assertTrue(guard < 50, "Possible infinite loop while resolving mandatory actions."); assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); } - private static class FinalTestBuildingCard extends BuildingCard { - FinalTestBuildingCard() { - super(12, 1, 1, 0); - } - - @Override - public it.polimi.ingsw.gc14.Model.Cards.Building.EffectType getEffectType() { - return it.polimi.ingsw.gc14.Model.Cards.Building.EffectType.FINAL; - } - - @Override - public void applyEffect(Player player) { - player.addPrestige(10); - } - } private void setCurrentStateEra(Game game, int era) { try { @@ -115,49 +124,73 @@ class GameTest { } } - @Test void Game() - { - int nPlayers = 3; - Game game=new Game(nPlayers); - assertEquals(nPlayers,game.getNPlayers()); - assertEquals(GameStages.WAITING,game.getCurrentState().getGameStage()); + private static class FinalTestBuildingCard extends BuildingCard { - assertThrows(IllegalArgumentException.class,()->new Game(6)); + FinalTestBuildingCard() { + super(12, 1, 1, 0); + } + + @Override + public EffectType getEffectType() { + return EffectType.FINAL; + } + + @Override + public void applyEffect(Player player) { + player.addPrestige(10); + } + } + + @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(); + + 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()); } @@ -184,7 +217,7 @@ class GameTest { } @Test - void addPlayer() { + void addPlayerShouldRejectDuplicatesAndStartSlotChoiceWhenFull() { Game game = new Game(3); Player p1 = new Player("p1"); Player p2 = new Player("p2"); @@ -229,45 +262,50 @@ class GameTest { @Test void drawingByIndex() { - Game game=new Game(3); - Player p1=new Player("p1"); - Player p2=new Player("p2"); - Player p3=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; - 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(); @@ -276,42 +314,50 @@ class GameTest { 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)); + temp_player.addFood(100); - 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)); + + 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)); + } } - 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; } @@ -533,24 +579,6 @@ class GameTest { } } - @Test - void drawUpperTribeCardShouldReturnFalseForEventCardIfPresent() { - Game game = new Game(3); - - addPlayers(game, 3, "event_"); - - completeSlotChoice(game); - - Player current = game.getCurrentState().getCurrentPlayer(); - assertNotNull(current); - - int eventIndex = firstEventIndexOrMinusOne(game.getUpperListTribeCards()); - - if (eventIndex != -1) { - assertFalse(game.DrawUpperTribeCardByIndex(current, eventIndex)); - } - } - @Test void drawLowerBuildingCardShouldWorkWhenLowerBuildingExists() { Game game = new Game(3); @@ -596,7 +624,7 @@ class GameTest { } @Test - void optionalMethodsShouldRejectWrongPlayerInvalidIndexesAndEventCards() { + void optionalMethodsShouldRejectWrongPlayerAndInvalidIndexes() { Game game = new Game(3); List players = addPlayers(game, 3, "optional_invalid_"); @@ -621,11 +649,6 @@ class GameTest { assertFalse(game.PickOptionalBuildingCard(current, -1)); assertFalse(game.PickOptionalBuildingCard(current, 999)); - int eventIndex = firstEventIndexOrMinusOne(game.getUpperListTribeCards()); - - if (eventIndex != -1) { - assertFalse(game.PickOptionalTribeCardByIndex(current, eventIndex)); - } } @Test @@ -670,22 +693,6 @@ class GameTest { assertEquals(roundBefore + 1, game.getCurrentState().getRound()); } - @Test - void nextRoundAtRoundTenShouldEndGame() { - Game game = new Game(3); - - for (int i = 0; i < 9; i++) { - game.getCurrentState().RoundUpdate(); - } - - assertEquals(10, game.getCurrentState().getRound()); - - invokePrivateMethod(game, "nextRound"); - - assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); - } - - @Test void addObserverAndNotifyObserversShouldCallObserver() { Game game = new Game(3); @@ -797,7 +804,7 @@ class GameTest { } @Test - void eventResolutionShouldActivateNormalAndSustenanceEvents() { + void eventResolutionShouldNotCrashWithNormalAndSustenanceEvents() { Game game = new Game(3); addPlayers(game, 3, "events_"); @@ -838,7 +845,12 @@ class GameTest { Game game = new Game(3); Player player = new Player("final_player"); + Player p2 = new Player("p2"); + Player p3 = new Player("p3"); + assertTrue(game.addPlayer(player)); + assertTrue(game.addPlayer(p2)); + assertTrue(game.addPlayer(p3)); player.buildingCards.add(new FinalTestBuildingCard()); @@ -850,4 +862,126 @@ class GameTest { assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); } + @Test + 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 + void nextRoundAtRoundTenShouldNotIncreaseRoundAfterEndingGame() { + Game game = new Game(3); + + for (int i = 0; i < 9; i++) { + game.getCurrentState().RoundUpdate(); + } + + assertEquals(10, game.getCurrentState().getRound()); + + invokePrivateMethod(game, "nextRound"); + + assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); + assertEquals(10, game.getCurrentState().getRound()); + } + + @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 + void shouldNotCrashWhenOnlyOptionalPlayerSkipsOptionalCard() { + Game game = new Game(3); + + List players = addPlayers(game, 3, "single_optional_"); + + players.get(0).buildingCards.add(new BuildingCard(12, 1, 1, 0)); + + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertDoesNotThrow(() -> assertTrue(game.NoOptionalCard(current))); + + assertNotEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + } + + @Test + void optionalPhaseShouldFinishAfterAllPlayersSkipOptionalCard() { + 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); + + assertDoesNotThrow(() -> { + int guard = 0; + + while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT && guard < 10) { + guard++; + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertTrue(game.NoOptionalCard(current)); + } + + assertTrue(guard < 10, "Possible infinite loop during optional phase."); + assertNotEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + }); + } + + } \ No newline at end of file From 29df367e850c7b82a0e999668755b6e8d7d52c9e Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Sat, 25 Apr 2026 20:16:59 +0200 Subject: [PATCH 05/13] Fix: GameTest and Game --- .../java/it/polimi/ingsw/gc14/Model/Game.java | 63 ++++-- .../it/polimi/ingsw/gc14/Model/GameTest.java | 206 ++++++++++++------ 2 files changed, 189 insertions(+), 80 deletions(-) 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 4da7f49..c04e25b 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -157,8 +157,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<>(); @@ -406,7 +407,7 @@ public class Game implements Serializable { { return false; } - + if(!player.equals(currentState.getCurrentPlayer())) { return false; @@ -497,8 +498,8 @@ public class Game implements Serializable { else { return false; } - nextPlayerSetup(); OptionalCardQueue.removeIf(x->x.equals(player)); + nextPlayerSetup(); return true; } @@ -588,7 +589,7 @@ public class Game implements Serializable { { OptionalCardQueue.add(e.getKey()); } - currentState.PlayerUpdate(OptionalCardQueue.remove(), null); + currentState.PlayerUpdate(OptionalCardQueue.poll(), null); if(currentState.getCurrentPlayer()==null) { currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); @@ -605,14 +606,27 @@ public class Game implements Serializable { return; } + return; } } - if(GameStages.OPTIONAL_CARD_EFFECT==currentState.getGameStage()) { - currentState.PlayerUpdate(OptionalCardQueue.remove(), null); - if(currentState.getCurrentPlayer()==null) - { - currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); + 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(); + } else { + EventResolution(); + currentState.GameStageUpdate(GameStages.ENDING); + endGame(); + } + } } @@ -657,9 +671,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(); } @@ -683,11 +701,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; } 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 6f6d5ec..4709a9b 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -141,6 +141,87 @@ class GameTest { } } + private int slotIndexById(Game game, char slotId) { + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + List slots = board.getSlotList(); + + for (int i = 0; i < slots.size(); i++) { + if (slots.get(i).getSlotId() == slotId) { + return i; + } + } + + fail("No slot found with id: " + slotId); + return -1; + } + + private Player completeSlotChoiceAndAdvanceToPlayerOnSlot(Game game, char slotId) { + Player targetPlayer = game.getCurrentState().getCurrentPlayer(); + int targetSlotIndex = slotIndexById(game, slotId); + + assertTrue(game.SlotChoiceByIndex(targetPlayer, targetSlotIndex)); + + Set usedSlots = new HashSet<>(); + usedSlots.add(targetSlotIndex); + + int nextSlotIndex = 0; + + while (game.getCurrentState().getGameStage() == GameStages.SLOT_CHOICE) { + while (usedSlots.contains(nextSlotIndex)) { + nextSlotIndex++; + } + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertTrue(game.SlotChoiceByIndex(current, nextSlotIndex)); + usedSlots.add(nextSlotIndex); + } + + assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + + int guard = 0; + + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS + && !targetPlayer.equals(game.getCurrentState().getCurrentPlayer()) + && guard < 20) { + guard++; + resolveOneMandatoryAction(game); + } + + assertTrue(guard < 20, "Possible infinite loop while reaching target player's slot."); + assertEquals(targetPlayer, game.getCurrentState().getCurrentPlayer()); + + return targetPlayer; + } + + private void resolveOptionalPhaseIfPresent(Game game) { + int guard = 0; + + while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT && guard < 10) { + guard++; + + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); + + assertTrue(game.NoOptionalCard(current)); + } + + assertTrue(guard < 10, "Possible infinite loop during optional phase."); + } + + 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); + } + @Test void constructorShouldInitializeGameCorrectly() { int nPlayers = 3; @@ -290,6 +371,7 @@ class GameTest { temp_player = players.poll(); assertEquals(temp_player, game.getCurrentState().getCurrentPlayer()); + int nCards = game.getUpperListTribeCards().size(); int countCards = 0; HashMap nCardsByType = new HashMap(); @@ -327,6 +409,17 @@ class GameTest { 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()); + } @@ -584,13 +677,10 @@ class GameTest { Game game = new Game(3); addPlayers(game, 3, "lower_building_"); - completeSlotChoice(game); - Player current = game.getCurrentState().getCurrentPlayer(); + Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'D'); assertNotNull(current); - game.getCurrentState().PlayerUpdate(current, new Slot('D')); - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); assertNotNull(board); @@ -714,13 +804,10 @@ class GameTest { Game game = new Game(3); addPlayers(game, 3, "no_lower_"); - completeSlotChoice(game); - Player current = game.getCurrentState().getCurrentPlayer(); + Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'C'); assertNotNull(current); - game.getCurrentState().PlayerUpdate(current, new Slot('C')); - int index = firstNonEventIndex(game.getLowerListTribeCards()); assertEquals(0, game.getCurrentState().getNLower()); @@ -732,13 +819,10 @@ class GameTest { Game game = new Game(3); addPlayers(game, 3, "lower_event_"); - completeSlotChoice(game); - Player current = game.getCurrentState().getCurrentPlayer(); + Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'B'); assertNotNull(current); - game.getCurrentState().PlayerUpdate(current, new Slot('B')); - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); assertNotNull(board); @@ -754,13 +838,10 @@ class GameTest { Game game = new Game(3); addPlayers(game, 3, "no_upper_building_"); - completeSlotChoice(game); - Player current = game.getCurrentState().getCurrentPlayer(); + Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'B'); assertNotNull(current); - game.getCurrentState().PlayerUpdate(current, new Slot('B')); - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); assertNotNull(board); @@ -778,13 +859,10 @@ class GameTest { Game game = new Game(3); addPlayers(game, 3, "upper_buy_true_"); - completeSlotChoice(game); - Player current = game.getCurrentState().getCurrentPlayer(); + Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'F'); assertNotNull(current); - game.getCurrentState().PlayerUpdate(current, new Slot('F')); - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); assertNotNull(board); @@ -803,30 +881,6 @@ class GameTest { assertEquals(1, game.getCurrentState().getNUpper()); } - @Test - void eventResolutionShouldNotCrashWithNormalAndSustenanceEvents() { - Game game = new Game(3); - - addPlayers(game, 3, "events_"); - - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); - - board.lowerListTribe.clear(); - - board.lowerListTribe.add( - new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.ShamanicRitual(1, 15, 7)); - - board.lowerListTribe.add( - new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.Sustenance(1, 3)); - - game.getCurrentState().GameStageUpdate(GameStages.RESOLVING_EVENT); - - invokePrivateMethod(game, "EventResolution"); - - assertEquals(GameStages.RESOLVING_EVENT, game.getCurrentState().getGameStage()); - } - @Test void nextRoundShouldUpdateEraWhenBoardEraDiffersFromCurrentStateEra() { Game game = new Game(3); @@ -900,17 +954,30 @@ class GameTest { } @Test - void nextRoundAtRoundTenShouldNotIncreaseRoundAfterEndingGame() { + void fullGameShouldEndAfterTenRoundsUsingOnlyPublicGameFlow() { Game game = new Game(3); - for (int i = 0; i < 9; i++) { - game.getCurrentState().RoundUpdate(); + 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()); + + int guard = 0; + + while (game.getCurrentState().getGameStage() != GameStages.ENDED && guard < 20) { + guard++; + + playOneFullRound(game); + + assertTrue( + game.getCurrentState().getGameStage() == GameStages.SLOT_CHOICE + || game.getCurrentState().getGameStage() == GameStages.ENDED, + "After a full round, the game should either start the next slot choice phase or end." + ); } - assertEquals(10, game.getCurrentState().getRound()); - - invokePrivateMethod(game, "nextRound"); - + assertTrue(guard < 20, "Possible infinite loop while playing the full game."); assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); assertEquals(10, game.getCurrentState().getRound()); } @@ -931,26 +998,30 @@ class GameTest { } @Test - void shouldNotCrashWhenOnlyOptionalPlayerSkipsOptionalCard() { + void roundShouldAdvanceAfterOnlyOptionalPlayerSkipsOptionalCard() { Game game = new Game(3); List players = addPlayers(game, 3, "single_optional_"); players.get(0).buildingCards.add(new BuildingCard(12, 1, 1, 0)); + int roundBefore = game.getCurrentState().getRound(); + completeSlotChoice(game); resolveActionsUntilOptionalCardEffect(game); Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); - assertDoesNotThrow(() -> assertTrue(game.NoOptionalCard(current))); + assertTrue(game.NoOptionalCard(current)); - assertNotEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(roundBefore + 1, game.getCurrentState().getRound()); + assertNotNull(game.getCurrentState().getCurrentPlayer()); } @Test - void optionalPhaseShouldFinishAfterAllPlayersSkipOptionalCard() { + void roundShouldAdvanceAfterAllOptionalPlayersSkipOptionalCard() { Game game = new Game(3); Player p1 = new Player("p1"); @@ -963,24 +1034,27 @@ class GameTest { giveOptionalEffectToAllPlayers(p1, p2, p3); + int roundBefore = game.getCurrentState().getRound(); + completeSlotChoice(game); resolveActionsUntilOptionalCardEffect(game); - assertDoesNotThrow(() -> { - int guard = 0; + int guard = 0; - while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT && guard < 10) { - guard++; + while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT && guard < 10) { + guard++; - Player current = game.getCurrentState().getCurrentPlayer(); - assertNotNull(current); + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); - assertTrue(game.NoOptionalCard(current)); - } + assertTrue(game.NoOptionalCard(current)); + } - assertTrue(guard < 10, "Possible infinite loop during optional phase."); - assertNotEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); - }); + assertTrue(guard < 10, "Possible infinite loop during optional phase."); + + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(roundBefore + 1, game.getCurrentState().getRound()); + assertNotNull(game.getCurrentState().getCurrentPlayer()); } From d35d6d154c814e4f0e7a1d5caf174e11674f1e21 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Tue, 28 Apr 2026 19:39:48 +0200 Subject: [PATCH 06/13] Fix: GameTest and Game --- .../java/it/polimi/ingsw/gc14/Model/Game.java | 51 +++---- .../it/polimi/ingsw/gc14/Model/GameTest.java | 124 ++++++++++++++---- 2 files changed, 124 insertions(+), 51 deletions(-) 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 c04e25b..58c09ce 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -589,26 +589,29 @@ public class Game implements Serializable { { OptionalCardQueue.add(e.getKey()); } - currentState.PlayerUpdate(OptionalCardQueue.poll(), 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; } + + 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(); @@ -619,13 +622,17 @@ public class Game implements Serializable { currentState.GameStageUpdate(GameStages.RESOLVING_EVENT); - if (currentState.getRound() < 10) { - nextRound(); - } else { - EventResolution(); - currentState.GameStageUpdate(GameStages.ENDING); - endGame(); - } + if (currentState.getRound() < 10) { + nextRound(); + currentState.PlayerUpdate(orderLogicCard.pull(), null); + currentState.GameStageUpdate(GameStages.SLOT_CHOICE); + } else { + EventResolution(); + currentState.GameStageUpdate(GameStages.ENDING); + endGame(); + } + + return; } } 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 4709a9b..9346b9b 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -954,32 +954,75 @@ class GameTest { } @Test - void fullGameShouldEndAfterTenRoundsUsingOnlyPublicGameFlow() { - Game game = new Game(3); + void fullGameShouldEndAfterTenRoundsForTwoThreeAndFourPlayersUsingOnlyPublicGameFlow() { + for (int nPlayers : new int[]{2, 3, 4}) { + Game game = new Game(nPlayers); - assertTrue(game.addPlayer(new Player("p1"))); - assertTrue(game.addPlayer(new Player("p2"))); - assertTrue(game.addPlayer(new Player("p3"))); + for (int i = 1; i <= nPlayers; i++) { + assertTrue(game.addPlayer(new Player("p" + nPlayers + "_" + i))); + } - assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(1, game.getCurrentState().getRound()); + assertNotNull(game.getCurrentState().getCurrentPlayer()); - int guard = 0; + int guard = 0; - while (game.getCurrentState().getGameStage() != GameStages.ENDED && guard < 20) { - guard++; + while (game.getCurrentState().getGameStage() != GameStages.ENDED && guard < 15) { + guard++; - playOneFullRound(game); + int roundBefore = game.getCurrentState().getRound(); + + playOneFullRound(game); + + if (roundBefore < 10) { + assertEquals( + GameStages.SLOT_CHOICE, + game.getCurrentState().getGameStage(), + "After a non-final round, the game must return to SLOT_CHOICE." + ); + + assertEquals( + roundBefore + 1, + game.getCurrentState().getRound(), + "The round number must increase by one after each completed round." + ); + + assertNotNull( + game.getCurrentState().getCurrentPlayer(), + "At the beginning of the next round there must be a current player." + ); + } else { + assertEquals( + GameStages.ENDED, + game.getCurrentState().getGameStage(), + "After round 10, the game must end." + ); + + assertEquals( + 10, + game.getCurrentState().getRound(), + "The game must end at round 10." + ); + } + } assertTrue( - game.getCurrentState().getGameStage() == GameStages.SLOT_CHOICE - || game.getCurrentState().getGameStage() == GameStages.ENDED, - "After a full round, the game should either start the next slot choice phase or end." + guard < 15, + "Possible infinite loop while playing the full game with " + nPlayers + " players." + ); + assertEquals( + GameStages.ENDED, + game.getCurrentState().getGameStage(), + "The game must end after round 10 with " + nPlayers + " players." + ); + + assertEquals( + 10, + game.getCurrentState().getRound(), + "The game must end at round 10 with " + nPlayers + " players." ); } - - assertTrue(guard < 20, "Possible infinite loop while playing the full game."); - assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); - assertEquals(10, game.getCurrentState().getRound()); } @Test @@ -1039,23 +1082,46 @@ class GameTest { completeSlotChoice(game); resolveActionsUntilOptionalCardEffect(game); - int guard = 0; - - while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT && guard < 10) { - guard++; - - Player current = game.getCurrentState().getCurrentPlayer(); - assertNotNull(current); - - assertTrue(game.NoOptionalCard(current)); - } - - assertTrue(guard < 10, "Possible infinite loop during optional phase."); + resolveOptionalPhaseIfPresent(game); assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); assertEquals(roundBefore + 1, game.getCurrentState().getRound()); assertNotNull(game.getCurrentState().getCurrentPlayer()); } + @Test + void fourPlayerGameShouldAllowPlayingSlotG() { + Game game = new Game(4); + + addPlayers(game, 4, "slot_g_"); + + Player playerOnG = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'G'); + + assertNotNull(playerOnG); + assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); + assertEquals(playerOnG, game.getCurrentState().getCurrentPlayer()); + assertEquals('G', game.getCurrentState().getSlot().getSlotId()); + + assertEquals(1, game.getCurrentState().getNLower()); + assertEquals(2, game.getCurrentState().getNUpper()); + + resolveOneMandatoryAction(game); + assertEquals(0, game.getCurrentState().getNLower()); + assertEquals(2, game.getCurrentState().getNUpper()); + + resolveOneMandatoryAction(game); + assertEquals(0, game.getCurrentState().getNLower()); + assertEquals(1, game.getCurrentState().getNUpper()); + + resolveOneMandatoryAction(game); + + assertFalse( + game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS + && playerOnG.equals(game.getCurrentState().getCurrentPlayer()) + && game.getCurrentState().getSlot().getSlotId() == 'G', + "After resolving all actions of slot G, the game must not still be resolving slot G for the same player." + ); + } + } \ No newline at end of file From 1d68b3acfa9f62c286c11227f3400c7ef057b25e Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Wed, 29 Apr 2026 15:47:01 +0200 Subject: [PATCH 07/13] Fix:Game Automatic Slot --- .../java/it/polimi/ingsw/gc14/Model/Game.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) 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 58c09ce..a7f5609 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -301,10 +301,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; - } /** @@ -343,7 +342,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; @@ -382,7 +381,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; @@ -422,7 +421,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; @@ -555,10 +554,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; @@ -570,7 +575,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)) From 2127263540a1146b6ba3df96e3d3cf4c2c6e54c1 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Wed, 29 Apr 2026 15:49:15 +0200 Subject: [PATCH 08/13] Fix: Order Remove Food --- src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order3.java | 2 +- src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order4.java | 2 +- src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order5.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 fc7f6d2..28037ff 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 @@ -44,7 +44,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 06bb44a..442858f 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 @@ -52,7 +52,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 41b7228..d527b83 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 @@ -53,7 +53,7 @@ public class Order5 extends OrderLogicCard { return; } if(index==4){ - if(player.removeFood(1)){ + if(!player.removeFood(1)){ player.removePrestige(2); } } From a93b2ebf375a04b59430ce45dde866b900075654 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Wed, 29 Apr 2026 16:14:49 +0200 Subject: [PATCH 09/13] Fix: update Order tests --- .../ingsw/gc14/Model/Orders/Order3Test.java | 30 ++----------------- .../ingsw/gc14/Model/Orders/Order4Test.java | 8 ++--- .../ingsw/gc14/Model/Orders/Order5Test.java | 15 ++++------ 3 files changed, 12 insertions(+), 41 deletions(-) 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 d5cb5d4..44108ed 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 @@ -68,7 +68,7 @@ class Order3Test { } @Test - void thirdReturnPaysFoodAndLosesPrestige() { + void thirdReturnPaysFoodWithoutLosingPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -89,33 +89,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 3ae1ac2..c2395c2 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 @@ -101,7 +101,7 @@ class Order4Test { } @Test - void fourthReturnPaysFoodAndLosesPrestige() { + void fourthReturnPaysFoodWithoutLosingPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -126,11 +126,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"); @@ -156,7 +156,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 929bc6a..0ea1740 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 @@ -5,13 +5,10 @@ import it.polimi.ingsw.gc14.Model.Player; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.*; - -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 { @@ -148,7 +145,7 @@ class Order5Test { } @Test - void fifthReturnPaysFoodAndLosesPrestige() { + void fifthReturnPaysFoodWithoutLosingPrestige() { Player p1 = new Player("p1"); Player p2 = new Player("p2"); Player p3 = new Player("p3"); @@ -177,11 +174,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"); @@ -211,7 +208,7 @@ class Order5Test { order.push(fifthToAct); assertEquals(initialFood, fifthToAct.getFoodValue()); - assertEquals(initialPrestige, fifthToAct.getPrestigeValue()); + assertEquals(initialPrestige - 2, fifthToAct.getPrestigeValue()); } @Test From d62283ca8d1181a3a57aad76c08f890ee879f5e7 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Wed, 29 Apr 2026 16:48:46 +0200 Subject: [PATCH 10/13] Fix: GameTest --- .../it/polimi/ingsw/gc14/Model/GameTest.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) 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 9346b9b..8bb92ca 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -72,32 +72,28 @@ class GameTest { Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); - if (game.getCurrentState().getNLower() > 0) { + if (game.getCurrentState().getNLower() > 0 && hasDrawableLower(game)) { int index = firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()); if (index != -1) { assertTrue(game.DrawLowerTribeCardByIndex(current, index)); - } else if (!game.getLowerListBuilding().isEmpty()) { + } else { current.addFood(100); assertTrue(game.DrawLowerBuildingCardByIndex(current, 0)); - } else { - fail("No valid lower card available."); } - } else if (game.getCurrentState().getNUpper() > 0) { + } else if (game.getCurrentState().getNUpper() > 0 && hasDrawableUpper(game)) { int index = firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()); if (index != -1) { assertTrue(game.DrawUpperTribeCardByIndex(current, index)); - } else if (!game.getUpperListBuilding().isEmpty()) { + } else { current.addFood(100); assertTrue(game.DrawUpperBuildingCardByIndex(current, 0)); - } else { - fail("No valid upper card available."); } } else { - fail("Current player has no remaining draws."); + fail("Current player has no drawable cards, although the game is still resolving actions."); } } @@ -222,6 +218,16 @@ class GameTest { 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; @@ -954,8 +960,8 @@ class GameTest { } @Test - void fullGameShouldEndAfterTenRoundsForTwoThreeAndFourPlayersUsingOnlyPublicGameFlow() { - for (int nPlayers : new int[]{2, 3, 4}) { + void fullGameShouldEndAfterTenRoundsForTwoThreeFourAndFivePlayersUsingOnlyPublicGameFlow() { + for (int nPlayers : new int[]{2, 3, 4, 5}) { Game game = new Game(nPlayers); for (int i = 1; i <= nPlayers; i++) { From fbe511678b2463cb98197d06779f0e61b1e3ed83 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Wed, 29 Apr 2026 17:46:24 +0200 Subject: [PATCH 11/13] Fix: GameTest --- .../it/polimi/ingsw/gc14/Model/GameTest.java | 55 ++++++------------- 1 file changed, 18 insertions(+), 37 deletions(-) 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 8bb92ca..c9fc334 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -7,8 +7,10 @@ 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.Test; +import org.junit.jupiter.api.Timeout; import java.util.*; +import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; @@ -58,14 +60,9 @@ class GameTest { } private void resolveAllMandatoryActions(Game game) { - int guard = 0; - - while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS && guard < 50) { - guard++; + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS) { resolveOneMandatoryAction(game); } - - assertTrue(guard < 50, "Possible infinite loop while resolving mandatory actions."); } private void resolveOneMandatoryAction(Game game) { @@ -98,14 +95,10 @@ class GameTest { } private void resolveActionsUntilOptionalCardEffect(Game game) { - int guard = 0; - - while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS && guard < 50) { - guard++; + while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS) { resolveOneMandatoryAction(game); } - assertTrue(guard < 50, "Possible infinite loop while resolving mandatory actions."); assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); } @@ -176,34 +169,24 @@ class GameTest { assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); - int guard = 0; while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS - && !targetPlayer.equals(game.getCurrentState().getCurrentPlayer()) - && guard < 20) { - guard++; + && !targetPlayer.equals(game.getCurrentState().getCurrentPlayer())) { resolveOneMandatoryAction(game); } - assertTrue(guard < 20, "Possible infinite loop while reaching target player's slot."); assertEquals(targetPlayer, game.getCurrentState().getCurrentPlayer()); return targetPlayer; } private void resolveOptionalPhaseIfPresent(Game game) { - int guard = 0; - - while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT && guard < 10) { - guard++; - + while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT) { Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); assertTrue(game.NoOptionalCard(current)); } - - assertTrue(guard < 10, "Possible infinite loop during optional phase."); } private void playOneFullRound(Game game) { @@ -322,7 +305,7 @@ class GameTest { } @Test - void slotChoiceByIndexShouldRejectInvalidWrongAndOccupiedSlot() { + void shouldRejectInvalidSlotChoices() { Game game = new Game(3); Player p1 = new Player("p1"); @@ -625,7 +608,7 @@ class GameTest { } @Test - void drawMethodsShouldRejectWrongStateInvalidIndexesAndWrongPlayer() { + void shouldRejectInvalidDrawRequests() { Game game = new Game(3); Player p1 = new Player("p1"); @@ -767,7 +750,7 @@ class GameTest { } @Test - void eventResolutionShouldDoNothingOutsideResolvingEventStage() { + void eventResolutionIgnoredOutsideItsStage() { Game game = new Game(3); assertEquals(GameStages.WAITING, game.getCurrentState().getGameStage()); @@ -779,7 +762,7 @@ class GameTest { @Test - void nextRoundShouldIncreaseRound() { + void nextRoundIncreasesRound() { Game game = new Game(3); int roundBefore = game.getCurrentState().getRound(); @@ -888,7 +871,7 @@ class GameTest { } @Test - void nextRoundShouldUpdateEraWhenBoardEraDiffersFromCurrentStateEra() { + void nextRoundUpdatesEra() { Game game = new Game(3); setCurrentStateEra(game, 0); @@ -923,6 +906,7 @@ class GameTest { } @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) void shouldNotCrashWhenNoPlayerHasOptionalEffect() { Game game = new Game(3); @@ -960,7 +944,8 @@ class GameTest { } @Test - void fullGameShouldEndAfterTenRoundsForTwoThreeFourAndFivePlayersUsingOnlyPublicGameFlow() { + @Timeout(value = 2, unit = TimeUnit.SECONDS) + void shouldEndAfterTenRounds() { for (int nPlayers : new int[]{2, 3, 4, 5}) { Game game = new Game(nPlayers); @@ -972,10 +957,7 @@ class GameTest { assertEquals(1, game.getCurrentState().getRound()); assertNotNull(game.getCurrentState().getCurrentPlayer()); - int guard = 0; - - while (game.getCurrentState().getGameStage() != GameStages.ENDED && guard < 15) { - guard++; + while (game.getCurrentState().getGameStage() != GameStages.ENDED) { int roundBefore = game.getCurrentState().getRound(); @@ -1013,10 +995,6 @@ class GameTest { } } - assertTrue( - guard < 15, - "Possible infinite loop while playing the full game with " + nPlayers + " players." - ); assertEquals( GameStages.ENDED, game.getCurrentState().getGameStage(), @@ -1047,6 +1025,7 @@ class GameTest { } @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) void roundShouldAdvanceAfterOnlyOptionalPlayerSkipsOptionalCard() { Game game = new Game(3); @@ -1070,6 +1049,7 @@ class GameTest { } @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) void roundShouldAdvanceAfterAllOptionalPlayersSkipOptionalCard() { Game game = new Game(3); @@ -1096,6 +1076,7 @@ class GameTest { } @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) void fourPlayerGameShouldAllowPlayingSlotG() { Game game = new Game(4); From dfb2a51816027bc63cf005dfe5e25ee5866259d7 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Thu, 30 Apr 2026 16:08:50 +0200 Subject: [PATCH 12/13] Fix: GameTest --- .../it/polimi/ingsw/gc14/Model/GameTest.java | 161 +++++++++++++----- 1 file changed, 117 insertions(+), 44 deletions(-) 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 c9fc334..a7c32de 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -55,7 +55,7 @@ class GameTest { private void giveOptionalEffectToAllPlayers(Player... players) { for (Player player : players) { - player.buildingCards.add(new BuildingCard(12, 1, 1, 0)); + player.buildingCards.add(new BuildingCard(12, 1, 1, 1)); } } @@ -90,7 +90,23 @@ class GameTest { } } else { - fail("Current player has no drawable cards, although the game is still resolving actions."); + 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()) + ); } } @@ -116,7 +132,7 @@ class GameTest { private static class FinalTestBuildingCard extends BuildingCard { FinalTestBuildingCard() { - super(12, 1, 1, 0); + super(12, 1, 1, 1); } @Override @@ -674,7 +690,7 @@ class GameTest { assertNotNull(board); board.lowerListBuilding.clear(); - board.lowerListBuilding.add(new BuildingCard(12, 1, 1, 0)); + board.lowerListBuilding.add(new BuildingCard(12, 1, 1, 1)); current.addFood(100); @@ -731,6 +747,7 @@ class GameTest { } @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) void pickOptionalBuildingCardShouldReturnFalseIfPlayerCannotPay() { Game game = new Game(3); @@ -744,9 +761,18 @@ class GameTest { Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); - if (!game.getUpperListBuilding().isEmpty()) { - assertFalse(game.PickOptionalBuildingCard(current, 0)); + while (current.getFoodValue() > 0) { + current.removeFood(1); } + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.upperListBuilding.clear(); + board.upperListBuilding.add(new BuildingCard(12, 1, 1, 1)); + + assertEquals(0, current.getFoodValue()); + assertFalse(game.PickOptionalBuildingCard(current, 0)); } @Test @@ -835,7 +861,7 @@ class GameTest { assertNotNull(board); board.upperListBuilding.clear(); - board.upperListBuilding.add(new BuildingCard(12, 1, 1, 0)); + board.upperListBuilding.add(new BuildingCard(12, 1, 1, 1)); current.addFood(100); @@ -856,7 +882,7 @@ class GameTest { assertNotNull(board); board.upperListBuilding.clear(); - board.upperListBuilding.add(new BuildingCard(12, 1, 1, 0)); + board.upperListBuilding.add(new BuildingCard(12, 1, 1, 1)); current.addFood(100); @@ -944,8 +970,8 @@ class GameTest { } @Test - @Timeout(value = 2, unit = TimeUnit.SECONDS) - void shouldEndAfterTenRounds() { + @Timeout(value = 10, unit = TimeUnit.SECONDS) + void shouldCompleteFullGameThroughRealFlow() { for (int nPlayers : new int[]{2, 3, 4, 5}) { Game game = new Game(nPlayers); @@ -957,54 +983,42 @@ class GameTest { assertEquals(1, game.getCurrentState().getRound()); assertNotNull(game.getCurrentState().getCurrentPlayer()); - while (game.getCurrentState().getGameStage() != GameStages.ENDED) { - - int roundBefore = game.getCurrentState().getRound(); + for (int expectedRound = 1; expectedRound < 10; expectedRound++) { + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + assertEquals(expectedRound, game.getCurrentState().getRound()); playOneFullRound(game); - if (roundBefore < 10) { - assertEquals( - GameStages.SLOT_CHOICE, - game.getCurrentState().getGameStage(), - "After a non-final round, the game must return to SLOT_CHOICE." - ); + assertEquals( + GameStages.SLOT_CHOICE, + game.getCurrentState().getGameStage(), + "After round " + expectedRound + ", the game should return to SLOT_CHOICE." + ); - assertEquals( - roundBefore + 1, - game.getCurrentState().getRound(), - "The round number must increase by one after each completed round." - ); + assertEquals( + expectedRound + 1, + game.getCurrentState().getRound(), + "The round should increase after completing round " + expectedRound + "." + ); - assertNotNull( - game.getCurrentState().getCurrentPlayer(), - "At the beginning of the next round there must be a current player." - ); - } else { - assertEquals( - GameStages.ENDED, - game.getCurrentState().getGameStage(), - "After round 10, the game must end." - ); - - assertEquals( - 10, - game.getCurrentState().getRound(), - "The game must end at round 10." - ); - } + 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 must end after round 10 with " + nPlayers + " players." + "The game should end after completing round 10 with " + nPlayers + " players." ); assertEquals( 10, game.getCurrentState().getRound(), - "The game must end at round 10 with " + nPlayers + " players." + "The game should end at round 10 with " + nPlayers + " players." ); } } @@ -1031,7 +1045,7 @@ class GameTest { List players = addPlayers(game, 3, "single_optional_"); - players.get(0).buildingCards.add(new BuildingCard(12, 1, 1, 0)); + players.get(0).buildingCards.add(new BuildingCard(12, 1, 1, 1)); int roundBefore = game.getCurrentState().getRound(); @@ -1110,5 +1124,64 @@ class GameTest { ); } + @Test + @Timeout(value = 2, unit = TimeUnit.SECONDS) + void pickOptionalTribeCardShouldRejectEventCard() { + 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); + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.upperListTribe.add(0, + new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.Sustenance(1, 3)); + + assertTrue(board.upperListTribe.get(0).IsEventCard()); + assertFalse(game.PickOptionalTribeCardByIndex(current, 0)); + } + + @Test + void drawLowerBuildingCardShouldRejectWrongPlayer() { + 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 = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'D'); + assertNotNull(current); + + Player wrongPlayer = current.equals(p1) ? p2 : p1; + + it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); + assertNotNull(board); + + board.lowerListBuilding.clear(); + board.lowerListBuilding.add(new BuildingCard(12, 1, 1, 1)); + + wrongPlayer.addFood(100); + + assertFalse(game.DrawLowerBuildingCardByIndex(wrongPlayer, 0)); + } + } \ No newline at end of file From fbc77533e315ee71b2702faffff714c457b5b483 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Thu, 30 Apr 2026 17:07:27 +0200 Subject: [PATCH 13/13] Fix: GameTest --- .../it/polimi/ingsw/gc14/Model/GameTest.java | 408 +----------------- 1 file changed, 15 insertions(+), 393 deletions(-) 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 a7c32de..163876d 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -1,6 +1,5 @@ package it.polimi.ingsw.gc14.Model; -import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; @@ -14,6 +13,7 @@ import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.*; +@Timeout(value = 10, unit = TimeUnit.SECONDS) class GameTest { @@ -118,84 +118,6 @@ class GameTest { assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); } - - private void setCurrentStateEra(Game game, int era) { - try { - java.lang.reflect.Field field = game.getCurrentState().getClass().getDeclaredField("Era"); - field.setAccessible(true); - field.set(game.getCurrentState(), era); - } catch (Exception e) { - fail("Failed to set CurrentState era: " + e.getMessage()); - } - } - - private static class FinalTestBuildingCard extends BuildingCard { - - FinalTestBuildingCard() { - super(12, 1, 1, 1); - } - - @Override - public EffectType getEffectType() { - return EffectType.FINAL; - } - - @Override - public void applyEffect(Player player) { - player.addPrestige(10); - } - } - - private int slotIndexById(Game game, char slotId) { - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - List slots = board.getSlotList(); - - for (int i = 0; i < slots.size(); i++) { - if (slots.get(i).getSlotId() == slotId) { - return i; - } - } - - fail("No slot found with id: " + slotId); - return -1; - } - - private Player completeSlotChoiceAndAdvanceToPlayerOnSlot(Game game, char slotId) { - Player targetPlayer = game.getCurrentState().getCurrentPlayer(); - int targetSlotIndex = slotIndexById(game, slotId); - - assertTrue(game.SlotChoiceByIndex(targetPlayer, targetSlotIndex)); - - Set usedSlots = new HashSet<>(); - usedSlots.add(targetSlotIndex); - - int nextSlotIndex = 0; - - while (game.getCurrentState().getGameStage() == GameStages.SLOT_CHOICE) { - while (usedSlots.contains(nextSlotIndex)) { - nextSlotIndex++; - } - - Player current = game.getCurrentState().getCurrentPlayer(); - assertNotNull(current); - - assertTrue(game.SlotChoiceByIndex(current, nextSlotIndex)); - usedSlots.add(nextSlotIndex); - } - - assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); - - - while (game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS - && !targetPlayer.equals(game.getCurrentState().getCurrentPlayer())) { - resolveOneMandatoryAction(game); - } - - assertEquals(targetPlayer, game.getCurrentState().getCurrentPlayer()); - - return targetPlayer; - } - private void resolveOptionalPhaseIfPresent(Game game) { while (game.getCurrentState().getGameStage() == GameStages.OPTIONAL_CARD_EFFECT) { Player current = game.getCurrentState().getCurrentPlayer(); @@ -571,27 +493,6 @@ class GameTest { return -1; } - private it.polimi.ingsw.gc14.Model.GamePackage.Board getBoard(Game game) { - try { - java.lang.reflect.Field field = Game.class.getDeclaredField("board"); - field.setAccessible(true); - return (it.polimi.ingsw.gc14.Model.GamePackage.Board) field.get(game); - } catch (Exception e) { - fail("Failed to access board field: " + e.getMessage()); - return null; - } - } - - private void invokePrivateMethod(Game game, String methodName) { - try { - java.lang.reflect.Method method = Game.class.getDeclaredMethod(methodName); - method.setAccessible(true); - method.invoke(game); - } catch (Exception e) { - fail("Failed to invoke private method " + methodName + ": " + e.getMessage()); - } - } - @Test void getCurrentPlayerNumberShouldTrackAddedPlayers() { Game game = new Game(3); @@ -677,32 +578,6 @@ class GameTest { } } - @Test - void drawLowerBuildingCardShouldWorkWhenLowerBuildingExists() { - Game game = new Game(3); - - addPlayers(game, 3, "lower_building_"); - - Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'D'); - assertNotNull(current); - - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); - - board.lowerListBuilding.clear(); - board.lowerListBuilding.add(new BuildingCard(12, 1, 1, 1)); - - current.addFood(100); - - int foodBefore = current.getFoodValue(); - int buildingsBefore = current.buildingCards.size(); - - assertTrue(game.DrawLowerBuildingCardByIndex(current, 0)); - - assertTrue(current.getFoodValue() < foodBefore); - assertEquals(buildingsBefore + 1, current.buildingCards.size()); - assertEquals(1, game.getCurrentState().getNLower()); - } @Test void optionalMethodsShouldReturnFalseOutsideOptionalState() { @@ -746,191 +621,6 @@ class GameTest { } - @Test - @Timeout(value = 2, unit = TimeUnit.SECONDS) - void pickOptionalBuildingCardShouldReturnFalseIfPlayerCannotPay() { - Game game = new Game(3); - - List players = addPlayers(game, 3, "optional_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) { - current.removeFood(1); - } - - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); - - board.upperListBuilding.clear(); - board.upperListBuilding.add(new BuildingCard(12, 1, 1, 1)); - - assertEquals(0, current.getFoodValue()); - assertFalse(game.PickOptionalBuildingCard(current, 0)); - } - - @Test - void eventResolutionIgnoredOutsideItsStage() { - Game game = new Game(3); - - assertEquals(GameStages.WAITING, game.getCurrentState().getGameStage()); - - invokePrivateMethod(game, "EventResolution"); - - assertEquals(GameStages.WAITING, game.getCurrentState().getGameStage()); - } - - - @Test - void nextRoundIncreasesRound() { - Game game = new Game(3); - - int roundBefore = game.getCurrentState().getRound(); - - invokePrivateMethod(game, "nextRound"); - - assertEquals(roundBefore + 1, game.getCurrentState().getRound()); - } - - @Test - void addObserverAndNotifyObserversShouldCallObserver() { - Game game = new Game(3); - - final boolean[] notified = {false}; - - game.addObserver(updatedGame -> { - assertSame(game, updatedGame); - notified[0] = true; - }); - - invokePrivateMethod(game, "notifyObservers"); - - assertTrue(notified[0]); - } - - @Test - void drawLowerTribeCardShouldReturnFalseWhenNoLowerDrawsAreAvailable() { - Game game = new Game(3); - - addPlayers(game, 3, "no_lower_"); - - Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'C'); - assertNotNull(current); - - int index = firstNonEventIndex(game.getLowerListTribeCards()); - - assertEquals(0, game.getCurrentState().getNLower()); - assertFalse(game.DrawLowerTribeCardByIndex(current, index)); - } - - @Test - void drawLowerTribeCardShouldReturnFalseForEventCard() { - Game game = new Game(3); - - addPlayers(game, 3, "lower_event_"); - - Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'B'); - assertNotNull(current); - - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); - - board.lowerListTribe.add(0, - new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.Sustenance(1, 3)); - - assertTrue(board.lowerListTribe.get(0).IsEventCard()); - assertFalse(game.DrawLowerTribeCardByIndex(current, 0)); - } - - @Test - void drawUpperBuildingCardShouldReturnFalseWhenNoUpperDrawsAreAvailable() { - Game game = new Game(3); - - addPlayers(game, 3, "no_upper_building_"); - - Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'B'); - assertNotNull(current); - - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); - - board.upperListBuilding.clear(); - board.upperListBuilding.add(new BuildingCard(12, 1, 1, 1)); - - current.addFood(100); - - assertEquals(0, game.getCurrentState().getNUpper()); - assertFalse(game.DrawUpperBuildingCardByIndex(current, 0)); - } - - @Test - void drawUpperBuildingCardShouldBuyBuildingAndDecreaseUpperDraws() { - Game game = new Game(3); - - addPlayers(game, 3, "upper_buy_true_"); - - Player current = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'F'); - assertNotNull(current); - - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); - - board.upperListBuilding.clear(); - board.upperListBuilding.add(new BuildingCard(12, 1, 1, 1)); - - current.addFood(100); - - int foodBefore = current.getFoodValue(); - int buildingsBefore = current.buildingCards.size(); - - assertTrue(game.DrawUpperBuildingCardByIndex(current, 0)); - - assertTrue(current.getFoodValue() < foodBefore); - assertEquals(buildingsBefore + 1, current.buildingCards.size()); - assertEquals(1, game.getCurrentState().getNUpper()); - } - - @Test - void nextRoundUpdatesEra() { - Game game = new Game(3); - - setCurrentStateEra(game, 0); - - assertEquals(0, game.getCurrentState().getEra()); - - invokePrivateMethod(game, "nextRound"); - - assertEquals(1, game.getCurrentState().getEra()); - } - - @Test - void endGameShouldApplyFinalBuildingEffectsAndSetEndedStage() { - Game game = new Game(3); - - Player player = new Player("final_player"); - Player p2 = new Player("p2"); - Player p3 = new Player("p3"); - - assertTrue(game.addPlayer(player)); - assertTrue(game.addPlayer(p2)); - assertTrue(game.addPlayer(p3)); - - player.buildingCards.add(new FinalTestBuildingCard()); - - int prestigeBefore = player.getPrestigeValue(); - - invokePrivateMethod(game, "endGame"); - - assertEquals(prestigeBefore + 10, player.getPrestigeValue()); - assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); - } - @Test @Timeout(value = 2, unit = TimeUnit.SECONDS) void shouldNotCrashWhenNoPlayerHasOptionalEffect() { @@ -970,7 +660,7 @@ class GameTest { } @Test - @Timeout(value = 10, unit = TimeUnit.SECONDS) + @Timeout(value = 20, unit = TimeUnit.SECONDS) void shouldCompleteFullGameThroughRealFlow() { for (int nPlayers : new int[]{2, 3, 4, 5}) { Game game = new Game(nPlayers); @@ -1090,54 +780,11 @@ class GameTest { } @Test - @Timeout(value = 2, unit = TimeUnit.SECONDS) - void fourPlayerGameShouldAllowPlayingSlotG() { - Game game = new Game(4); - - addPlayers(game, 4, "slot_g_"); - - Player playerOnG = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'G'); - - assertNotNull(playerOnG); - assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); - assertEquals(playerOnG, game.getCurrentState().getCurrentPlayer()); - assertEquals('G', game.getCurrentState().getSlot().getSlotId()); - - assertEquals(1, game.getCurrentState().getNLower()); - assertEquals(2, game.getCurrentState().getNUpper()); - - resolveOneMandatoryAction(game); - assertEquals(0, game.getCurrentState().getNLower()); - assertEquals(2, game.getCurrentState().getNUpper()); - - resolveOneMandatoryAction(game); - assertEquals(0, game.getCurrentState().getNLower()); - assertEquals(1, game.getCurrentState().getNUpper()); - - resolveOneMandatoryAction(game); - - assertFalse( - game.getCurrentState().getGameStage() == GameStages.RESOLVING_ACTIONS - && playerOnG.equals(game.getCurrentState().getCurrentPlayer()) - && game.getCurrentState().getSlot().getSlotId() == 'G', - "After resolving all actions of slot G, the game must not still be resolving slot G for the same player." - ); - } - - @Test - @Timeout(value = 2, unit = TimeUnit.SECONDS) - void pickOptionalTribeCardShouldRejectEventCard() { + void pickOptionalBuildingCardShouldReturnFalseIfPlayerCannotPay() { Game game = new Game(3); + List players = addPlayers(game, 3, "no_food_"); - 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); + giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); completeSlotChoice(game); resolveActionsUntilOptionalCardEffect(game); @@ -1145,43 +792,18 @@ class GameTest { Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); + while (current.getFoodValue() > 0) { + assertTrue(current.removeFood(1)); + } - board.upperListTribe.add(0, - new it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.Sustenance(1, 3)); + assertEquals(0, current.getFoodValue()); - assertTrue(board.upperListTribe.get(0).IsEventCard()); - assertFalse(game.PickOptionalTribeCardByIndex(current, 0)); + 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 drawLowerBuildingCardShouldRejectWrongPlayer() { - 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 = completeSlotChoiceAndAdvanceToPlayerOnSlot(game, 'D'); - assertNotNull(current); - - Player wrongPlayer = current.equals(p1) ? p2 : p1; - - it.polimi.ingsw.gc14.Model.GamePackage.Board board = getBoard(game); - assertNotNull(board); - - board.lowerListBuilding.clear(); - board.lowerListBuilding.add(new BuildingCard(12, 1, 1, 1)); - - wrongPlayer.addFood(100); - - assertFalse(game.DrawLowerBuildingCardByIndex(wrongPlayer, 0)); - } - - } \ No newline at end of file