From 56801c5032968d0770b0930844e7d380e718ae83 Mon Sep 17 00:00:00 2001 From: swordshine Date: Sat, 24 May 2014 03:55:15 +0000 Subject: [PATCH] - CNS: Added Coercive Portal and Council's Judgment --- .../src/main/java/forge/ai/ComputerUtil.java | 37 ++++++++++++- .../java/forge/ai/PlayerControllerAi.java | 6 +-- .../main/java/forge/ai/ability/VoteAi.java | 16 ++++++ .../game/ability/effects/VoteEffect.java | 53 +++++++++++++++---- .../forge/game/player/PlayerController.java | 3 +- .../util/PlayerControllerForTests.java | 3 +- .../forge/player/PlayerControllerHuman.java | 3 +- 7 files changed, 102 insertions(+), 19 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index 2b6602d1be8..71634a133b0 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -18,6 +18,7 @@ package forge.ai; import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import forge.ai.ability.ProtectAi; @@ -1811,13 +1812,45 @@ public class ComputerUtil { return chosen; } - public static String vote(Player ai, List options, String logic) { - if (logic == null) { + public static Object vote(Player ai, List options, SpellAbility sa, ArrayListMultimap votes) { + if (!sa.hasParam("AILogic")) { return Aggregates.random(options); } else { + String logic = sa.getParam("AILogic"); switch (logic) { case "GraceOrCondemnation": return ai.getCreaturesInPlay().size() > ai.getOpponent().getCreaturesInPlay().size() ? "Grace" : "Condemnation"; + case "CarnageOrHomage": + List cardsInPlay = CardLists.getNotType(sa.getHostCard().getGame().getCardsIn(ZoneType.Battlefield), "Land"); + List humanlist = CardLists.filterControlledBy(cardsInPlay, ai.getOpponents()); + List computerlist = CardLists.filterControlledBy(cardsInPlay, ai); + return (ComputerUtilCard.evaluatePermanentList(computerlist) + 3) < ComputerUtilCard + .evaluatePermanentList(humanlist) ? "Carnage" : "Homage"; + case "Judgment": + if (votes.isEmpty()) { + List list = new ArrayList(); + for (Object o : options) { + if (o instanceof Card) { + list.add((Card) o); + } + } + return ComputerUtilCard.getBestAI(list); + } else { + return Iterables.getFirst(votes.keySet(), null); + } + case "Protection": + if (votes.isEmpty()) { + List restrictedToColors = new ArrayList(); + for (Object o : options) { + if (o instanceof String) { + restrictedToColors.add((String) o); + } + } + List lists = CardLists.filterControlledBy(ai.getGame().getCardsInGame(), ai.getOpponents()); + return StringUtils.capitalize(ComputerUtilCard.getMostProminentColor(lists, restrictedToColors)); + } else { + return Iterables.getFirst(votes.keySet(), null); + } default: return Iterables.getFirst(options, null); } } diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index bfd0cb479d3..fba2ea372dd 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -3,6 +3,7 @@ package forge.ai; import com.esotericsoftware.minlog.Log; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; @@ -368,9 +369,8 @@ public class PlayerControllerAi extends PlayerController { } @Override - public String vote(SpellAbility sa, String prompt, List options) { - String result = ComputerUtil.vote(player, options, sa.getParam("AILogic")); - return result; + public Object vote(SpellAbility sa, String prompt, List options, ArrayListMultimap votes) { + return ComputerUtil.vote(player, options, sa, votes); } /* (non-Javadoc) diff --git a/forge-ai/src/main/java/forge/ai/ability/VoteAi.java b/forge-ai/src/main/java/forge/ai/ability/VoteAi.java index b86023f524d..6781a2069be 100644 --- a/forge-ai/src/main/java/forge/ai/ability/VoteAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/VoteAi.java @@ -2,8 +2,11 @@ package forge.ai.ability; import forge.ai.SpellAbilityAi; +import forge.game.card.Card; +import forge.game.card.CardLists; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; public class VoteAi extends SpellAbilityAi { /* (non-Javadoc) @@ -12,6 +15,14 @@ public class VoteAi extends SpellAbilityAi { @Override protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { // TODO: add ailogic + String logic = sa.getParam("AILogic"); + final Card host = sa.getHostCard(); + if ("Always".equals(logic)) { + return true; + } else if ("Judgment".equals(logic)) { + return !CardLists.getValidCards(host.getGame().getCardsIn(ZoneType.Battlefield), + sa.getParam("VoteCard"), host.getController(), host).isEmpty(); + } return false; } @@ -22,4 +33,9 @@ public class VoteAi extends SpellAbilityAi { public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) { return canPlayAI(aiPlayer, sa); } + + @Override + protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) { + return true; + } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java b/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java index 843ad109cc3..3be25c20d01 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java @@ -4,14 +4,18 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import forge.game.Game; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; +import forge.game.card.CardLists; import forge.game.player.Player; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -24,8 +28,15 @@ public class VoteEffect extends SpellAbilityEffect { */ @Override protected String getStackDescription(SpellAbility sa) { - return StringUtils.join(getDefinedPlayersOrTargeted(sa), ", ") + " vote " - + StringUtils.join(sa.getParam("VoteType").split(","), " or "); + StringBuilder sb = new StringBuilder(); + sb.append(StringUtils.join(getDefinedPlayersOrTargeted(sa), ", ")); + sb.append(" vote "); + if (sa.hasParam("VoteType")) { + sb.append(StringUtils.join(sa.getParam("VoteType").split(","), " or ")); + } else if (sa.hasParam("VoteMessage")) { + sb.append(sa.getParam("VoteMessage")); + } + return sb.toString(); } /* (non-Javadoc) @@ -34,20 +45,32 @@ public class VoteEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { final List tgtPlayers = getDefinedPlayersOrTargeted(sa); - final List voteType = Arrays.asList(sa.getParam("VoteType").split(",")); + final List voteType = new ArrayList(); final Card host = sa.getHostCard(); + final Game game = host.getGame(); + + if (sa.hasParam("VoteType")) { + voteType.addAll(Arrays.asList(sa.getParam("VoteType").split(","))); + } else if (sa.hasParam("VoteCard")) { + ZoneType zone = sa.hasParam("Zone") ? ZoneType.smartValueOf(sa.getParam("Zone")) : ZoneType.Battlefield; + voteType.addAll(CardLists.getValidCards(game.getCardsIn(zone), sa.getParam("VoteCard"), host.getController(), host)); + } + if (voteType.isEmpty()) { + return; + } + // starting with the activator int pSize = tgtPlayers.size(); Player activator = sa.getActivatingPlayer(); while (tgtPlayers.contains(activator) && !activator.equals(Iterables.getFirst(tgtPlayers, null))) { tgtPlayers.add(pSize - 1, tgtPlayers.remove(0)); } - ArrayListMultimap votes = ArrayListMultimap.create(); + ArrayListMultimap votes = ArrayListMultimap.create(); for (final Player p : tgtPlayers) { int voteAmount = p.getAmountOfKeyword("You get an additional vote.") + 1; for (int i = 0; i < voteAmount; i++) { - final String result = p.getController().vote(sa, sa.getHostCard() + "Vote:", voteType); + final Object result = p.getController().vote(sa, host + "Vote:", voteType, votes); votes.put(result, p); host.getGame().getAction().nofityOfValue(sa, p, result + "\r\nCurrent Votes:" + votes, p); } @@ -55,12 +78,17 @@ public class VoteEffect extends SpellAbilityEffect { List subAbs = Lists.newArrayList(); - final List mostVotes = getMostVotes(votes); + final List mostVotes = getMostVotes(votes); if (sa.hasParam("Tied") && mostVotes.size() > 1) { subAbs.add(sa.getParam("Tied")); + } else if (sa.hasParam("VoteSubAbility")) { + for (final Object o : mostVotes) { + host.addRemembered(o); + } + subAbs.add(sa.getParam("VoteSubAbility")); } else { - for (String type : mostVotes) { - subAbs.add(sa.getParam("Vote" + type)); + for (Object type : mostVotes) { + subAbs.add(sa.getParam("Vote" + type.toString())); } } @@ -70,12 +98,15 @@ public class VoteEffect extends SpellAbilityEffect { ((AbilitySub) action).setParent(sa); AbilityUtils.resolve(action); } + if (sa.hasParam("VoteSubAbility")) { + host.clearRemembered(); + } } - private List getMostVotes(ArrayListMultimap votes) { - List most = Lists.newArrayList(); + private List getMostVotes(ArrayListMultimap votes) { + List most = Lists.newArrayList(); int amount = 0; - for (String voteType : votes.keySet()) { + for (Object voteType : votes.keySet()) { int voteAmount = votes.get(voteType).size(); if (voteAmount == amount) { most.add(voteType); diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index 730cf77d637..629ab4e7eba 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -1,6 +1,7 @@ package forge.game.player; import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import forge.LobbyPlayer; @@ -176,7 +177,7 @@ public abstract class PlayerController { return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false); } public abstract String chooseSomeType(String kindOfType, SpellAbility sa, List validTypes, List invalidTypes, boolean isOptional); - public abstract String vote(SpellAbility sa, String prompt, List options); + public abstract Object vote(SpellAbility sa, String prompt, List options, ArrayListMultimap votes); public abstract Pair chooseAndRemoveOrPutCounter(Card cardWithCounter); public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question); public abstract List getCardsToMulligan(boolean isCommander, Player firstPlayer); diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index cffd596dad3..4447ab4c763 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -1,6 +1,7 @@ package forge.gamesimulationtests.util; import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; @@ -447,7 +448,7 @@ public class PlayerControllerForTests extends PlayerController { } @Override - public String vote(SpellAbility sa, String prompt, List options) { + public Object vote(SpellAbility sa, String prompt, List options, ArrayListMultimap votes) { return chooseItem(options); } diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 2562a75f05e..59a1abef6de 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -2,6 +2,7 @@ package forge.player; import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; @@ -572,7 +573,7 @@ public class PlayerControllerHuman extends PlayerController { } @Override - public String vote(SpellAbility sa, String prompt, List options) { + public Object vote(SpellAbility sa, String prompt, List options, ArrayListMultimap votes) { return SGuiChoose.one(prompt, options); }