mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- CNS: Added Coercive Portal and Council's Judgment
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user