diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/assign/FreePeoplePlayerAssignsMinionsGameProcess.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/assign/FreePeoplePlayerAssignsMinionsGameProcess.java index e4924ae6e..c41ebee34 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/assign/FreePeoplePlayerAssignsMinionsGameProcess.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/assign/FreePeoplePlayerAssignsMinionsGameProcess.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; public class FreePeoplePlayerAssignsMinionsGameProcess implements GameProcess { private Set _leftoverMinions; @@ -45,7 +46,7 @@ public class FreePeoplePlayerAssignsMinionsGameProcess implements GameProcess { final GameState gameState = game.getGameState(); final Collection minions = Filters.filterActive(game, CardType.MINION, Filters.assignableToSkirmish(Side.FREE_PEOPLE, false, false)); - if (minions.size() > 0) { + if (!minions.isEmpty()) { final Collection freePeopleTargets = Filters.filterActive(game, Filters.and( @@ -60,8 +61,16 @@ public class FreePeoplePlayerAssignsMinionsGameProcess implements GameProcess { public void decisionMade(String result) throws DecisionResultInvalidException { Map> assignments = getAssignmentsBasedOnResponse(result); - Set unassignedMinions = new HashSet<>(Filters.filterActive(game, CardType.MINION, Filters.assignableToSkirmish(Side.FREE_PEOPLE, false, false))); - // Validate minion count (Defender) + //Start with all minions on the field + Set unassignedMinions = new HashSet<>(Filters.filterActive(game, CardType.MINION)); + + //Then remove all minions who have already gotten themselves assigned (via assignment actions) + var existingAssignments = gameState.getAssignments(); + unassignedMinions.removeAll(existingAssignments.stream().flatMap(x -> x.getShadowCharacters().stream()).collect( + Collectors.toSet())); + + //Finally, remove all minions just recently assigned by the Free Peoples player + // (while incidentally double-checking that freeps did not violate assignment boundaries) for (PhysicalCard freeCard : assignments.keySet()) { Set minionsAssigned = assignments.get(freeCard); if (minionsAssigned.size() + getMinionsAssignedBeforeCount(freeCard, gameState) > 1 + game.getModifiersQuerying().getKeywordCount(game, freeCard, Keyword.DEFENDER)) diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set02/Card_02_075_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set02/Card_02_075_Tests.java index 6ff1f3b76..82198b116 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set02/Card_02_075_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set02/Card_02_075_Tests.java @@ -3,13 +3,13 @@ package com.gempukku.lotro.cards.official.set02; import com.gempukku.lotro.cards.GenericCardTestHelper; import com.gempukku.lotro.common.*; import com.gempukku.lotro.game.CardNotFoundException; -import com.gempukku.lotro.game.PhysicalCardImpl; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; import org.junit.Test; import java.util.HashMap; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class Card_02_075_Tests { @@ -18,8 +18,10 @@ public class Card_02_075_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "2_75"); - // put other cards in here as needed for the test case + put("ferny", "2_75"); + put("runner", "1_178"); + + put("gimli", "1_13"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -42,12 +44,13 @@ public class Card_02_075_Tests * Strength: 4 * Vitality: 1 * Site Number: 2 - * Game Text: Nazgûl are not roaming.
The Free Peoples player may not assign a character to skirmish Bill Ferny. Discard Bill Ferny if underground. + * Game Text: Nazgûl are not roaming. + * The Free Peoples player may not assign a character to skirmish Bill Ferny. Discard Bill Ferny if underground. */ var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("ferny"); assertEquals("Bill Ferny", card.getBlueprint().getTitle()); assertEquals("Swarthy Sneering Fellow", card.getBlueprint().getSubtitle()); @@ -62,18 +65,50 @@ public class Card_02_075_Tests assertEquals(2, card.getBlueprint().getSiteNumber()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void BillFernyTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void BillFernyCannotBeAssignedByFreepsWhenAlone() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var frodo = scn.GetRingBearer(); + var ferny = scn.GetShadowCard("ferny"); + scn.ShadowMoveCharToTable(ferny); scn.StartGame(); - scn.FreepsPlayCard(card); - assertEquals(2, scn.GetTwilight()); + scn.SkipToPhase(Phase.ASSIGNMENT); + scn.FreepsPassCurrentPhaseAction(); + scn.ShadowPassCurrentPhaseAction(); + + assertEquals(1, scn.ShadowGetShadowAssignmentTargetCount()); + + scn.ShadowAssignToMinions(frodo, ferny); + scn.FreepsResolveSkirmish(frodo); + } + + @Test + public void BillFernyCannotBeAssignedByFreepsWhenWithOtherMinions() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var frodo = scn.GetRingBearer(); + var gimli = scn.GetFreepsCard("gimli"); + scn.FreepsMoveCharToTable(gimli); + + var ferny = scn.GetShadowCard("ferny"); + var runner = scn.GetShadowCard("runner"); + scn.ShadowMoveCharToTable(ferny, runner); + + scn.StartGame(); + + scn.SkipToAssignments(); + + assertEquals(1, scn.FreepsGetShadowAssignmentTargetCount()); + scn.FreepsAssignToMinions(frodo, runner); + + assertEquals(1, scn.ShadowGetShadowAssignmentTargetCount()); + + scn.ShadowAssignToMinions(frodo, ferny); + scn.FreepsResolveSkirmish(frodo); } }