From 601b3c47648da2d674bf3c88101c71b7af0711a0 Mon Sep 17 00:00:00 2001 From: "marcin.sciesinski" Date: Sat, 16 Jan 2021 13:14:34 -0800 Subject: [PATCH] Consolidating card resolving --- .../appender/resolver/CardResolver.java | 368 ++++++------------ 1 file changed, 112 insertions(+), 256 deletions(-) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java index 7f89df597..245e1fb0c 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java @@ -44,57 +44,24 @@ public class CardResolver { String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { Function> cardSource = actionContext -> { final Filterable stackedOnFilter = stackedOn.getFilterable(actionContext); - return Filters.filterActive(actionContext.getGame(), stackedOnFilter); + return Filters.filterActive(actionContext.getGame(), Filters.stackedOn(stackedOnFilter)); }; if (type.startsWith("memory(") && type.endsWith(")")) { return resolveMemoryCards(type, choiceFilter, playabilityFilter, countSource, memory, cardSource); } else if (type.startsWith("choose(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); - return new DelayedAppender() { - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - final int min = countSource.getMinimum(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - final Filterable stackedOnFilter = stackedOn.getFilterable(actionContext); - - Filterable additionalFilterable = Filters.any; - if (playabilityFilter != null) - additionalFilterable = playabilityFilter.getFilterable(actionContext); - - List choice = new LinkedList<>(); - - final LotroGame game = actionContext.getGame(); - for (PhysicalCard stackedOn : Filters.filterActive(game, stackedOnFilter)) { - final List stackedCards = game.getGameState().getStackedCards(stackedOn); - choice.addAll(Filters.filter(stackedCards, game, filterable, additionalFilterable)); + ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> { + String choicePlayerId = playerSource.getPlayer(actionContext); + return new ChooseStackedCardsEffect(action, choicePlayerId, min, max, stackedOn.getFilterable(actionContext), Filters.in(possibleCards)) { + @Override + protected void cardsChosen(LotroGame game, Collection stackedCards) { + actionContext.setCardMemory(memory, stackedCards); } - - return choice.size() >= min; - } - - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - final Filterable filterable = filterableSource.getFilterable(actionContext); - final Filterable stackedOnFilter = stackedOn.getFilterable(actionContext); - String choicePlayerId = playerSource.getPlayer(actionContext); - int min = countSource.getMinimum(actionContext); - int max = countSource.getMaximum(actionContext); - - Filterable additionalFilterable = Filters.any; - if (choiceFilter != null) - additionalFilterable = choiceFilter.getFilterable(actionContext); - - return new ChooseStackedCardsEffect(action, choicePlayerId, min, max, stackedOnFilter, Filters.and(filterable, additionalFilterable)) { - @Override - protected void cardsChosen(LotroGame game, Collection stackedCards) { - actionContext.setCardMemory(memory, stackedCards); - } - }; - } + }; }; + + return resolveChoiceCards(type, choiceFilter, playabilityFilter, countSource, environment, cardSource, effectSource); } throw new RuntimeException("Unable to resolve card resolver of type: " + type); } @@ -140,75 +107,19 @@ public class CardResolver { } else if (type.startsWith("memory(") && type.endsWith(")")) { return resolveMemoryCards(type, additionalFilter, additionalFilter, countSource, memory, cardSource); } else if (type.startsWith("all(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); - return new DelayedAppender() { - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - return new UnrespondableEffect() { - @Override - protected void doPlayEffect(LotroGame game) { - final Filterable filterable = filterableSource.getFilterable(actionContext); - String handId = handSource.getPlayer(actionContext); - Filterable additionalFilterable = Filters.any; - if (additionalFilter != null) - additionalFilterable = additionalFilter.getFilterable(actionContext); - actionContext.setCardMemory(memory, Filters.filter(game.getGameState().getHand(handId), game, filterable, additionalFilterable)); - } - }; - } - - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - return true; - } - }; + return resolveAllCards(type, additionalFilter, memory, environment, cardSource); } else if (type.startsWith("choose(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); - final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); - return new DelayedAppender() { - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - int min = countSource.getMinimum(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - String handId = handSource.getPlayer(actionContext); - Filterable additionalFilterable = Filters.any; - if (additionalFilter != null) - additionalFilterable = additionalFilter.getFilterable(actionContext); - final LotroGame game = actionContext.getGame(); - return Filters.filter(game.getGameState().getHand(handId), game, filterable, additionalFilterable).size() >= min; - } - - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - int min = countSource.getMinimum(actionContext); - int max = countSource.getMaximum(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - String choicePlayerId = playerSource.getPlayer(actionContext); - String handId = handSource.getPlayer(actionContext); - Filterable additionalFilterable = Filters.any; - if (additionalFilter != null) - additionalFilterable = additionalFilter.getFilterable(actionContext); - if (handId.equals(choicePlayerId)) { - return new ChooseCardsFromHandEffect(choicePlayerId, min, max, filterable, additionalFilterable) { - @Override - protected void cardsSelected(LotroGame game, Collection cards) { - actionContext.setCardMemory(memory, cards); - } - }; - } else { - final LotroGame game = actionContext.getGame(); - final Collection matchingCards = Filters.filter(game.getGameState().getHand(handId), game, filterable, additionalFilterable); - return new ChooseArbitraryCardsEffect(choicePlayerId, choiceText, matchingCards, min, max) { - @Override - protected void cardsSelected(LotroGame game, Collection selectedCards) { - actionContext.setCardMemory(memory, selectedCards); - } - }; + ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> { + String handId = handSource.getPlayer(actionContext); + return new ChooseCardsFromHandEffect(handId, min, max, Filters.in(possibleCards)) { + @Override + protected void cardsSelected(LotroGame game, Collection cards) { + actionContext.setCardMemory(memory, cards); } - } + }; }; + + return resolveChoiceCards(type, additionalFilter, additionalFilter, countSource, environment, cardSource, effectSource); } throw new RuntimeException("Unable to resolve card resolver of type: " + type); } @@ -234,62 +145,19 @@ public class CardResolver { } else if (type.startsWith("memory(") && type.endsWith(")")) { return resolveMemoryCards(type, choiceFilter, playabilityFilter, countSource, memory, cardSource); } else if (type.startsWith("all(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); - return new DelayedAppender() { - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - return true; - } - - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - return new UnrespondableEffect() { - @Override - protected void doPlayEffect(LotroGame game) { - final Filterable filter = filterableSource.getFilterable(actionContext); - String choicePlayerId = playerSource.getPlayer(actionContext); - Filterable filterable = Filters.any; - if (choiceFilter != null) - filterable = choiceFilter.getFilterable(actionContext); - actionContext.setCardMemory(memory, Filters.filter(game.getGameState().getDiscard(choicePlayerId), game, filter, filterable)); - } - }; - } - }; + return resolveAllCards(type, choiceFilter, memory, environment, cardSource); } else if (type.startsWith("choose(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); - return new DelayedAppender() { - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - int min = countSource.getMinimum(actionContext); - final Filterable filter = filterableSource.getFilterable(actionContext); - String choicePlayerId = playerSource.getPlayer(actionContext); - Filterable additionalFilterable = Filters.any; - if (playabilityFilter != null) - additionalFilterable = playabilityFilter.getFilterable(actionContext); - final LotroGame game = actionContext.getGame(); - return Filters.filter(game.getGameState().getDiscard(choicePlayerId), game, filter, additionalFilterable).size() >= min; - } - - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - int min = countSource.getMinimum(actionContext); - int max = countSource.getMaximum(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - String choicePlayerId = playerSource.getPlayer(actionContext); - Filterable additionalFilterable = Filters.any; - if (choiceFilter != null) - additionalFilterable = choiceFilter.getFilterable(actionContext); - return new ChooseCardsFromDiscardEffect(choicePlayerId, min, max, filterable, additionalFilterable) { - @Override - protected void cardsSelected(LotroGame game, Collection cards) { - actionContext.setCardMemory(memory, cards); - } - }; - } + ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> { + String choicePlayerId = playerSource.getPlayer(actionContext); + return new ChooseCardsFromDiscardEffect(choicePlayerId, min, max, Filters.in(possibleCards)) { + @Override + protected void cardsSelected(LotroGame game, Collection cards) { + actionContext.setCardMemory(memory, cards); + } + }; }; + + return resolveChoiceCards(type, choiceFilter, playabilityFilter, countSource, environment, cardSource, effectSource); } throw new RuntimeException("Unable to resolve card resolver of type: " + type); } @@ -304,52 +172,19 @@ public class CardResolver { if (type.startsWith("memory(") && type.endsWith(")")) { return resolveMemoryCards(type, choiceFilter, choiceFilter, countSource, memory, cardSource); } else if (type.startsWith("all(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); - return new DelayedAppender() { - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - return new UnrespondableEffect() { - @Override - protected void doPlayEffect(LotroGame game) { - final String player = playerSource.getPlayer(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - actionContext.setCardMemory(memory, Filters.filter(game.getGameState().getDeck(player), game, filterable)); - } - }; - } - - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - return true; - } - }; + return resolveAllCards(type, choiceFilter, memory, environment, cardSource); } else if (type.startsWith("choose(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); - return new DelayedAppender() { - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - return true; - } - - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - int min = countSource.getMinimum(actionContext); - int max = countSource.getMaximum(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - String choicePlayerId = playerSource.getPlayer(actionContext); - Filterable additionalFilterable = Filters.any; - if (choiceFilter != null) - additionalFilterable = choiceFilter.getFilterable(actionContext); - return new ChooseCardsFromDeckEffect(choicePlayerId, min, max, filterable, additionalFilterable) { - @Override - protected void cardsSelected(LotroGame game, Collection cards) { - actionContext.setCardMemory(memory, cards); - } - }; - } + ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> { + String choicePlayerId = playerSource.getPlayer(actionContext); + return new ChooseCardsFromDeckEffect(choicePlayerId, min, max, Filters.in(possibleCards)) { + @Override + protected void cardsSelected(LotroGame game, Collection cards) { + actionContext.setCardMemory(memory, cards); + } + }; }; + + return resolveChoiceCards(type, choiceFilter, choiceFilter, countSource, environment, cardSource, effectSource); } throw new RuntimeException("Unable to resolve card resolver of type: " + type); } @@ -401,57 +236,20 @@ public class CardResolver { } else if (type.startsWith("memory(") && type.endsWith(")")) { return resolveMemoryCards(type, additionalFilter, playabilityFilter, countSource, memory, cardSource); } else if (type.startsWith("all(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); - return new DelayedAppender() { - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - return new UnrespondableEffect() { - @Override - protected void doPlayEffect(LotroGame game) { - final Filterable filterable = filterableSource.getFilterable(actionContext); - actionContext.setCardMemory(memory, Filters.filterActive(game, filterable)); - } - }; - } - - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - return true; - } - }; + return resolveAllCards(type, additionalFilter, memory, environment, cardSource); } else if (type.startsWith("choose(") && type.endsWith(")")) { - final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); - final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); - return new DelayedAppender() { - @Override - public boolean isPlayableInFull(ActionContext actionContext) { - int min = countSource.getMinimum(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - Filterable additionalFilterable = Filters.any; - if (playabilityFilter != null) - additionalFilterable = playabilityFilter.getFilterable(actionContext); - return PlayConditions.isActive(actionContext.getGame(), min, filterable, additionalFilterable); - } - - @Override - protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { - int min = countSource.getMinimum(actionContext); - int max = countSource.getMaximum(actionContext); - final Filterable filterable = filterableSource.getFilterable(actionContext); - Filterable additionalFilterable = Filters.any; - if (additionalFilter != null) - additionalFilterable = additionalFilter.getFilterable(actionContext); - String choicePlayerId = playerSource.getPlayer(actionContext); - return new ChooseActiveCardsEffect(actionContext.getSource(), choicePlayerId, choiceText, min, max, filterable, additionalFilterable) { - @Override - protected void cardsSelected(LotroGame game, Collection cards) { - actionContext.setCardMemory(memory, cards); - } - }; - } + ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> { + String choicePlayerId = playerSource.getPlayer(actionContext); + return new ChooseActiveCardsEffect(actionContext.getSource(), choicePlayerId, choiceText, min, max, Filters.in(possibleCards)) { + @Override + protected void cardsSelected(LotroGame game, Collection cards) { + actionContext.setCardMemory(memory, cards); + } + }; }; + + return resolveChoiceCards(type, additionalFilter, playabilityFilter, countSource, environment, cardSource, effectSource); } throw new InvalidCardDefinitionException("Unable to resolve card resolver of type: " + type); } @@ -497,7 +295,7 @@ public class CardResolver { return new DelayedAppender() { @Override public boolean isPlayableInFull(ActionContext actionContext) { - int min = countSource.getMinimum(null); + int min = countSource.getMinimum(actionContext); return filterCards(actionContext, playabilityFilter).size() >= min; } @@ -521,4 +319,62 @@ public class CardResolver { } }; } + + private static DelayedAppender resolveChoiceCards(String type, FilterableSource choiceFilter, FilterableSource playabilityFilter, + ValueSource countSource, CardGenerationEnvironment environment, Function> cardSource, ChoiceEffectSource effectSource) throws InvalidCardDefinitionException { + final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); + final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); + + return new DelayedAppender() { + @Override + public boolean isPlayableInFull(ActionContext actionContext) { + int min = countSource.getMinimum(actionContext); + return filterCards(actionContext, playabilityFilter).size() >= min; + } + + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + int min = countSource.getMinimum(actionContext); + int max = countSource.getMaximum(actionContext); + return effectSource.createEffect(filterCards(actionContext, choiceFilter), action, actionContext, min, max); + } + + private Collection filterCards(ActionContext actionContext, FilterableSource filter) { + Filterable filterable = filterableSource.getFilterable(actionContext); + Filterable additionalFilterable = Filters.any; + if (filter != null) + additionalFilterable = filter.getFilterable(actionContext); + return Filters.filter(cardSource.apply(actionContext), actionContext.getGame(), filterable, additionalFilterable); + } + }; + } + + private static DelayedAppender resolveAllCards(String type, FilterableSource additionalFilter, String memory, CardGenerationEnvironment environment, Function> cardSource) throws InvalidCardDefinitionException { + final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); + final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment); + return new DelayedAppender() { + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + return new UnrespondableEffect() { + @Override + protected void doPlayEffect(LotroGame game) { + actionContext.setCardMemory(memory, filterCards(actionContext, additionalFilter)); + } + + private Collection filterCards(ActionContext actionContext, FilterableSource filter) { + final Filterable filterable = filterableSource.getFilterable(actionContext); + Filterable additionalFilterable = Filters.any; + if (filter != null) + additionalFilterable = filter.getFilterable(actionContext); + return Filters.filter(cardSource.apply(actionContext), actionContext.getGame(), filterable, additionalFilterable); + } + }; + } + }; + } + + private interface ChoiceEffectSource { + Effect createEffect(Collection possibleCards, CostToEffectAction action, ActionContext actionContext, + int min, int max); + } }