- CNS: Added Coercive Portal and Council's Judgment

This commit is contained in:
swordshine
2014-05-24 03:55:15 +00:00
parent 5ae465ede4
commit 56801c5032
7 changed files with 102 additions and 19 deletions

View File

@@ -18,6 +18,7 @@
package forge.ai; package forge.ai;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.ai.ability.ProtectAi; import forge.ai.ability.ProtectAi;
@@ -1811,13 +1812,45 @@ public class ComputerUtil {
return chosen; return chosen;
} }
public static String vote(Player ai, List<String> options, String logic) { public static Object vote(Player ai, List<Object> options, SpellAbility sa, ArrayListMultimap<Object, Player> votes) {
if (logic == null) { if (!sa.hasParam("AILogic")) {
return Aggregates.random(options); return Aggregates.random(options);
} else { } else {
String logic = sa.getParam("AILogic");
switch (logic) { switch (logic) {
case "GraceOrCondemnation": case "GraceOrCondemnation":
return ai.getCreaturesInPlay().size() > ai.getOpponent().getCreaturesInPlay().size() ? "Grace" : "Condemnation"; return ai.getCreaturesInPlay().size() > ai.getOpponent().getCreaturesInPlay().size() ? "Grace" : "Condemnation";
case "CarnageOrHomage":
List<Card> cardsInPlay = CardLists.getNotType(sa.getHostCard().getGame().getCardsIn(ZoneType.Battlefield), "Land");
List<Card> humanlist = CardLists.filterControlledBy(cardsInPlay, ai.getOpponents());
List<Card> computerlist = CardLists.filterControlledBy(cardsInPlay, ai);
return (ComputerUtilCard.evaluatePermanentList(computerlist) + 3) < ComputerUtilCard
.evaluatePermanentList(humanlist) ? "Carnage" : "Homage";
case "Judgment":
if (votes.isEmpty()) {
List<Card> list = new ArrayList<Card>();
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<String> restrictedToColors = new ArrayList<String>();
for (Object o : options) {
if (o instanceof String) {
restrictedToColors.add((String) o);
}
}
List<Card> 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); default: return Iterables.getFirst(options, null);
} }
} }

View File

@@ -3,6 +3,7 @@ package forge.ai;
import com.esotericsoftware.minlog.Log; import com.esotericsoftware.minlog.Log;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
@@ -368,9 +369,8 @@ public class PlayerControllerAi extends PlayerController {
} }
@Override @Override
public String vote(SpellAbility sa, String prompt, List<String> options) { public Object vote(SpellAbility sa, String prompt, List<Object> options, ArrayListMultimap<Object, Player> votes) {
String result = ComputerUtil.vote(player, options, sa.getParam("AILogic")); return ComputerUtil.vote(player, options, sa, votes);
return result;
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -2,8 +2,11 @@ package forge.ai.ability;
import forge.ai.SpellAbilityAi; import forge.ai.SpellAbilityAi;
import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
public class VoteAi extends SpellAbilityAi { public class VoteAi extends SpellAbilityAi {
/* (non-Javadoc) /* (non-Javadoc)
@@ -12,6 +15,14 @@ public class VoteAi extends SpellAbilityAi {
@Override @Override
protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) { protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
// TODO: add ailogic // 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; return false;
} }
@@ -22,4 +33,9 @@ public class VoteAi extends SpellAbilityAi {
public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) { public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) {
return canPlayAI(aiPlayer, sa); return canPlayAI(aiPlayer, sa);
} }
@Override
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
return true;
}
} }

View File

@@ -4,14 +4,18 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.game.Game;
import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect; import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.AbilitySub; import forge.game.spellability.AbilitySub;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -24,8 +28,15 @@ public class VoteEffect extends SpellAbilityEffect {
*/ */
@Override @Override
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
return StringUtils.join(getDefinedPlayersOrTargeted(sa), ", ") + " vote " StringBuilder sb = new StringBuilder();
+ StringUtils.join(sa.getParam("VoteType").split(","), " or "); 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) /* (non-Javadoc)
@@ -34,20 +45,32 @@ public class VoteEffect extends SpellAbilityEffect {
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa); final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa);
final List<String> voteType = Arrays.asList(sa.getParam("VoteType").split(",")); final List<Object> voteType = new ArrayList<Object>();
final Card host = sa.getHostCard(); 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 // starting with the activator
int pSize = tgtPlayers.size(); int pSize = tgtPlayers.size();
Player activator = sa.getActivatingPlayer(); Player activator = sa.getActivatingPlayer();
while (tgtPlayers.contains(activator) && !activator.equals(Iterables.getFirst(tgtPlayers, null))) { while (tgtPlayers.contains(activator) && !activator.equals(Iterables.getFirst(tgtPlayers, null))) {
tgtPlayers.add(pSize - 1, tgtPlayers.remove(0)); tgtPlayers.add(pSize - 1, tgtPlayers.remove(0));
} }
ArrayListMultimap<String, Player> votes = ArrayListMultimap.create(); ArrayListMultimap<Object, Player> votes = ArrayListMultimap.create();
for (final Player p : tgtPlayers) { for (final Player p : tgtPlayers) {
int voteAmount = p.getAmountOfKeyword("You get an additional vote.") + 1; int voteAmount = p.getAmountOfKeyword("You get an additional vote.") + 1;
for (int i = 0; i < voteAmount; i++) { 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); votes.put(result, p);
host.getGame().getAction().nofityOfValue(sa, p, result + "\r\nCurrent Votes:" + votes, p); host.getGame().getAction().nofityOfValue(sa, p, result + "\r\nCurrent Votes:" + votes, p);
} }
@@ -55,12 +78,17 @@ public class VoteEffect extends SpellAbilityEffect {
List<String> subAbs = Lists.newArrayList(); List<String> subAbs = Lists.newArrayList();
final List<String> mostVotes = getMostVotes(votes); final List<Object> mostVotes = getMostVotes(votes);
if (sa.hasParam("Tied") && mostVotes.size() > 1) { if (sa.hasParam("Tied") && mostVotes.size() > 1) {
subAbs.add(sa.getParam("Tied")); subAbs.add(sa.getParam("Tied"));
} else if (sa.hasParam("VoteSubAbility")) {
for (final Object o : mostVotes) {
host.addRemembered(o);
}
subAbs.add(sa.getParam("VoteSubAbility"));
} else { } else {
for (String type : mostVotes) { for (Object type : mostVotes) {
subAbs.add(sa.getParam("Vote" + type)); subAbs.add(sa.getParam("Vote" + type.toString()));
} }
} }
@@ -70,12 +98,15 @@ public class VoteEffect extends SpellAbilityEffect {
((AbilitySub) action).setParent(sa); ((AbilitySub) action).setParent(sa);
AbilityUtils.resolve(action); AbilityUtils.resolve(action);
} }
if (sa.hasParam("VoteSubAbility")) {
host.clearRemembered();
}
} }
private List<String> getMostVotes(ArrayListMultimap<String, Player> votes) { private List<Object> getMostVotes(ArrayListMultimap<Object, Player> votes) {
List<String> most = Lists.newArrayList(); List<Object> most = Lists.newArrayList();
int amount = 0; int amount = 0;
for (String voteType : votes.keySet()) { for (Object voteType : votes.keySet()) {
int voteAmount = votes.get(voteType).size(); int voteAmount = votes.get(voteType).size();
if (voteAmount == amount) { if (voteAmount == amount) {
most.add(voteType); most.add(voteType);

View File

@@ -1,6 +1,7 @@
package forge.game.player; package forge.game.player;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import forge.LobbyPlayer; import forge.LobbyPlayer;
@@ -176,7 +177,7 @@ public abstract class PlayerController {
return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false); return chooseSomeType(kindOfType, sa, validTypes, invalidTypes, false);
} }
public abstract String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes, boolean isOptional); public abstract String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes, boolean isOptional);
public abstract String vote(SpellAbility sa, String prompt, List<String> options); public abstract Object vote(SpellAbility sa, String prompt, List<Object> options, ArrayListMultimap<Object, Player> votes);
public abstract Pair<CounterType,String> chooseAndRemoveOrPutCounter(Card cardWithCounter); public abstract Pair<CounterType,String> chooseAndRemoveOrPutCounter(Card cardWithCounter);
public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question); public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question);
public abstract List<Card> getCardsToMulligan(boolean isCommander, Player firstPlayer); public abstract List<Card> getCardsToMulligan(boolean isCommander, Player firstPlayer);

View File

@@ -1,6 +1,7 @@
package forge.gamesimulationtests.util; package forge.gamesimulationtests.util;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
@@ -447,7 +448,7 @@ public class PlayerControllerForTests extends PlayerController {
} }
@Override @Override
public String vote(SpellAbility sa, String prompt, List<String> options) { public Object vote(SpellAbility sa, String prompt, List<Object> options, ArrayListMultimap<Object, Player> votes) {
return chooseItem(options); return chooseItem(options);
} }

View File

@@ -2,6 +2,7 @@ package forge.player;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
@@ -572,7 +573,7 @@ public class PlayerControllerHuman extends PlayerController {
} }
@Override @Override
public String vote(SpellAbility sa, String prompt, List<String> options) { public Object vote(SpellAbility sa, String prompt, List<Object> options, ArrayListMultimap<Object, Player> votes) {
return SGuiChoose.one(prompt, options); return SGuiChoose.one(prompt, options);
} }