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; import it.polimi.ingsw.gc14.Model.Player; import org.junit.jupiter.api.Test; import java.util.LinkedList; import java.util.List; import java.util.Queue; 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 < game.getNPlayers(); 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 < 100) { guard++; resolveOneMandatoryAction(game, controller); } assertEquals(GameStages.OPTIONAL_CARD_EFFECT, game.getCurrentState().getGameStage()); } private void resolveOneMandatoryAction(Game game, GameController controller) { Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); String username = current.getUserName(); if (game.getCurrentState().getNLower() > 0) { int index = firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()); if (index != -1) { assertTrue(controller.drawLowerTribeCard(username, index)); return; } if (!game.getLowerListBuilding().isEmpty()) { current.addFood(100); assertTrue(controller.drawLowerBuildingCard(username, 0)); return; } assertTrue(controller.SkipLowerDrawing(username)); return; } if (game.getCurrentState().getNUpper() > 0) { int index = firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()); if (index != -1) { assertTrue(controller.drawUpperTribeCard(username, index)); return; } if (!game.getUpperListBuilding().isEmpty()) { current.addFood(100); assertTrue(controller.drawUpperBuildingCard(username, 0)); return; } assertTrue(controller.SkipUpperDrawing(username)); return; } fail("Current player has no remaining draw actions."); } private Queue completeSlotChoiceWithSlots(Game game, GameController controller, int... slotIndexes) { assertEquals(game.getNPlayers(), slotIndexes.length); Queue order = new LinkedList<>(); for (int i = 0; i < game.getNPlayers(); i++) { Player current = game.getCurrentState().getCurrentPlayer(); order.add(current); assertTrue(controller.slotChoice(current.getUserName(), slotIndexes[i])); } assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); return order; } @Test void addPlayer() { Game game = new Game(3); GameController controller = new GameController(game); assertTrue(controller.addPlayer("Giorgio")); assertTrue(controller.addPlayer("Marco")); assertTrue(controller.addPlayer("Luca")); assertNotNull(game.getPlayerByUsername("Giorgio")); assertNotNull(game.getPlayerByUsername("Marco")); assertNotNull(game.getPlayerByUsername("Luca")); assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); assertFalse(controller.addPlayer("Extra")); } @Test void allMethodsShouldReturnFalseForUnknownUsername() { Game game = new Game(3); GameController controller = new GameController(game); assertFalse(controller.slotChoice("ghost", 0)); assertFalse(controller.drawUpperTribeCard("ghost", 0)); assertFalse(controller.drawLowerTribeCard("ghost", 0)); assertFalse(controller.drawUpperBuildingCard("ghost", 0)); assertFalse(controller.drawLowerBuildingCard("ghost", 0)); assertFalse(controller.SkipUpperDrawing("ghost")); assertFalse(controller.SkipLowerDrawing("ghost")); assertFalse(controller.pickOptionalTribeCard("ghost", 0)); assertFalse(controller.pickOptionalBuildingCard("ghost", 0)); assertFalse(controller.noOptionalCard("ghost")); } @Test void slotChoice() { Game game = createStartedGame(); GameController controller = new GameController(game); String cur = game.getCurrentState().getCurrentPlayer().getUserName(); String other = cur.equals("Giorgio") ? "Marco" : "Giorgio"; assertFalse(controller.slotChoice(other, 0)); Queue order = completeSlotChoice(game, controller); assertEquals(GameStages.RESOLVING_ACTIONS, game.getCurrentState().getGameStage()); assertEquals(order.poll(), game.getCurrentState().getCurrentPlayer()); } @Test void drawLowerTribeCard() { Game game = createStartedGame(); GameController controller = new GameController(game); Queue order = completeSlotChoice(game, controller); Player first = order.poll(); assertEquals(first, game.getCurrentState().getCurrentPlayer()); List cards = game.getLowerListTribeCards(); 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 = createStartedGame(); GameController controller = new GameController(game); completeSlotChoice(game, controller); while (game.getCurrentState().getNUpper() == 0) { assertTrue(game.getCurrentState().getNLower() > 0); Player current = game.getCurrentState().getCurrentPlayer(); List lower = game.getLowerListTribeCards(); int lowerIdx = firstNonEventIndex(lower); assertTrue(controller.drawLowerTribeCard(current.getUserName(), lowerIdx)); } Player current = game.getCurrentState().getCurrentPlayer(); int beforeTot = current.getTotCharacters(); List upper = game.getUpperListTribeCards(); int upperIdx = firstNonEventIndex(upper); assertTrue(controller.drawUpperTribeCard(current.getUserName(), upperIdx)); assertEquals(beforeTot + 1, current.getTotCharacters()); } @Test void drawUpperBuildingCard() { Game game = createStartedGame(); GameController controller = new GameController(game); completeSlotChoice(game, controller); while (game.getCurrentState().getNUpper() == 0) { assertTrue(game.getCurrentState().getNLower() > 0); Player current = game.getCurrentState().getCurrentPlayer(); List lower = game.getLowerListTribeCards(); int lowerIdx = firstNonEventIndex(lower); assertTrue(controller.drawLowerTribeCard(current.getUserName(), lowerIdx)); } Player current = game.getCurrentState().getCurrentPlayer(); while (current.getFoodValue() > 0) { assertTrue(current.removeFood(1)); } if (current.builders.isEmpty()) { 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 drawingByIndexThroughController() { Game game = new Game(3); GameController controller = new GameController(game); assertTrue(controller.addPlayer("p1")); assertTrue(controller.addPlayer("p2")); assertFalse(controller.addPlayer("p2")); assertTrue(controller.addPlayer("p3")); Queue players = new LinkedList<>(); for (int i = 0; i < game.getNPlayers(); 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; } 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 drawLowerBuildingCardShouldReturnFalseForUnavailableLowerBuildingCard() { Game game = createStartedGame(); GameController controller = new GameController(game); completeSlotChoice(game, controller); Player current = game.getCurrentState().getCurrentPlayer(); 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)); } @Test void noOptionalCardShouldWorkDuringOptionalCardEffectState() { 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)); assertTrue(controller.noOptionalCard(optionalPlayer.getUserName())); } @Test void constructorsGetModelAndSetModelShouldWork() { Game game = new Game(3); GameController controller = new GameController(game); assertEquals(game, controller.getModel()); GameController emptyController = new GameController(); emptyController.setModel(game); assertEquals(game, emptyController.getModel()); } @Test void slotChoiceShouldReturnFalseForInvalidIndexes() { Game game = createStartedGame(); GameController controller = new GameController(game); Player current = game.getCurrentState().getCurrentPlayer(); assertFalse(controller.slotChoice(current.getUserName(), -1)); assertFalse(controller.slotChoice(current.getUserName(), 999)); } @Test void optionalCardMethodsShouldReturnFalseForInvalidIndexesDuringOptionalCardEffectState() { Game game = createStartedGame(); GameController controller = new GameController(game); giveOptionalEffectToAllPlayers(game); completeSlotChoice(game, controller); resolveActionsUntilOptionalCardEffect(game, controller); Player optionalPlayer = game.getCurrentState().getCurrentPlayer(); assertNotNull(optionalPlayer); String username = optionalPlayer.getUserName(); assertFalse(controller.pickOptionalTribeCard(username, -1)); assertFalse(controller.pickOptionalTribeCard(username, 999)); assertFalse(controller.pickOptionalBuildingCard(username, -1)); assertFalse(controller.pickOptionalBuildingCard(username, 999)); } @Test void optionalCardMethodsShouldReturnFalseForWrongPlayer() { Game game = createStartedGame(); GameController controller = new GameController(game); giveOptionalEffectToAllPlayers(game); completeSlotChoice(game, controller); resolveActionsUntilOptionalCardEffect(game, controller); Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); Player wrongPlayer = game.getPlayers().stream() .filter(player -> !player.equals(current)) .findFirst() .orElse(null); assertNotNull(wrongPlayer); assertFalse(controller.pickOptionalTribeCard(wrongPlayer.getUserName(), 0)); assertFalse(controller.pickOptionalBuildingCard(wrongPlayer.getUserName(), 0)); assertFalse(controller.noOptionalCard(wrongPlayer.getUserName())); } @Test void skipLowerDrawingShouldReturnFalseWhenLowerCharacterIsAvailable() { Game game = createStartedGame(); GameController controller = new GameController(game); completeSlotChoiceWithSlots(game, controller, 0, 1, 2); Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); assertEquals(1, game.getCurrentState().getNLower()); assertEquals(0, game.getCurrentState().getNUpper()); assertFalse(game.getLowerListTribeCards().isEmpty()); assertTrue(firstNonEventIndexOrMinusOne(game.getLowerListTribeCards()) != -1); assertFalse(controller.SkipLowerDrawing(current.getUserName())); } @Test void skipUpperDrawingShouldReturnFalseWhenUpperCharacterIsAvailable() { Game game = createStartedGame(); GameController controller = new GameController(game); completeSlotChoiceWithSlots(game, controller, 1, 2, 3); Player current = game.getCurrentState().getCurrentPlayer(); assertNotNull(current); assertEquals(0, game.getCurrentState().getNLower()); assertEquals(1, game.getCurrentState().getNUpper()); assertFalse(game.getUpperListTribeCards().isEmpty()); assertTrue(firstNonEventIndexOrMinusOne(game.getUpperListTribeCards()) != -1); assertFalse(controller.SkipUpperDrawing(current.getUserName())); } }