Add: GameTest coverage for totem choice and disconnected players

This commit is contained in:
MatteoPellegrino05
2026-05-15 16:20:23 +02:00
parent 0b36470e90
commit 6a7491483a
2 changed files with 221 additions and 40 deletions
@@ -19,13 +19,9 @@ import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
import java.util.random.RandomGenerator;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import it.polimi.ingsw.gc14.View.TUI.AsciiTable;
import it.polimi.ingsw.gc14.View.TUI.BorderStyle;
/** /**
* Represents the main game model. * Represents the main game model.
* A Game object stores the players, the current state of the match, * A Game object stores the players, the current state of the match,
@@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.Timeout;
import java.util.*; import java.util.*;
import java.util.stream.Stream;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@@ -18,8 +19,33 @@ import static org.junit.jupiter.api.Assertions.*;
@Timeout(value = 10, unit = TimeUnit.SECONDS) @Timeout(value = 10, unit = TimeUnit.SECONDS)
class GameTest { class GameTest {
private void completeTotemChoice(Game game) {
assertEquals(GameStages.TOTEM_CHOICE, game.getCurrentState().getGameStage());
while (game.getCurrentState().getGameStage() == GameStages.TOTEM_CHOICE) {
Player current = game.getCurrentState().getCurrentPlayer();
assertNotNull(current);
List<Totems> availableTotems = game.getAvailableTotems();
assertFalse(availableTotems.isEmpty());
Totems selectedTotem = availableTotems.get(0);
assertTrue(game.TotemChoice(current, selectedTotem));
assertEquals(selectedTotem, current.totem);
}
assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage());
assertNotNull(game.getCurrentState().getCurrentPlayer());
}
private Queue<Player> completeSlotChoice(Game game) { private Queue<Player> completeSlotChoice(Game game) {
if (game.getCurrentState().getGameStage() == GameStages.TOTEM_CHOICE) {
completeTotemChoice(game);
}
assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage());
Queue<Player> order = new LinkedList<>(); Queue<Player> order = new LinkedList<>();
for (int i = 0; i < game.getNPlayers(); i++) { for (int i = 0; i < game.getNPlayers(); i++) {
@@ -252,7 +278,7 @@ class GameTest {
} }
@Test @Test
void addPlayerShouldRejectDuplicatesAndStartSlotChoiceWhenFull() { void addPlayerShouldRejectDuplicatesAndStartTotemChoiceWhenFull() {
Game game = new Game(3); Game game = new Game(3);
Player p1 = new Player("p1"); Player p1 = new Player("p1");
Player p2 = new Player("p2"); Player p2 = new Player("p2");
@@ -264,11 +290,118 @@ class GameTest {
assertFalse(game.addPlayer(p2)); assertFalse(game.addPlayer(p2));
assertTrue(game.addPlayer(p3)); assertTrue(game.addPlayer(p3));
assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); assertEquals(GameStages.TOTEM_CHOICE, game.getCurrentState().getGameStage());
assertNotNull(game.getCurrentState().getCurrentPlayer());
assertFalse(game.addPlayer(p4)); assertFalse(game.addPlayer(p4));
} }
@Test
void gameShouldEnterTotemChoiceWhenAllPlayersAreAdded() {
Game game = new Game(3);
assertTrue(game.addPlayer(new Player("p1")));
assertTrue(game.addPlayer(new Player("p2")));
assertTrue(game.addPlayer(new Player("p3")));
assertEquals(GameStages.TOTEM_CHOICE, game.getCurrentState().getGameStage());
assertNotNull(game.getCurrentState().getCurrentPlayer());
}
@Test
void totemChoiceShouldAssignDistinctTotemsAndStartSlotChoice() {
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));
completeTotemChoice(game);
assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage());
assertNotNull(p1.totem);
assertNotNull(p2.totem);
assertNotNull(p3.totem);
assertEquals(
3,
Stream.of(p1.totem, p2.totem, p3.totem).distinct().count()
);
}
@Test
void totemChoiceShouldRejectAlreadyChosenTotem() {
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 firstPlayer = game.getCurrentState().getCurrentPlayer();
Totems chosenTotem = game.getAvailableTotems().get(0);
assertTrue(game.TotemChoice(firstPlayer, chosenTotem));
Player secondPlayer = game.getCurrentState().getCurrentPlayer();
assertNotNull(secondPlayer);
assertFalse(game.TotemChoice(secondPlayer, chosenTotem));
}
@Test
void totemChoiceShouldRejectWrongPlayer() {
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();
Player wrongPlayer = current.equals(p1) ? p2 : p1;
Totems availableTotem = game.getAvailableTotems().get(0);
assertFalse(game.TotemChoice(wrongPlayer, availableTotem));
}
@Test
void getAvailableTotemsShouldExcludeChosenTotems() {
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));
int initialAvailableTotems = game.getAvailableTotems().size();
Player current = game.getCurrentState().getCurrentPlayer();
Totems chosenTotem = game.getAvailableTotems().get(0);
assertTrue(game.TotemChoice(current, chosenTotem));
assertEquals(initialAvailableTotems - 1, game.getAvailableTotems().size());
assertFalse(game.getAvailableTotems().contains(chosenTotem));
}
@Test @Test
void shouldRejectInvalidSlotChoices() { void shouldRejectInvalidSlotChoices() {
Game game = new Game(3); Game game = new Game(3);
@@ -281,6 +414,8 @@ class GameTest {
assertTrue(game.addPlayer(p2)); assertTrue(game.addPlayer(p2));
assertTrue(game.addPlayer(p3)); assertTrue(game.addPlayer(p3));
completeTotemChoice(game);
Player current = game.getCurrentState().getCurrentPlayer(); Player current = game.getCurrentState().getCurrentPlayer();
assertFalse(game.SlotChoiceByIndex(current, -1)); assertFalse(game.SlotChoiceByIndex(current, -1));
@@ -307,6 +442,8 @@ class GameTest {
assertFalse(game.addPlayer(p2)); assertFalse(game.addPlayer(p2));
assertTrue(game.addPlayer(p3)); assertTrue(game.addPlayer(p3));
completeTotemChoice(game);
Queue<Player> players = new LinkedList<>(); Queue<Player> players = new LinkedList<>();
for (int i = 0; i < game.getNPlayers(); i++) { for (int i = 0; i < game.getNPlayers(); i++) {
players.add(game.getCurrentState().getCurrentPlayer()); players.add(game.getCurrentState().getCurrentPlayer());
@@ -523,6 +660,10 @@ class GameTest {
assertTrue(game.addPlayer(player)); assertTrue(game.addPlayer(player));
} }
if (game.getCurrentState().getGameStage() == GameStages.TOTEM_CHOICE) {
completeTotemChoice(game);
}
return players; return players;
} }
@@ -579,6 +720,10 @@ class GameTest {
assertTrue(game.addPlayer(p2)); assertTrue(game.addPlayer(p2));
assertTrue(game.addPlayer(p3)); assertTrue(game.addPlayer(p3));
/*
* The game is currently in TOTEM_CHOICE:
* draw requests must be rejected because the game is not in RES_ACTIONS.
*/
Player current = game.getCurrentState().getCurrentPlayer(); Player current = game.getCurrentState().getCurrentPlayer();
assertNotNull(current); assertNotNull(current);
@@ -587,6 +732,10 @@ class GameTest {
assertFalse(game.DrawUpperBuildingCardByIndex(current, 0)); assertFalse(game.DrawUpperBuildingCardByIndex(current, 0));
assertFalse(game.DrawLowerBuildingCardByIndex(current, 0)); assertFalse(game.DrawLowerBuildingCardByIndex(current, 0));
/*
* The totem choice phase and the slot choice phase are completed,
* so the game enters RES_ACTIONS.
*/
completeSlotChoice(game); completeSlotChoice(game);
current = game.getCurrentState().getCurrentPlayer(); current = game.getCurrentState().getCurrentPlayer();
@@ -621,7 +770,6 @@ class GameTest {
} }
} }
@Test @Test
void optionalMethodsShouldReturnFalseOutsideOptionalState() { void optionalMethodsShouldReturnFalseOutsideOptionalState() {
Game game = new Game(3); Game game = new Game(3);
@@ -694,6 +842,10 @@ class GameTest {
assertTrue(game.addPlayer(new Player("p2"))); assertTrue(game.addPlayer(new Player("p2")));
assertTrue(game.addPlayer(new Player("p3"))); assertTrue(game.addPlayer(new Player("p3")));
assertEquals(GameStages.TOTEM_CHOICE, game.getCurrentState().getGameStage());
completeTotemChoice(game);
assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage());
Player current = game.getCurrentState().getCurrentPlayer(); Player current = game.getCurrentState().getCurrentPlayer();
@@ -712,6 +864,8 @@ class GameTest {
assertTrue(game.addPlayer(new Player("p" + nPlayers + "_" + i))); assertTrue(game.addPlayer(new Player("p" + nPlayers + "_" + i)));
} }
completeTotemChoice(game);
assertEquals(nPlayers, game.getCurrentPlayerNumber()); assertEquals(nPlayers, game.getCurrentPlayerNumber());
assertEquals(nPlayers, game.getPlayers().size()); assertEquals(nPlayers, game.getPlayers().size());
assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage());
@@ -852,34 +1006,6 @@ class GameTest {
assertFalse(game.PickOptionalBuildingCard(current, 0)); assertFalse(game.PickOptionalBuildingCard(current, 0));
} }
@Test
void toStringModel() {
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));
Queue<Player>players=new LinkedList<>();
for (int i = 0; i < game.getNPlayers(); i++) {
players.add(game.getCurrentState().getCurrentPlayer());
assertTrue(game.SlotChoiceByIndex(game.getCurrentState().getCurrentPlayer(), i));
}
String result = game.toString();
assertNotNull(result);
assertFalse(result.isBlank());
assertTrue(result.contains("CURRENT STATE"));
}
@Test @Test
@Timeout(value = 5, unit = TimeUnit.SECONDS) @Timeout(value = 5, unit = TimeUnit.SECONDS)
void shouldDrawLowerBuildingWhenAvailableAndPlayerCanPay() { void shouldDrawLowerBuildingWhenAvailableAndPlayerCanPay() {
@@ -1076,8 +1202,8 @@ class GameTest {
} }
/* /*
* Mantiene l'effetto opzionale, ma con prestigio finale nullo. * Keeps the optional effect, but with zero final prestige.
* Così la fase OPT_CARD_E rimane coerente e il confronto resta controllato. * This preserves the OPT_CARD_E phase while keeping the comparison controlled.
*/ */
player.buildingCards.add(new BuildingCard(12, 1, 1, 0)); player.buildingCards.add(new BuildingCard(12, 1, 1, 0));
} }
@@ -1223,6 +1349,65 @@ class GameTest {
assertFalse(game.SkipNoDrawable(current)); assertFalse(game.SkipNoDrawable(current));
} }
@Test
void disconnectedCurrentPlayerDuringSlotChoiceShouldAdvanceTurn() {
Game game = new Game(3);
addPlayers(game, 3, "disconnect_slot_");
Player current = game.getCurrentState().getCurrentPlayer();
assertNotNull(current);
assertTrue(game.DisconnectedPlayer(current));
assertTrue(game.disconnetedPlayers.containsKey(current));
assertTrue(game.disconnetedPlayers.get(current));
assertNotEquals(current, game.getCurrentState().getCurrentPlayer());
}
@Test
void disconnectedPlayerShouldReturnFalseIfAlreadyDisconnected() {
Game game = new Game(3);
addPlayers(game, 3, "disconnect_twice_");
Player current = game.getCurrentState().getCurrentPlayer();
assertTrue(game.DisconnectedPlayer(current));
assertFalse(game.DisconnectedPlayer(current));
}
@Test
void reconnectPlayerShouldRemovePlayerFromDisconnectedMapDuringSlotChoice() {
Game game = new Game(3);
addPlayers(game, 3, "reconnect_");
Player current = game.getCurrentState().getCurrentPlayer();
assertTrue(game.DisconnectedPlayer(current));
assertTrue(game.disconnetedPlayers.containsKey(current));
assertTrue(game.ReconnectPlayer(current));
assertFalse(game.disconnetedPlayers.containsKey(current));
}
@Test
void clearDisconnectedShouldEmptyDisconnectedPlayersMap() {
Game game = new Game(3);
addPlayers(game, 3, "clear_disconnect_");
Player current = game.getCurrentState().getCurrentPlayer();
assertTrue(game.DisconnectedPlayer(current));
assertFalse(game.disconnetedPlayers.isEmpty());
game.ClearDisconnected();
assertTrue(game.disconnetedPlayers.isEmpty());
}
@Test @Test
@Timeout(value = 5, unit = TimeUnit.SECONDS) @Timeout(value = 5, unit = TimeUnit.SECONDS)
void drawLowerBuildingShouldReturnFalseIfPlayerCannotPay() { void drawLowerBuildingShouldReturnFalseIfPlayerCannotPay() {
@@ -1376,7 +1561,7 @@ class GameTest {
assertTrue(game.addPlayer(p4)); assertTrue(game.addPlayer(p4));
assertTrue(game.addPlayer(p5)); assertTrue(game.addPlayer(p5));
assertEquals(GameStages.SLOT_CHOICE, game.getCurrentState().getGameStage()); assertEquals(GameStages.TOTEM_CHOICE, game.getCurrentState().getGameStage());
List<Integer> foodValues = game.getPlayers().stream() List<Integer> foodValues = game.getPlayers().stream()
.map(Player::getFoodValue) .map(Player::getFoodValue)
@@ -1446,8 +1631,8 @@ class GameTest {
assertNotNull(testedPlayer); assertNotNull(testedPlayer);
/* /*
* I due player vengono resi identici rispetto a Eventi e final scoring. * The two players are made equivalent with respect to events and final scoring.
* La partita è comunque arrivata realmente al round 10. * The game has still reached round 10 through the real flow.
*/ */
preparePlayerForComparableFinalScoring(controlPlayer); preparePlayerForComparableFinalScoring(controlPlayer);
preparePlayerForComparableFinalScoring(testedPlayer); preparePlayerForComparableFinalScoring(testedPlayer);