From aee1d3ad873d8fcd5772789d0cd50e3ab6bcabd6 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Fri, 24 Apr 2026 20:15:27 +0200 Subject: [PATCH] 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