From 6d1e41bb44aa8ecf34716bf46d0b716d2b27cb07 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Fri, 24 Apr 2026 18:05:58 +0200 Subject: [PATCH 01/48] 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/48] 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/48] 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/48] 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/48] 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/48] 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/48] 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/48] 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/48] 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/48] 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/48] 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 389b446ae64ce4a5f59bf7a1025dbb1c7f02bd74 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Wed, 29 Apr 2026 17:49:20 +0200 Subject: [PATCH 12/48] Fix: Fixed PlayerTest.java. --- src/test/java/it/polimi/ingsw/gc14/Model/PlayerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 31cd1b0..1a30d9b 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/PlayerTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/PlayerTest.java @@ -220,7 +220,7 @@ class PlayerTest { p.buildingCards.add(new Building1(2, 5, 5, CharacterType.INVENTOR)); p.buildingCards.add(new Building1(2, 5, 5, CharacterType.SHAMAN)); p.buildingCards.add(new Building11(1, 5, 7, CharacterType.ARTIST , 3)); - //System.out.println(p.toString()); + System.out.println(p.toString()); assertEquals(""+ "╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\n" + "║ test_usr ║\n" + From 1af39bc558142433159da0900c87b01aea4eb3e7 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Wed, 29 Apr 2026 18:20:19 +0200 Subject: [PATCH 13/48] Add: Added Javadoc For "toStringBoard" Method In CavePaintings.java. --- .../Model/Cards/TribeCards/Events/CavePaintings.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java index 5a70bfb..c0477fe 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java @@ -86,6 +86,17 @@ public class CavePaintings extends EventCard { return new CavePaintings(getEra(), NLower, NPrestigeRem, NPrestigeMul) ; } + + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version; includes: {@code NLower}, {@code NUpper}, {@code NPrestigeRem} and {@code NPrestigeMul}. + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + * @see #NLower + * @see #NPrestigeRem + * @see #NPrestigeMul + */ @Override public String toStringBoard() { return super.toString()+" 0-"+(NLower-1)+":"+NPrestigeRem+" "+NLower+"+:"+NPrestigeMul; From 61caba4b4748d9b2c4e9eacab83bce570289502e Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 30 Apr 2026 15:32:26 +0200 Subject: [PATCH 14/48] Fix: OrderPlayer is now serializable --- src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java | 4 +++- .../java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index 8da0d9e..cb0e1ae 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -40,10 +40,12 @@ public class ClientLauncherTUI { } Thread.sleep(500); } - System.out.println("Model set\n\n"); + System.out.print("\033[H\033[2J"); + System.out.flush(); + System.out.println(controller.localModel); } else if (networkType == 1) { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java index 360bebc..0332e70 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java @@ -2,12 +2,14 @@ package it.polimi.ingsw.gc14.Model.Orders; import it.polimi.ingsw.gc14.Model.Player; +import java.io.Serializable; + /** * Abstract base class for all order logic cards. * An OrderLogicCard manages a queue of players and defines the effects * applied when players are pushed back into the queue. */ -public class OrderPlayer{ +public class OrderPlayer implements Serializable { public Player player; public boolean played; public OrderPlayer(Player player,boolean played){ From fe5e08e5cdccb3addcf47ecf8e2b49e2f62fcf23 Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 30 Apr 2026 16:08:13 +0200 Subject: [PATCH 15/48] Fix: client TCP complete connection and receive game model --- .../polimi/ingsw/gc14/ClientLauncherTUI.java | 29 +++++++++++++---- .../gc14/Network/RMI/Client/RMIClient.java | 12 ++++--- .../gc14/Network/TCP/Client/TCPClient.java | 9 ++++-- .../Network/TCP/Server/ClientHandler.java | 31 +++++++++---------- .../gc14/Network/TCP/Server/TCPServer.java | 7 +++-- 5 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index cb0e1ae..a7e08fa 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -1,6 +1,7 @@ package it.polimi.ingsw.gc14; import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient; +import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient; import it.polimi.ingsw.gc14.View.IView; import java.util.Scanner; @@ -13,21 +14,18 @@ public class ClientLauncherTUI { System.out.println("Selezionare nome utente: "); String username = scanner.next(); - System.out.println(username); System.out.println("Selezionare numero di giocatori desiderato: "); int proposedNumPlayers = scanner.nextInt(); - System.out.println(proposedNumPlayers); System.out.println("Selezionare RMI[0] o TCP[1]: "); int networkType = scanner.nextInt(); - System.out.println(networkType); scanner.close(); if (networkType == 0) { - RMIClient client = new RMIClient("localhost", 1099); - if (client.connect(username, proposedNumPlayers, controller)) { + RMIClient client = new RMIClient(controller, "localhost", 1099); + if (client.connect(username, proposedNumPlayers)) { System.out.println("Succesfully connected to RMI server\n\n"); } else { System.out.println("RMI connection refused\n\n"); @@ -49,7 +47,26 @@ public class ClientLauncherTUI { } else if (networkType == 1) { - return; + TCPClient client = new TCPClient(controller, "localhost", 8080); + if (client.start(username, proposedNumPlayers)) { + System.out.println("Succesfully connected to TCP server\n\n"); + } else { + System.out.println("TCP connection refused\n\n"); + } + + while(true) { + System.out.flush(); + if (controller.localModel!=null) { + break; + } + Thread.sleep(500); + } + System.out.println("Model set\n\n"); + + + System.out.print("\033[H\033[2J"); + System.out.flush(); + System.out.println(controller.localModel); } } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java index 19bd574..3bb68b4 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java @@ -22,13 +22,18 @@ public class RMIClient { /** The remote stub used to call methods on the server */ private IGameServer stub; + /** Client game's controller */ + ClientController controller; + /** * Class constructor. + * @param controller the client controller used to create the callback * @param host the host address of the RMI server * @param port the port of the RMI server */ - public RMIClient(String host, int port) { + public RMIClient(ClientController controller, String host, int port) { + this.controller=controller; this.host = host; this.port = port; } @@ -40,14 +45,13 @@ public class RMIClient { * Then, creates a {@link ClientCallbackImpl} and calls {@link RMIServer#joinGame(String, int, IClientCallback)}. * @param username the player's username * @param preferredInt the desired number of players - * @param clientController the client controller used to create the callback * @return true if the player successfully joined the game, false otherwise */ - public boolean connect(String username,int preferredInt, ClientController clientController) { + public boolean connect(String username,int preferredInt) { try { Registry registry = LocateRegistry.getRegistry(host, port); this.stub = (IGameServer) registry.lookup("RMIGameServer"); - ClientCallbackImpl callback = new ClientCallbackImpl(clientController); + ClientCallbackImpl callback = new ClientCallbackImpl(controller); return stub.joinGame(username, preferredInt, callback); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java index c69734e..3806ce5 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java @@ -1,5 +1,6 @@ package it.polimi.ingsw.gc14.Network.TCP.Client; +import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Network.NetworkEvent; @@ -23,7 +24,7 @@ public class TCPClient { ObjectOutputStream socketSend; /** Client game's controller */ - GameController controller; + ClientController controller; /** IP address of the server to connect to */ String hostname; @@ -38,7 +39,7 @@ public class TCPClient { * @param hostname The IP address of the server * @param port The TCP port of the server */ - public TCPClient(GameController controller, String hostname, int port) { + public TCPClient(ClientController controller, String hostname, int port) { this.controller = controller; this.hostname = hostname; this.port = port; @@ -55,10 +56,12 @@ public class TCPClient { */ public boolean start(String user, int proposedNPlayers) { try { + communicationSocket = new Socket(hostname, port); socketSend = new ObjectOutputStream(communicationSocket.getOutputStream()); socketReceive = new ObjectInputStream(communicationSocket.getInputStream()); + sendEvent(new AddPlayer(user, proposedNPlayers)); if (communicationSocket.getInputStream().read() == -1) { System.out.println("Could not connect to server"); @@ -89,7 +92,7 @@ public class TCPClient { if (event.getIsError()) { System.out.println(event); } else { - event.apply(controller); + event.apply(controller.localController); //clientController.view.update(); TODO } } else if (read instanceof Game model) { diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java index 07864f0..3da705e 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java @@ -41,8 +41,10 @@ public class ClientHandler implements Runnable { * @param clientHandlers The shared list of all active client handlers * @param actionQueue The queue containing incoming events */ - public ClientHandler(Socket clientSocket, List clientHandlers, BlockingQueue actionQueue) { + public ClientHandler(Socket clientSocket, ObjectOutputStream out, ObjectInputStream in, List clientHandlers, BlockingQueue actionQueue) { this.clientSocket = clientSocket; + this.in = in; + this.out = out; this.clientHandlers = clientHandlers; this.actionQueue = actionQueue; } @@ -76,15 +78,13 @@ public class ClientHandler implements Runnable { * Sends a {@link NetworkEvent} to the client. * @param event The network event to send to the client. */ - public void notifyEvent(NetworkEvent event) { - synchronized (out) { - try { - out = new ObjectOutputStream(clientSocket.getOutputStream()); - out.writeObject(event); - } catch (IOException e) { - e.printStackTrace(); - } + public synchronized void notifyEvent(NetworkEvent event) { + try { + out.writeObject(event); + } catch (IOException e) { + e.printStackTrace(); } + } @@ -92,14 +92,11 @@ public class ClientHandler implements Runnable { * Sends the current game model to this client. * @param game The current state of the game to send to the client. */ - public void notifyModel(Game game) { - synchronized (out) { - try { - out = new ObjectOutputStream(clientSocket.getOutputStream()); - out.writeObject(game); - } catch (IOException e) { - e.printStackTrace(); - } + public synchronized void notifyModel(Game game) { + try { + out.writeObject(game); + } catch (IOException e) { + e.printStackTrace(); } } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java index 16c4cfb..55fd6a6 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java @@ -88,8 +88,9 @@ public class TCPServer { try{ clientSocket = socketTCP.accept(); - ObjectInputStream clientSocketObj = new ObjectInputStream(clientSocket.getInputStream()); - NetworkEvent event = (NetworkEvent) clientSocketObj.readObject(); + ObjectOutputStream clientSend = new ObjectOutputStream(clientSocket.getOutputStream()); + ObjectInputStream clientReceive = new ObjectInputStream(clientSocket.getInputStream()); + NetworkEvent event = (NetworkEvent) clientReceive.readObject(); if(!(event.getEventType() == EventType.ADD_PLAYER)){ clientSocket.getOutputStream().write((int)(-1)); @@ -114,7 +115,7 @@ public class TCPServer { clientSocket.getOutputStream().write((int) (1)); System.out.println("Accepted player: " + eventAddPlayer.getUsername()); - ClientHandler clientHandler = new ClientHandler(clientSocket, clientHandlers, actionQueue); + ClientHandler clientHandler = new ClientHandler(clientSocket, clientSend, clientReceive, clientHandlers, actionQueue); clientHandlers.add(clientHandler); ConnectedPlayers++; From dfb2a51816027bc63cf005dfe5e25ee5866259d7 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Thu, 30 Apr 2026 16:08:50 +0200 Subject: [PATCH 16/48] 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 6d99b3e4e93ab48bbb1b9aeef026ca865bb785c4 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:41:14 +0200 Subject: [PATCH 17/48] Add: Added Javadoc For "toString" Method In Player.java. Fix: "addSeparator" Method In AsciiTable.java Now Correctly Positons Separators. --- .../it/polimi/ingsw/gc14/Model/Player.java | 34 ++++++++++++++----- .../ingsw/gc14/View/TUI/AsciiTable.java | 2 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Player.java b/src/main/java/it/polimi/ingsw/gc14/Model/Player.java index fd0a3ba..82151f8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Player.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Player.java @@ -8,7 +8,6 @@ import it.polimi.ingsw.gc14.View.TUI.AsciiTable; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import static it.polimi.ingsw.gc14.View.TUI.BorderStyle.*; @@ -228,17 +227,34 @@ public class Player implements Serializable { // endregion constructors // region Functions + /** + * Prints the {@code Player}'s attributes for the {@code Board}'s representation. + * Uses the {@code UNICODE} border style. + *

Includes: + *

  • {@link #FoodValue Food} + *
  • {@link #PrestigeValue Prestige} + *
  • {@link #artists Artists} + *
  • {@link #builders Builders} + *
  • {@link #gatherers Gatherers} + *
  • {@link #shamans Shamans} + *
  • {@link #inventors Inventors} + *
  • {@link #hunters Hunters} + *
  • {@link #buildingCards Buildings} + *

    + * @return {@code String} - A string representation of the {@code Player}'s attributes. + * @see it.polimi.ingsw.gc14.View.TUI.BorderStyle BorderStyle + */ @Override public String toString() { - int Last = 6; + int Last = -1; var table = new AsciiTable(UNICODE, 1); table.addHeader(this.getUserName()); table.addRow("RESOURCES:"); table.addRow("Food: " + this.getFoodValue()); - table.addSeparator(); table.addRow("Prestige: " + this.getPrestigeValue()); + table.addSeparator(); if(!this.hunters.isEmpty()){ Last = 6; @@ -267,44 +283,44 @@ public class Player implements Serializable { } table.addRow("CHARACTERS:"); if(!this.artists.isEmpty()){ + table.addRow("Artists: " + this.artists.toString()); if(Last == 1){ table.addSeparator(); } - table.addRow("Artists: " + this.artists.toString()); } if(!this.builders.isEmpty()){ + table.addRow("Builders: " + this.builders.toString()); if(Last == 2){ table.addSeparator(); } - table.addRow("Builders: " + this.builders.toString()); } if(!this.gatherers.isEmpty()){ + table.addRow("Gatherers: " + this.gatherers.toString()); if(Last == 3){ table.addSeparator(); } - table.addRow("Gatherers: " + this.gatherers.toString()); } if(!this.shamans.isEmpty()){ + table.addRow("Shamans: " + this.shamans.toString()); if(Last == 4){ table.addSeparator(); } - table.addRow("Shamans: " + this.shamans.toString()); } if(!this.inventors.isEmpty()){ + table.addRow("Inventors: " + this.inventors.toString()); if(Last == 5){ table.addSeparator(); } - table.addRow("Inventors: " + this.inventors.toString()); } if(!this.hunters.isEmpty()){ - table.addSeparator(); table.addRow("Hunters: " + this.hunters.toString()); + table.addSeparator(); } table.addRow("BUILDING CARDS:"); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java index 33e93ad..8fad4eb 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java @@ -15,7 +15,7 @@ public class AsciiTable { public void addRow(String... cells) { rows.add(Arrays.asList(cells)); } public void addRow(List cells) { rows.add(cells); } public void addHeader(String... cells) { rows.add(0, Arrays.asList(cells)); separators.add(0); } - public void addSeparator() { separators.add(rows.size()); } + public void addSeparator() { separators.add(rows.size()-1); } public String build() { var sb = new StringBuilder(); From 3c0ea0f9eb94fd5b40924be1242ac881ead8237f Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:41:14 +0200 Subject: [PATCH 18/48] Add: Added Javadoc For "toStringBoard" Method In CavePaintings.java. --- .../TribeCards/Events/CavePaintings.java | 14 +++++--- .../it/polimi/ingsw/gc14/Model/Player.java | 34 ++++++++++++++----- .../ingsw/gc14/View/TUI/AsciiTable.java | 2 +- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java index c0477fe..a5ae2c9 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java @@ -89,13 +89,19 @@ public class CavePaintings extends EventCard { /** * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s - * toString to print a more detailed version; includes: {@code NLower}, {@code NUpper}, {@code NPrestigeRem} and {@code NPrestigeMul}. + * toString to print a more detailed version. + *

    NOTE: {@code NUpper} is not a real attribute used in calculations (only {@code NLower} is needed), + * however it's a parameter on the cards' design. + *

    + *

    includes: + *

  • {@link #NLower} + *
  • {@code NUpper} + *
  • {@link #NPrestigeRem} + *
  • {@link #NPrestigeMul} + *

    * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game - * @see #NLower - * @see #NPrestigeRem - * @see #NPrestigeMul */ @Override public String toStringBoard() { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Player.java b/src/main/java/it/polimi/ingsw/gc14/Model/Player.java index fd0a3ba..82151f8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Player.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Player.java @@ -8,7 +8,6 @@ import it.polimi.ingsw.gc14.View.TUI.AsciiTable; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import static it.polimi.ingsw.gc14.View.TUI.BorderStyle.*; @@ -228,17 +227,34 @@ public class Player implements Serializable { // endregion constructors // region Functions + /** + * Prints the {@code Player}'s attributes for the {@code Board}'s representation. + * Uses the {@code UNICODE} border style. + *

    Includes: + *

  • {@link #FoodValue Food} + *
  • {@link #PrestigeValue Prestige} + *
  • {@link #artists Artists} + *
  • {@link #builders Builders} + *
  • {@link #gatherers Gatherers} + *
  • {@link #shamans Shamans} + *
  • {@link #inventors Inventors} + *
  • {@link #hunters Hunters} + *
  • {@link #buildingCards Buildings} + *

    + * @return {@code String} - A string representation of the {@code Player}'s attributes. + * @see it.polimi.ingsw.gc14.View.TUI.BorderStyle BorderStyle + */ @Override public String toString() { - int Last = 6; + int Last = -1; var table = new AsciiTable(UNICODE, 1); table.addHeader(this.getUserName()); table.addRow("RESOURCES:"); table.addRow("Food: " + this.getFoodValue()); - table.addSeparator(); table.addRow("Prestige: " + this.getPrestigeValue()); + table.addSeparator(); if(!this.hunters.isEmpty()){ Last = 6; @@ -267,44 +283,44 @@ public class Player implements Serializable { } table.addRow("CHARACTERS:"); if(!this.artists.isEmpty()){ + table.addRow("Artists: " + this.artists.toString()); if(Last == 1){ table.addSeparator(); } - table.addRow("Artists: " + this.artists.toString()); } if(!this.builders.isEmpty()){ + table.addRow("Builders: " + this.builders.toString()); if(Last == 2){ table.addSeparator(); } - table.addRow("Builders: " + this.builders.toString()); } if(!this.gatherers.isEmpty()){ + table.addRow("Gatherers: " + this.gatherers.toString()); if(Last == 3){ table.addSeparator(); } - table.addRow("Gatherers: " + this.gatherers.toString()); } if(!this.shamans.isEmpty()){ + table.addRow("Shamans: " + this.shamans.toString()); if(Last == 4){ table.addSeparator(); } - table.addRow("Shamans: " + this.shamans.toString()); } if(!this.inventors.isEmpty()){ + table.addRow("Inventors: " + this.inventors.toString()); if(Last == 5){ table.addSeparator(); } - table.addRow("Inventors: " + this.inventors.toString()); } if(!this.hunters.isEmpty()){ - table.addSeparator(); table.addRow("Hunters: " + this.hunters.toString()); + table.addSeparator(); } table.addRow("BUILDING CARDS:"); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java index 33e93ad..8fad4eb 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java @@ -15,7 +15,7 @@ public class AsciiTable { public void addRow(String... cells) { rows.add(Arrays.asList(cells)); } public void addRow(List cells) { rows.add(cells); } public void addHeader(String... cells) { rows.add(0, Arrays.asList(cells)); separators.add(0); } - public void addSeparator() { separators.add(rows.size()); } + public void addSeparator() { separators.add(rows.size()-1); } public String build() { var sb = new StringBuilder(); From 8e8f170fdcf22a79eaa6c83716842dfb94c638e3 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:06:06 +0200 Subject: [PATCH 19/48] Add: Added Javadoc For "toStringBoard" Method In Hunt.java. --- .../gc14/Model/Cards/TribeCards/Events/Hunt.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java index 59898d3..9da4873 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java @@ -70,6 +70,17 @@ public class Hunt extends EventCard { public EventCard clone() { return new Hunt(getEra(), prestigeMultiplier); } + + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    includes: + *

  • {@link #prestigeMultiplier} + *

    + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + */ @Override public String toStringBoard() { return super.toString()+" 1F+"+prestigeMultiplier+"PP"+" X N Hunter"; From 0da74efe01fbd7490557fdcf18c716768c6fcc8a Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:06:28 +0200 Subject: [PATCH 20/48] Add: Added Javadoc For "toStringBoard" Method In ShamanicRitual.java. --- .../Cards/TribeCards/Events/ShamanicRitual.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java index 573f1f0..34cbd35 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java @@ -96,6 +96,18 @@ public class ShamanicRitual extends EventCard { public EventCard clone() { return new ShamanicRitual(getEra(), prestigeToAdd, prestigeToRemove); } + + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    includes: + *

  • {@link #prestigeToAdd} + *
  • {@link #prestigeToRemove} + *

    + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + */ @Override public String toStringBoard() { return super.toString()+" *>:"+prestigeToAdd+" *<:"+prestigeToRemove; From b75a4224ee09fda4a33361c3b0489430d09e2c8b Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:06:40 +0200 Subject: [PATCH 21/48] Add: Added Javadoc For "toStringBoard" Method In Sustenance.java. --- .../gc14/Model/Cards/TribeCards/Events/Sustenance.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java index 0d92015..55b3e75 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java @@ -90,6 +90,16 @@ public class Sustenance extends EventCard { return new Sustenance(getEra(), PrestigeDebt); } + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    includes: + *

  • {@link #PrestigeDebt} + *

    + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + */ @Override public String toStringBoard() { return super.toString()+" -1F/-"+PrestigeDebt+"PP"; From fbc77533e315ee71b2702faffff714c457b5b483 Mon Sep 17 00:00:00 2001 From: MatteoPellegrino05 Date: Thu, 30 Apr 2026 17:07:27 +0200 Subject: [PATCH 22/48] 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 From 76e3d19283d22bcdf08df9826d62b36fde6dc513 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:31:11 +0200 Subject: [PATCH 23/48] Add: Added Javadoc For "toStringBoard" Method In Builder.java. --- .../Model/Cards/TribeCards/Characters/Builder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java index 975fa6f..d34349c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java @@ -89,6 +89,18 @@ public class Builder extends Character public String toString() { return super.toString() + " RV:" + String.valueOf(reductionValue) + " PV:" + String.valueOf(prestigeValue); } + + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    Includes: + *

  • {@link #reductionValue Reduction Value} + *
  • {@link #prestigeValue Prestige Value} + *

    + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + */ @Override public String toStringBoard() { From 3fa0f24e52f6c59371469fab04eb3e5c8bc2edfa Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:32:04 +0200 Subject: [PATCH 24/48] Add: Added Javadoc For "toStringBoard" Method And "icon" Field In Hunter.java. --- .../Cards/TribeCards/Characters/Hunter.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java index 0137dd2..a2a9280 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java @@ -5,6 +5,12 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; import it.polimi.ingsw.gc14.Model.Player; public class Hunter extends Character { + + /** + * Describes whether the {@code Hunter Icon} is present or not. Whenever an + * {@code Hunter} with an {@code Hunter Icon} is added to the tribe, 1 {@code Food token} is awarded for each Hunter in the tribe + * (with or without an icon). + */ private boolean icon; /** @@ -53,6 +59,17 @@ public class Hunter extends Character { } return toPrint; } + + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    Potentially includes: + *

  • {@link #icon Icon} + *

    + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + */ @Override public String toStringBoard() { String toPrint = super.toStringBoard(); @@ -62,7 +79,6 @@ public class Hunter extends Character { return toPrint; } - /** * Creates and returns a copy of this Hunter card. * From 137a88fef032c4933f9ade190793f5c5663dc2b7 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:32:22 +0200 Subject: [PATCH 25/48] Add: Added Javadoc For "toStringBoard" Method And "icon" Field In Inventor.java. --- .../Cards/TribeCards/Characters/Inventor.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java index 4d6b77b..e591255 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java @@ -4,6 +4,9 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; import it.polimi.ingsw.gc14.Model.Player; public class Inventor extends Character { + /** + * The {@code Icons}'s ID. There are a total of 10 different Icons. + */ private int icon; /** @@ -54,6 +57,17 @@ public class Inventor extends Character { public String toString() { return super.toString() + " I_ID:" + String.valueOf(icon); } + + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    Includes: + *

  • {@link #icon Icons's ID} + *

    + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + */ @Override public String toStringBoard() { return super.toStringBoard() + " I_ID:" + String.valueOf(icon); From d0027463d18d487c6fe849b13b0d43d3fefc6f4c Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:33:14 +0200 Subject: [PATCH 26/48] Add: Added Javadoc For "toStringBoard" Method And "icon" Field In Shaman.java. --- .../Cards/TribeCards/Characters/Shaman.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java index 10b3360..d529f2a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java @@ -7,6 +7,14 @@ import it.polimi.ingsw.gc14.Model.Player; public class Shaman extends Character { + + /** + * The number of star {@code Icons} the card possesses. + * During the {@link it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.ShamanicRitual Shamanic Ritual Event}, having the + * majority of these icons provides Prestige Points; + * having the minority, on the other hand, results in + * losing Prestige Points. + */ private int icon; /** @@ -51,12 +59,22 @@ public class Shaman extends Character { public String toString() { return super.toString() + " *:" + String.valueOf(icon); } + + /** + * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    Includes: + *

  • {@link #icon Number of stars} + *

    + * @return {@code String} - a string representation of this {@code TribeCard}. + * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard + * @see it.polimi.ingsw.gc14.Model.Game Game + */ @Override public String toStringBoard() { return super.toStringBoard() + " *:" + String.valueOf(icon); } - /** * Creates and returns a copy of this Shaman card. * From a3e415afda94aac8744865a7dcdf530e7b7d9db4 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:33:29 +0200 Subject: [PATCH 27/48] Refactor. --- .../ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java | 2 +- .../gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java | 2 +- .../ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java index a5ae2c9..18ed0c4 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java @@ -93,7 +93,7 @@ public class CavePaintings extends EventCard { *

    NOTE: {@code NUpper} is not a real attribute used in calculations (only {@code NLower} is needed), * however it's a parameter on the cards' design. *

    - *

    includes: + *

    Includes: *

  • {@link #NLower} *
  • {@code NUpper} *
  • {@link #NPrestigeRem} diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java index 34cbd35..73ec0f3 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java @@ -100,7 +100,7 @@ public class ShamanicRitual extends EventCard { /** * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s * toString to print a more detailed version. - *

    includes: + *

    Includes: *

  • {@link #prestigeToAdd} *
  • {@link #prestigeToRemove} *

    diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java index 55b3e75..24305d8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java @@ -93,7 +93,7 @@ public class Sustenance extends EventCard { /** * Prints a string representation of this {@code TribeCard}. This specific variation is used in the {@code Game}'s * toString to print a more detailed version. - *

    includes: + *

    Includes: *

  • {@link #PrestigeDebt} *

    * @return {@code String} - a string representation of this {@code TribeCard}. From e10413b9eb4907a7b45ca72deb22bf7e5ea7091a Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 30 Apr 2026 17:38:09 +0200 Subject: [PATCH 28/48] Add:TUI.java --- .../java/it/polimi/ingsw/gc14/Model/Game.java | 107 +++++----- .../java/it/polimi/ingsw/gc14/View/IView.java | 6 +- .../ingsw/gc14/View/TUI/AsciiTable.java | 2 +- .../it/polimi/ingsw/gc14/View/TUI/TUI.java | 184 +++++++++--------- .../it/polimi/ingsw/gc14/Model/GameTest.java | 15 +- 5 files changed, 158 insertions(+), 156 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 893ea24..d3a34a8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -705,88 +705,85 @@ public class Game implements Serializable { @Override public String toString() { - var table = new AsciiTable(BorderStyle.UNICODE, slotMap.size()); - List stringUp=new ArrayList<>(); - List stringEmpty=new ArrayList<>(); - List stringDown=new ArrayList<>(); + return PlayersStamp()+"\n"+BoardStamp()+"\n"; + } + public String PlayersStamp() + { + StringBuilder stringBuilder=new StringBuilder(); + for(int i=0;i stringUpOffer=new ArrayList<>(); + List stringDownOffer=new ArrayList<>(); + for(Map.Entry entry:slotMap.entrySet()) { - stringEmpty.add(" "); - stringDown.add(entry.getKey().toStringTUI()); + stringDownOffer.add(entry.getKey().toStringTUI()); if(entry.getValue()!=null) - stringUp.add(entry.getValue().getUserName()); + stringUpOffer.add(entry.getValue().getUserName()); else - stringUp.add(" "); + stringUpOffer.add(" "); } - table.addRow(stringUp); - table.addRow(stringEmpty); - table.addRow(stringDown); - Listlines=List.of(orderLogicCard.toString().split("\n")); - List lines2=new ArrayList<>(); - lines2.add("OFFER TRACK"); - lines2.addAll(List.of(table.build().split("\n"))); + var TribeTableUpper = new AsciiTable(BorderStyle.UNICODE,1); + var TribeTableLower = new AsciiTable(BorderStyle.UNICODE,1); - String boardToString=AsciiTable.sideBySide(lines,lines2,1); - - - - var table2 = new AsciiTable(BorderStyle.UNICODE, Math.max(getUpperListTribeCards().size(),getLowerListTribeCards().size())); - List stringUp2=new ArrayList<>(); - List stringDown2=new ArrayList<>(); + List stringUpperListTribe=new ArrayList<>(); + List stringLowerListTribe=new ArrayList<>(); + stringUpperListTribe.add("Char/Events"); + stringLowerListTribe.add("Char/Events"); for(int i=0;i stringUp3=new ArrayList<>(); - List stringDown3=new ArrayList<>(); for(int i=0;iTribeTableUpper.addRow(x)); + stringLowerListTribe.forEach(x->TribeTableLower.addRow(x)); + + offerTrack.addRow(stringUpOffer); + offerTrack.addRow(stringDownOffer); + //offerTrack.addRow(stringLowerListTribe); + + + + return orderLogicCard.toString()+"\n"+ AsciiTable.sideBySide(Arrays.stream((TribeTableUpper.build().split("\n"))).toList(), Arrays.stream(BuildTableUpper.build().split("\n")).toList(),2)+"\n"+offerTrack.build()+"\n"+AsciiTable.sideBySide(List.of(TribeTableLower.build().split("\n")), Arrays.stream(BuildTableLower.build().split("\n")).toList(),2); //return s.toString()+"\n"++"\nOFFER TRACK\n"+ table.build()+"\n" ; } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/IView.java b/src/main/java/it/polimi/ingsw/gc14/View/IView.java index 80c7616..9ffaa16 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/IView.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/IView.java @@ -5,8 +5,8 @@ import it.polimi.ingsw.gc14.Network.NetworkEvent; public interface IView { - void render(Game model); - void showMessage(String message); - void showError(String message); + public void render(Game model); + public void showMessage(String message); + public void showError(String message); } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java index 33e93ad..8fad4eb 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java @@ -15,7 +15,7 @@ public class AsciiTable { public void addRow(String... cells) { rows.add(Arrays.asList(cells)); } public void addRow(List cells) { rows.add(cells); } public void addHeader(String... cells) { rows.add(0, Arrays.asList(cells)); separators.add(0); } - public void addSeparator() { separators.add(rows.size()); } + public void addSeparator() { separators.add(rows.size()-1); } public String build() { var sb = new StringBuilder(); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java index 8d25fa3..911ef66 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java @@ -1,93 +1,91 @@ -//package it.polimi.ingsw.gc14.View.TUI; -//import it.polimi.ingsw.gc14.Model.Game; -// -//public class TUI { -// -// // ── dati di stato ─────────────────────────────────────────── -// private BorderStyle style = BorderStyle.UNICODE; -// private Game model; -// // ── punto di ingresso ─────────────────────────────────────── -// public String render() { -// var sb = new StringBuilder(); -// sb.append(renderHeader()); -// sb.append(renderTurnOrder()); -// sb.append(renderOfferTrack()); -// sb.append(renderCardRows()); -// sb.append(renderTableaux()); -// sb.append(renderFooter()); -// return sb.toString(); -// } -// -// // ── sezioni ───────────────────────────────────────────────── -// private String renderTurnOrder() { -// var table = new AsciiTable(style, 4, 10); // 4 colonne, largh 10 -// table.addRow(model.getPlayers().stream() -// .map(p -> + ". " + p.getUserName()) -// .toList()); -// table.addRow(state.getPlayers().stream() -// .map(p -> p.getTotemPosition() != null -// ? "totem: " + p.getTotemPosition() -// : "(da piaz)") -// .toList()); -// return " TURN ORDER\n" + table.build() + "\n"; -// } -// -// private String renderOfferTrack() { -// var table = new AsciiTable(style, 5, 14); -// table.addRow(state.getOfferTiles().stream() -// .map(t -> t.getId() + ": " + t.getLabel()).toList()); -// table.addRow(state.getOfferTiles().stream() -// .map(OfferTile::getRowsLabel).toList()); -// table.addRow(state.getOfferTiles().stream() -// .map(t -> state.getTotemOnTile(t.getId())).toList()); -// return " OFFER TRACK\n" + table.build() + "\n"; -// } -// -// private String renderCardRows() { -// int cols = state.getTopRow().size(); -// var table = new AsciiTable(style, cols, 13); -// table.addRow(state.getTopRow().stream() -// .map(c -> "[" + c.getTypeLabel() + "]").toList()); -// table.addRow(state.getTopRow().stream() -// .map(Card::getName).toList()); -// table.addSeparator(); -// table.addRow(state.getBotRow().stream() -// .map(c -> "[" + c.getTypeLabel() + "]").toList()); -// table.addRow(state.getBotRow().stream() -// .map(Card::getName).toList()); -// return " CARTE IN GIOCO\n" + prefix("TOP ", "BOT ", table.build()) + "\n"; -// } -// -// private String renderTableaux() { -// var sb = new StringBuilder(" TABLEAU GIOCATORI\n\n"); -// for (Player p : state.getPlayers()) { -// String marker = p.isActive() ? ">>>" : " "; -// sb.append(String.format(" %s %s%s Food:%d PP:%d%n", -// marker, p.getName(), -// p.isActive() ? " [TUO TURNO]" : "", -// p.getFood(), p.getPP())); -// sb.append(renderPlayerTableau(p)); -// sb.append("\n"); -// } -// return sb.toString(); -// } -// -// private String renderPlayerTableau(Player p) { -// var table = new AsciiTable(style, 3, 14); -// table.addHeader("PERSONAGGI", "EDIFICI", "RISORSE"); -// int rows = Math.max(p.getChars().size(), -// Math.max(p.getBuildings().size(), 3)); -// for (int i = 0; i < rows; i++) { -// String ch = i < p.getChars().size() ? p.getChars().get(i) : ""; -// String bd = i < p.getBuildings().size() ? p.getBuildings().get(i) : ""; -// String rs = switch (i) { -// case 0 -> "Food: " + "O".repeat(p.getFood()); -// case 1 -> "PP: " + p.getPP(); -// case 2 -> "Chars:" + p.getChars().size() + " Edif:" + p.getBuildings().size(); -// default -> ""; -// }; -// table.addRow(ch, bd, rs); -// } -// return " " + table.build().replace("\n", "\n "); -// } -//} +package it.polimi.ingsw.gc14.View.TUI; +import it.polimi.ingsw.gc14.Model.Game; +import it.polimi.ingsw.gc14.View.IView; + +public class TUI implements IView { + + // ── dati di stato ─────────────────────────────────────────── + private BorderStyle style = BorderStyle.UNICODE; + private Game model; + public TUI(Game model) { + this.model = model; + } + // ── punto di ingresso ─────────────────────────────────────── + public void render(Game model) + { + try{ + String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb; + if (os.contains("win")) { + pb = new ProcessBuilder("cmd", "/c", "cls"); + } else { + pb = new ProcessBuilder("clear"); + } + pb.inheritIO().start().waitFor(); + } + catch(Exception e){ + } + System.out.println(model.toString()); + } + + public void renderBoard(Game model) + { + try{ + String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb; + if (os.contains("win")) { + pb = new ProcessBuilder("cmd", "/c", "cls"); + } else { + pb = new ProcessBuilder("clear"); + } + pb.inheritIO().start().waitFor(); + } + catch(Exception e){ + } + System.out.println(model.BoardStamp()); + } + public void renderPlayer(Game model) + { + try{ + String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb; + if (os.contains("win")) { + pb = new ProcessBuilder("cmd", "/c", "cls"); + } else { + pb = new ProcessBuilder("clear"); + } + pb.inheritIO().start().waitFor(); + } + catch(Exception e){ + } + System.out.println(model.BoardStamp()); + } + public void renderMyHand(Game model,String username) + { + try{ + String os = System.getProperty("os.name").toLowerCase(); + ProcessBuilder pb; + if (os.contains("win")) { + pb = new ProcessBuilder("cmd", "/c", "cls"); + } else { + pb = new ProcessBuilder("clear"); + } + pb.inheritIO().start().waitFor(); + } + catch(Exception e){ + } + System.out.println(model.getPlayerByUsername(username)); + } + + public void showMessage(String message) + { + System.out.println(message); + } + + + public void showError(String message) + { + System.out.println(message); + } + +} 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 ac50d5a..0d6087b 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import org.junit.platform.commons.annotation.Testable; +import java.io.IOException; import java.util.*; import static org.junit.jupiter.api.Assertions.*; @@ -200,22 +201,28 @@ class GameTest { void noOptionalCard() { } @Test - void toStringModel() - { - Game game=new Game(3); + void toStringModel() throws IOException, InterruptedException { + Game game=new Game(5); Player p1=new Player("p1"); Player p2=new Player("p2"); Player p3=new Player("p3"); + Player p4=new Player("p4"); + Player p5=new Player("p5"); assertTrue(game.addPlayer(p1)); assertTrue(game.addPlayer(p2)); assertTrue(game.addPlayer(p3)); + assertTrue(game.addPlayer(p4)); + assertTrue(game.addPlayer(p5)); Queueplayers=new LinkedList<>(); for(int i=0;i<3;i++) { players.add( game.getCurrentState().getCurrentPlayer()); assertTrue(game.SlotChoiceByIndex(game.getCurrentState().getCurrentPlayer(), i)); } - System.out.println(game); + + System.out.println(game.BoardStamp()); + String os = System.getProperty("os.name").toLowerCase(); + System.out.println(game.PlayersStamp()); } } \ No newline at end of file From 406b9c1b3e2f9d19ab7aad517f901305d8503c82 Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 30 Apr 2026 17:39:01 +0200 Subject: [PATCH 29/48] Removed parameter when creating client controller --- .../java/it/polimi/ingsw/gc14/Controller/ClientController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java index 1da7933..463237d 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java @@ -17,7 +17,7 @@ public class ClientController { } public ClientController() { - this.localController = new GameController(localModel); + this.localController = new GameController(); } public void setModel(Game model) { From 8b8f565eb1ecdb306c25c16411cec5bf1aacbbe7 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:45:04 +0200 Subject: [PATCH 30/48] Add: Added Javadoc For "toStringBoard" Method In EventCard.java. --- .../ingsw/gc14/Model/Cards/TribeCards/EventCard.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/EventCard.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/EventCard.java index 43b937a..5f8fdbc 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/EventCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/EventCard.java @@ -64,6 +64,17 @@ public abstract class EventCard extends TribeCard { public String toString() { return super.toString()+" "+type.toString(); } + + /** + * Prints a string representation of this {@code EventCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    Includes: + *

  • {@link #type Type} + *

    + * @return {@code String} - a string representation of this {@code EventCard}. + * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board + */ @Override public String toStringBoard() { return super.toString()+" "+type.toString(); From 805f71d80a5c5afc9dbbd433807c3d4f40ac9054 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:45:21 +0200 Subject: [PATCH 31/48] Add: Added Javadoc For "toStringBoard" Method In Character.java. --- .../ingsw/gc14/Model/Cards/TribeCards/Character.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Character.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Character.java index ba405ce..b7e5ef0 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Character.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Character.java @@ -60,6 +60,17 @@ public abstract class Character extends TribeCard implements Cloneable { return super.toString(); } + + /** + * Prints a string representation of this {@code Character}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    Includes: + *

  • {@link it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType Type} + *

    + * @return {@code String} - a string representation of this {@code Character}. + * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board + */ @Override public String toStringBoard() { From c6df35040156a2efad601a9fd9d2c6759de94cf2 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:45:34 +0200 Subject: [PATCH 32/48] Refactor. --- .../ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java | 1 + .../ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java | 1 + .../ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java | 1 + .../ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java | 1 + .../ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java | 1 + .../it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java | 1 + .../ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java | 1 + .../ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java | 1 + 8 files changed, 8 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java index d34349c..e5c5642 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java @@ -100,6 +100,7 @@ public class Builder extends Character * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java index a2a9280..5254216 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Hunter.java @@ -69,6 +69,7 @@ public class Hunter extends Character { * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java index e591255..083359d 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Inventor.java @@ -67,6 +67,7 @@ public class Inventor extends Character { * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java index d529f2a..2259ca7 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java @@ -69,6 +69,7 @@ public class Shaman extends Character { * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java index 18ed0c4..16d7395 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/CavePaintings.java @@ -102,6 +102,7 @@ public class CavePaintings extends EventCard { * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java index 9da4873..090b3bd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Hunt.java @@ -80,6 +80,7 @@ public class Hunt extends EventCard { * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java index 73ec0f3..70703d5 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/ShamanicRitual.java @@ -107,6 +107,7 @@ public class ShamanicRitual extends EventCard { * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() { diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java index 24305d8..164f779 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Events/Sustenance.java @@ -99,6 +99,7 @@ public class Sustenance extends EventCard { * @return {@code String} - a string representation of this {@code TribeCard}. * @see it.polimi.ingsw.gc14.Model.Cards.TribeCard TribeCard * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board */ @Override public String toStringBoard() { From c9abac6d5783d397b64da01a4aaeb4aead07920a Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:56:30 +0200 Subject: [PATCH 33/48] Fix: Fixed Food / Prestige Removal Logic In Order*.java (Missing "!") + Refactor Of Corresponding Javadoc. --- .../java/it/polimi/ingsw/gc14/Model/Orders/Order2.java | 2 +- .../java/it/polimi/ingsw/gc14/Model/Orders/Order3.java | 5 +++-- .../java/it/polimi/ingsw/gc14/Model/Orders/Order4.java | 4 ++-- .../java/it/polimi/ingsw/gc14/Model/Orders/Order5.java | 4 ++-- .../it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java | 7 ++++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order2.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order2.java index 6d926c4..548f483 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order2.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order2.java @@ -26,7 +26,7 @@ public class Order2 extends OrderLogicCard { /** * Applies the effect associated with the specified position index for the given player. *

    If {@code index == 0}, the player gains 1 Food and the building effect is applied. - *

    If {@code index == 1}, the player tries to remove 1 Food; if the player cannot remove it, + *

    If {@code index == 1}, the player tries to remove 1 Food; if the player pay it, * the player loses 2 Prestige. * * @param player the player to whom the effect is applied. diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order3.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order3.java index fb4c71a..14bc2db 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 @@ -27,7 +27,8 @@ public class Order3 extends OrderLogicCard { * Applies the effect associated with the specified position index for the given player. *

    If {@code index == 0}, the player gains 2 Food and the building effect is applied. *

    If {@code index == 1}, no effect is applied. - *

    If {@code index == 2}, if the player can remove 1 Food, the player loses 2 Prestige. + *

    If {@code index == 2}, the player tries to remove 1 Food; if the player pay it, + * the player loses 2 Prestige. * * @param player the player to whom the effect is applied. * @param index the position index of the effect to apply. @@ -47,7 +48,7 @@ public class Order3 extends OrderLogicCard { return; } if(index==2){ - if(player.removeFood(1)){ + if(!player.removeFood(1)){ player.removePrestige(2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order4.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order4.java index 966f15a..1fc229c 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 @@ -28,7 +28,7 @@ public class Order4 extends OrderLogicCard { *

    If {@code index == 0}, the player gains 2 Food and the building effect is applied. *

    If {@code index == 1}, the player gains 1 Food and the building effect is applied. *

    If {@code index == 2}, no effect is applied. - *

    If {@code index == 3}, the player tries to remove 1 Food; if the removal succeeds, + *

    If {@code index == 3}, the player tries to remove 1 Food; if the player pay it, * the player loses 2 Prestige. * * @param player the player to whom the effect is applied. @@ -55,7 +55,7 @@ public class Order4 extends OrderLogicCard { return; } if(index==3){ - if(player.removeFood(1)){ + if(!player.removeFood(1)){ player.removePrestige(2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order5.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/Order5.java index 468c626..d184bcc 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 @@ -29,7 +29,7 @@ public class Order5 extends OrderLogicCard { *

    If {@code index == 1}, the player gains 1 Food and the building effect is applied. *

    If {@code index == 2}, no effect is applied. *

    If {@code index == 3}, no effect is applied. - *

    If {@code index == 4}, the player tries to remove 1 Food; if the removal succeeds, + *

    If {@code index == 4}, the player tries to remove 1 Food; if the player pay it, * the player loses 2 Prestige. * * @param player the player to whom the effect is applied. @@ -56,7 +56,7 @@ public class Order5 extends OrderLogicCard { return; } if(index==4){ - if(player.removeFood(1)){ + if(!player.removeFood(1)){ player.removePrestige(2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java index 360bebc..56ac136 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Orders/OrderPlayer.java @@ -3,9 +3,10 @@ package it.polimi.ingsw.gc14.Model.Orders; import it.polimi.ingsw.gc14.Model.Player; /** - * Abstract base class for all order logic cards. - * An OrderLogicCard manages a queue of players and defines the effects - * applied when players are pushed back into the queue. + * Abstract base class for all order {@code logic cards}. + * An {@code OrderLogicCard} manages a queue of {@code players} and defines the effects + * applied when they are pushed back into the queue. + * @see it.polimi.ingsw.gc14.Model.Player Player */ public class OrderPlayer{ public Player player; From 7e3623d3aee1e30f39291b762243d29c8898edc2 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 30 Apr 2026 18:01:35 +0200 Subject: [PATCH 34/48] Bind: TUI->Launcher --- .../polimi/ingsw/gc14/ClientLauncherTUI.java | 14 +++++++---- .../gc14/Controller/ClientController.java | 13 ++-------- .../RMI/Client/ClientCallbackImpl.java | 3 ++- .../java/it/polimi/ingsw/gc14/View/IView.java | 4 ++-- .../it/polimi/ingsw/gc14/View/TUI/TUI.java | 24 +++++++++++++++---- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index a7e08fa..2280b72 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -3,12 +3,15 @@ import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient; import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient; import it.polimi.ingsw.gc14.View.IView; +import it.polimi.ingsw.gc14.View.TUI.TUI; import java.util.Scanner; public class ClientLauncherTUI { + private IView view; public void main() throws InterruptedException { - ClientController controller = new ClientController(); + view=new TUI(null); + ClientController controller = new ClientController(view); Scanner scanner = new Scanner(System.in); @@ -29,11 +32,12 @@ public class ClientLauncherTUI { System.out.println("Succesfully connected to RMI server\n\n"); } else { System.out.println("RMI connection refused\n\n"); + return; } while(true) { System.out.flush(); - if (controller.localModel!=null) { + if (controller.localController.getModel()!=null) { break; } Thread.sleep(500); @@ -43,7 +47,7 @@ public class ClientLauncherTUI { System.out.print("\033[H\033[2J"); System.out.flush(); - System.out.println(controller.localModel); + System.out.println(controller.localController.getModel()); } else if (networkType == 1) { @@ -56,7 +60,7 @@ public class ClientLauncherTUI { while(true) { System.out.flush(); - if (controller.localModel!=null) { + if (controller.localController.getModel()!=null) { break; } Thread.sleep(500); @@ -66,7 +70,7 @@ public class ClientLauncherTUI { System.out.print("\033[H\033[2J"); System.out.flush(); - System.out.println(controller.localModel); + System.out.println(controller.localController.getModel()); } } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java index 463237d..74ab567 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java @@ -6,28 +6,19 @@ import it.polimi.ingsw.gc14.View.IView; public class ClientController { - public Game localModel; public GameController localController; public IView view=null; - public ClientController(IView view,Game localModel) { + public ClientController(IView view) { this.view = view; - this.localModel = localModel; - this.localController = new GameController(localModel); - } - - public ClientController() { this.localController = new GameController(); } public void setModel(Game model) { - this.localModel = model; localController.setModel(model); - // localModel.addObserver((Observer) view); // registra la view come observer + view.update(localController.getModel()); } - - public void onError(String message) { view.showError(message); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java index 5b16b76..beb9c91 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java @@ -39,6 +39,7 @@ public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCa @Override public void onGameInit(Game model) throws RemoteException { clientController.setModel(model); + clientController.view.render(); } @@ -55,7 +56,7 @@ public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCa System.out.println(event.toString()); } else { event.apply(clientController.localController); - //clientController.view.update(); TODO + clientController.view.render(); } } } diff --git a/src/main/java/it/polimi/ingsw/gc14/View/IView.java b/src/main/java/it/polimi/ingsw/gc14/View/IView.java index 9ffaa16..2169583 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/IView.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/IView.java @@ -4,8 +4,8 @@ import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Network.NetworkEvent; public interface IView { - - public void render(Game model); + public void update(Game game); + public void render(); public void showMessage(String message); public void showError(String message); diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java index 911ef66..caaa040 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java @@ -1,18 +1,31 @@ package it.polimi.ingsw.gc14.View.TUI; import it.polimi.ingsw.gc14.Model.Game; +import it.polimi.ingsw.gc14.Network.Observer; import it.polimi.ingsw.gc14.View.IView; -public class TUI implements IView { +public class TUI implements IView, Observer { // ── dati di stato ─────────────────────────────────────────── private BorderStyle style = BorderStyle.UNICODE; private Game model; + private String username; public TUI(Game model) { this.model = model; + this.username=""; } + public void setUsername(String username) { + this.username = username; + } + + @Override + public void update(Game model) { + this.model = model; + } + // ── punto di ingresso ─────────────────────────────────────── - public void render(Game model) + public void render() { + this.model=model; try{ String os = System.getProperty("os.name").toLowerCase(); ProcessBuilder pb; @@ -28,7 +41,7 @@ public class TUI implements IView { System.out.println(model.toString()); } - public void renderBoard(Game model) + public void renderBoard() { try{ String os = System.getProperty("os.name").toLowerCase(); @@ -44,7 +57,7 @@ public class TUI implements IView { } System.out.println(model.BoardStamp()); } - public void renderPlayer(Game model) + public void renderPlayer() { try{ String os = System.getProperty("os.name").toLowerCase(); @@ -60,7 +73,7 @@ public class TUI implements IView { } System.out.println(model.BoardStamp()); } - public void renderMyHand(Game model,String username) + public void renderMyHand() { try{ String os = System.getProperty("os.name").toLowerCase(); @@ -76,6 +89,7 @@ public class TUI implements IView { } System.out.println(model.getPlayerByUsername(username)); } + public void showMessage(String message) { From d66af3a112b6c0d53642a3d26a76711e2cd3dea6 Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 30 Apr 2026 18:10:11 +0200 Subject: [PATCH 35/48] Both TCP and RMI works and receive correctly the model. After receiving the model, it is printed in stdout --- .../polimi/ingsw/gc14/ClientLauncherTUI.java | 28 ++++--------------- .../gc14/Network/TCP/Client/TCPClient.java | 3 +- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index 2280b72..4993aeb 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -24,7 +24,7 @@ public class ClientLauncherTUI { System.out.println("Selezionare RMI[0] o TCP[1]: "); int networkType = scanner.nextInt(); - scanner.close(); + if (networkType == 0) { RMIClient client = new RMIClient(controller, "localhost", 1099); @@ -36,19 +36,10 @@ public class ClientLauncherTUI { } while(true) { - System.out.flush(); - if (controller.localController.getModel()!=null) { - break; - } - Thread.sleep(500); + int h = scanner.nextInt(); } - System.out.println("Model set\n\n"); - System.out.print("\033[H\033[2J"); - System.out.flush(); - System.out.println(controller.localController.getModel()); - } else if (networkType == 1) { TCPClient client = new TCPClient(controller, "localhost", 8080); @@ -58,19 +49,12 @@ public class ClientLauncherTUI { System.out.println("TCP connection refused\n\n"); } + while(true) { - System.out.flush(); - if (controller.localController.getModel()!=null) { - break; - } - Thread.sleep(500); + int h = scanner.nextInt(); } - System.out.println("Model set\n\n"); - - - System.out.print("\033[H\033[2J"); - System.out.flush(); - System.out.println(controller.localController.getModel()); } + + scanner.close(); } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java index 3806ce5..42b2d6c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java @@ -93,10 +93,11 @@ public class TCPClient { System.out.println(event); } else { event.apply(controller.localController); - //clientController.view.update(); TODO + controller.view.render(); } } else if (read instanceof Game model) { controller.setModel(model); + controller.view.render(); } } catch (IOException e) { e.printStackTrace(); From 4360cf023de6f1149e0709e12639a9f9f0da28c7 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:10:37 +0200 Subject: [PATCH 36/48] Add: Added Javadoc For "toString" Method In Game.java. --- src/main/java/it/polimi/ingsw/gc14/Model/Game.java | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 893ea24..054b2f6 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -703,6 +703,16 @@ public class Game implements Serializable { return true; } + /** + * Prints a string representation of the {@code Game}. Used in the TUI implementation to draw: + *

  • {@link it.polimi.ingsw.gc14.Model.GamePackage.Board Board} + *
  • {@link it.polimi.ingsw.gc14.Model.Player Players} + *
  • {@link #getUpperListTribeCards() Upper TribeCard List}
  • {@link #getUpperListBuilding() Upper Building List} + *
  • {@link #getLowerListTribeCards() Lower TribeCard List}
  • {@link #getLowerListBuilding() Lower Building List} + *
  • {@link it.polimi.ingsw.gc14.Model.OrderLogicCard Offer Track} + * + * @return {@code String} - a string representation of the {@code Game}. + */ @Override public String toString() { var table = new AsciiTable(BorderStyle.UNICODE, slotMap.size()); From ff6953e5237cf0d1627c92c88978135a38d41c03 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:19:29 +0200 Subject: [PATCH 37/48] Add: Added Javadoc For "toStringBoard" Method In PlayableCard.java. --- .../java/it/polimi/ingsw/gc14/Model/PlayableCard.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/PlayableCard.java b/src/main/java/it/polimi/ingsw/gc14/Model/PlayableCard.java index 386f731..f2446bd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/PlayableCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/PlayableCard.java @@ -45,6 +45,14 @@ public abstract class PlayableCard implements Serializable { public String toString() { return "⎕:"; } + + /** + * Prints a string representation of this {@code PlayableCard}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version (in this specific case the two methods are equal). + * @return {@code String} - a string representation of this {@code PlayableCard}. + * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board + */ public String toStringBoard() { return "⎕:"; From 6826886d4b73fa26d625057bbbb722785ffc118c Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:19:46 +0200 Subject: [PATCH 38/48] Add: Added Javadoc For "toStringTUI" Method In Slot.java. --- src/main/java/it/polimi/ingsw/gc14/Model/Slot.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Slot.java b/src/main/java/it/polimi/ingsw/gc14/Model/Slot.java index 456ee1a..5ec72db 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Slot.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Slot.java @@ -156,6 +156,19 @@ public class Slot implements Serializable { } + /** + * Prints a string representation of this {@code Slot}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version for the TUI implementation. + *

    includes: + *

  • {@link #slotId SlotId} + *
  • {@link #NUpper NUpper} + *
  • {@link #NLower NLower} + *
  • {@link #Food Food} + *

    + * @return {@code String} - a string representation of this {@code Slot}. + * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board + */ public String toStringTUI() { StringBuilder s = new StringBuilder(); From 5246818fca9c1a8e41f60a2d767a0cb7e3acf863 Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 30 Apr 2026 18:34:40 +0200 Subject: [PATCH 39/48] Fix: MVC (Client) Add:IClient --- .../polimi/ingsw/gc14/ClientLauncherTUI.java | 20 ++-- .../gc14/Controller/ClientController.java | 92 ++++++++++++++++++- .../it/polimi/ingsw/gc14/Network/IClient.java | 8 ++ .../gc14/Network/RMI/Client/RMIClient.java | 11 ++- .../gc14/Network/TCP/Client/TCPClient.java | 10 +- src/main/java/module-info.java | 1 + 6 files changed, 127 insertions(+), 15 deletions(-) create mode 100644 src/main/java/it/polimi/ingsw/gc14/Network/IClient.java diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index 4993aeb..09a606f 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -8,7 +8,7 @@ import it.polimi.ingsw.gc14.View.TUI.TUI; import java.util.Scanner; public class ClientLauncherTUI { - private IView view; + private TUI view; public void main() throws InterruptedException { view=new TUI(null); ClientController controller = new ClientController(view); @@ -34,22 +34,30 @@ public class ClientLauncherTUI { System.out.println("RMI connection refused\n\n"); return; } - + controller.setClient(client); + int h; + while(controller.localController.getModel()==null){ + h = scanner.nextInt(); + if(controller.localController.getModel()!=null) + { + break; + } + } while(true) { - int h = scanner.nextInt(); + h = scanner.nextInt(); } } else if (networkType == 1) { TCPClient client = new TCPClient(controller, "localhost", 8080); - if (client.start(username, proposedNumPlayers)) { + if (client.connect(username, proposedNumPlayers)) { System.out.println("Succesfully connected to TCP server\n\n"); } else { System.out.println("TCP connection refused\n\n"); + return; } - - + controller.setClient(client); while(true) { int h = scanner.nextInt(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java index 74ab567..3224152 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java @@ -1,6 +1,9 @@ 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.Network.NetworkEvents.*; import it.polimi.ingsw.gc14.Network.Observer; import it.polimi.ingsw.gc14.View.IView; @@ -8,12 +11,15 @@ public class ClientController { public GameController localController; public IView view=null; + private IClient client; public ClientController(IView view) { this.view = view; this.localController = new GameController(); } - + public void setClient(IClient client) { + this.client = client; + } public void setModel(Game model) { localController.setModel(model); view.update(localController.getModel()); @@ -23,4 +29,88 @@ public class ClientController { view.showError(message); } + /** + * Attempts to draw an upper tribe card for the specified player from the specified position. + * + * @param playerUsername the username of the player performing the action. + * @param pos the position of the upper tribe card to draw. + * @return {@code true} if the action succeeds, {@code false} if the player does not exist + * or if the draw operation fails. + */ + public void drawUpperTribeCard(String playerUsername,int pos) { + client.doEvent(new DrawUpperTribeCard(playerUsername,pos)); + } + + /** + * Attempts to draw a lower tribe card for the specified player from the specified position. + * + * @param playerUsername the username of the player performing the action. + * @param pos the position of the lower tribe card to draw. + * @return {@code true} if the action succeeds, {@code false} if the player does not exist + * or if the draw operation fails. + */ + public void drawLowerTribeCard(String playerUsername,int pos) { + client.doEvent(new DrawLowerTribeCard(playerUsername,pos)); + } + + /** + * Attempts to draw an upper building card for the specified player from the specified position. + * + * @param playerUsername the username of the player performing the action. + * @param pos the position of the upper building card to draw. + * @return {@code true} if the action succeeds, {@code false} if the player does not exist + * or if the draw operation fails. + */ + public void drawUpperBuildingCard(String playerUsername,int pos) { + client.doEvent(new DrawUpperBuildingCard(playerUsername,pos)); + } + + /** + * Attempts to draw a lower building card for the specified player from the specified position. + * + * @param playerUsername the username of the player performing the action. + * @param pos the position of the lower building card to draw. + * @return {@code true} if the action succeeds, {@code false} if the player does not exist + * or if the draw operation fails. + */ + public void drawLowerBuildingCard(String playerUsername,int pos) { + client.doEvent(new DrawLowerBuildingCard(playerUsername,pos)); + } + + /** + * Attempts to pick an optional tribe card for the specified player from the specified position. + * + * @param playerUsername the username of the player performing the action. + * @param pos the position of the optional tribe card to pick. + * @return {@code true} if the action succeeds, {@code false} if the player does not exist + * or if the pick operation fails. + */ + public void pickOptionalTribeCard(String playerUsername,int pos) { + client.doEvent(new PickOptionalTribeCard(playerUsername,pos)); + } + + /** + * Attempts to pick an optional building card for the specified player from the specified position. + * + * @param playerUsername the username of the player performing the action. + * @param pos the position of the optional building card to pick. + * @return {@code true} if the action succeeds, {@code false} if the player does not exist + * or if the pick operation fails. + */ + public void pickOptionalBuildingCard(String playerUsername,int pos) { + client.doEvent(new PickOptionalBuildingCard(playerUsername,pos)); + } + + /** + * Attempts to perform the slot choice action for the specified player at the specified position. + * + * @param playerUsername the username of the player performing the action. + * @param pos the position of the chosen slot. + * @return {@code true} if the action succeeds, {@code false} if the player does not exist + * or if the slot choice operation fails. + */ + public void slotChoice(String playerUsername,int pos) { + client.doEvent(new SlotChoice(playerUsername,pos)); + } + } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/IClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/IClient.java new file mode 100644 index 0000000..86f6435 --- /dev/null +++ b/src/main/java/it/polimi/ingsw/gc14/Network/IClient.java @@ -0,0 +1,8 @@ +package it.polimi.ingsw.gc14.Network; + +import java.rmi.RemoteException; + +public interface IClient { + public boolean connect(String username,int preferredInt); + public void doEvent(NetworkEvent event) ; +} diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java index 3bb68b4..03e0251 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java @@ -4,6 +4,7 @@ import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import it.polimi.ingsw.gc14.Controller.ClientController; +import it.polimi.ingsw.gc14.Network.IClient; import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback; import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer; @@ -11,7 +12,7 @@ import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer; /** * Client RMI. Uses the methods exposed by the server RMI. */ -public class RMIClient { +public class RMIClient implements IClient { /** The host address of the RMI server */ private final String host; @@ -67,8 +68,12 @@ public class RMIClient { * @param event the event to send * @throws RemoteException if any RMI error occurs */ - public void doEvent(NetworkEvent event) throws RemoteException { - stub.doEvent(event); + public void doEvent(NetworkEvent event) { + try { + stub.doEvent(event); + }catch (Exception e) { + + } } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java index 42b2d6c..3408e99 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java @@ -1,8 +1,8 @@ package it.polimi.ingsw.gc14.Network.TCP.Client; import it.polimi.ingsw.gc14.Controller.ClientController; -import it.polimi.ingsw.gc14.Controller.GameController; import it.polimi.ingsw.gc14.Model.Game; +import it.polimi.ingsw.gc14.Network.IClient; import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.NetworkEvents.AddPlayer; @@ -12,7 +12,7 @@ import java.net.*; /** * Client TCP. Sends and receives messages with the TCP server. */ -public class TCPClient { +public class TCPClient implements IClient { /** Socket TCP */ Socket communicationSocket; @@ -54,7 +54,7 @@ public class TCPClient { * @param proposedNPlayers The desired number of players for the game * @return true if the connection is successful, false otherwise. */ - public boolean start(String user, int proposedNPlayers) { + public boolean connect(String user, int proposedNPlayers) { try { communicationSocket = new Socket(hostname, port); @@ -62,7 +62,7 @@ public class TCPClient { socketReceive = new ObjectInputStream(communicationSocket.getInputStream()); - sendEvent(new AddPlayer(user, proposedNPlayers)); + doEvent(new AddPlayer(user, proposedNPlayers)); if (communicationSocket.getInputStream().read() == -1) { System.out.println("Could not connect to server"); return false; @@ -112,7 +112,7 @@ public class TCPClient { * Sends a {@link NetworkEvent} to the server. * @param event The NetworkEvent to send. */ - private void sendEvent(NetworkEvent event) { + public void doEvent(NetworkEvent event) { try { socketSend.writeObject(event); } catch (IOException e) { diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index e178647..5e72256 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -5,6 +5,7 @@ module it.polimi.ingsw.gc14 { requires java.rmi; requires java.smartcardio; requires com.google.gson; + requires it.polimi.ingsw.gc14; opens it.polimi.ingsw.gc14 to javafx.fxml, com.google.gson; opens it.polimi.ingsw.gc14.Model to com.google.gson; From 9992808426c45d8134ef90de2f47b24a24b13efd Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:39:16 +0200 Subject: [PATCH 40/48] Add: Added Javadoc For "getPosition" Method And "playerList" Field In OrderLogicCard.java. --- .../it/polimi/ingsw/gc14/Model/OrderLogicCard.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java index 84eb72c..5a970db 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/OrderLogicCard.java @@ -12,9 +12,13 @@ import java.util.stream.Collectors; public abstract class OrderLogicCard implements Serializable { /** - * The queue of players associated with this order logic card. + * The queue of {@link Player Players} associated with this order logic card. */ protected Queue players; + + /** + * The list of {@link Player Players} associated with this order logic card. + */ protected List playerList; @@ -98,6 +102,12 @@ public abstract class OrderLogicCard implements Serializable { player.addFood(1); } + /** + * Returns the {@code Player}'s position based on it's {@code Username}. + * @param username The desired {@code Player}'s username. + * @return {@code int} - the {@code Player}'s position. + * @see Player + */ protected int getPosition(String username) { int pos = 0; From b3ece597e1150d68848845d2d6bbd1a456338c01 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:49:43 +0200 Subject: [PATCH 41/48] Add: TODO. --- .../polimi/ingsw/gc14/ClientLauncherTUI.java | 2 +- .../gc14/Controller/ClientController.java | 13 ++++++++---- .../it/polimi/ingsw/gc14/LimitedList.java | 9 ++++++++ .../Cards/Building/Effects/Building13.java | 1 - .../Cards/TribeCards/Characters/Builder.java | 4 +--- .../Cards/TribeCards/Characters/Gatherer.java | 1 - .../Cards/TribeCards/Characters/Shaman.java | 2 -- .../polimi/ingsw/gc14/Model/DecksCreator.java | 17 ++++++++++++--- .../ingsw/gc14/Network/NetworkEvent.java | 17 +++++++++++++++ .../gc14/Network/NetworkEvents/AddPlayer.java | 8 +++++++ .../NetworkEvents/DrawLowerBuildingCard.java | 5 +++++ .../NetworkEvents/DrawLowerTribeCard.java | 4 ++++ .../NetworkEvents/DrawUpperBuildingCard.java | 5 +++++ .../NetworkEvents/DrawUpperTribeCard.java | 5 +++++ .../PickOptionalBuildingCard.java | 5 +++++ .../NetworkEvents/PickOptionalTribeCard.java | 6 ++++++ .../Network/NetworkEvents/SlotChoice.java | 5 +++++ .../gc14/Network/RMI/Client/RMIClient.java | 2 +- .../ingsw/gc14/View/TUI/AsciiTable.java | 21 +++++++++++++++++++ 19 files changed, 116 insertions(+), 16 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index 8da0d9e..cec543c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -2,10 +2,10 @@ package it.polimi.ingsw.gc14; import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient; import it.polimi.ingsw.gc14.View.IView; - import java.util.Scanner; public class ClientLauncherTUI { + //TODO Javadoc public void main() throws InterruptedException { ClientController controller = new ClientController(); diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java index 1da7933..e41a0b1 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java +++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java @@ -4,18 +4,25 @@ import it.polimi.ingsw.gc14.Model.Game; import it.polimi.ingsw.gc14.Network.Observer; import it.polimi.ingsw.gc14.View.IView; +//TODO Javadoc public class ClientController { - + //TODO Javadoc public Game localModel; + + //TODO Javadoc public GameController localController; + + //TODO Javadoc public IView view=null; + //TODO Javadoc public ClientController(IView view,Game localModel) { this.view = view; this.localModel = localModel; this.localController = new GameController(localModel); } + //TODO Javadoc public ClientController() { this.localController = new GameController(localModel); } @@ -26,10 +33,8 @@ public class ClientController { // localModel.addObserver((Observer) view); // registra la view come observer } - - + //TODO Javadoc public void onError(String message) { view.showError(message); } - } diff --git a/src/main/java/it/polimi/ingsw/gc14/LimitedList.java b/src/main/java/it/polimi/ingsw/gc14/LimitedList.java index 6aa8cf9..ad351d0 100644 --- a/src/main/java/it/polimi/ingsw/gc14/LimitedList.java +++ b/src/main/java/it/polimi/ingsw/gc14/LimitedList.java @@ -2,15 +2,21 @@ package it.polimi.ingsw.gc14; import java.util.ArrayList; +//TODO Javadoc public class LimitedList extends ArrayList { + //TODO Javadoc private int limit; + + //TODO Javadoc private Runnable action; + //TODO Javadoc public LimitedList(int limit, Runnable action) { this.limit = limit; this.action = action; } + //TODO Javadoc @Override public boolean add(T element) { boolean result = super.add(element); @@ -20,12 +26,15 @@ public class LimitedList extends ArrayList { return result; } + //TODO Javadoc public void setLimit(int num) { this.limit=num; } + //TODO Javadoc public int getLimit(){return limit;} + //TODO Javadoc public void setAction(Runnable action) { this.action=action; } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building13.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building13.java index 32cc32e..9c049dd 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building13.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building13.java @@ -5,7 +5,6 @@ import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Player; public class Building13 extends BuildingCard{ - /** * Creates a Building13 card with the specified era, price, and prestige value. * diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java index e5c5642..0204d5f 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Builder.java @@ -4,9 +4,7 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.Character; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; import it.polimi.ingsw.gc14.Model.Player; -public class Builder extends Character -{ - +public class Builder extends Character { /** * The reduction value provided by this Builder card. */ diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Gatherer.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Gatherer.java index f74149b..9c438a6 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Gatherer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Gatherer.java @@ -5,7 +5,6 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; import it.polimi.ingsw.gc14.Model.Player; public class Gatherer extends Character { - /** * Creates a Gatherer character card with the specified era. * diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java index 2259ca7..2b3f5cc 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/TribeCards/Characters/Shaman.java @@ -6,8 +6,6 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; import it.polimi.ingsw.gc14.Model.Player; public class Shaman extends Character { - - /** * The number of star {@code Icons} the card possesses. * During the {@link it.polimi.ingsw.gc14.Model.Cards.TribeCards.Events.ShamanicRitual Shamanic Ritual Event}, having the diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/DecksCreator.java b/src/main/java/it/polimi/ingsw/gc14/Model/DecksCreator.java index ea2df87..4b7388a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/DecksCreator.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/DecksCreator.java @@ -1,7 +1,6 @@ package it.polimi.ingsw.gc14.Model; import com.google.gson.*; -import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType; import it.polimi.ingsw.gc14.Model.Cards.Building.Effects.*; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; @@ -16,9 +15,10 @@ import java.io.*; import java.lang.reflect.Type; import java.util.*; - +//TODO javadoc public class DecksCreator { + //TODO javadoc public static List loadTribeDeckByEra(int era) throws IllegalArgumentException { return switch (era) { @@ -28,6 +28,8 @@ public class DecksCreator { default -> throw new IllegalArgumentException(); }; } + + //TODO javadoc public static List loadTribeDeck(String resourcePath) { Gson gson = new Gson(); Type listType = new com.google.gson.reflect.TypeToken>(){}.getType(); @@ -48,11 +50,15 @@ public class DecksCreator { throw new RuntimeException("Errore caricamento mazzo: " + resourcePath, e); } } + + //TODO javadoc public static List loadBuildingDeckByEra(int era) throws IllegalArgumentException { if(era<=0 || era>3) throw new IllegalArgumentException(); return loadBuildingDeck("/Cards/buildingCards.json").stream().filter(x->x.getEra()==era).toList(); } + + //TODO javadoc public static List loadBuildingDeck(String resourcePath) { Gson gson = new Gson(); Type listType = new com.google.gson.reflect.TypeToken>(){}.getType(); @@ -74,6 +80,7 @@ public class DecksCreator { } } + //TODO javadoc public static List loadSlotDeck() { List slots = new ArrayList<>(); @@ -82,6 +89,8 @@ public class DecksCreator { slots.add(new Slot(c)); return slots; } + + //TODO javadoc private static TribeCard createCard(TribeCardDefinition def) { int era = def.era; @@ -129,6 +138,7 @@ public class DecksCreator { }; } + //TODO javadoc private static BuildingCard createCard(BuildingCardDefinition def) { return switch (def.effectId) { case 0 -> new Building0(def.era, def.price, def.prestigeValue); @@ -143,7 +153,7 @@ public class DecksCreator { } - + //TODO javadoc private static class TribeCardDefinition { String type; int era; @@ -152,6 +162,7 @@ public class DecksCreator { List params; // Object per gestire boolean e int misti } + //TODO javadoc private static class BuildingCardDefinition { int effectId; int era; diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java index 1a5d50c..e38e7a3 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvent.java @@ -4,23 +4,39 @@ import it.polimi.ingsw.gc14.Controller.GameController; import java.io.Serializable; +//TODO javadoc public abstract class NetworkEvent implements Serializable { + //TODO javadoc protected String username; + + //TODO javadoc public String getUsername() { return username; } + + //TODO javadoc protected EventType eventType; + + //TODO javadoc public EventType getEventType() {return eventType;} + + //TODO javadoc protected boolean isError; + + //TODO javadoc public boolean getIsError() {return isError;} + + //TODO javadoc public void setIsError(boolean isError) {this.isError = isError;} + //TODO javadoc protected NetworkEvent(String username, EventType eventType, boolean isError) { this.username = username; this.eventType = eventType; this.isError = isError; } + //TODO javadoc @Override public String toString() { if(isError) { @@ -30,5 +46,6 @@ public abstract class NetworkEvent implements Serializable { } } + //TODO javadoc public abstract boolean apply(GameController gameController); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java index 8466942..54b633a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java @@ -7,15 +7,23 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; +//TODO javadoc public class AddPlayer extends NetworkEvent implements Serializable { + //TODO javadoc private int proposedNPlayer; + + //TODO javadoc public int getProposedNPlayer() { return proposedNPlayer; } + + //TODO javadoc public AddPlayer(String username, int proposedNPlayer) { super(username, EventType.ADD_PLAYER, false); this.proposedNPlayer = proposedNPlayer; } + + //TODO javadoc @Override public boolean apply(GameController gameController) { diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java index 5656ac8..a160629 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java @@ -7,19 +7,24 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; +//TODO javadoc public class DrawLowerBuildingCard extends NetworkEvent implements Serializable{ + //TODO javadoc private int pos; + //TODO javadoc public DrawLowerBuildingCard(String username, int pos){ super(username, EventType.DRAW_LOWER_BUILD, false); this.pos = pos; } + //TODO javadoc @Override public boolean apply(GameController gameController){ return gameController.drawLowerBuildingCard(username, pos); } + //TODO javadoc public String apply(IView gameController){ return gameController.toString(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java index 277627a..f0109c8 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java @@ -8,18 +8,22 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; public class DrawLowerTribeCard extends NetworkEvent implements Serializable{ + //TODO javadoc private int pos; + //TODO javadoc public DrawLowerTribeCard(String username, int pos){ super(username, EventType.DRAW_LOWER_TRIBE, false); this.pos = pos; } + //TODO javadoc @Override public boolean apply(GameController gameController){ return gameController.drawLowerTribeCard(username, pos); } + //TODO javadoc public String apply(IView gameController){ return gameController.toString(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java index 6fb06cf..56be872 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java @@ -7,19 +7,24 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; +//TODO javadoc public class DrawUpperBuildingCard extends NetworkEvent implements Serializable{ + //TODO javadoc private int pos; + //TODO javadoc public DrawUpperBuildingCard(String username, int pos){ super(username, EventType.DRAW_UPPER_BUILD, false); this.pos = pos; } + //TODO javadoc @Override public boolean apply(GameController gameController){ return gameController.drawUpperBuildingCard(username, pos); } + //TODO javadoc public String apply(IView gameController){ return gameController.toString(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java index 8d37f02..4cdbc7e 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java @@ -7,19 +7,24 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; +//TODO javadoc public class DrawUpperTribeCard extends NetworkEvent implements Serializable{ + //TODO javadoc private int pos; + //TODO javadoc public DrawUpperTribeCard(String username, int pos){ super(username, EventType.DRAW_UPPER_TRIBE, false); this.pos = pos; } + //TODO javadoc @Override public boolean apply(GameController gameController){ return gameController.drawUpperTribeCard(username, pos); } + //TODO javadoc public String apply(IView gameController){ return gameController.toString(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalBuildingCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalBuildingCard.java index 36be45c..1996398 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalBuildingCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalBuildingCard.java @@ -7,19 +7,24 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; +//TODO javadoc public class PickOptionalBuildingCard extends NetworkEvent implements Serializable{ + //TODO javadoc private int pos; + //TODO javadoc public PickOptionalBuildingCard(String username, int pos){ super(username, EventType.PICK_OPTIONAL_BUILD, false); this.pos = pos; } + //TODO javadoc @Override public boolean apply(GameController gameController){ return gameController.pickOptionalBuildingCard(username, pos); } + //TODO javadoc public String apply(IView gameController){ return gameController.toString(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalTribeCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalTribeCard.java index f2dadac..0ad9def 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalTribeCard.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/PickOptionalTribeCard.java @@ -7,19 +7,25 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; +//TODO javadoc + public class PickOptionalTribeCard extends NetworkEvent implements Serializable{ + //TODO javadoc private int pos; + //TODO javadoc public PickOptionalTribeCard(String username, int pos){ super(username, EventType.PICK_OPTIONAL_TRIBE, false); this.pos = pos; } + //TODO javadoc @Override public boolean apply(GameController gameController){ return gameController.pickOptionalTribeCard(username, pos); } + //TODO javadoc public String apply(IView gameController){ return gameController.toString(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java index 4bf0d12..e22e491 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java @@ -7,19 +7,24 @@ import it.polimi.ingsw.gc14.View.IView; import java.io.Serializable; +//TODO javadoc public class SlotChoice extends NetworkEvent implements Serializable { + //TODO javadoc private int pos; + //TODO javadoc public SlotChoice(String username, int pos) { super(username, EventType.SLOT_CHOICE, false); this.pos = pos; } + //TODO javadoc @Override public boolean apply(GameController gameController) { return gameController.slotChoice(username, pos); } + //TODO javadoc public String apply(IView gameController) { return gameController.toString(); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java index 19bd574..fda4005 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java @@ -33,7 +33,7 @@ public class RMIClient { this.port = port; } - + //TODO Javadoc fix /** * Connects to the RMI server and attempts to join the game. * Looks up the RMI registry to retrieve the {@link IGameServer} stub. diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java index 8fad4eb..26ccb31 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/AsciiTable.java @@ -1,22 +1,39 @@ package it.polimi.ingsw.gc14.View.TUI; import java.util.*; +//TODO javadoc // Helper generale per costruire tabelle ASCII public class AsciiTable { + //TODO javadoc private final BorderStyle s; + + //TODO javadoc private final int cols; + + //TODO javadoc private final List> rows = new ArrayList<>(); + + //TODO javadoc private final List separators = new ArrayList<>(); + //TODO javadoc public AsciiTable(BorderStyle s, int cols) { this.s = s; this.cols = cols; } + //TODO javadoc public void addRow(String... cells) { rows.add(Arrays.asList(cells)); } + + //TODO javadoc public void addRow(List cells) { rows.add(cells); } + + //TODO javadoc public void addHeader(String... cells) { rows.add(0, Arrays.asList(cells)); separators.add(0); } + + //TODO javadoc public void addSeparator() { separators.add(rows.size()-1); } + //TODO javadoc public String build() { var sb = new StringBuilder(); int maxWidth = rows.stream().mapToInt(x->x.stream().mapToInt(y->y.length()).max().getAsInt()).max().getAsInt()+1; @@ -34,6 +51,7 @@ public class AsciiTable { return sb.toString(); } + //TODO javadoc private String hline(String l, String m, String r,int maxWidth) { var sb = new StringBuilder(l); for (int i = 0; i < cols; i++) { @@ -43,10 +61,13 @@ public class AsciiTable { return sb.append(r).toString(); } + //TODO javadoc private static String rpad(String s, int w) { if (s.length() >= w) return s.substring(0, w); return s + " ".repeat(w - s.length()); } + + //TODO javadoc public static String sideBySide(List left, List right, int gap) { int leftWidth = left.stream().mapToInt(String::length).max().orElse(0); int maxHeight = Math.max(left.size(), right.size()); From 6069ae944707825deb1de8534159e556579491da Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 30 Apr 2026 18:49:56 +0200 Subject: [PATCH 42/48] Add: CurrentStageToString --- .../java/it/polimi/ingsw/gc14/Model/Game.java | 11 +------- .../gc14/Model/GamePackage/CurrentState.java | 27 +++++++++++++++++++ .../it/polimi/ingsw/gc14/Model/GameTest.java | 4 +-- 3 files changed, 29 insertions(+), 13 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 d3a34a8..dd67a26 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Game.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Game.java @@ -771,19 +771,10 @@ public class Game implements Serializable { BuildTableLower.addRow(getLowerListBuilding().get(i).toString()); } } - - - //offerTrack.addRow(stringUpperListTribe); stringUpperListTribe.forEach(x->TribeTableUpper.addRow(x)); stringLowerListTribe.forEach(x->TribeTableLower.addRow(x)); - offerTrack.addRow(stringUpOffer); offerTrack.addRow(stringDownOffer); - //offerTrack.addRow(stringLowerListTribe); - - - - return orderLogicCard.toString()+"\n"+ AsciiTable.sideBySide(Arrays.stream((TribeTableUpper.build().split("\n"))).toList(), Arrays.stream(BuildTableUpper.build().split("\n")).toList(),2)+"\n"+offerTrack.build()+"\n"+AsciiTable.sideBySide(List.of(TribeTableLower.build().split("\n")), Arrays.stream(BuildTableLower.build().split("\n")).toList(),2); - //return s.toString()+"\n"++"\nOFFER TRACK\n"+ table.build()+"\n" ; + return "CURRENT STATE\n"+getCurrentState()+"\n"+orderLogicCard.toString()+"\n"+ AsciiTable.sideBySide(Arrays.stream((TribeTableUpper.build().split("\n"))).toList(), Arrays.stream(BuildTableUpper.build().split("\n")).toList(),2)+"\n"+offerTrack.build()+"\n"+AsciiTable.sideBySide(List.of(TribeTableLower.build().split("\n")), Arrays.stream(BuildTableLower.build().split("\n")).toList(),2); } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java index b2489b8..f464e02 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/CurrentState.java @@ -3,7 +3,12 @@ package it.polimi.ingsw.gc14.Model.GamePackage; import it.polimi.ingsw.gc14.Model.Player; import it.polimi.ingsw.gc14.Model.Slot; import it.polimi.ingsw.gc14.Model.GamePackage.GameStages; +import it.polimi.ingsw.gc14.View.TUI.AsciiTable; +import it.polimi.ingsw.gc14.View.TUI.BorderStyle; + import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; /** * Represents the current state of the game. @@ -194,5 +199,27 @@ public class CurrentState implements Serializable { } } + @Override + public String toString(){ + var table= new AsciiTable(BorderStyle.UNICODE,6); + Listheader= new ArrayList<>(); + header.add("Player"); + header.add("NUpper"); + header.add("NLower"); + header.add("Round"); + header.add("Era"); + header.add("GameStage"); + table.addRow(header); + table.addSeparator(); + Listvalues= new ArrayList<>(); + values.add(player.getUserName()); + values.add(Integer.toString(NUpper)); + values.add(Integer.toString(NLower)); + values.add(Integer.toString(round)); + values.add(Integer.toString(Era)); + values.add(GameStage.toString()); + table.addRow(values); + return table.build(); + } // endregion functions } diff --git a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java index 0d6087b..eca198a 100644 --- a/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java +++ b/src/test/java/it/polimi/ingsw/gc14/Model/GameTest.java @@ -221,8 +221,6 @@ class GameTest { assertTrue(game.SlotChoiceByIndex(game.getCurrentState().getCurrentPlayer(), i)); } - System.out.println(game.BoardStamp()); - String os = System.getProperty("os.name").toLowerCase(); - System.out.println(game.PlayersStamp()); + System.out.println(game.toString()); } } \ No newline at end of file From 6141395ba340503c6d0fd84a2b0c07079f4c13bf Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:55:03 +0200 Subject: [PATCH 43/48] Add: Added Javadoc For "toString" Method And "icon" Field In Building11.java. --- .../Model/Cards/Building/Effects/Building11.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building11.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building11.java index 543adcf..eefff8a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building11.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building11.java @@ -7,6 +7,9 @@ import it.polimi.ingsw.gc14.Model.Player; public class Building11 extends BuildingCard { + /** + * The icon attribute indicates the character type involved in the building effect. + */ private CharacterType icon ; /** @@ -68,6 +71,17 @@ public class Building11 extends BuildingCard { player.addPrestige(player.getNType(getIcon()) * this.getPrestigeMul()); } + /** + * Prints a string representation of this {@code Building1}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    includes: + *

  • {@link #icon Icon} + *
  • {@link #PrestigeMul Prestige Multiplier} + *

    + * @return {@code String} - a string representation of this {@code Building1}. + * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board + */ @Override public String toString() { return super.toString() + " Icon: " + this.icon.toString().charAt(0) + " MP: " + this.PrestigeMul; From 5813600a4da1c569a73cadc38ed572f65b2f6271 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:55:19 +0200 Subject: [PATCH 44/48] Add: Added Javadoc For "toString" Method In Building1.java. --- .../gc14/Model/Cards/Building/Effects/Building1.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building1.java b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building1.java index e0b064c..e63df7c 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building1.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Cards/Building/Effects/Building1.java @@ -4,7 +4,6 @@ import it.polimi.ingsw.gc14.Model.Cards.Building.EffectType; import it.polimi.ingsw.gc14.Model.Cards.BuildingCard; import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType; - /** * During the Sustenance Event, you have a discount of 1 food token on the total you * would have to pay, for each of the indicated characters in your tribe. @@ -44,6 +43,16 @@ public class Building1 extends BuildingCard { return new Building1(getEra(),getPrice(),getPrestigeValue(),getIcon()); } + /** + * Prints a string representation of this {@code Building1}. This specific variation is used in the {@code Game}'s + * toString to print a more detailed version. + *

    includes: + *

  • {@link #icon Icon} + *

    + * @return {@code String} - a string representation of this {@code Building1}. + * @see it.polimi.ingsw.gc14.Model.Game Game + * @see it.polimi.ingsw.gc14.Model.GamePackage.Board Board + */ @Override public String toString() { return super.toString() + " Icon: " + this.icon.toString().charAt(0); From cca3b5224f6879c937dfd3dc8cfd9383395967a2 Mon Sep 17 00:00:00 2001 From: GabrieleRadice <265572328+GabrieleRadice@users.noreply.github.com> Date: Thu, 30 Apr 2026 19:03:47 +0200 Subject: [PATCH 45/48] Fix: Removed Redundant TODO. --- src/main/java/it/polimi/ingsw/gc14/Model/Player.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/Player.java b/src/main/java/it/polimi/ingsw/gc14/Model/Player.java index 82151f8..c3eaf90 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Model/Player.java +++ b/src/main/java/it/polimi/ingsw/gc14/Model/Player.java @@ -124,13 +124,6 @@ public class Player implements Serializable { public int getPrestigeValue() { return PrestigeValue; } - - /* TODO - * private Game game; - * public Game getGame(){ - * return Game; - * } - */ // endregion getters // region Setters From 671c523599298b5253fa45d714797799c9e911d2 Mon Sep 17 00:00:00 2001 From: AleandroPagani Date: Thu, 30 Apr 2026 19:20:56 +0200 Subject: [PATCH 46/48] Client Launcher TUI input handler added --- .../polimi/ingsw/gc14/ClientLauncherTUI.java | 50 ++++++++++++------- .../it/polimi/ingsw/gc14/View/TUI/TUI.java | 1 - 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java index 09a606f..9facc69 100644 --- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherTUI.java @@ -1,32 +1,30 @@ package it.polimi.ingsw.gc14; import it.polimi.ingsw.gc14.Controller.ClientController; +import it.polimi.ingsw.gc14.Network.NetworkEvent; import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient; import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient; -import it.polimi.ingsw.gc14.View.IView; import it.polimi.ingsw.gc14.View.TUI.TUI; import java.util.Scanner; public class ClientLauncherTUI { - private TUI view; public void main() throws InterruptedException { - view=new TUI(null); + TUI view=new TUI(null); ClientController controller = new ClientController(view); Scanner scanner = new Scanner(System.in); - System.out.println("Selezionare nome utente: "); String username = scanner.next(); - System.out.println("Selezionare numero di giocatori desiderato: "); int proposedNumPlayers = scanner.nextInt(); - System.out.println("Selezionare RMI[0] o TCP[1]: "); int networkType = scanner.nextInt(); + // RMI if (networkType == 0) { + // Connect RMIClient client = new RMIClient(controller, "localhost", 1099); if (client.connect(username, proposedNumPlayers)) { System.out.println("Succesfully connected to RMI server\n\n"); @@ -35,21 +33,19 @@ public class ClientLauncherTUI { return; } controller.setClient(client); - int h; - while(controller.localController.getModel()==null){ - h = scanner.nextInt(); - if(controller.localController.getModel()!=null) - { - break; - } - } + + // Play + //while(controller.localController.getModel()==null){ + // scanner.nextInt(); + //} while(true) { - h = scanner.nextInt(); + getInput(scanner, controller, username); } - + // TCP } else if (networkType == 1) { + // Connect TCPClient client = new TCPClient(controller, "localhost", 8080); if (client.connect(username, proposedNumPlayers)) { System.out.println("Succesfully connected to TCP server\n\n"); @@ -58,11 +54,31 @@ public class ClientLauncherTUI { return; } controller.setClient(client); + + // Play while(true) { - int h = scanner.nextInt(); + getInput(scanner, controller, username); } } scanner.close(); } + + + + private void getInput(Scanner scanner, ClientController controller, String username) { + int action = scanner.nextInt(); + int pos = scanner.nextInt(); + + switch(action) { + case 1 -> controller.drawLowerBuildingCard(username, pos); + case 2 -> controller.drawLowerTribeCard(username, pos); + case 3 -> controller.drawUpperBuildingCard(username, pos); + case 4 -> controller.drawUpperTribeCard(username, pos); + case 5 -> controller.pickOptionalBuildingCard(username, pos); + case 6 -> controller.slotChoice(username, pos); + } + + return; + } } \ No newline at end of file diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java index caaa040..a71487a 100644 --- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java +++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java @@ -25,7 +25,6 @@ public class TUI implements IView, Observer { // ── punto di ingresso ─────────────────────────────────────── public void render() { - this.model=model; try{ String os = System.getProperty("os.name").toLowerCase(); ProcessBuilder pb; From 34952deb39ae80874daa49946e5737b8ae47a8de Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 30 Apr 2026 19:52:12 +0200 Subject: [PATCH 47/48] Fix: TCPClient --- .../it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java index 3da705e..539416e 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/ClientHandler.java @@ -57,8 +57,7 @@ public class ClientHandler implements Runnable { @Override public void run() { try { - in = new ObjectInputStream(clientSocket.getInputStream()); - out = new ObjectOutputStream(clientSocket.getOutputStream()); + while (true) { NetworkEvent event = (NetworkEvent) in.readObject(); if (!actionQueue.add(event)) { From 3e863a8a1e7c0732ae38369d3e18068222de4c9b Mon Sep 17 00:00:00 2001 From: rubenpirreram Date: Thu, 30 Apr 2026 19:53:12 +0200 Subject: [PATCH 48/48] Fix: module info --- src/main/java/module-info.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 5e72256..e178647 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -5,7 +5,6 @@ module it.polimi.ingsw.gc14 { requires java.rmi; requires java.smartcardio; requires com.google.gson; - requires it.polimi.ingsw.gc14; opens it.polimi.ingsw.gc14 to javafx.fxml, com.google.gson; opens it.polimi.ingsw.gc14.Model to com.google.gson;