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 #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