Fixed a persistent issue with testing stacked cards via the test rig (finally). Improved ChooseANumber to use value resolvers.
This commit is contained in:
@@ -1,13 +1,11 @@
|
||||
package com.gempukku.lotro.cards.build.field.effect.appender;
|
||||
|
||||
import com.gempukku.lotro.cards.build.ActionContext;
|
||||
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
|
||||
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
|
||||
import com.gempukku.lotro.cards.build.PlayerSource;
|
||||
import com.gempukku.lotro.cards.build.*;
|
||||
import com.gempukku.lotro.cards.build.field.FieldUtils;
|
||||
import com.gempukku.lotro.cards.build.field.effect.EffectAppender;
|
||||
import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer;
|
||||
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver;
|
||||
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
|
||||
import com.gempukku.lotro.logic.actions.CostToEffectAction;
|
||||
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
||||
import com.gempukku.lotro.logic.decisions.IntegerAwaitingDecision;
|
||||
@@ -22,8 +20,9 @@ public class ChooseANumber implements EffectAppenderProducer {
|
||||
|
||||
final String player = FieldUtils.getString(effectObject.get("player"), "player", "you");
|
||||
final String displayText = FieldUtils.getString(effectObject.get("text"), "text", "Choose a number");
|
||||
final int from = FieldUtils.getInteger(effectObject.get("from"), "from", 0);
|
||||
final int to = FieldUtils.getInteger(effectObject.get("to"), "to", 1);
|
||||
final ValueSource fromSource = ValueResolver.resolveEvaluator(effectObject.get("from"), 0, environment);
|
||||
final ValueSource toSource = ValueResolver.resolveEvaluator(effectObject.get("to"), 1, environment);
|
||||
|
||||
final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize");
|
||||
|
||||
final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment);
|
||||
@@ -35,7 +34,10 @@ public class ChooseANumber implements EffectAppenderProducer {
|
||||
@Override
|
||||
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {
|
||||
return new PlayoutDecisionEffect(actionContext.getPerformingPlayer(),
|
||||
new IntegerAwaitingDecision(1, displayText, from, to) {
|
||||
new IntegerAwaitingDecision(1, displayText,
|
||||
fromSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null),
|
||||
toSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null))
|
||||
{
|
||||
@Override
|
||||
public void decisionMade(String result) throws DecisionResultInvalidException {
|
||||
actionContext.setValueToMemory(memorize, String.valueOf(getValidatedResult(result)));
|
||||
|
||||
@@ -46,7 +46,8 @@ public class CardResolver {
|
||||
|
||||
if (type.startsWith("memory(") && type.endsWith(")")) {
|
||||
return resolveMemoryCards(type, choiceFilter, playabilityFilter, countSource, memory, cardSource);
|
||||
} else if (type.startsWith("choose(") && type.endsWith(")")) {
|
||||
}
|
||||
else if (type.startsWith("choose(") && type.endsWith(")")) {
|
||||
final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment);
|
||||
ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> {
|
||||
String choicePlayerId = playerSource.getPlayer(actionContext);
|
||||
|
||||
@@ -55,13 +55,15 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
// Player key, then name/card
|
||||
public Map<String, Map<String, PhysicalCardImpl>> Cards = new HashMap<>();
|
||||
|
||||
public GenericCardTestHelper(Map<String, String> cardIDs) throws CardNotFoundException, DecisionResultInvalidException {
|
||||
public GenericCardTestHelper(HashMap<String, String> cardIDs) throws CardNotFoundException, DecisionResultInvalidException {
|
||||
this(cardIDs, null, null, null);
|
||||
}
|
||||
|
||||
public GenericCardTestHelper(Map<String, String> cardIDs, Map<String, String> siteIDs, String ringBearerID, String ringID) throws CardNotFoundException, DecisionResultInvalidException {
|
||||
public GenericCardTestHelper(HashMap<String, String> cardIDs, HashMap<String, String> siteIDs, String ringBearerID, String ringID) throws CardNotFoundException, DecisionResultInvalidException {
|
||||
super();
|
||||
|
||||
|
||||
|
||||
if(siteIDs == null || ringBearerID == null || ringID == null) {
|
||||
initializeSimplestGame();
|
||||
}
|
||||
@@ -91,20 +93,17 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
if(cardIDs != null) {
|
||||
for(String name : cardIDs.keySet()) {
|
||||
String id = cardIDs.get(name);
|
||||
PhysicalCardImpl card = CreateCard(P1, id);
|
||||
PhysicalCardImpl card = createCard(P1, id);
|
||||
Cards.get(P1).put(name, card);
|
||||
FreepsMoveCardsToTopOfDeck(card);
|
||||
|
||||
card = CreateCard(P2, id);
|
||||
card = createCard(P2, id);
|
||||
Cards.get(P2).put(name, card);
|
||||
FreepsMoveCardsToTopOfDeck(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PhysicalCardImpl CreateCard(String playerID, String cardID) throws CardNotFoundException {
|
||||
return new PhysicalCardImpl(LastCardID++, cardID, playerID, _library.getLotroCardBlueprint(cardID));
|
||||
}
|
||||
|
||||
public void StartGame() throws DecisionResultInvalidException {
|
||||
skipMulligans();
|
||||
@@ -256,10 +255,9 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
|
||||
public int GetFreepsDiscardCount() { return GetPlayerDiscardCount(P1); }
|
||||
public int GetShadowDiscardCount() { return GetPlayerDiscardCount(P2); }
|
||||
public int GetPlayerDiscardCount(String player)
|
||||
{
|
||||
return _game.getGameState().getDiscard(player).size();
|
||||
}
|
||||
public int GetPlayerDiscardCount(String player) { return _game.getGameState().getDiscard(player).size(); }
|
||||
|
||||
public int GetFreepsDeadCount() { return _game.getGameState().getDeadPile(P1).size(); }
|
||||
|
||||
public Phase GetCurrentPhase() { return _game.getGameState().getCurrentPhase(); }
|
||||
|
||||
@@ -360,6 +358,8 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
RemoveCardZone(card.getOwner(), card);
|
||||
_game.getGameState().putCardOnTopOfDeck(card);
|
||||
});
|
||||
|
||||
ShuffleFreepsDeck();
|
||||
}
|
||||
public void ShadowShuffleCardsInDeck(String...cardNames) {
|
||||
Arrays.stream(cardNames).forEach(cardName -> ShadowShuffleCardsInDeck(GetShadowCard(cardName)));
|
||||
@@ -369,6 +369,14 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
RemoveCardZone(card.getOwner(), card);
|
||||
_game.getGameState().putCardOnTopOfDeck(card);
|
||||
});
|
||||
|
||||
ShuffleShadowDeck();
|
||||
}
|
||||
|
||||
public void ShuffleFreepsDeck() { ShuffleDeck(P1); }
|
||||
public void ShuffleShadowDeck() { ShuffleDeck(P2); }
|
||||
public void ShuffleDeck(String player) {
|
||||
_game.getGameState().shuffleDeck(player);
|
||||
}
|
||||
|
||||
public void FreepsMoveCharToTable(String...names) {
|
||||
@@ -385,22 +393,43 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
}
|
||||
|
||||
|
||||
public void FreepsMoveCardToSupportArea(String cardName) { FreepsMoveCardToSupportArea(GetFreepsCard(cardName)); }
|
||||
public void FreepsMoveCardToSupportArea(String...names) {
|
||||
Arrays.stream(names).forEach(name -> FreepsMoveCardToSupportArea(GetFreepsCard(name)));
|
||||
}
|
||||
public void FreepsMoveCardToSupportArea(PhysicalCardImpl...cards) {
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P1, card, Zone.SUPPORT));
|
||||
}
|
||||
public void ShadowMoveCardToSupportArea(String cardName) { ShadowMoveCardToSupportArea(GetShadowCard(cardName)); }
|
||||
public void ShadowMoveCardToSupportArea(PhysicalCardImpl...cards) {
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P1, card, Zone.SUPPORT));
|
||||
public void ShadowMoveCardToSupportArea(String...names) {
|
||||
Arrays.stream(names).forEach(name -> ShadowMoveCardToSupportArea(GetFreepsCard(name)));
|
||||
}
|
||||
public void ShadowMoveCardToSupportArea(PhysicalCardImpl...cards) {
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P2, card, Zone.SUPPORT));
|
||||
}
|
||||
public void FreepsMoveCardToDiscard(String...names) {
|
||||
Arrays.stream(names).forEach(name -> FreepsMoveCardToDiscard(GetFreepsCard(name)));
|
||||
}
|
||||
|
||||
public void FreepsMoveCardToDiscard(String cardName) { FreepsMoveCardToDiscard(GetFreepsCard(cardName)); }
|
||||
public void FreepsMoveCardToDiscard(PhysicalCardImpl...cards) {
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P1, card, Zone.DISCARD));
|
||||
}
|
||||
public void ShadowMoveCardToDiscard(String cardName) { ShadowMoveCardToDiscard(GetShadowCard(cardName)); }
|
||||
public void ShadowMoveCardToDiscard(String...names) {
|
||||
Arrays.stream(names).forEach(name -> ShadowMoveCardToDiscard(GetFreepsCard(name)));
|
||||
}
|
||||
public void ShadowMoveCardToDiscard(PhysicalCardImpl...cards) {
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P1, card, Zone.DISCARD));
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P2, card, Zone.DISCARD));
|
||||
}
|
||||
|
||||
|
||||
public void FreepsMoveCardToDeadPile(String...names) {
|
||||
Arrays.stream(names).forEach(name -> FreepsMoveCardToDeadPile(GetFreepsCard(name)));
|
||||
}
|
||||
public void FreepsMoveCardToDeadPile(PhysicalCardImpl...cards) {
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P1, card, Zone.DEAD));
|
||||
}
|
||||
public void ShadowMoveCardToDeadPile(String...names) {
|
||||
Arrays.stream(names).forEach(name -> ShadowMoveCardToDeadPile(GetFreepsCard(name)));
|
||||
}
|
||||
public void ShadowMoveCardToDeadPile(PhysicalCardImpl...cards) {
|
||||
Arrays.stream(cards).forEach(card -> MoveCardToZone(P2, card, Zone.DEAD));
|
||||
}
|
||||
|
||||
|
||||
@@ -557,25 +586,27 @@ public class GenericCardTestHelper extends AbstractAtTest {
|
||||
public int GetFreepsCardChoiceCount() { return FreepsGetCardChoices().size(); }
|
||||
public int GetShadowCardChoiceCount() { return ShadowGetCardChoices().size(); }
|
||||
|
||||
public void FreepsChooseCardBPFromSelection(PhysicalCardImpl card) throws DecisionResultInvalidException { ChooseCardBPFromSelection(P1, card);}
|
||||
public void ShadowChooseCardBPFromSelection(PhysicalCardImpl card) throws DecisionResultInvalidException { ChooseCardBPFromSelection(P2, card);}
|
||||
public void FreepsChooseCardBPFromSelection(PhysicalCardImpl...cards) throws DecisionResultInvalidException { ChooseCardBPFromSelection(P1, cards);}
|
||||
public void ShadowChooseCardBPFromSelection(PhysicalCardImpl...cards) throws DecisionResultInvalidException { ChooseCardBPFromSelection(P2, cards);}
|
||||
|
||||
public void ChooseCardBPFromSelection(String player, PhysicalCardImpl card) throws DecisionResultInvalidException {
|
||||
AwaitingDecision decision = _userFeedback.getAwaitingDecision(player);
|
||||
public void ChooseCardBPFromSelection(String player, PhysicalCardImpl...cards) throws DecisionResultInvalidException {
|
||||
String[] choices = GetAwaitingDecisionParam(player,"blueprintId");
|
||||
ArrayList<String> bps = new ArrayList<String>();
|
||||
|
||||
String[] ids = GetAwaitingDecisionParam(player,"blueprintId");
|
||||
for(int i = 0; i < ids.length; i++)
|
||||
for(int i = 0; i < choices.length; i++)
|
||||
{
|
||||
String id = ids[i];
|
||||
if(id == card.getBlueprintId())
|
||||
for(PhysicalCardImpl card : cards)
|
||||
{
|
||||
// I have no idea why the spacing is required, but the BP parser skips to the fourth position
|
||||
playerDecided(player, " " + i);
|
||||
return;
|
||||
if(card.getBlueprintId() == choices[i])
|
||||
{
|
||||
// I have no idea why the spacing is required, but the BP parser skips to the fourth position
|
||||
bps.add(" " + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playerDecided(player, card.getBlueprintId());
|
||||
playerDecided(player, String.join(",", bps));
|
||||
}
|
||||
|
||||
public void FreepsChooseCardIDFromSelection(PhysicalCardImpl card) throws DecisionResultInvalidException { ChooseCardIDFromSelection(P1, card);}
|
||||
|
||||
@@ -112,19 +112,18 @@ public class Card_09_039_Tests
|
||||
|
||||
PhysicalCardImpl library = scn.GetShadowCard("library");
|
||||
PhysicalCardImpl troop1 = scn.GetShadowCard("troop1");
|
||||
PhysicalCardImpl troop2 = scn.GetShadowCard("troop2");
|
||||
PhysicalCardImpl axe1 = scn.GetShadowCard("axe1");
|
||||
|
||||
scn.ShadowMoveCardToHand(library, troop1);
|
||||
scn.ShadowMoveCardToSupportArea(library);
|
||||
scn.ShadowMoveCharToTable(troop1);
|
||||
scn.StackCardsOn(library, axe1, troop2);
|
||||
|
||||
scn.StartGame();
|
||||
scn.SetTwilight(20);
|
||||
|
||||
scn.FreepsSkipCurrentPhaseAction();
|
||||
|
||||
scn.ShadowPlayCard(library);
|
||||
scn.ShadowUseCardAction(library);
|
||||
assertEquals(library, axe1.getStackedOn());
|
||||
|
||||
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||
scn.SkipCurrentPhaseActions();
|
||||
scn.FreepsAssignToMinions(scn.GetRingBearer(), troop1);
|
||||
@@ -132,17 +131,54 @@ public class Card_09_039_Tests
|
||||
scn.FreepsSkipCurrentPhaseAction();
|
||||
|
||||
assertTrue(scn.ShadowCardActionAvailable(library));
|
||||
// 20 initially, +2 from move, -2 from library, -5 for troop, -2 for roaming
|
||||
assertEquals(13, scn.GetTwilight());
|
||||
// 20 initially, +2 from move, the rest were all cheated in
|
||||
assertEquals(22, scn.GetTwilight());
|
||||
assertEquals(9, scn.GetStrength(troop1));
|
||||
assertEquals(1, scn.GetStackedCards(library).size());
|
||||
assertEquals(2, scn.GetStackedCards(library).size());
|
||||
|
||||
scn.ShadowUseCardAction(library);
|
||||
assertEquals(13, scn.GetTwilight());
|
||||
assertEquals(9, scn.GetStrength(troop1));
|
||||
assertEquals(0, scn.GetStackedCards(library).size());
|
||||
assertFalse(scn.ShadowAnyDecisionsAvailable()); // only 1 valid choice even with 2 stacked, so should have no decision
|
||||
assertEquals(21, scn.GetTwilight());
|
||||
assertEquals(10, scn.GetStrength(troop1));
|
||||
assertEquals(1, scn.GetStackedCards(library).size());
|
||||
assertEquals(Zone.DISCARD, axe1.getZone());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void RegroupAbilityRemoves1AndTakesStackedIsengardCardIntoHand() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
GenericCardTestHelper scn = GetScenario();
|
||||
|
||||
PhysicalCardImpl library = scn.GetShadowCard("library");
|
||||
PhysicalCardImpl troop1 = scn.GetShadowCard("troop1");
|
||||
PhysicalCardImpl runner = scn.GetShadowCard("runner");
|
||||
PhysicalCardImpl axe1 = scn.GetShadowCard("axe1");
|
||||
|
||||
scn.ShadowMoveCardToSupportArea(library);
|
||||
scn.StackCardsOn(library, axe1, runner, troop1);
|
||||
|
||||
scn.StartGame();
|
||||
scn.SetTwilight(20);
|
||||
|
||||
scn.FreepsSkipCurrentPhaseAction();
|
||||
|
||||
scn.SkipToPhase(Phase.REGROUP);
|
||||
scn.FreepsSkipCurrentPhaseAction();
|
||||
|
||||
assertTrue(scn.ShadowCardActionAvailable(library));
|
||||
// 20 initially, +2 from move, the rest were all cheated in
|
||||
assertEquals(22, scn.GetTwilight());
|
||||
assertEquals(0, scn.GetShadowHandCount());
|
||||
assertEquals(3, scn.GetStackedCards(library).size());
|
||||
|
||||
scn.ShadowUseCardAction(library);
|
||||
assertFalse(scn.ShadowAnyDecisionsAvailable()); // only 1 valid choice even with 3 stacked, so should have no decision
|
||||
assertEquals(21, scn.GetTwilight());
|
||||
assertEquals(1, scn.GetShadowHandCount());
|
||||
assertEquals(2, scn.GetStackedCards(library).size());
|
||||
assertEquals(Zone.HAND, troop1.getZone());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user