From a6e40e0aaa32434fb216494e4e6d5ed03e170238 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Thu, 7 May 2026 16:20:44 +0200 Subject: [PATCH 1/3] Add: complete tests for model cards and player logic --- .../gc14/Model/Cards/BuildingCardTest.java | 105 ++++++++++++++++-- .../TribeCards/Characters/BuilderTest.java | 52 +++++++++ .../TribeCards/Characters/InventorTest.java | 59 +++++++++- .../ingsw/gc14/Model/DecksCreatorTest.java | 19 ++++ .../ingsw/gc14/Model/PlayableCardTest.java | 15 +++ .../polimi/ingsw/gc14/Model/PlayerTest.java | 53 +++++++++ 6 files changed, 290 insertions(+), 13 deletions(-) diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/Cards/BuildingCardTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/Cards/BuildingCardTest.java index c5fd426..f4b9ebc 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/Cards/BuildingCardTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/Cards/BuildingCardTest.java @@ -69,7 +69,7 @@ class BuildingCardTest { @Test @DisplayName("Testing the second constructor (4 parameters)") - void testBuildingCard2() {}{ + void testBuildingCard2() { // Testing right parameters BuildingCard bc2 = new BuildingCard(2,1,1,1); BuildingCard bc3 = new BuildingCard(3,1,1,1); @@ -87,15 +87,13 @@ class BuildingCardTest { assertEquals(EffectType.ON_EVENT, bc9.getEffectType()); assertEquals(EffectType.ON_ROUND_END, bc12.getEffectType()); - // Testing wrong parameters - assertThrows(IllegalArgumentException.class, () -> {new BuildingCard(0,1,1,1);}); - assertThrows(IllegalArgumentException.class, () -> {new BuildingCard(1,1,1,1);}); - assertThrows(IllegalArgumentException.class, () -> {new BuildingCard(4,1,1,1);}); - assertThrows(IllegalArgumentException.class, () -> {new BuildingCard(8,1,1,1);}); - assertThrows(IllegalArgumentException.class, () -> {new BuildingCard(10,1,1,1);}); - assertThrows(IllegalArgumentException.class, () -> {new BuildingCard(11,1,1,1);}); - assertThrows(IllegalArgumentException.class, () -> {new BuildingCard(13,1,1,1);}); - + assertThrows(IllegalArgumentException.class, () -> new BuildingCard(0,1,1,1)); + assertThrows(IllegalArgumentException.class, () -> new BuildingCard(1,1,1,1)); + assertThrows(IllegalArgumentException.class, () -> new BuildingCard(4,1,1,1)); + assertThrows(IllegalArgumentException.class, () -> new BuildingCard(8,1,1,1)); + assertThrows(IllegalArgumentException.class, () -> new BuildingCard(10,1,1,1)); + assertThrows(IllegalArgumentException.class, () -> new BuildingCard(11,1,1,1)); + assertThrows(IllegalArgumentException.class, () -> new BuildingCard(13,1,1,1)); } @Test @@ -146,6 +144,10 @@ class BuildingCardTest { BuildingCard bc0 = new BuildingCard(2, 1,1,1); assertTrue(bc0.buy(p1)); + + assertTrue(p1.buildingCards.contains(bc0)); + assertEquals(1, p1.buildingCards.size()); + assertFalse(bc0.buy(p1)); assertFalse(bc0.buy(p2)); } @@ -338,4 +340,87 @@ class BuildingCardTest { assertEquals(0, p.getPrestigeValue()); assertEquals(user, p.getUserName()); } + + @Test + void constructorWithIdIMGTest() { + BuildingCard b = new BuildingCard("building1", 1, 5, 6); + + assertEquals(1, b.getEra()); + assertEquals(5, b.getPrice()); + assertEquals(6, b.getPrestigeValue()); + + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("building1", 1, 0, 6) + ); + + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("building1", 1, 5, -1) + ); + } + + @Test + void constructorWithIdIMGAndEffectIdTest() { + BuildingCard bc2 = new BuildingCard("b2", 2, 1, 1, 1); + BuildingCard bc3 = new BuildingCard("b3", 3, 1, 1, 1); + BuildingCard bc5 = new BuildingCard("b5", 5, 1, 1, 1); + BuildingCard bc6 = new BuildingCard("b6", 6, 1, 1, 1); + BuildingCard bc7 = new BuildingCard("b7", 7, 1, 1, 1); + BuildingCard bc9 = new BuildingCard("b9", 9, 1, 1, 1); + BuildingCard bc12 = new BuildingCard("b12", 12, 1, 1, 1); + + assertEquals(2, bc2.getEffectId()); + assertEquals(3, bc3.getEffectId()); + assertEquals(5, bc5.getEffectId()); + assertEquals(6, bc6.getEffectId()); + assertEquals(7, bc7.getEffectId()); + assertEquals(9, bc9.getEffectId()); + assertEquals(12, bc12.getEffectId()); + + assertEquals(EffectType.ON_EVENT, bc2.getEffectType()); + assertEquals(EffectType.ON_END_TURN, bc3.getEffectType()); + assertEquals(EffectType.ON_EVENT, bc5.getEffectType()); + assertEquals(EffectType.ON_EVENT, bc6.getEffectType()); + assertEquals(EffectType.ON_EVENT, bc7.getEffectType()); + assertEquals(EffectType.ON_EVENT, bc9.getEffectType()); + assertEquals(EffectType.ON_ROUND_END, bc12.getEffectType()); + } + + @Test + void constructorWithIdIMGAndEffectIdInvalidValuesTest() { + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("b0", 0, 1, 1, 1) + ); + + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("b1", 1, 1, 1, 1) + ); + + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("b4", 4, 1, 1, 1) + ); + + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("b13", 13, 1, 1, 1) + ); + + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("b2", 2, 1, 0, 1) + ); + + assertThrows(IllegalArgumentException.class, () -> + new BuildingCard("b2", 2, 1, 1, -1) + ); + } + + @Test + void buyShouldFailWhenPlayerHasNotEnoughFood() { + Player p = new Player("test"); + p.addFood(2); + + BuildingCard b = new BuildingCard(2, 1, 5, 1); + + assertFalse(b.buy(p)); + assertFalse(p.buildingCards.contains(b)); + assertEquals(2, p.getFoodValue()); + } } \ No newline at end of file diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/BuilderTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/BuilderTest.java index 0ad64a9..0ae8d0a 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/BuilderTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/BuilderTest.java @@ -108,4 +108,56 @@ class BuilderTest { new Builder(1, 2, -3); }); } + + @Test + void constructorWithIdIMGTest() { + Builder b = new Builder("builder1", 1, 2, 3); + + assertEquals(1, b.getEra()); + assertEquals(CharacterType.BUILDER, b.getType()); + assertEquals(2, b.getReductionValue()); + assertEquals(3, b.getPrestigeValue()); + } + + @Test + void constructorWithIdIMGAndNMinTest() { + Builder b = new Builder("builder1", 1, 2, 3, 4); + + assertEquals(1, b.getEra()); + assertEquals(CharacterType.BUILDER, b.getType()); + assertEquals(2, b.getReductionValue()); + assertEquals(3, b.getPrestigeValue()); + assertEquals(4, b.getNMin()); + assertFalse(b.IsEventCard()); + } + + @Test + void constructorWithIdIMGInvalidValuesTest() { + assertThrows(IllegalArgumentException.class, () -> + new Builder("builder1", 1, -1, 3) + ); + + assertThrows(IllegalArgumentException.class, () -> + new Builder("builder1", 1, 2, -1) + ); + + assertThrows(IllegalArgumentException.class, () -> + new Builder("builder1", 1, -1, 3, 4) + ); + + assertThrows(IllegalArgumentException.class, () -> + new Builder("builder1", 1, 2, -1, 4) + ); + } + + @Test + void testToStringBoard() { + Builder b = new Builder(1, 2, 3); + + String s = b.toStringBoard(); + + assertNotNull(s); + assertTrue(s.contains("RV:2")); + assertTrue(s.contains("PV:3")); + } } \ No newline at end of file diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/InventorTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/InventorTest.java index fc0e85f..1f0fbbc 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/InventorTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/InventorTest.java @@ -1,12 +1,9 @@ package it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; -import it.polimi.ingsw.gc14.Model.Orders.Order2; import it.polimi.ingsw.gc14.Model.Player; import org.junit.jupiter.api.Test; -import java.util.ArrayList; - import static org.junit.jupiter.api.Assertions.*; class InventorTest { @@ -109,4 +106,60 @@ class InventorTest { new Inventor(1, 10, 3); }); } + + @Test + void constructorWithIdIMGTest() { + Inventor i = new Inventor("inventor1", 1, 5); + + assertEquals(1, i.getEra()); + assertEquals(CharacterType.INVENTOR, i.getType()); + assertEquals(5, i.Icon()); + assertEquals(0, i.getNMin()); + assertFalse(i.IsEventCard()); + } + + @Test + void constructorWithIdIMGAndToStringBoardCoverageTest() { + // Valid constructor with idIMG + Inventor i1 = new Inventor("inventor1", 1, 5); + + assertEquals(1, i1.getEra()); + assertEquals(CharacterType.INVENTOR, i1.getType()); + assertEquals(5, i1.Icon()); + assertEquals(0, i1.getNMin()); + assertFalse(i1.IsEventCard()); + + // Valid constructor with idIMG and nMin + Inventor i2 = new Inventor("inventor2", 1, 7, 3); + + assertEquals(1, i2.getEra()); + assertEquals(CharacterType.INVENTOR, i2.getType()); + assertEquals(7, i2.Icon()); + assertEquals(3, i2.getNMin()); + assertFalse(i2.IsEventCard()); + + // Invalid icon with idIMG constructor + assertThrows(IllegalArgumentException.class, () -> { + new Inventor("inventor3", 1, -1); + }); + + assertThrows(IllegalArgumentException.class, () -> { + new Inventor("inventor4", 1, 10); + }); + + // Invalid icon with idIMG and nMin constructor + assertThrows(IllegalArgumentException.class, () -> { + new Inventor("inventor5", 1, -1, 3); + }); + + assertThrows(IllegalArgumentException.class, () -> { + new Inventor("inventor6", 1, 10, 3); + }); + + // toStringBoard coverage + String s = i1.toStringBoard(); + + assertNotNull(s); + assertTrue(s.contains("I_ID:5")); + } } \ No newline at end of file diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/DecksCreatorTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/DecksCreatorTest.java index 58ef20a..533b245 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/DecksCreatorTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/DecksCreatorTest.java @@ -81,4 +81,23 @@ class DecksCreatorTest { assertEquals(7, slots.size()); assertFalse(slots.contains(null)); } + + @Test + void loadTribeDeckByEra() { + List era1 = DecksCreator.loadTribeDeckByEra(1); + List era2 = DecksCreator.loadTribeDeckByEra(2); + List era3 = DecksCreator.loadTribeDeckByEra(3); + + assertNotNull(era1); + assertNotNull(era2); + assertNotNull(era3); + + assertEquals(33, era1.size()); + assertEquals(32, era2.size()); + assertEquals(29, era3.size()); + + assertTrue(era1.stream().allMatch(c -> c.getEra() == 1)); + assertTrue(era2.stream().allMatch(c -> c.getEra() == 2)); + assertTrue(era3.stream().allMatch(c -> c.getEra() == 3)); + } } diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/PlayableCardTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/PlayableCardTest.java index e0e84bb..4ac7f97 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/PlayableCardTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/PlayableCardTest.java @@ -31,6 +31,21 @@ class PlayableCardTest { }); } + + @Test + void playableCardWithIdIMGShouldRejectInvalidEra() { + assertThrows(IllegalArgumentException.class, () -> { + new BuildingCard("building1", 2, 0, 5, 1); + }); + + assertThrows(IllegalArgumentException.class, () -> { + new BuildingCard("building1", 2, 4, 5, 1); + }); + + assertThrows(IllegalArgumentException.class, () -> { + new BuildingCard("building1", 2, -1, 5, 1); + }); + } } diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/PlayerTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/PlayerTest.java index b0fdc51..2dc2893 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/PlayerTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/PlayerTest.java @@ -240,4 +240,57 @@ class PlayerTest { "║ Buildings: [⎕: ID:2 $:2 PV:5, ⎕: ID:2 $:3 PV:6, ⎕: ID:1 $:5 PV:5 Icon: I, ⎕: ID:1 $:5 PV:5 Icon: S, ⎕: ID:11 $:5 PV:7 Icon: A MP: 3]║\n" + "╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝", p.toString()); } + + @Test + void toStringShouldCoverAllLastCharacterCases() { + Player empty = new Player("empty"); + String emptyString = empty.toString(); + + assertNotNull(emptyString); + assertTrue(emptyString.contains("empty")); + assertTrue(emptyString.contains("CHARACTERS:")); + assertTrue(emptyString.contains("BUILDING CARDS:")); + + Player onlyArtist = new Player("onlyArtist"); + onlyArtist.artists.add(new Artist(1)); + String artistString = onlyArtist.toString(); + + assertTrue(artistString.contains("Artists:")); + assertTrue(artistString.contains("BUILDING CARDS:")); + + Player onlyBuilder = new Player("onlyBuilder"); + onlyBuilder.builders.add(new Builder(1, 1, 1)); + String builderString = onlyBuilder.toString(); + + assertTrue(builderString.contains("Builders:")); + assertTrue(builderString.contains("BUILDING CARDS:")); + + Player onlyGatherer = new Player("onlyGatherer"); + onlyGatherer.gatherers.add(new Gatherer(1, 1)); + String gathererString = onlyGatherer.toString(); + + assertTrue(gathererString.contains("Gatherers:")); + assertTrue(gathererString.contains("BUILDING CARDS:")); + + Player onlyShaman = new Player("onlyShaman"); + onlyShaman.shamans.add(new Shaman(1, 1)); + String shamanString = onlyShaman.toString(); + + assertTrue(shamanString.contains("Shamans:")); + assertTrue(shamanString.contains("BUILDING CARDS:")); + + Player onlyInventor = new Player("onlyInventor"); + onlyInventor.inventors.add(new Inventor(1, 1)); + String inventorString = onlyInventor.toString(); + + assertTrue(inventorString.contains("Inventors:")); + assertTrue(inventorString.contains("BUILDING CARDS:")); + + Player onlyHunter = new Player("onlyHunter"); + onlyHunter.hunters.add(new Hunter(1, true)); + String hunterString = onlyHunter.toString(); + + assertTrue(hunterString.contains("Hunters:")); + assertTrue(hunterString.contains("BUILDING CARDS:")); + } } \ No newline at end of file From 92df0fb828e6769c42813dff72226de8677faaee Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Thu, 7 May 2026 17:22:58 +0200 Subject: [PATCH 2/3] Add: ClientControllertest --- .../gc14/Controller/ClientControllerTest.java | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/test/java/it/polimi/ingsw/gc14/Controller/ClientControllerTest.java diff --git a/src/test/java/it/polimi/ingsw/gc14/Controller/ClientControllerTest.java b/src/test/java/it/polimi/ingsw/gc14/Controller/ClientControllerTest.java new file mode 100644 index 0000000..3f071fd --- /dev/null +++ b/src/test/java/it/polimi/ingsw/gc14/Controller/ClientControllerTest.java @@ -0,0 +1,141 @@ +package it.polimi.ingsw.gc14.Controller; + +import it.polimi.ingsw.gc14.Model.Game; +import it.polimi.ingsw.gc14.Model.Player; +import it.polimi.ingsw.gc14.Network.IClient; +import it.polimi.ingsw.gc14.View.IView; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.rmi.RemoteException; + +import static org.junit.jupiter.api.Assertions.*; + +class ClientControllerTest { + + private FakeView view; + private FakeClient client; + private ClientController controller; + + @BeforeEach + void setUp() { + view = new FakeView(); + client = new FakeClient(); + controller = new ClientController(view); + controller.setClient(client); + } + + @Test + void testConstructorInitialization() { + assertSame(view, controller.view); + assertNotNull(controller.localController); + } + + @Test + void testSetModelUpdatesLocalControllerAndView() { + Game game = createGame(); + controller.setModel(game); + + assertSame(game, controller.localController.getModel()); + assertSame(game, view.model); + } + + @Test + void testOnError() { + controller.onError("Errore di test"); + assertEquals("Errore di test", view.lastError); + } + + @Test + void testSetClientDelegatesAction() { + FakeClient newClient = new FakeClient(); + controller.setClient(newClient); + + Game game = createGame(); + controller.setModel(game); + + String current = game.getCurrentState().getCurrentPlayer().getUserName(); + controller.drawUpperTribeCard(current, 0); + + assertEquals("drawUpperTribeCard", newClient.lastMethodCalled); + assertEquals(current, newClient.lastUsername); + assertEquals(0, newClient.lastPos); + } + + @Test + void testDrawUpperTribeCardDelegatesCorrectly() { + Game game = createGame(); + controller.setModel(game); + + String current = game.getCurrentState().getCurrentPlayer().getUserName(); + controller.drawUpperTribeCard(current, 0); + + assertEquals("drawUpperTribeCard", client.lastMethodCalled); + assertEquals(current, client.lastUsername); + assertEquals(0, client.lastPos); + assertNull(view.lastError); + } + + @Test + void testDrawUpperTribeCardWrongPlayerShowsError() { + Game game = createGame(); + controller.setModel(game); + + String current = game.getCurrentState().getCurrentPlayer().getUserName(); + String wrong = current.equals("p1") ? "p2" : "p1"; + controller.drawUpperTribeCard(wrong, 0); + + assertEquals("It's not your turn!", view.lastError); + assertNull(client.lastMethodCalled); + } + + @Test + void testSlotChoiceDelegatesCorrectly() { + Game game = createGame(); + controller.setModel(game); + + String current = game.getCurrentState().getCurrentPlayer().getUserName(); + controller.slotChoice(current, 1); + + assertEquals("slotChoice", client.lastMethodCalled); + assertEquals(current, client.lastUsername); + assertEquals(1, client.lastPos); + assertNull(view.lastError); + } + + + private Game createGame() { + Game game = new Game(2); + game.addPlayer(new Player("p1")); + game.addPlayer(new Player("p2")); + return game; + } + + + private static class FakeView implements IView { + Game model; + String lastError; + + @Override public void setModel(Game game) { this.model = game; } + @Override public void render() {} + @Override public void showMessage(String message) {} + @Override public void showError(String message) { this.lastError = message; } + } + + private static class FakeClient implements IClient { + String lastMethodCalled; + String lastUsername; + int lastPos; + + @Override public boolean connect(String username, int preferredInt) { return true; } + @Override public void drawUpperTribeCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawUpperTribeCard"; lastUsername = u; lastPos = pos; } + @Override public void drawLowerTribeCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawLowerTribeCard"; lastUsername = u; lastPos = pos; } + @Override public void drawUpperBuildingCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawUpperBuildingCard"; lastUsername = u; lastPos = pos; } + @Override public void drawLowerBuildingCard(String u, int pos) throws RemoteException { lastMethodCalled = "drawLowerBuildingCard"; lastUsername = u; lastPos = pos; } + @Override public void skipTurn(String u) throws RemoteException { lastMethodCalled = "skipTurn"; lastUsername = u; } + @Override public void pickOptionalTribeCard(String u, int pos) throws RemoteException { lastMethodCalled = "pickOptionalTribeCard"; lastUsername = u; lastPos = pos; } + @Override public void pickOptionalBuildingCard(String u, int pos) throws RemoteException { lastMethodCalled = "pickOptionalBuildingCard"; lastUsername = u; lastPos = pos; } + @Override public void noOptionalCard(String u) throws RemoteException { lastMethodCalled = "noOptionalCard"; lastUsername = u; } + @Override public void slotChoice(String u, int pos) throws RemoteException { lastMethodCalled = "slotChoice"; lastUsername = u; lastPos = pos; } + } +} \ No newline at end of file From 828f5d2c21f969853c0da41798e0317eb7945e0b Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Fri, 8 May 2026 17:57:09 +0200 Subject: [PATCH 3/3] Add: final scoring and Game flow coverage tests --- .../it/polimi/ingsw/gc14/Model/GameTest.java | 405 ++++++++++++------ 1 file changed, 268 insertions(+), 137 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 66fdbcb..ed83c8d 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -4,15 +4,12 @@ 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; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; -import it.polimi.ingsw.gc14.Model.GamePackage.Board; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; -import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Artist; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Builder; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters.Inventor; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; -import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.TimeUnit; @@ -28,8 +25,15 @@ class GameTest { for (int i = 0; i < game.getNPlayers(); i++) { Player current = game.getCurrentState().getCurrentPlayer(); order.add(current); + assertTrue(game.SlotChoiceByIndex(current, i)); - assertEquals(current.getUserName(),game.getSlotMap().get(new ArrayList<>(game.getSlotMap().keySet()).get(i)).getUserName()); + + assertTrue( + game.getSlotMap().values().stream() + .anyMatch(player -> player != null + && player.getUserName().equals(current.getUserName())), + "The selected player should be present in the slot map." + ); } assertEquals(GameStages.RES_ACTIONS, game.getCurrentState().getGameStage()); @@ -1057,121 +1061,25 @@ class GameTest { assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); } - @Test - @Timeout(value = 20, unit = TimeUnit.SECONDS) - void endGameShouldAddBuildingPrestigeValues() { - Game game = new Game(3); + private void preparePlayerForComparableFinalScoring(Player player) { + player.buildingCards.clear(); - List players = addPlayers(game, 3, "building_prestige_"); + player.builders.clear(); + player.inventors.clear(); + player.artists.clear(); + player.hunters.clear(); + player.shamans.clear(); + player.gatherers.clear(); - giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); - - while (game.getCurrentState().getRound() < 10) { - playOneFullRound(game); + while (player.getFoodValue() > 0) { + assertTrue(player.removeFood(1)); } - completeSlotChoice(game); - resolveAllMandatoryActions(game); - - assertEquals(GameStages.OPT_CARD_E, game.getCurrentState().getGameStage()); - - Player player = players.get(0); - - try { - Field boardField = Game.class.getDeclaredField("board"); - boardField.setAccessible(true); - Board board = (Board) boardField.get(game); - - Field upperTribe = Board.class.getDeclaredField("upperListTribe"); - upperTribe.setAccessible(true); - List upper = (List) upperTribe.get(board); - upper.removeIf(TribeCard::IsEventCard); - - Field lowerTribe = Board.class.getDeclaredField("lowerListTribe"); - lowerTribe.setAccessible(true); - List lower = (List) lowerTribe.get(board); - lower.removeIf(TribeCard::IsEventCard); - - } catch (NoSuchFieldException | IllegalAccessException e) { - fail("Reflection fallita: " + e.getMessage()); - } - - int prestigeBefore = player.getPrestigeValue(); - - player.buildingCards.add(new BuildingCard(12, 1, 1, 7)); - player.buildingCards.add(new BuildingCard(12, 1, 1, 5)); - - int expectedMinimumIncrease = 7 + 5; - - resolveOptionalPhaseIfPresent(game); - - assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); - - assertTrue( - player.getPrestigeValue() >= prestigeBefore + expectedMinimumIncrease, - "Final scoring should add at least the prestige values of the two added building cards." - ); - } - - @Test - @Timeout(value = 20, unit = TimeUnit.SECONDS) - void endGameShouldApplyFinalCharacterPrestigeBonuses() { - Game game = new Game(3); - - List players = addPlayers(game, 3, "final_characters_"); - giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); - - while (game.getCurrentState().getRound() < 10) { - playOneFullRound(game); - } - - completeSlotChoice(game); - resolveAllMandatoryActions(game); - - assertEquals(GameStages.OPT_CARD_E, game.getCurrentState().getGameStage()); - - Player player = players.get(0); - assertNotNull(player); - - try { - Field boardField = Game.class.getDeclaredField("board"); - boardField.setAccessible(true); - Board board = (Board) boardField.get(game); - - Field upperTribe = Board.class.getDeclaredField("upperListTribe"); - upperTribe.setAccessible(true); - List upper = (List) upperTribe.get(board); - upper.removeIf(TribeCard::IsEventCard); - - Field lowerTribe = Board.class.getDeclaredField("lowerListTribe"); - lowerTribe.setAccessible(true); - List lower = (List) lowerTribe.get(board); - lower.removeIf(TribeCard::IsEventCard); - - } catch (NoSuchFieldException | IllegalAccessException e) { - fail("Reflection fallita: " + e.getMessage()); - } - - int prestigeBefore = player.getPrestigeValue(); - - player.builders.add(new Builder(1, 0, 4)); - - player.inventors.add(new Inventor(1, 0)); - player.inventors.add(new Inventor(1, 1)); - - player.artists.add(new Artist(1)); - player.artists.add(new Artist(1)); - - int expectedMinimumIncrease = 4 + 4 + 10; - - resolveOptionalPhaseIfPresent(game); - - assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); - - assertTrue( - player.getPrestigeValue() >= prestigeBefore + expectedMinimumIncrease, - "Final scoring should add at least builder prestige, inventor bonus, and artist pair bonus." - ); + /* + * Mantiene l'effetto opzionale, ma con prestigio finale nullo. + * Così la fase OPT_CARD_E rimane coerente e il confronto resta controllato. + */ + player.buildingCards.add(new BuildingCard(12, 1, 1, 0)); } @Test @@ -1202,46 +1110,63 @@ class GameTest { Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); - boolean checkedAtLeastOneSkip = false; + boolean hasDrawableLowerTribe = + game.getCurrentState().getNLower() > 0 + && firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()) != -1; - if (game.getCurrentState().getNLower() > 0 || game.getLowerListTribeCards().stream().allMatch(TribeCard::IsEventCard)) { - assertFalse(game.SkipNoDrawable(current)); - checkedAtLeastOneSkip = true; - } - - if (game.getCurrentState().getNUpper() > 0|| game.getUpperListTribeCards().stream().allMatch(TribeCard::IsEventCard)) { - assertFalse(game.SkipNoDrawable(current)); - checkedAtLeastOneSkip = true; - } + boolean hasDrawableUpperTribe = + game.getCurrentState().getNUpper() > 0 + && firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()) != -1; assertTrue( - checkedAtLeastOneSkip, - "The test should check at least one skip rejection when drawable cards exist." + hasDrawableLowerTribe || hasDrawableUpperTribe, + "The test requires at least one drawable tribe card." ); + + assertFalse(game.SkipNoDrawable(current)); } @Test - void pickOptionalTribeCardShouldRejectEventCard() { + @Timeout(value = 20, unit = TimeUnit.SECONDS) + void pickOptionalTribeCardShouldRejectEventCardIfPresent() { Game game = new Game(3); List players = addPlayers(game, 3, "optional_event_"); giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); - completeSlotChoice(game); - resolveActionsUntilOptionalCardEffect(game); + while (game.getCurrentState().getGameStage() != GameStages.ENDED) { + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); - Player current = game.getCurrentState().getCurrentPlayer(); - assertNotNull(current); + completeSlotChoice(game); + resolveActionsUntilOptionalCardEffect(game); - int eventIndex = firstEventIndexOrMinusOne(game.getUpperListTribeCards()); + Player current = game.getCurrentState().getCurrentPlayer(); + assertNotNull(current); - if(eventIndex==-1) - { - assertFalse(game.NoOptionalCard(current)); + int eventIndex = firstEventIndexOrMinusOne(game.getUpperListTribeCards()); + + if (eventIndex != -1) { + int charactersBefore = current.getTotCharacters(); + int upperSizeBefore = game.getUpperListTribeCards().size(); + + assertFalse(game.PickOptionalTribeCardByIndex(current, eventIndex)); + + assertEquals(GameStages.OPT_CARD_E, game.getCurrentState().getGameStage()); + assertEquals(current, game.getCurrentState().getCurrentPlayer()); + assertEquals(charactersBefore, current.getTotCharacters()); + assertEquals(upperSizeBefore, game.getUpperListTribeCards().size()); + + return; + } + + resolveOptionalPhaseIfPresent(game); } - assertFalse(game.PickOptionalTribeCardByIndex(current, eventIndex)); + org.junit.jupiter.api.Assumptions.assumeTrue( + false, + "No optional phase with an event card in the upper tribe list was reached." + ); } @Test @@ -1492,4 +1417,210 @@ class GameTest { assertEquals(foodBefore, current.getFoodValue()); } + + @Test + @Timeout(value = 20, unit = TimeUnit.SECONDS) + void endGameShouldAddExactBuildingPrestigeValues() { + Game game = new Game(3); + + List players = addPlayers(game, 3, "final_building_scoring_"); + + giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); + + while (game.getCurrentState().getRound() < 10) { + playOneFullRound(game); + } + + assertEquals(10, game.getCurrentState().getRound()); + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + + completeSlotChoice(game); + resolveAllMandatoryActions(game); + + assertEquals(GameStages.OPT_CARD_E, game.getCurrentState().getGameStage()); + + Player controlPlayer = players.get(0); + Player testedPlayer = players.get(1); + + assertNotNull(controlPlayer); + assertNotNull(testedPlayer); + + /* + * I due player vengono resi identici rispetto a Eventi e final scoring. + * La partita è comunque arrivata realmente al round 10. + */ + preparePlayerForComparableFinalScoring(controlPlayer); + preparePlayerForComparableFinalScoring(testedPlayer); + preparePlayerForComparableFinalScoring(players.get(2)); + + BuildingCard firstBuilding = new BuildingCard(12, 1, 1, 7); + BuildingCard secondBuilding = new BuildingCard(12, 1, 1, 5); + + testedPlayer.buildingCards.add(firstBuilding); + testedPlayer.buildingCards.add(secondBuilding); + + int prestigeDifferenceBefore = + testedPlayer.getPrestigeValue() - controlPlayer.getPrestigeValue(); + + int expectedExtraIncrease = + firstBuilding.getPrestigeValue() + + secondBuilding.getPrestigeValue(); + + resolveOptionalPhaseIfPresent(game); + + assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); + + int prestigeDifferenceAfter = + testedPlayer.getPrestigeValue() - controlPlayer.getPrestigeValue(); + + assertEquals( + expectedExtraIncrease, + prestigeDifferenceAfter - prestigeDifferenceBefore, + "Final scoring should add exactly the printed prestige values of the added buildings." + ); + } + + @Test + void playersStampShouldReturnPlayersInformation() { + Game game = new Game(3); + + addPlayers(game, 3, "stamp_"); + + String result = game.PlayersStamp(); + + assertNotNull(result); + assertFalse(result.isBlank()); + assertTrue(result.contains("stamp_1")); + assertTrue(result.contains("stamp_2")); + assertTrue(result.contains("stamp_3")); + } + + @Test + void boardStampShouldReturnBoardInformation() { + Game game = new Game(3); + + addPlayers(game, 3, "board_stamp_"); + + String result = game.BoardStamp(); + + assertNotNull(result); + assertFalse(result.isBlank()); + assertTrue(result.contains("CURRENT STATE")); + assertTrue(result.contains("Char/Events")); + assertTrue(result.contains("Building")); + } + + @Test + @Timeout(value = 20, unit = TimeUnit.SECONDS) + void endGameShouldAddExactBuilderPrestigeValues() { + Game game = new Game(3); + + List players = addPlayers(game, 3, "final_builder_scoring_"); + + giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); + + while (game.getCurrentState().getRound() < 10) { + playOneFullRound(game); + } + + assertEquals(10, game.getCurrentState().getRound()); + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + + completeSlotChoice(game); + resolveAllMandatoryActions(game); + + assertEquals(GameStages.OPT_CARD_E, game.getCurrentState().getGameStage()); + + Player controlPlayer = players.get(0); + Player testedPlayer = players.get(1); + + assertNotNull(controlPlayer); + assertNotNull(testedPlayer); + + preparePlayerForComparableFinalScoring(controlPlayer); + preparePlayerForComparableFinalScoring(testedPlayer); + preparePlayerForComparableFinalScoring(players.get(2)); + + controlPlayer.builders.add(new Builder(1, 0, 0)); + controlPlayer.builders.add(new Builder(1, 0, 0)); + + testedPlayer.builders.add(new Builder(1, 0, 4)); + testedPlayer.builders.add(new Builder(1, 0, 3)); + + int prestigeDifferenceBefore = + testedPlayer.getPrestigeValue() - controlPlayer.getPrestigeValue(); + + int expectedExtraIncrease = 4 + 3; + + resolveOptionalPhaseIfPresent(game); + + assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); + + int prestigeDifferenceAfter = + testedPlayer.getPrestigeValue() - controlPlayer.getPrestigeValue(); + + assertEquals( + expectedExtraIncrease, + prestigeDifferenceAfter - prestigeDifferenceBefore, + "Final scoring should add exactly the prestige values of the builders." + ); + } + + @Test + @Timeout(value = 20, unit = TimeUnit.SECONDS) + void endGameShouldAddExactInventorPrestigeValues() { + Game game = new Game(3); + + List players = addPlayers(game, 3, "final_inventor_scoring_"); + + giveOptionalEffectToAllPlayers(players.get(0), players.get(1), players.get(2)); + + while (game.getCurrentState().getRound() < 10) { + playOneFullRound(game); + } + + assertEquals(10, game.getCurrentState().getRound()); + assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); + + completeSlotChoice(game); + resolveAllMandatoryActions(game); + + assertEquals(GameStages.OPT_CARD_E, game.getCurrentState().getGameStage()); + + Player controlPlayer = players.get(0); + Player testedPlayer = players.get(1); + + assertNotNull(controlPlayer); + assertNotNull(testedPlayer); + + preparePlayerForComparableFinalScoring(controlPlayer); + preparePlayerForComparableFinalScoring(testedPlayer); + preparePlayerForComparableFinalScoring(players.get(2)); + + controlPlayer.builders.add(new Builder(1, 0, 0)); + controlPlayer.builders.add(new Builder(1, 0, 0)); + controlPlayer.builders.add(new Builder(1, 0, 0)); + + testedPlayer.inventors.add(new Inventor(1, 0)); + testedPlayer.inventors.add(new Inventor(1, 1)); + testedPlayer.inventors.add(new Inventor(1, 1)); + + int prestigeDifferenceBefore = + testedPlayer.getPrestigeValue() - controlPlayer.getPrestigeValue(); + + int expectedExtraIncrease = 3 * 2; + + resolveOptionalPhaseIfPresent(game); + + assertEquals(GameStages.ENDED, game.getCurrentState().getGameStage()); + + int prestigeDifferenceAfter = + testedPlayer.getPrestigeValue() - controlPlayer.getPrestigeValue(); + + assertEquals( + expectedExtraIncrease, + prestigeDifferenceAfter - prestigeDifferenceBefore, + "Final scoring should add exactly inventors times different invention icons." + ); + } } \ No newline at end of file