mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
moved a lot of AI-used methods from CardFactoryUtil to ComputerUtilCard.java
switched Encode to getSingleCardForEffect
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -14096,6 +14096,7 @@ src/main/java/forge/game/ai/AiInputBlock.java -text
|
||||
src/main/java/forge/game/ai/AiInputCommon.java svneol=native#text/plain
|
||||
src/main/java/forge/game/ai/ComputerUtil.java svneol=native#text/plain
|
||||
src/main/java/forge/game/ai/ComputerUtilBlock.java svneol=native#text/plain
|
||||
src/main/java/forge/game/ai/ComputerUtilCard.java -text
|
||||
src/main/java/forge/game/ai/ComputerUtilCombat.java -text
|
||||
src/main/java/forge/game/ai/ComputerUtilCost.java -text
|
||||
src/main/java/forge/game/ai/ComputerUtilMana.java -text
|
||||
|
||||
@@ -27,8 +27,8 @@ import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
@@ -74,13 +74,6 @@ public class CardLists {
|
||||
return b.getNetCombatDamage() - a.getNetCombatDamage();
|
||||
}
|
||||
};
|
||||
public static final Comparator<Card> EvaluateCreatureComparator = new Comparator<Card>() {
|
||||
@Override
|
||||
public int compare(final Card a, final Card b) {
|
||||
return CardFactoryUtil.evaluateCreature(b) - CardFactoryUtil.evaluateCreature(a);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Comparator<Card> CmcComparator = new Comparator<Card>() {
|
||||
@Override
|
||||
public int compare(final Card a, final Card b) {
|
||||
@@ -131,7 +124,7 @@ public class CardLists {
|
||||
* a {@link forge.CardList} object.
|
||||
*/
|
||||
public static void sortByEvaluateCreature(final List<Card> list) {
|
||||
Collections.sort(list, EvaluateCreatureComparator);
|
||||
Collections.sort(list, ComputerUtilCard.EvaluateCreatureComparator);
|
||||
} // sortByEvaluateCreature()
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.Untap;
|
||||
@@ -393,12 +392,5 @@ public final class CardPredicates {
|
||||
return a.getCMC();
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function<Card, Integer> fnEvaluateCreature = new Function<Card, Integer>() {
|
||||
@Override
|
||||
public Integer apply(Card a) {
|
||||
return CardFactoryUtil.evaluateCreature(a);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import forge.card.CardSplitType;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
import forge.card.mana.ManaCostBeingPaid;
|
||||
import forge.card.spellability.AbilityManaPart;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.Player;
|
||||
@@ -99,29 +98,6 @@ public final class CardUtil {
|
||||
return c.determineColor().toStringList();
|
||||
}
|
||||
|
||||
|
||||
// this function checks, if duplicates of a keyword are not necessary (like
|
||||
// flying, trample, etc.)
|
||||
/**
|
||||
* <p>
|
||||
* isNonStackingKeyword.
|
||||
* </p>
|
||||
*
|
||||
* @param keyword
|
||||
* a {@link java.lang.String} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean isNonStackingKeyword(final String keyword) {
|
||||
String kw = new String(keyword);
|
||||
if (kw.startsWith("HIDDEN")) {
|
||||
kw = kw.substring(7);
|
||||
}
|
||||
if (kw.startsWith("Protection")) {
|
||||
return true;
|
||||
}
|
||||
return Constant.Keywords.NON_STACKING_LIST.contains(kw);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* isStackingKeyword.
|
||||
@@ -132,25 +108,12 @@ public final class CardUtil {
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean isStackingKeyword(final String keyword) {
|
||||
return !CardUtil.isNonStackingKeyword(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the ideal filename.
|
||||
*
|
||||
* @param cardName
|
||||
* the card name
|
||||
* @param artIndex
|
||||
* the art index
|
||||
* @param artIndexMax
|
||||
* the art index max
|
||||
* @return the string
|
||||
*/
|
||||
public static String buildIdealFilename(final String cardName, final int artIndex, final int artIndexMax) {
|
||||
final String nn = artIndexMax > 1 ? Integer.toString(artIndex + 1) : "";
|
||||
final String mwsCardName = GuiDisplayUtil.cleanStringMWS(cardName);
|
||||
// 3 letter set code with MWS filename format
|
||||
return String.format("%s%s.full.jpg", mwsCardName, nn);
|
||||
String kw = new String(keyword);
|
||||
if (kw.startsWith("HIDDEN")) {
|
||||
kw = kw.substring(7);
|
||||
}
|
||||
|
||||
return !kw.startsWith("Protection") && !Constant.Keywords.NON_STACKING_LIST.contains(kw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,35 +395,6 @@ public final class CardUtil {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the convokable colors.
|
||||
*
|
||||
* @param cardToConvoke
|
||||
* the card to convoke
|
||||
* @param cost
|
||||
* the cost
|
||||
* @return the convokable colors
|
||||
*/
|
||||
public static ArrayList<String> getConvokableColors(final Card cardToConvoke, final ManaCostBeingPaid cost) {
|
||||
final ArrayList<String> usableColors = new ArrayList<String>();
|
||||
|
||||
if (cost.getColorlessManaAmount() > 0) {
|
||||
usableColors.add("colorless");
|
||||
}
|
||||
for (final CardColor col : cardToConvoke.getColor()) {
|
||||
for (final String strCol : col.toStringList()) {
|
||||
if (strCol.equals("colorless")) {
|
||||
continue;
|
||||
}
|
||||
if (cost.toString().contains(MagicColor.toShortString(strCol))) {
|
||||
usableColors.add(strCol.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usableColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the face down characteristic.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@ import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.card.staticability.StaticAbility;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -96,7 +97,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
|
||||
// TODO If Not Mandatory, make sure the card is "good enough"
|
||||
if (c.isCreature()) {
|
||||
final int eval = CardFactoryUtil.evaluateCreature(c);
|
||||
final int eval = ComputerUtilCard.evaluateCreature(c);
|
||||
if (eval < 130) {
|
||||
return null;
|
||||
}
|
||||
@@ -119,7 +120,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CardFactoryUtil.getWorstPermanentAI(list, true, true, true, false);
|
||||
return ComputerUtilCard.getWorstPermanentAI(list, true, true, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,7 +137,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CardFactoryUtil.getBestAI(list);
|
||||
return ComputerUtilCard.getBestAI(list);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +175,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
list = CardLists.getNotType(list, type); // Filter out Basic Lands that have the
|
||||
// same type as the changing type
|
||||
|
||||
final Card c = CardFactoryUtil.getBestAI(list);
|
||||
final Card c = ComputerUtilCard.getBestAI(list);
|
||||
|
||||
// TODO Port over some of the existing code, but rewrite most of it.
|
||||
// Ultimately, these spells need to be used to reduce mana base of a
|
||||
@@ -234,7 +235,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
}
|
||||
});
|
||||
|
||||
final Card c = CardFactoryUtil.getBestAI(prefList);
|
||||
final Card c = ComputerUtilCard.getBestAI(prefList);
|
||||
|
||||
if (c == null) {
|
||||
return chooseLessPreferred(mandatory, list);
|
||||
@@ -333,7 +334,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
});
|
||||
}
|
||||
|
||||
final Card c = CardFactoryUtil.getMostExpensivePermanentAI(betterList);
|
||||
final Card c = ComputerUtilCard.getMostExpensivePermanentAI(betterList);
|
||||
|
||||
// If Mandatory (brought directly into play without casting) gotta
|
||||
// choose something
|
||||
@@ -361,7 +362,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
final Card attachSource) {
|
||||
// AI For choosing a Card to Animate.
|
||||
// TODO Add some more restrictions for Reanimation Auras
|
||||
final Card c = CardFactoryUtil.getBestCreatureAI(list);
|
||||
final Card c = ComputerUtilCard.getBestCreatureAI(list);
|
||||
|
||||
// If Mandatory (brought directly into play without casting) gotta
|
||||
// choose something
|
||||
@@ -406,7 +407,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
chosen = CardFactoryUtil.getBestCreatureAI(creatures);
|
||||
chosen = ComputerUtilCard.getBestCreatureAI(creatures);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,7 +446,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
|
||||
}
|
||||
|
||||
final Card c = CardFactoryUtil.getBestAI(list);
|
||||
final Card c = ComputerUtilCard.getBestAI(list);
|
||||
|
||||
// If Mandatory (brought directly into play without casting) gotta
|
||||
// choose something
|
||||
@@ -537,7 +538,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
if ((prefList == null) || prefList.isEmpty()) {
|
||||
prefList = new ArrayList<Card>(list);
|
||||
} else {
|
||||
c = CardFactoryUtil.getBestAI(prefList);
|
||||
c = ComputerUtilCard.getBestAI(prefList);
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
@@ -559,7 +560,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
});
|
||||
}
|
||||
|
||||
c = CardFactoryUtil.getBestAI(prefList);
|
||||
c = ComputerUtilCard.getBestAI(prefList);
|
||||
|
||||
if (c == null) {
|
||||
return chooseLessPreferred(mandatory, list);
|
||||
@@ -602,7 +603,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
//don't equip a worse creature
|
||||
if (card.isEquipping()) {
|
||||
Card oldTarget = card.getEquipping().get(0);
|
||||
if (CardFactoryUtil.evaluateCreature(oldTarget) > CardFactoryUtil.evaluateCreature(newTarget)) {
|
||||
if (ComputerUtilCard.evaluateCreature(oldTarget) > ComputerUtilCard.evaluateCreature(newTarget)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -723,7 +724,7 @@ public class AttachAi extends SpellAbilityAi {
|
||||
}
|
||||
});
|
||||
|
||||
return CardFactoryUtil.getBestAI(magnetList);
|
||||
return ComputerUtilCard.getBestAI(magnetList);
|
||||
}
|
||||
|
||||
int totToughness = 0;
|
||||
@@ -809,11 +810,11 @@ public class AttachAi extends SpellAbilityAi {
|
||||
return !c.isCreature() || CombatUtil.canAttackNextTurn(c);
|
||||
}
|
||||
});
|
||||
c = CardFactoryUtil.getBestAI(prefList);
|
||||
c = ComputerUtilCard.getBestAI(prefList);
|
||||
} else {
|
||||
// If we grant abilities, we may want to put it on something Weak?
|
||||
// Possibly more defensive?
|
||||
c = CardFactoryUtil.getWorstPermanentAI(prefList, false, false, false, false);
|
||||
c = ComputerUtilCard.getWorstPermanentAI(prefList, false, false, false, false);
|
||||
}
|
||||
|
||||
if (c == null) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.ability.effects.AttachEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostDiscard;
|
||||
import forge.card.cost.CostPart;
|
||||
@@ -29,6 +28,7 @@ import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellPermanent;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilBlock;
|
||||
@@ -507,7 +507,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
}
|
||||
} else {
|
||||
// not urgent, get the largest creature possible
|
||||
card = CardFactoryUtil.getBestCreatureAI(list);
|
||||
card = ComputerUtilCard.getBestCreatureAI(list);
|
||||
}
|
||||
return card;
|
||||
}
|
||||
@@ -730,7 +730,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
|
||||
if (!threatenedTargets.isEmpty()) {
|
||||
// Choose "best" of the remaining to save
|
||||
tgt.addTarget(CardFactoryUtil.getBestAI(threatenedTargets));
|
||||
tgt.addTarget(ComputerUtilCard.getBestAI(threatenedTargets));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -762,7 +762,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
});
|
||||
if (!aiPermanents.isEmpty()) {
|
||||
// Choose "best" of the remaining to save
|
||||
tgt.addTarget(CardFactoryUtil.getBestAI(aiPermanents));
|
||||
tgt.addTarget(ComputerUtilCard.getBestAI(aiPermanents));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -839,15 +839,15 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
Card choice = null;
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
final Card mostExpensive = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, false);
|
||||
final Card mostExpensive = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, false);
|
||||
if (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield)) {
|
||||
if (mostExpensive.isCreature()) {
|
||||
// if a creature is most expensive take the best one
|
||||
if (destination.equals(ZoneType.Exile)) {
|
||||
// If Exiling things, don't give bonus to Tokens
|
||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getBestCreatureToBounceAI(list);
|
||||
choice = ComputerUtilCard.getBestCreatureToBounceAI(list);
|
||||
}
|
||||
} else {
|
||||
choice = mostExpensive;
|
||||
@@ -870,7 +870,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
} else {
|
||||
// Get the best card in there.
|
||||
System.out.println("No creature and lots of life, finding something good.");
|
||||
choice = CardFactoryUtil.getBestAI(nonLands);
|
||||
choice = ComputerUtilCard.getBestAI(nonLands);
|
||||
}
|
||||
}
|
||||
if (choice == null) {
|
||||
@@ -879,7 +879,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
choice = list.get(0);
|
||||
}
|
||||
} else {
|
||||
choice = CardFactoryUtil.getBestAI(list);
|
||||
choice = ComputerUtilCard.getBestAI(list);
|
||||
}
|
||||
}
|
||||
if (choice == null) { // can't find anything left
|
||||
@@ -957,12 +957,12 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
Card choice = null;
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
if (CardFactoryUtil.getMostExpensivePermanentAI(list, sa, false).isCreature()
|
||||
if (ComputerUtilCard.getMostExpensivePermanentAI(list, sa, false).isCreature()
|
||||
&& (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield))) {
|
||||
// if a creature is most expensive take the best
|
||||
choice = CardFactoryUtil.getBestCreatureToBounceAI(list);
|
||||
choice = ComputerUtilCard.getBestCreatureToBounceAI(list);
|
||||
} else if (destination.equals(ZoneType.Battlefield) || origin.equals(ZoneType.Battlefield)) {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, false);
|
||||
} else if (destination.equals(ZoneType.Hand) || destination.equals(ZoneType.Library)) {
|
||||
List<Card> nonLands = CardLists.getNotType(list, "Land");
|
||||
// Prefer to pull a creature, generally more useful for AI.
|
||||
@@ -981,7 +981,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
} else {
|
||||
// Get the best card in there.
|
||||
System.out.println("No creature and lots of life, finding something good.");
|
||||
choice = CardFactoryUtil.getBestAI(nonLands);
|
||||
choice = ComputerUtilCard.getBestAI(nonLands);
|
||||
}
|
||||
}
|
||||
if (choice == null) {
|
||||
@@ -990,7 +990,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
choice = list.get(0);
|
||||
}
|
||||
} else {
|
||||
choice = CardFactoryUtil.getBestAI(list);
|
||||
choice = ComputerUtilCard.getBestAI(list);
|
||||
}
|
||||
}
|
||||
if (choice == null) { // can't find anything left
|
||||
@@ -1168,9 +1168,9 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
if (ZoneType.Exile.equals(destination) || origin.contains(ZoneType.Battlefield)) {
|
||||
// Exiling or bouncing stuff
|
||||
if (player.isOpponentOf(ai)) {
|
||||
c = CardFactoryUtil.getBestAI(fetchList);
|
||||
c = ComputerUtilCard.getBestAI(fetchList);
|
||||
} else {
|
||||
c = CardFactoryUtil.getWorstAI(fetchList);
|
||||
c = ComputerUtilCard.getWorstAI(fetchList);
|
||||
}
|
||||
} else if (origin.contains(ZoneType.Library)
|
||||
&& (type.contains("Basic") || areAllBasics(type))) {
|
||||
@@ -1179,9 +1179,9 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
c = chooseCreature(ai, fetchList);
|
||||
} else if (ZoneType.Battlefield.equals(destination) || ZoneType.Graveyard.equals(destination)) {
|
||||
if (!activator.equals(ai) && sa.hasParam("GainControl")) {
|
||||
c = CardFactoryUtil.getWorstAI(fetchList);
|
||||
c = ComputerUtilCard.getWorstAI(fetchList);
|
||||
} else {
|
||||
c = CardFactoryUtil.getBestAI(fetchList);
|
||||
c = ComputerUtilCard.getBestAI(fetchList);
|
||||
}
|
||||
} else {
|
||||
// Don't fetch another tutor with the same name
|
||||
@@ -1222,7 +1222,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
} else {
|
||||
// Get the best card in there.
|
||||
System.out.println("No creature and lots of life, finding something good.");
|
||||
c = CardFactoryUtil.getBestAI(fetchList);
|
||||
c = ComputerUtilCard.getBestAI(fetchList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1263,7 +1263,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
||||
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), c.getController(), c);
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
final Card attachedTo = CardFactoryUtil.getBestAI(list);
|
||||
final Card attachedTo = ComputerUtilCard.getBestAI(list);
|
||||
if (c.isEnchanting()) {
|
||||
// If this Card is already Enchanting something, need
|
||||
// to unenchant it, then clear out the commands
|
||||
|
||||
@@ -8,10 +8,10 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.AIPlayer;
|
||||
@@ -89,13 +89,13 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
computerType.clear();
|
||||
}
|
||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||
if ((CardFactoryUtil.evaluateCreatureList(computerType) + 200) >= CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluateCreatureList(computerType) + 200) >= ComputerUtilCard
|
||||
.evaluateCreatureList(humanType)) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are more valuable
|
||||
else if ((CardFactoryUtil.evaluatePermanentList(computerType) + 3) >= CardFactoryUtil
|
||||
else if ((ComputerUtilCard.evaluatePermanentList(computerType) + 3) >= ComputerUtilCard
|
||||
.evaluatePermanentList(humanType)) {
|
||||
return false;
|
||||
}
|
||||
@@ -127,26 +127,26 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
if (sa.getParam("GainControl") != null) {
|
||||
// Check if the cards are valuable enough
|
||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||
if ((CardFactoryUtil.evaluateCreatureList(computerType) + CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluateCreatureList(computerType) + ComputerUtilCard
|
||||
.evaluateCreatureList(humanType)) < 400) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are less valuable
|
||||
else if ((CardFactoryUtil.evaluatePermanentList(computerType) + CardFactoryUtil
|
||||
else if ((ComputerUtilCard.evaluatePermanentList(computerType) + ComputerUtilCard
|
||||
.evaluatePermanentList(humanType)) < 6) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// don't activate if human gets more back than AI does
|
||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||
if (CardFactoryUtil.evaluateCreatureList(computerType) <= (CardFactoryUtil
|
||||
if (ComputerUtilCard.evaluateCreatureList(computerType) <= (ComputerUtilCard
|
||||
.evaluateCreatureList(humanType) + 100)) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are less valuable
|
||||
else if (CardFactoryUtil.evaluatePermanentList(computerType) <= (CardFactoryUtil
|
||||
else if (ComputerUtilCard.evaluatePermanentList(computerType) <= (ComputerUtilCard
|
||||
.evaluatePermanentList(humanType) + 2)) {
|
||||
return false;
|
||||
}
|
||||
@@ -206,13 +206,13 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
// if only creatures are affected evaluate both lists and pass only
|
||||
// if human creatures are more valuable
|
||||
if ((CardLists.getNotType(humanType, "Creature").isEmpty()) && (CardLists.getNotType(computerType, "Creature").isEmpty())) {
|
||||
if (CardFactoryUtil.evaluateCreatureList(computerType) >= CardFactoryUtil
|
||||
if (ComputerUtilCard.evaluateCreatureList(computerType) >= ComputerUtilCard
|
||||
.evaluateCreatureList(humanType)) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are more valuable
|
||||
else if (CardFactoryUtil.evaluatePermanentList(computerType) >= CardFactoryUtil
|
||||
else if (ComputerUtilCard.evaluatePermanentList(computerType) >= ComputerUtilCard
|
||||
.evaluatePermanentList(humanType)) {
|
||||
return false;
|
||||
}
|
||||
@@ -240,26 +240,26 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
|
||||
if (sa.getParam("GainControl") != null) {
|
||||
// Check if the cards are valuable enough
|
||||
if ((CardLists.getNotType(humanType, "Creature").size() == 0) && (CardLists.getNotType(computerType, "Creature").size() == 0)) {
|
||||
if ((CardFactoryUtil.evaluateCreatureList(computerType) + CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluateCreatureList(computerType) + ComputerUtilCard
|
||||
.evaluateCreatureList(humanType)) < 1) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are less valuable
|
||||
else if ((CardFactoryUtil.evaluatePermanentList(computerType) + CardFactoryUtil
|
||||
else if ((ComputerUtilCard.evaluatePermanentList(computerType) + ComputerUtilCard
|
||||
.evaluatePermanentList(humanType)) < 1) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// don't activate if human gets more back than AI does
|
||||
if ((CardLists.getNotType(humanType, "Creature").isEmpty()) && (CardLists.getNotType(computerType, "Creature").isEmpty())) {
|
||||
if (CardFactoryUtil.evaluateCreatureList(computerType) <= CardFactoryUtil
|
||||
if (ComputerUtilCard.evaluateCreatureList(computerType) <= ComputerUtilCard
|
||||
.evaluateCreatureList(humanType)) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are less valuable
|
||||
else if (CardFactoryUtil.evaluatePermanentList(computerType) <= CardFactoryUtil
|
||||
else if (ComputerUtilCard.evaluatePermanentList(computerType) <= ComputerUtilCard
|
||||
.evaluatePermanentList(humanType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.MyRandom;
|
||||
@@ -39,19 +39,19 @@ public class ControlExchangeAi extends SpellAbilityAi {
|
||||
return !vars.containsKey("RemAIDeck") && c.canBeTargetedBy(sa);
|
||||
}
|
||||
});
|
||||
object1 = CardFactoryUtil.getBestAI(list);
|
||||
object1 = ComputerUtilCard.getBestAI(list);
|
||||
if (sa.hasParam("Defined")) {
|
||||
object2 = AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa).get(0);
|
||||
} else if (tgt.getMinTargets(sa.getSourceCard(), sa) > 1) {
|
||||
List<Card> list2 = ai.getCardsIn(ZoneType.Battlefield);
|
||||
list2 = CardLists.getValidCards(list2, tgt.getValidTgts(), ai, sa.getSourceCard());
|
||||
object2 = CardFactoryUtil.getWorstAI(list2);
|
||||
object2 = ComputerUtilCard.getWorstAI(list2);
|
||||
tgt.addTarget(object2);
|
||||
}
|
||||
if (object1 == null || object2 == null) {
|
||||
return false;
|
||||
}
|
||||
if (CardFactoryUtil.evaluateCreature(object1) > CardFactoryUtil.evaluateCreature(object2) + 40) {
|
||||
if (ComputerUtilCard.evaluateCreature(object1) > ComputerUtilCard.evaluateCreature(object2) + 40) {
|
||||
tgt.addTarget(object1);
|
||||
return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
@@ -139,15 +139,15 @@ public class ControlGainAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (hasCreature) {
|
||||
t = CardFactoryUtil.getBestCreatureAI(list);
|
||||
t = ComputerUtilCard.getBestCreatureAI(list);
|
||||
} else if (hasArtifact) {
|
||||
t = CardFactoryUtil.getBestArtifactAI(list);
|
||||
t = ComputerUtilCard.getBestArtifactAI(list);
|
||||
} else if (hasLand) {
|
||||
t = CardFactoryUtil.getBestLandAI(list);
|
||||
t = ComputerUtilCard.getBestLandAI(list);
|
||||
} else if (hasEnchantment) {
|
||||
t = CardFactoryUtil.getBestEnchantmentAI(list, sa, true);
|
||||
t = ComputerUtilCard.getBestEnchantmentAI(list, sa, true);
|
||||
} else {
|
||||
t = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, true);
|
||||
t = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true);
|
||||
}
|
||||
|
||||
tgt.addTarget(t);
|
||||
|
||||
@@ -11,9 +11,9 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -82,9 +82,9 @@ public class CopyPermanentAi extends SpellAbilityAi {
|
||||
|
||||
Card choice;
|
||||
if (!CardLists.filter(list, Presets.CREATURES).isEmpty()) {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, true);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true);
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
|
||||
@@ -9,6 +9,7 @@ import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.card.spellability.TargetSelection;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.player.AIPlayer;
|
||||
@@ -62,7 +63,7 @@ public class CounterAi extends SpellAbilityAi {
|
||||
|
||||
if (unlessCost != null && !unlessCost.endsWith(">")) {
|
||||
// Is this Usable Mana Sources? Or Total Available Mana?
|
||||
final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent());
|
||||
final int usableManaSources = ComputerUtilCard.getUsableManaSources(ai.getOpponent());
|
||||
int toPay = 0;
|
||||
boolean setPayX = false;
|
||||
if (unlessCost.equals("X") && source.getSVar(unlessCost).equals("Count$xPaid")) {
|
||||
@@ -130,7 +131,7 @@ public class CounterAi extends SpellAbilityAi {
|
||||
final Card source = sa.getSourceCard();
|
||||
if (unlessCost != null) {
|
||||
// Is this Usable Mana Sources? Or Total Available Mana?
|
||||
final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent());
|
||||
final int usableManaSources = ComputerUtilCard.getUsableManaSources(ai.getOpponent());
|
||||
int toPay = 0;
|
||||
boolean setPayX = false;
|
||||
if (unlessCost.equals("X") && source.getSVar(unlessCost).equals("Count$xPaid")) {
|
||||
|
||||
@@ -25,7 +25,7 @@ import forge.Card;
|
||||
|
||||
import forge.CardLists;
|
||||
import forge.CounterType;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
|
||||
|
||||
/**
|
||||
@@ -63,13 +63,13 @@ public abstract class CountersAi {
|
||||
}
|
||||
});
|
||||
if (killable.size() > 0) {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(killable);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(killable);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||
}
|
||||
} else {
|
||||
// improve random choice here
|
||||
choice = CardFactoryUtil.getRandomCard(list);
|
||||
choice = ComputerUtilCard.getRandomCard(list);
|
||||
}
|
||||
return choice;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public abstract class CountersAi {
|
||||
public static Card chooseBoonTarget(final List<Card> list, final String type) {
|
||||
Card choice;
|
||||
if (type.equals("P1P1")) {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||
} else if (type.equals("DIVINITY")) {
|
||||
final List<Card> boon = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
@@ -96,12 +96,12 @@ public abstract class CountersAi {
|
||||
return c.getCounters(CounterType.DIVINITY) == 0;
|
||||
}
|
||||
});
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(boon, null, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(boon, null, false);
|
||||
} else {
|
||||
// The AI really should put counters on cards that can use it.
|
||||
// Charge counters on things with Charge abilities, etc. Expand
|
||||
// these above
|
||||
choice = CardFactoryUtil.getRandomCard(list);
|
||||
choice = ComputerUtilCard.getRandomCard(list);
|
||||
}
|
||||
return choice;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ import forge.CardLists;
|
||||
import forge.CounterType;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -103,9 +103,9 @@ public class CountersMoveAi extends SpellAbilityAi {
|
||||
|
||||
else {
|
||||
if (type.equals("M1M1")) {
|
||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
||||
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getRandomCard(list);
|
||||
choice = ComputerUtilCard.getRandomCard(list);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -115,9 +115,9 @@ public class CountersMoveAi extends SpellAbilityAi {
|
||||
|
||||
else {
|
||||
if (type.equals("P1P1")) {
|
||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
||||
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getRandomCard(list);
|
||||
choice = ComputerUtilCard.getRandomCard(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ import forge.CounterType;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -279,9 +279,9 @@ public class CountersPutAi extends SpellAbilityAi {
|
||||
|
||||
else {
|
||||
if (type.equals("M1M1")) {
|
||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
||||
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getRandomCard(list);
|
||||
choice = ComputerUtilCard.getRandomCard(list);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -291,9 +291,9 @@ public class CountersPutAi extends SpellAbilityAi {
|
||||
|
||||
else {
|
||||
if (type.equals("P1P1")) {
|
||||
choice = CardFactoryUtil.getWorstCreatureAI(list);
|
||||
choice = ComputerUtilCard.getWorstCreatureAI(list);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getRandomCard(list);
|
||||
choice = ComputerUtilCard.getRandomCard(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
@@ -96,7 +96,7 @@ public class DamageAllAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
// evaluate both lists and pass only if human creatures are more valuable
|
||||
if ((CardFactoryUtil.evaluateCreatureList(computerList) + minGain) >= CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluateCreatureList(computerList) + minGain) >= ComputerUtilCard
|
||||
.evaluateCreatureList(humanList)) {
|
||||
return false;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ public class DamageAllAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!computerList.isEmpty() && CardFactoryUtil.evaluateCreatureList(computerList) > CardFactoryUtil
|
||||
if (!computerList.isEmpty() && ComputerUtilCard.evaluateCreatureList(computerList) > ComputerUtilCard
|
||||
.evaluateCreatureList(humanList)) {
|
||||
return false;
|
||||
}
|
||||
@@ -233,7 +233,7 @@ public class DamageAllAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!computerList.isEmpty() && CardFactoryUtil.evaluateCreatureList(computerList) + 50 >= CardFactoryUtil
|
||||
if (!computerList.isEmpty() && ComputerUtilCard.evaluateCreatureList(computerList) + 50 >= ComputerUtilCard
|
||||
.evaluateCreatureList(humanList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.card.spellability.TargetSelection;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
@@ -165,7 +165,7 @@ public class DamageDealAi extends DamageAiBase {
|
||||
|
||||
Card targetCard;
|
||||
if (pl.isOpponentOf(ai) && (killables.size() > 0)) {
|
||||
targetCard = CardFactoryUtil.getBestCreatureAI(killables);
|
||||
targetCard = ComputerUtilCard.getBestCreatureAI(killables);
|
||||
|
||||
return targetCard;
|
||||
}
|
||||
@@ -176,9 +176,9 @@ public class DamageDealAi extends DamageAiBase {
|
||||
|
||||
if (hPlay.size() > 0) {
|
||||
if (pl.isOpponentOf(ai)) {
|
||||
targetCard = CardFactoryUtil.getBestCreatureAI(hPlay);
|
||||
targetCard = ComputerUtilCard.getBestCreatureAI(hPlay);
|
||||
} else {
|
||||
targetCard = CardFactoryUtil.getWorstCreatureAI(hPlay);
|
||||
targetCard = ComputerUtilCard.getWorstCreatureAI(hPlay);
|
||||
}
|
||||
|
||||
return targetCard;
|
||||
|
||||
@@ -9,11 +9,11 @@ import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -113,7 +113,7 @@ public class DamagePreventAi extends SpellAbilityAi {
|
||||
|
||||
if (!threatenedTargets.isEmpty()) {
|
||||
// Choose "best" of the remaining to save
|
||||
tgt.addTarget(CardFactoryUtil.getBestCreatureAI(threatenedTargets));
|
||||
tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets));
|
||||
chance = true;
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ public class DamagePreventAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
|
||||
tgt.addTarget(CardFactoryUtil.getCheapestPermanentAI(targetables, sa, true));
|
||||
tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityRestriction;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -164,7 +164,7 @@ public class DebuffAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
t = CardFactoryUtil.getBestCreatureAI(list);
|
||||
t = ComputerUtilCard.getBestCreatureAI(list);
|
||||
tgt.addTarget(t);
|
||||
list.remove(t);
|
||||
}
|
||||
@@ -242,9 +242,9 @@ public class DebuffAi extends SpellAbilityAi {
|
||||
|
||||
Card c;
|
||||
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getBestCreatureAI(pref);
|
||||
c = ComputerUtilCard.getBestCreatureAI(pref);
|
||||
} else {
|
||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref, sa, true);
|
||||
c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
|
||||
}
|
||||
|
||||
pref.remove(c);
|
||||
@@ -261,9 +261,9 @@ public class DebuffAi extends SpellAbilityAi {
|
||||
// keyword
|
||||
Card c;
|
||||
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getWorstCreatureAI(forced);
|
||||
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
||||
} else {
|
||||
c = CardFactoryUtil.getCheapestPermanentAI(forced, sa, true);
|
||||
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
|
||||
}
|
||||
|
||||
forced.remove(c);
|
||||
|
||||
@@ -12,13 +12,13 @@ import forge.CounterType;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostPart;
|
||||
import forge.card.cost.CostSacrifice;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
@@ -130,11 +130,11 @@ public class DestroyAi extends SpellAbilityAi {
|
||||
Card choice = null;
|
||||
// If the targets are only of one type, take the best
|
||||
if (CardLists.getNotType(list, "Creature").isEmpty()) {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(list);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(list);
|
||||
} else if (CardLists.getNotType(list, "Land").isEmpty()) {
|
||||
choice = CardFactoryUtil.getBestLandAI(list);
|
||||
choice = ComputerUtilCard.getBestLandAI(list);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(list, sa, true);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(list, sa, true);
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
@@ -218,11 +218,11 @@ public class DestroyAi extends SpellAbilityAi {
|
||||
} else {
|
||||
Card c;
|
||||
if (CardLists.getNotType(preferred, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getBestCreatureAI(preferred);
|
||||
c = ComputerUtilCard.getBestCreatureAI(preferred);
|
||||
} else if (CardLists.getNotType(preferred, "Land").size() == 0) {
|
||||
c = CardFactoryUtil.getBestLandAI(preferred);
|
||||
c = ComputerUtilCard.getBestLandAI(preferred);
|
||||
} else {
|
||||
c = CardFactoryUtil.getMostExpensivePermanentAI(preferred, sa, false);
|
||||
c = ComputerUtilCard.getMostExpensivePermanentAI(preferred, sa, false);
|
||||
}
|
||||
tgt.addTarget(c);
|
||||
preferred.remove(c);
|
||||
@@ -235,9 +235,9 @@ public class DestroyAi extends SpellAbilityAi {
|
||||
} else {
|
||||
Card c;
|
||||
if (CardLists.getNotType(list, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getWorstCreatureAI(list);
|
||||
c = ComputerUtilCard.getWorstCreatureAI(list);
|
||||
} else {
|
||||
c = CardFactoryUtil.getCheapestPermanentAI(list, sa, false);
|
||||
c = ComputerUtilCard.getCheapestPermanentAI(list, sa, false);
|
||||
}
|
||||
tgt.addTarget(c);
|
||||
list.remove(c);
|
||||
|
||||
@@ -8,10 +8,10 @@ import com.google.common.base.Predicate;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.player.AIPlayer;
|
||||
@@ -60,13 +60,13 @@ public class DestroyAllAi extends SpellAbilityAi {
|
||||
// if only creatures are affected evaluate both lists and pass only if
|
||||
// human creatures are more valuable
|
||||
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
||||
if (CardFactoryUtil.evaluateCreatureList(computerlist) >= CardFactoryUtil.evaluateCreatureList(humanlist)
|
||||
if (ComputerUtilCard.evaluateCreatureList(computerlist) >= ComputerUtilCard.evaluateCreatureList(humanlist)
|
||||
&& !computerlist.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are more valuable
|
||||
else if (CardFactoryUtil.evaluatePermanentList(computerlist) >= CardFactoryUtil.evaluatePermanentList(humanlist)) {
|
||||
else if (ComputerUtilCard.evaluatePermanentList(computerlist) >= ComputerUtilCard.evaluatePermanentList(humanlist)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -127,19 +127,19 @@ public class DestroyAllAi extends SpellAbilityAi {
|
||||
// if only creatures are affected evaluate both lists and pass only if
|
||||
// human creatures are more valuable
|
||||
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
||||
if ((CardFactoryUtil.evaluateCreatureList(computerlist) + 200) >= CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluateCreatureList(computerlist) + 200) >= ComputerUtilCard
|
||||
.evaluateCreatureList(humanlist)) {
|
||||
return false;
|
||||
}
|
||||
} // only lands involved
|
||||
else if ((CardLists.getNotType(humanlist, "Land").size() == 0) && (CardLists.getNotType(computerlist, "Land").size() == 0)) {
|
||||
if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 1) >= CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 1) >= ComputerUtilCard
|
||||
.evaluatePermanentList(humanlist)) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are more valuable
|
||||
else if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 3) >= CardFactoryUtil
|
||||
else if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 3) >= ComputerUtilCard
|
||||
.evaluatePermanentList(humanlist)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -61,7 +61,7 @@ public class EffectAi extends SpellAbilityAi {
|
||||
List<Card> list = game.getCombat().getAttackerList();
|
||||
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
|
||||
list = CardLists.getTargetableCards(list, sa);
|
||||
Card target = CardFactoryUtil.getBestCreatureAI(list);
|
||||
Card target = ComputerUtilCard.getBestCreatureAI(list);
|
||||
if (target == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -86,7 +86,7 @@ public class MustBlockAi extends SpellAbilityAi {
|
||||
if (list.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
final Card blocker = CardFactoryUtil.getBestCreatureAI(list);
|
||||
final Card blocker = ComputerUtilCard.getBestCreatureAI(list);
|
||||
if (blocker == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -62,7 +62,7 @@ public class PlayAi extends SpellAbilityAi {
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
tgt.addTarget(CardFactoryUtil.getBestAI(cards));
|
||||
tgt.addTarget(ComputerUtilCard.getBestAI(cards));
|
||||
} else if (!sa.hasParam("Valid")) {
|
||||
cards = new ArrayList<Card>(AbilityUtils.getDefinedCards(sa.getSourceCard(), sa.getParam("Defined"), sa));
|
||||
if (cards.isEmpty()) {
|
||||
|
||||
@@ -11,11 +11,11 @@ import forge.Constant;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -86,7 +86,7 @@ public class ProtectAi extends SpellAbilityAi {
|
||||
// will the creature attack (only relevant for sorcery speed)?
|
||||
if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||
&& game.getPhaseHandler().isPlayerTurn(ai)
|
||||
&& CardFactoryUtil.doesCreatureAttackAI(ai, c)) {
|
||||
&& ComputerUtilCard.doesCreatureAttackAI(ai, c)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ public class ProtectAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
t = CardFactoryUtil.getBestCreatureAI(list);
|
||||
t = ComputerUtilCard.getBestCreatureAI(list);
|
||||
tgt.addTarget(t);
|
||||
list.remove(t);
|
||||
}
|
||||
@@ -290,9 +290,9 @@ public class ProtectAi extends SpellAbilityAi {
|
||||
|
||||
Card c;
|
||||
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getBestCreatureAI(pref);
|
||||
c = ComputerUtilCard.getBestCreatureAI(pref);
|
||||
} else {
|
||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref, sa, true);
|
||||
c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
|
||||
}
|
||||
|
||||
pref.remove(c);
|
||||
@@ -307,9 +307,9 @@ public class ProtectAi extends SpellAbilityAi {
|
||||
|
||||
Card c;
|
||||
if (CardLists.getNotType(pref2, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getBestCreatureAI(pref2);
|
||||
c = ComputerUtilCard.getBestCreatureAI(pref2);
|
||||
} else {
|
||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref2, sa, true);
|
||||
c = ComputerUtilCard.getMostExpensivePermanentAI(pref2, sa, true);
|
||||
}
|
||||
|
||||
pref2.remove(c);
|
||||
@@ -324,9 +324,9 @@ public class ProtectAi extends SpellAbilityAi {
|
||||
|
||||
Card c;
|
||||
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getWorstCreatureAI(forced);
|
||||
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
||||
} else {
|
||||
c = CardFactoryUtil.getCheapestPermanentAI(forced, sa, true);
|
||||
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
|
||||
}
|
||||
|
||||
forced.remove(c);
|
||||
|
||||
@@ -11,13 +11,13 @@ import forge.Singletons;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityRestriction;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -259,7 +259,7 @@ public class PumpAi extends PumpAiBase {
|
||||
}
|
||||
}
|
||||
|
||||
t = CardFactoryUtil.getBestAI(list);
|
||||
t = ComputerUtilCard.getBestAI(list);
|
||||
tgt.addTarget(t);
|
||||
list.remove(t);
|
||||
}
|
||||
@@ -303,9 +303,9 @@ public class PumpAi extends PumpAiBase {
|
||||
|
||||
Card c;
|
||||
if (CardLists.getNotType(pref, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getBestCreatureAI(pref);
|
||||
c = ComputerUtilCard.getBestCreatureAI(pref);
|
||||
} else {
|
||||
c = CardFactoryUtil.getMostExpensivePermanentAI(pref, sa, true);
|
||||
c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
|
||||
}
|
||||
|
||||
pref.remove(c);
|
||||
@@ -320,9 +320,9 @@ public class PumpAi extends PumpAiBase {
|
||||
|
||||
Card c;
|
||||
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getWorstCreatureAI(forced);
|
||||
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
||||
} else {
|
||||
c = CardFactoryUtil.getCheapestPermanentAI(forced, sa, true);
|
||||
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
|
||||
}
|
||||
|
||||
forced.remove(c);
|
||||
|
||||
@@ -13,10 +13,10 @@ import forge.CardPredicates;
|
||||
import forge.CardUtil;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.phase.Combat;
|
||||
import forge.game.phase.CombatUtil;
|
||||
@@ -403,7 +403,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
|
||||
&& phase.isPlayerTurn(ai)
|
||||
&& SpellAbilityAi.isSorcerySpeed(sa)
|
||||
&& attack > 0
|
||||
&& CardFactoryUtil.doesCreatureAttackAI(ai, c)) {
|
||||
&& ComputerUtilCard.doesCreatureAttackAI(ai, c)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.phase.CombatUtil;
|
||||
@@ -106,7 +106,7 @@ public class PumpAllAi extends PumpAiBase {
|
||||
|
||||
// evaluate both lists and pass only if human creatures are more
|
||||
// valuable
|
||||
if ((CardFactoryUtil.evaluateCreatureList(comp) + 200) >= CardFactoryUtil.evaluateCreatureList(human)) {
|
||||
if ((ComputerUtilCard.evaluateCreatureList(comp) + 200) >= ComputerUtilCard.evaluateCreatureList(human)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -27,11 +27,11 @@ import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -132,7 +132,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
|
||||
if (!threatenedTargets.isEmpty()) {
|
||||
// Choose "best" of the remaining to regenerate
|
||||
tgt.addTarget(CardFactoryUtil.getBestCreatureAI(threatenedTargets));
|
||||
tgt.addTarget(ComputerUtilCard.getBestCreatureAI(threatenedTargets));
|
||||
chance = true;
|
||||
}
|
||||
} else {
|
||||
@@ -225,7 +225,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
tgt.addTarget(CardFactoryUtil.getCheapestPermanentAI(targetables, sa, true));
|
||||
tgt.addTarget(ComputerUtilCard.getCheapestPermanentAI(targetables, sa, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
@@ -128,7 +128,7 @@ public class SacrificeAi extends SpellAbilityAi {
|
||||
List<Card> computerList =
|
||||
CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getSourceCard());
|
||||
for (Card c : computerList) {
|
||||
if (!c.getSVar("SacMe").equals("") || CardFactoryUtil.evaluateCreature(c) <= 135) {
|
||||
if (!c.getSVar("SacMe").equals("") || ComputerUtilCard.evaluateCreature(c) <= 135) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import java.util.Random;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.player.AIPlayer;
|
||||
@@ -55,19 +55,19 @@ public class SacrificeAllAi extends SpellAbilityAi {
|
||||
// if only creatures are affected evaluate both lists and pass only if
|
||||
// human creatures are more valuable
|
||||
if ((CardLists.getNotType(humanlist, "Creature").size() == 0) && (CardLists.getNotType(computerlist, "Creature").size() == 0)) {
|
||||
if ((CardFactoryUtil.evaluateCreatureList(computerlist) + 200) >= CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluateCreatureList(computerlist) + 200) >= ComputerUtilCard
|
||||
.evaluateCreatureList(humanlist)) {
|
||||
return false;
|
||||
}
|
||||
} // only lands involved
|
||||
else if ((CardLists.getNotType(humanlist, "Land").size() == 0) && (CardLists.getNotType(computerlist, "Land").size() == 0)) {
|
||||
if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 1) >= CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 1) >= ComputerUtilCard
|
||||
.evaluatePermanentList(humanlist)) {
|
||||
return false;
|
||||
}
|
||||
} // otherwise evaluate both lists by CMC and pass only if human
|
||||
// permanents are more valuable
|
||||
else if ((CardFactoryUtil.evaluatePermanentList(computerlist) + 3) >= CardFactoryUtil
|
||||
else if ((ComputerUtilCard.evaluatePermanentList(computerlist) + 3) >= ComputerUtilCard
|
||||
.evaluatePermanentList(humanlist)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import forge.CardPredicates;
|
||||
import forge.Singletons;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -69,9 +69,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
|
||||
if (CardLists.getNotType(tapList, "Creature").size() == 0) {
|
||||
// if only creatures take the best
|
||||
choice = CardFactoryUtil.getBestCreatureAI(tapList);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(tapList);
|
||||
} else {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
@@ -179,9 +179,9 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
Predicate<Card> findBlockers = CardPredicates.possibleBlockerForAtLeastOne(attackers);
|
||||
List<Card> creatureList = CardLists.filter(tapList, findBlockers);
|
||||
if (!attackers.isEmpty() && !creatureList.isEmpty()) {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(creatureList);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(creatureList);
|
||||
} else if (sa.isTrigger()) {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
}
|
||||
|
||||
} else if (phase.isPlayerTurn(opp)
|
||||
@@ -194,12 +194,12 @@ public abstract class TapAiBase extends SpellAbilityAi {
|
||||
return c.isCreature() && CombatUtil.canAttack(c, opp);
|
||||
}
|
||||
});
|
||||
choice = CardFactoryUtil.getBestCreatureAI(creatureList);
|
||||
choice = ComputerUtilCard.getBestCreatureAI(creatureList);
|
||||
} else { // no creatures available
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
}
|
||||
} else {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
|
||||
@@ -7,10 +7,10 @@ import forge.Card;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.AIPlayer;
|
||||
@@ -84,7 +84,7 @@ public class UnattachAllAi extends SpellAbilityAi {
|
||||
//don't equip a worse creature
|
||||
if (card.isEquipping()) {
|
||||
Card oldTarget = card.getEquipping().get(0);
|
||||
if (CardFactoryUtil.evaluateCreature(oldTarget) > CardFactoryUtil.evaluateCreature(newTarget)) {
|
||||
if (ComputerUtilCard.evaluateCreature(oldTarget) > ComputerUtilCard.evaluateCreature(newTarget)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import forge.Singletons;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
@@ -148,14 +148,14 @@ public class UntapAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (CardLists.getNotType(untapList, "Creature").size() == 0) {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(untapList); // if
|
||||
choice = ComputerUtilCard.getBestCreatureAI(untapList); // if
|
||||
// only
|
||||
// creatures
|
||||
// take
|
||||
// the
|
||||
// best
|
||||
} else {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(untapList, sa, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(untapList, sa, false);
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
@@ -267,13 +267,13 @@ public class UntapAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (CardLists.getNotType(tapList, "Creature").size() == 0) {
|
||||
choice = CardFactoryUtil.getBestCreatureAI(tapList); // if only
|
||||
choice = ComputerUtilCard.getBestCreatureAI(tapList); // if only
|
||||
// creatures
|
||||
// take
|
||||
// the
|
||||
// best
|
||||
} else {
|
||||
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
choice = ComputerUtilCard.getMostExpensivePermanentAI(tapList, sa, false);
|
||||
}
|
||||
|
||||
if (choice == null) { // can't find anything left
|
||||
|
||||
@@ -13,11 +13,11 @@ import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.ability.ai.ChangeZoneAi;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityStackInstance;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -403,7 +403,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
attachedTo = list.get(0);
|
||||
}
|
||||
} else { // AI player
|
||||
attachedTo = CardFactoryUtil.getBestAI(list);
|
||||
attachedTo = ComputerUtilCard.getBestAI(list);
|
||||
}
|
||||
if (tgtC.isAura()) {
|
||||
if (tgtC.isEnchanting()) {
|
||||
|
||||
@@ -74,52 +74,19 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
||||
for (final Player p : tgtPlayers) {
|
||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
for (int i = 0; i < validAmount; i++) {
|
||||
if (p.isHuman()) {
|
||||
final String choiceTitle = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ";
|
||||
Card o;
|
||||
if (sa.hasParam("AtRandom")) {
|
||||
o = Aggregates.random(choices);
|
||||
} else if (sa.hasParam("Mandatory")) {
|
||||
o = GuiChoose.one(choiceTitle, choices);
|
||||
} else {
|
||||
o = GuiChoose.oneOrNone(choiceTitle, choices);
|
||||
}
|
||||
if (o != null) {
|
||||
chosen.add(o);
|
||||
choices.remove(o);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else { // Computer
|
||||
String logic = sa.getParam("AILogic");
|
||||
Card choice = null;
|
||||
if (logic == null) {
|
||||
// Base Logic is choose "best"
|
||||
choice = CardFactoryUtil.getBestAI(choices);
|
||||
} else if ("WorstCard".equals(logic)) {
|
||||
choice = CardFactoryUtil.getWorstAI(choices);
|
||||
} else if (logic.equals("BestBlocker")) {
|
||||
if (!CardLists.filter(choices, Presets.UNTAPPED).isEmpty()) {
|
||||
choices = CardLists.filter(choices, Presets.UNTAPPED);
|
||||
}
|
||||
choice = CardFactoryUtil.getBestCreatureAI(choices);
|
||||
} else if (logic.equals("Clone")) {
|
||||
if (!CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
||||
choices = CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
||||
}
|
||||
choice = CardFactoryUtil.getBestAI(choices);
|
||||
} else if (logic.equals("Untap")) {
|
||||
if (!CardLists.getValidCards(choices, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host).isEmpty()) {
|
||||
choices = CardLists.getValidCards(choices, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host);
|
||||
}
|
||||
choice = CardFactoryUtil.getBestAI(choices);
|
||||
}
|
||||
if (choice != null) {
|
||||
chosen.add(choice);
|
||||
choices.remove(choice);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
Card c;
|
||||
if (sa.hasParam("AtRandom")) {
|
||||
c = Aggregates.random(choices);
|
||||
} else {
|
||||
c = p.getController().chooseSingleCardForEffect(choices, sa, sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card ", !sa.hasParam("Mandatory"));
|
||||
}
|
||||
|
||||
if (c != null) {
|
||||
chosen.add(c);
|
||||
choices.remove(c);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
host.setChosenCard(chosen);
|
||||
|
||||
@@ -16,9 +16,9 @@ import forge.Singletons;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.card.CardRulesPredicates;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -90,9 +90,9 @@ public class ChooseCardNameEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("AILogic")) {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
if (logic.equals("MostProminentInComputerDeck")) {
|
||||
chosen = CardFactoryUtil.getMostProminentCardName(p.getCardsIn(ZoneType.Library));
|
||||
chosen = ComputerUtilCard.getMostProminentCardName(p.getCardsIn(ZoneType.Library));
|
||||
} else if (logic.equals("MostProminentInHumanDeck")) {
|
||||
chosen = CardFactoryUtil.getMostProminentCardName(p.getOpponent().getCardsIn(ZoneType.Library));
|
||||
chosen = ComputerUtilCard.getMostProminentCardName(p.getOpponent().getCardsIn(ZoneType.Library));
|
||||
}
|
||||
} else {
|
||||
List<Card> list = CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), p.getOpponent());
|
||||
|
||||
@@ -9,9 +9,9 @@ import forge.CardPredicates;
|
||||
import forge.Constant;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -69,36 +69,36 @@ public class ChooseColorEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("AILogic")) {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
if (logic.equals("MostProminentInHumanDeck")) {
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp)));
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp)));
|
||||
} else if (logic.equals("MostProminentInComputerDeck")) {
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai)));
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai)));
|
||||
} else if (logic.equals("MostProminentDualInComputerDeck")) {
|
||||
List<String> prominence = CardFactoryUtil.getColorByProminence(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
||||
List<String> prominence = ComputerUtilCard.getColorByProminence(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
||||
chosen.add(prominence.get(0));
|
||||
chosen.add(prominence.get(1));
|
||||
}
|
||||
else if (logic.equals("MostProminentInGame")) {
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(Singletons.getModel().getGame().getCardsInGame()));
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(Singletons.getModel().getGame().getCardsInGame()));
|
||||
}
|
||||
else if (logic.equals("MostProminentHumanCreatures")) {
|
||||
List<Card> list = opp.getCreaturesInPlay();
|
||||
if (list.isEmpty()) {
|
||||
list = CardLists.filter(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp), CardPredicates.Presets.CREATURES);
|
||||
}
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(list));
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(list));
|
||||
}
|
||||
else if (logic.equals("MostProminentComputerControls")) {
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield)));
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(ai.getCardsIn(ZoneType.Battlefield)));
|
||||
}
|
||||
else if (logic.equals("MostProminentHumanControls")) {
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(ai.getOpponent().getCardsIn(ZoneType.Battlefield)));
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(ai.getOpponent().getCardsIn(ZoneType.Battlefield)));
|
||||
}
|
||||
else if (logic.equals("MostProminentPermanent")) {
|
||||
final List<Card> list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(list));
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(list));
|
||||
}
|
||||
else if (logic.equals("MostProminentAttackers")) {
|
||||
chosen.add(CardFactoryUtil.getMostProminentColor(Singletons.getModel().getGame().getCombat()
|
||||
chosen.add(ComputerUtilCard.getMostProminentColor(Singletons.getModel().getGame().getCombat()
|
||||
.getAttackerList()));
|
||||
}
|
||||
else if (logic.equals("MostProminentKeywordInComputerDeck")) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityStackInstance;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -181,10 +182,10 @@ public class ChooseSourceEffect extends SpellAbilityEffect {
|
||||
return ComputerUtilCombat.damageIfUnblocked(c, ai, Singletons.getModel().getGame().getCombat()) > 0;
|
||||
}
|
||||
});
|
||||
chosen.add(CardFactoryUtil.getBestCreatureAI(sourcesToChooseFrom));
|
||||
chosen.add(ComputerUtilCard.getBestCreatureAI(sourcesToChooseFrom));
|
||||
}
|
||||
} else {
|
||||
chosen.add(CardFactoryUtil.getBestAI(sourcesToChooseFrom));
|
||||
chosen.add(ComputerUtilCard.getBestAI(sourcesToChooseFrom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ import forge.Constant;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardType;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -103,22 +103,22 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("AILogic")) {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
if (logic.equals("MostProminentOnBattlefield")) {
|
||||
chosen = CardFactoryUtil.getMostProminentCreatureType(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield));
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield));
|
||||
}
|
||||
else if (logic.equals("MostProminentComputerControls")) {
|
||||
chosen = CardFactoryUtil.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
||||
}
|
||||
else if (logic.equals("MostProminentHumanControls")) {
|
||||
chosen = CardFactoryUtil.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||
chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp));
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), opp));
|
||||
}
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerDeck")) {
|
||||
chosen = CardFactoryUtil.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai));
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
||||
chosen = CardFactoryUtil.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
||||
}
|
||||
}
|
||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||
|
||||
@@ -12,9 +12,9 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -195,9 +195,9 @@ public class DigEffect extends SpellAbilityEffect {
|
||||
chosen = GuiChoose.one(prompt + destZone2, valid);
|
||||
movedCards.remove(chosen);
|
||||
} else { // Computer
|
||||
Card chosen = CardFactoryUtil.getBestAI(valid);
|
||||
Card chosen = ComputerUtilCard.getBestAI(valid);
|
||||
if (sa.getActivatingPlayer().isHuman() && p.isHuman()) {
|
||||
chosen = CardFactoryUtil.getWorstAI(valid);
|
||||
chosen = ComputerUtilCard.getWorstAI(valid);
|
||||
}
|
||||
movedCards.remove(chosen);
|
||||
}
|
||||
@@ -250,9 +250,9 @@ public class DigEffect extends SpellAbilityEffect {
|
||||
changeNum = valid.size(); // always take all
|
||||
}
|
||||
for (j = 0; j < changeNum; j++) {
|
||||
Card chosen = CardFactoryUtil.getBestAI(valid);
|
||||
Card chosen = ComputerUtilCard.getBestAI(valid);
|
||||
if (sa.getActivatingPlayer().isHuman() && p.isHuman()) {
|
||||
chosen = CardFactoryUtil.getWorstAI(valid);
|
||||
chosen = ComputerUtilCard.getWorstAI(valid);
|
||||
}
|
||||
if (chosen == null) {
|
||||
break;
|
||||
|
||||
@@ -15,6 +15,7 @@ import forge.card.ability.AbilityUtils;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -109,9 +110,9 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
if (sa.hasParam("DiscardValid")) {
|
||||
final String validString = sa.getParam("DiscardValid");
|
||||
if (validString.contains("Creature") && !validString.contains("nonCreature")) {
|
||||
final Card c = CardFactoryUtil.getBestCreatureAI(goodChoices);
|
||||
final Card c = ComputerUtilCard.getBestCreatureAI(goodChoices);
|
||||
if (c != null) {
|
||||
dChoices.add(CardFactoryUtil.getBestCreatureAI(goodChoices));
|
||||
dChoices.add(ComputerUtilCard.getBestCreatureAI(goodChoices));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,12 @@ import java.util.List;
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.trigger.Trigger;
|
||||
import forge.card.trigger.TriggerHandler;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.GuiDialog;
|
||||
|
||||
public class EncodeEffect extends SpellAbilityEffect {
|
||||
@Override
|
||||
@@ -43,10 +39,11 @@ public class EncodeEffect extends SpellAbilityEffect {
|
||||
|
||||
}
|
||||
// Handle choice of whether or not to encoded
|
||||
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Do you want to exile " + host + " and encode it onto a creature you control?");
|
||||
if (player.isHuman()
|
||||
&& !GuiDialog.confirm(host, sb.toString())) {
|
||||
if (!player.getController().confirmAction(sa, null, sb.toString())) {
|
||||
return;
|
||||
}
|
||||
// Note: AI will always choose to encode
|
||||
@@ -56,31 +53,8 @@ public class EncodeEffect extends SpellAbilityEffect {
|
||||
Card movedCard = Singletons.getModel().getGame().getAction().moveTo(ZoneType.Exile, host);
|
||||
|
||||
// choose a creature
|
||||
Card choice = null;
|
||||
if (player.isHuman()) {
|
||||
final String choiceTitle = "Choose a creature you control to encode ";
|
||||
choice = GuiChoose.oneOrNone(choiceTitle, choices);
|
||||
}
|
||||
else { // Computer
|
||||
// TODO: move this to AI method
|
||||
String logic = sa.getParam("AILogic");
|
||||
if (logic == null) {
|
||||
// Base Logic is choose "best"
|
||||
choice = CardFactoryUtil.getBestAI(choices);
|
||||
} else if ("WorstCard".equals(logic)) {
|
||||
choice = CardFactoryUtil.getWorstAI(choices);
|
||||
} else if (logic.equals("BestBlocker")) {
|
||||
if (!CardLists.filter(choices, Presets.UNTAPPED).isEmpty()) {
|
||||
choices = CardLists.filter(choices, Presets.UNTAPPED);
|
||||
}
|
||||
choice = CardFactoryUtil.getBestCreatureAI(choices);
|
||||
} else if (logic.equals("Clone")) {
|
||||
if (!CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
||||
choices = CardLists.getValidCards(choices, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
||||
}
|
||||
choice = CardFactoryUtil.getBestAI(choices);
|
||||
}
|
||||
}
|
||||
Card choice = player.getController().chooseSingleCardForEffect(choices, sa, "Choose a creature you control to encode ", true);
|
||||
|
||||
if (choice == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ import forge.Singletons;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.AbilityManaPart;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -82,7 +82,7 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
String chosen = Constant.Color.BLACK;
|
||||
if (logic.equals("MostProminentInComputerHand")) {
|
||||
chosen = CardFactoryUtil.getMostProminentColor(activator.getCardsIn(
|
||||
chosen = ComputerUtilCard.getMostProminentColor(activator.getCardsIn(
|
||||
ZoneType.Hand));
|
||||
}
|
||||
if (chosen.equals("")) {
|
||||
@@ -141,7 +141,7 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
String chosen = Constant.Color.BLACK;
|
||||
if (logic.equals("MostProminentInComputerHand")) {
|
||||
chosen = CardFactoryUtil.getMostProminentColor(act.getCardsIn(ZoneType.Hand));
|
||||
chosen = ComputerUtilCard.getMostProminentColor(act.getCardsIn(ZoneType.Hand));
|
||||
}
|
||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
||||
abMana.setExpressChoice(MagicColor.toShortString(chosen));
|
||||
|
||||
@@ -13,7 +13,6 @@ import forge.CardLists;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostPartMana;
|
||||
import forge.card.cost.CostPart;
|
||||
@@ -23,6 +22,7 @@ import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.SpellAbilityRestriction;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -126,7 +126,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
tgtCard = CardFactoryUtil.getBestAI(tgtCards);
|
||||
tgtCard = ComputerUtilCard.getBestAI(tgtCards);
|
||||
if (tgtCard == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.GuiChoose;
|
||||
|
||||
@@ -124,7 +124,7 @@ public class ProtectEffect extends SpellAbilityEffect {
|
||||
list = CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsInGame(), ai.getOpponents());
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
choice = CardFactoryUtil.getMostProminentColor(list);
|
||||
choice = ComputerUtilCard.getMostProminentColor(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import forge.CardLists;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.AbilitySub;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -221,11 +221,11 @@ public class TwoPilesEffect extends SpellAbilityEffect {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int cmc1 = CardFactoryUtil.evaluatePermanentList(new ArrayList<Card>(pile1));
|
||||
int cmc2 = CardFactoryUtil.evaluatePermanentList(new ArrayList<Card>(pile2));
|
||||
int cmc1 = ComputerUtilCard.evaluatePermanentList(new ArrayList<Card>(pile1));
|
||||
int cmc2 = ComputerUtilCard.evaluatePermanentList(new ArrayList<Card>(pile2));
|
||||
if (CardLists.getNotType(pool, "Creature").isEmpty()) {
|
||||
cmc1 = CardFactoryUtil.evaluateCreatureList(new ArrayList<Card>(pile1));
|
||||
cmc2 = CardFactoryUtil.evaluateCreatureList(new ArrayList<Card>(pile2));
|
||||
cmc1 = ComputerUtilCard.evaluateCreatureList(new ArrayList<Card>(pile1));
|
||||
cmc2 = ComputerUtilCard.evaluateCreatureList(new ArrayList<Card>(pile2));
|
||||
System.out.println("value:" + cmc1 + " " + cmc2);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
@@ -86,7 +87,7 @@ public class UntapEffect extends SpellAbilityEffect {
|
||||
while ((list.size() != 0) && (count < num)) {
|
||||
for (int i = 0; (i < list.size()) && (count < num); i++) {
|
||||
|
||||
final Card c = CardFactoryUtil.getBestLandAI(list);
|
||||
final Card c = ComputerUtilCard.getBestLandAI(list);
|
||||
c.untap();
|
||||
list.remove(c);
|
||||
count++;
|
||||
|
||||
@@ -50,6 +50,7 @@ import forge.card.trigger.Trigger;
|
||||
import forge.card.trigger.TriggerHandler;
|
||||
import forge.control.input.Input;
|
||||
import forge.control.input.InputSelectManyCards;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.PlayerZone;
|
||||
@@ -190,7 +191,7 @@ public class CardFactoryCreatures {
|
||||
}
|
||||
|
||||
this.getTarget().resetTargets();
|
||||
this.setTargetCard(CardFactoryUtil.getBestCreatureAI(targetables));
|
||||
this.setTargetCard(ComputerUtilCard.getBestCreatureAI(targetables));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -262,7 +263,7 @@ public class CardFactoryCreatures {
|
||||
|
||||
// Kill Wolves that can be killed first
|
||||
if (wolvesLeft.size() > 0) {
|
||||
final Card best = CardFactoryUtil.getBestCreatureAI(wolvesLeft);
|
||||
final Card best = ComputerUtilCard.getBestCreatureAI(wolvesLeft);
|
||||
best.addDamage(1, target);
|
||||
if ((ComputerUtilCombat.getDamageToKill(best) <= 0) || target.hasKeyword("Deathtouch")) {
|
||||
wolvesLeft.remove(best);
|
||||
|
||||
@@ -18,17 +18,12 @@
|
||||
package forge.card.cardfactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -45,7 +40,6 @@ import forge.CounterType;
|
||||
import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardCharacteristics;
|
||||
import forge.card.CardType;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityFactory;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
@@ -71,8 +65,8 @@ import forge.card.trigger.TriggerHandler;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.AiAttackController;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.event.TokenCreatedEvent;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
@@ -85,7 +79,6 @@ import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.gui.match.CMatchUI;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
@@ -98,659 +91,6 @@ import forge.view.ButtonUtil;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CardFactoryUtil {
|
||||
private static Random random = MyRandom.getRandom();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostExpensivePermanentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getMostExpensivePermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
List<Card> all = list;
|
||||
if (targeted) {
|
||||
all = CardLists.filter(all, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.canBeTargetedBy(spell);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return CardFactoryUtil.getMostExpensivePermanentAI(all);
|
||||
}
|
||||
|
||||
/**
|
||||
* getMostExpensivePermanentAI.
|
||||
*
|
||||
* @param all
|
||||
* the all
|
||||
* @return the card
|
||||
*/
|
||||
public static Card getMostExpensivePermanentAI(final List<Card> all) {
|
||||
if (all.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
Card biggest = null;
|
||||
biggest = all.get(0);
|
||||
|
||||
int bigCMC = 0;
|
||||
for (int i = 0; i < all.size(); i++) {
|
||||
final Card card = all.get(i);
|
||||
int curCMC = card.getCMC();
|
||||
|
||||
// Add all cost of all auras with the same controller
|
||||
final List<Card> auras = CardLists.filterControlledBy(card.getEnchantedBy(), card.getController());
|
||||
curCMC += Aggregates.sum(auras, CardPredicates.Accessors.fnGetCmc) + auras.size();
|
||||
|
||||
if (curCMC >= bigCMC) {
|
||||
bigCMC = curCMC;
|
||||
biggest = all.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
return biggest;
|
||||
}
|
||||
|
||||
// for Sarkhan the Mad
|
||||
/**
|
||||
* <p>
|
||||
* getCheapestCreatureAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getCheapestCreatureAI(List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.isCreature();
|
||||
}
|
||||
});
|
||||
return CardFactoryUtil.getCheapestPermanentAI(list, spell, targeted);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getCheapestPermanentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getCheapestPermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
List<Card> all = list;
|
||||
if (targeted) {
|
||||
all = CardLists.filter(all, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.canBeTargetedBy(spell);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (all.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// get cheapest card:
|
||||
Card cheapest = null;
|
||||
cheapest = all.get(0);
|
||||
|
||||
for (int i = 0; i < all.size(); i++) {
|
||||
if (cheapest.getManaCost().getCMC() <= cheapest.getManaCost().getCMC()) {
|
||||
cheapest = all.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
return cheapest;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getBestLandAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestLandAI(final List<Card> list) {
|
||||
final List<Card> land = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
||||
if (!(land.size() > 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// prefer to target non basic lands
|
||||
final List<Card> nbLand = CardLists.filter(land, Predicates.not(CardPredicates.Presets.BASIC_LANDS));
|
||||
|
||||
if (nbLand.size() > 0) {
|
||||
// TODO - Rank non basics?
|
||||
return Aggregates.random(nbLand);
|
||||
}
|
||||
|
||||
// if no non-basic lands, target the least represented basic land type
|
||||
String sminBL = "";
|
||||
int iminBL = 20000; // hopefully no one will ever have more than 20000
|
||||
// lands of one type....
|
||||
int n = 0;
|
||||
for (String name : Constant.Color.BASIC_LANDS) {
|
||||
n = CardLists.getType(land, name).size();
|
||||
if ((n < iminBL) && (n > 0)) {
|
||||
// if two or more are tied, only the
|
||||
// first
|
||||
// one checked will be used
|
||||
iminBL = n;
|
||||
sminBL = name;
|
||||
}
|
||||
}
|
||||
if (iminBL == 20000) {
|
||||
return null; // no basic land was a minimum
|
||||
}
|
||||
|
||||
final List<Card> bLand = CardLists.getType(land, sminBL);
|
||||
|
||||
for (Card ut : Iterables.filter(bLand, CardPredicates.Presets.UNTAPPED)) {
|
||||
return ut;
|
||||
}
|
||||
|
||||
|
||||
return Aggregates.random(bLand); // random tapped land of least represented type
|
||||
}
|
||||
|
||||
// The AI doesn't really pick the best enchantment, just the most expensive.
|
||||
/**
|
||||
* <p>
|
||||
* getBestEnchantmentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestEnchantmentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS);
|
||||
if (targeted) {
|
||||
all = CardLists.filter(all, new Predicate<Card>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.canBeTargetedBy(spell);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// get biggest Enchantment
|
||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
||||
}
|
||||
|
||||
// The AI doesn't really pick the best artifact, just the most expensive.
|
||||
/**
|
||||
* <p>
|
||||
* getBestArtifactAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestArtifactAI(final List<Card> list) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ARTIFACTS);
|
||||
if (all.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
// get biggest Artifact
|
||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* doesCreatureAttackAI.
|
||||
* </p>
|
||||
*
|
||||
* @param ai
|
||||
* the AI player
|
||||
* @param card
|
||||
* a {@link forge.Card} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean doesCreatureAttackAI(final Player ai, final Card card) {
|
||||
final List<Card> att = new AiAttackController(ai, ai.getOpponent()).getAttackers().getAttackers();
|
||||
|
||||
return att.contains(card);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* evaluateCreatureList.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int evaluateCreatureList(final List<Card> list) {
|
||||
int value = 0;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
value += CardFactoryUtil.evaluateCreature(list.get(i));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* evaluatePermanentList.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int evaluatePermanentList(final List<Card> list) {
|
||||
int value = 0;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
value += list.get(i).getCMC() + 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* evaluateCreature.
|
||||
* </p>
|
||||
*
|
||||
* @param c
|
||||
* a {@link forge.Card} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int evaluateCreature(final Card c) {
|
||||
|
||||
int value = 100;
|
||||
if (c.isToken()) {
|
||||
value = 80; // tokens should be worth less than actual cards
|
||||
}
|
||||
int power = c.getNetCombatDamage();
|
||||
final int toughness = c.getNetDefense();
|
||||
for (String keyword : c.getKeyword()) {
|
||||
if (keyword.equals("Prevent all combat damage that would be dealt by CARDNAME.")
|
||||
|| keyword.equals("Prevent all damage that would be dealt by CARDNAME.")
|
||||
|| keyword.equals("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")
|
||||
|| keyword.equals("Prevent all damage that would be dealt to and dealt by CARDNAME.")) {
|
||||
power = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
value += power * 15;
|
||||
value += toughness * 10;
|
||||
value += c.getCMC() * 5;
|
||||
|
||||
// Evasion keywords
|
||||
if (c.hasKeyword("Flying")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (c.hasKeyword("Horsemanship")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (c.hasKeyword("Unblockable")) {
|
||||
value += power * 10;
|
||||
} else {
|
||||
if (c.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||
value += power * 6;
|
||||
}
|
||||
if (c.hasKeyword("Fear")) {
|
||||
value += power * 6;
|
||||
}
|
||||
if (c.hasKeyword("Intimidate")) {
|
||||
value += power * 6;
|
||||
}
|
||||
if (c.hasStartOfKeyword("CARDNAME can't be blocked except by")) {
|
||||
value += power * 5;
|
||||
}
|
||||
if (c.hasStartOfKeyword("CARDNAME can't be blocked by")) {
|
||||
value += power * 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Other good keywords
|
||||
if (power > 0) {
|
||||
if (c.hasKeyword("Double Strike")) {
|
||||
value += 10 + (power * 15);
|
||||
} else if (c.hasKeyword("First Strike")) {
|
||||
value += 10 + (power * 5);
|
||||
}
|
||||
if (c.hasKeyword("Deathtouch")) {
|
||||
value += 25;
|
||||
}
|
||||
if (c.hasKeyword("Lifelink")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (power > 1 && c.hasKeyword("Trample")) {
|
||||
value += (power - 1) * 5;
|
||||
}
|
||||
if (c.hasKeyword("Vigilance")) {
|
||||
value += (power * 5) + (toughness * 5);
|
||||
}
|
||||
if (c.hasKeyword("Wither")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (c.hasKeyword("Infect")) {
|
||||
value += power * 15;
|
||||
}
|
||||
value += c.getKeywordMagnitude("Rampage");
|
||||
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
||||
+ "put into a graveyard, put a +1/+1 counter on CARDNAME.")) {
|
||||
value += 2;
|
||||
}
|
||||
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
||||
+ "put into a graveyard, put a +2/+2 counter on CARDNAME.")) {
|
||||
value += 3;
|
||||
}
|
||||
}
|
||||
|
||||
value += c.getKeywordMagnitude("Bushido") * 16;
|
||||
value += c.getAmountOfKeyword("Flanking") * 15;
|
||||
value += c.getAmountOfKeyword("Exalted") * 15;
|
||||
value += c.getKeywordMagnitude("Annihilator") * 50;
|
||||
|
||||
|
||||
// Defensive Keywords
|
||||
if (c.hasKeyword("Reach") && !c.hasKeyword("Flying")) {
|
||||
value += 5;
|
||||
}
|
||||
if (c.hasKeyword("CARDNAME can block creatures with shadow as though they didn't have shadow.")) {
|
||||
value += 3;
|
||||
}
|
||||
|
||||
// Protection
|
||||
if (c.hasKeyword("Indestructible")) {
|
||||
value += 70;
|
||||
}
|
||||
if (c.hasKeyword("Prevent all damage that would be dealt to CARDNAME.")) {
|
||||
value += 60;
|
||||
} else if (c.hasKeyword("Prevent all combat damage that would be dealt to CARDNAME.")) {
|
||||
value += 50;
|
||||
}
|
||||
if (c.hasKeyword("Hexproof")) {
|
||||
value += 35;
|
||||
} else if (c.hasKeyword("Shroud")) {
|
||||
value += 30;
|
||||
}
|
||||
if (c.hasStartOfKeyword("Protection")) {
|
||||
value += 20;
|
||||
}
|
||||
if (c.hasStartOfKeyword("PreventAllDamageBy")) {
|
||||
value += 10;
|
||||
}
|
||||
value += c.getKeywordMagnitude("Absorb") * 11;
|
||||
|
||||
// Bad keywords
|
||||
if (c.hasKeyword("Defender") || c.hasKeyword("CARDNAME can't attack.")) {
|
||||
value -= (power * 9) + 40;
|
||||
} else if (c.getSVar("SacrificeEndCombat").equals("True")) {
|
||||
value -= 40;
|
||||
}
|
||||
if (c.hasKeyword("CARDNAME can't block.")) {
|
||||
value -= 10;
|
||||
} else if (c.hasKeyword("CARDNAME attacks each turn if able.")) {
|
||||
value -= 10;
|
||||
} else if (c.hasKeyword("CARDNAME can block only creatures with flying.")) {
|
||||
value -= toughness * 5;
|
||||
}
|
||||
|
||||
if (c.hasStartOfKeyword("When CARDNAME is dealt damage, destroy it.")) {
|
||||
value -= (toughness - 1) * 9;
|
||||
}
|
||||
|
||||
if (c.hasKeyword("CARDNAME can't attack or block.")) {
|
||||
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
||||
}
|
||||
if (c.hasKeyword("CARDNAME doesn't untap during your untap step.")) {
|
||||
if (c.isTapped()) {
|
||||
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
||||
} else {
|
||||
value -= 50;
|
||||
}
|
||||
}
|
||||
if (c.hasKeyword("At the beginning of the end step, destroy CARDNAME.")
|
||||
|| c.hasKeyword("At the beginning of the end step, exile CARDNAME.")
|
||||
|| c.hasKeyword("At the beginning of the end step, sacrifice CARDNAME.")) {
|
||||
value -= 50;
|
||||
} else if (c.hasStartOfKeyword("Cumulative upkeep")) {
|
||||
value -= 30;
|
||||
} else if (c.hasStartOfKeyword("At the beginning of your upkeep, destroy CARDNAME unless you pay")
|
||||
|| c.hasStartOfKeyword("At the beginning of your upkeep, sacrifice CARDNAME unless you pay")
|
||||
|| c.hasStartOfKeyword("Upkeep:")) {
|
||||
value -= 20;
|
||||
} else if (c.hasStartOfKeyword("(Echo unpaid)")) {
|
||||
value -= 10;
|
||||
}
|
||||
|
||||
if (c.hasStartOfKeyword("At the beginning of your upkeep, CARDNAME deals")) {
|
||||
value -= 20;
|
||||
}
|
||||
if (c.hasStartOfKeyword("Fading")) {
|
||||
value -= 20;
|
||||
}
|
||||
if (c.hasStartOfKeyword("Vanishing")) {
|
||||
value -= 20;
|
||||
}
|
||||
if (c.getSVar("Targeting").equals("Dies")) {
|
||||
value -= 25;
|
||||
}
|
||||
|
||||
for (final SpellAbility sa : c.getSpellAbilities()) {
|
||||
if (sa.isAbility()) {
|
||||
value += 10;
|
||||
}
|
||||
}
|
||||
if (!c.getManaAbility().isEmpty()) {
|
||||
value += 10;
|
||||
}
|
||||
|
||||
if (c.isUntapped()) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
// paired creatures are more valuable because they grant a bonus to the other creature
|
||||
if (c.isPaired()) {
|
||||
value += 14;
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
} // evaluateCreature
|
||||
|
||||
// returns null if list.size() == 0
|
||||
/**
|
||||
* <p>
|
||||
* getBestAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestAI(final List<Card> list) {
|
||||
// Get Best will filter by appropriate getBest list if ALL of the list
|
||||
// is of that type
|
||||
if (CardLists.getNotType(list, "Creature").size() == 0) {
|
||||
return CardFactoryUtil.getBestCreatureAI(list);
|
||||
}
|
||||
|
||||
if (CardLists.getNotType(list, "Land").size() == 0) {
|
||||
return CardFactoryUtil.getBestLandAI(list);
|
||||
}
|
||||
|
||||
// TODO - Once we get an EvaluatePermanent this should call
|
||||
// getBestPermanent()
|
||||
return CardFactoryUtil.getMostExpensivePermanentAI(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* getBestCreatureAI.
|
||||
*
|
||||
* @param list
|
||||
* the list
|
||||
* @return the card
|
||||
*/
|
||||
public static Card getBestCreatureAI(final List<Card> list) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnEvaluateCreature);
|
||||
}
|
||||
|
||||
// This selection rates tokens higher
|
||||
/**
|
||||
* <p>
|
||||
* getBestCreatureToBounceAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestCreatureToBounceAI(final List<Card> list) {
|
||||
final int tokenBonus = 40;
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||
Card biggest = null; // returns null if list.size() == 0
|
||||
int biggestvalue = 0;
|
||||
int newvalue = 0;
|
||||
|
||||
if (all.size() != 0) {
|
||||
biggest = all.get(0);
|
||||
|
||||
for (int i = 0; i < all.size(); i++) {
|
||||
biggestvalue = CardFactoryUtil.evaluateCreature(biggest);
|
||||
if (biggest.isToken()) {
|
||||
biggestvalue += tokenBonus; // raise the value of tokens
|
||||
}
|
||||
newvalue = CardFactoryUtil.evaluateCreature(all.get(i));
|
||||
if (all.get(i).isToken()) {
|
||||
newvalue += tokenBonus; // raise the value of tokens
|
||||
}
|
||||
if (biggestvalue < newvalue) {
|
||||
biggest = all.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return biggest;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getWorstAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstAI(final List<Card> list) {
|
||||
return CardFactoryUtil.getWorstPermanentAI(list, false, false, false, false);
|
||||
}
|
||||
|
||||
// returns null if list.size() == 0
|
||||
/**
|
||||
* <p>
|
||||
* getWorstCreatureAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstCreatureAI(final List<Card> list) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||
// get smallest creature
|
||||
return Aggregates.itemWithMin(all, CardPredicates.Accessors.fnEvaluateCreature);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getWorstPermanentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param biasEnch
|
||||
* a boolean.
|
||||
* @param biasLand
|
||||
* a boolean.
|
||||
* @param biasArt
|
||||
* a boolean.
|
||||
* @param biasCreature
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstPermanentAI(final List<Card> list, final boolean biasEnch, final boolean biasLand,
|
||||
final boolean biasArt, final boolean biasCreature) {
|
||||
if (list.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (biasEnch && Iterables.any(list, CardPredicates.Presets.ENCHANTMENTS)) {
|
||||
return CardFactoryUtil.getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS), null, false);
|
||||
}
|
||||
|
||||
if (biasArt && Iterables.any(list, CardPredicates.Presets.ARTIFACTS)) {
|
||||
return CardFactoryUtil.getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ARTIFACTS), null, false);
|
||||
}
|
||||
|
||||
if (biasLand && Iterables.any(list, CardPredicates.Presets.LANDS)) {
|
||||
return CardFactoryUtil.getWorstLand(CardLists.filter(list, CardPredicates.Presets.LANDS));
|
||||
}
|
||||
|
||||
if (biasCreature && Iterables.any(list, CardPredicates.Presets.CREATURES)) {
|
||||
return CardFactoryUtil.getWorstCreatureAI(CardLists.filter(list, CardPredicates.Presets.CREATURES));
|
||||
}
|
||||
|
||||
List<Card> lands = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
||||
if (lands.size() > 6) {
|
||||
return CardFactoryUtil.getWorstLand(lands);
|
||||
}
|
||||
|
||||
if ((CardLists.getType(list, "Artifact").size() > 0) || (CardLists.getType(list, "Enchantment").size() > 0)) {
|
||||
return CardFactoryUtil.getCheapestPermanentAI(CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.isArtifact() || c.isEnchantment();
|
||||
}
|
||||
}), null, false);
|
||||
}
|
||||
|
||||
if (CardLists.getType(list, "Creature").size() > 0) {
|
||||
return CardFactoryUtil.getWorstCreatureAI(CardLists.getType(list, "Creature"));
|
||||
}
|
||||
|
||||
// Planeswalkers fall through to here, lands will fall through if there
|
||||
// aren't very many
|
||||
return CardFactoryUtil.getCheapestPermanentAI(list, null, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* inputDestroyNoRegeneration.
|
||||
@@ -3027,91 +2367,6 @@ public class CardFactoryUtil {
|
||||
return untap;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostProminentCardName.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getMostProminentCardName(final List<Card> list) {
|
||||
|
||||
if (list.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
|
||||
for (final Card c : list) {
|
||||
final String name = c.getName();
|
||||
Integer currentCnt = map.get(name);
|
||||
map.put(name, currentCnt == null ? Integer.valueOf(1) : Integer.valueOf(1 + currentCnt));
|
||||
} // for
|
||||
|
||||
int max = 0;
|
||||
String maxName = "";
|
||||
|
||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||
final String type = entry.getKey();
|
||||
// Log.debug(type + " - " + entry.getValue());
|
||||
|
||||
if (max < entry.getValue()) {
|
||||
max = entry.getValue();
|
||||
maxName = type;
|
||||
}
|
||||
}
|
||||
return maxName;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostProminentCreatureType.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getMostProminentCreatureType(final List<Card> list) {
|
||||
|
||||
if (list.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
|
||||
for (final Card c : list) {
|
||||
final ArrayList<String> typeList = c.getType();
|
||||
|
||||
for (final String var : typeList) {
|
||||
if (CardType.isACreatureType(var)) {
|
||||
if (!map.containsKey(var)) {
|
||||
map.put(var, 1);
|
||||
} else {
|
||||
map.put(var, map.get(var) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for
|
||||
|
||||
int max = 0;
|
||||
String maxType = "";
|
||||
|
||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||
final String type = entry.getKey();
|
||||
// Log.debug(type + " - " + entry.getValue());
|
||||
|
||||
if (max < entry.getValue()) {
|
||||
max = entry.getValue();
|
||||
maxType = type;
|
||||
}
|
||||
}
|
||||
|
||||
return maxType;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* isMostProminentColor.
|
||||
@@ -3153,96 +2408,6 @@ public class CardFactoryUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostProminentColor.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getMostProminentColor(final List<Card> list) {
|
||||
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
|
||||
for (final Card c : list) {
|
||||
for (final String color : CardUtil.getColors(c)) {
|
||||
if (color.equals("colorless")) {
|
||||
// nothing to do
|
||||
} else if (!map.containsKey(color)) {
|
||||
map.put(color, 1);
|
||||
} else {
|
||||
map.put(color, map.get(color) + 1);
|
||||
}
|
||||
}
|
||||
} // for
|
||||
|
||||
int max = 0;
|
||||
String maxColor = "";
|
||||
|
||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||
final String color = entry.getKey();
|
||||
Log.debug(color + " - " + entry.getValue());
|
||||
|
||||
if (max < entry.getValue()) {
|
||||
max = entry.getValue();
|
||||
maxColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
return maxColor;
|
||||
}
|
||||
|
||||
public static List<String> getColorByProminence(final List<Card> list) {
|
||||
final HashMap<String, Integer> counts = new HashMap<String, Integer>();
|
||||
for (String color : Constant.Color.ONLY_COLORS) {
|
||||
counts.put(color, 0);
|
||||
}
|
||||
for (Card c : list) {
|
||||
List<String> colors = c.determineColor().toStringList();
|
||||
for (String col : colors) {
|
||||
if (counts.containsKey(col)) {
|
||||
counts.put(col.toString(), counts.get(col.toString()) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayList<String> res = new ArrayList<String>(counts.keySet());
|
||||
Collections.sort(res, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(final String a, final String b) {
|
||||
return counts.get(b) - counts.get(a);
|
||||
}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getUsableManaSources.
|
||||
* </p>
|
||||
*
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int getUsableManaSources(final Player player) {
|
||||
List<Card> list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
for (final SpellAbility am : c.getAIPlayableMana()) {
|
||||
if (am.canPlay()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* makeToken.
|
||||
@@ -3423,66 +2588,6 @@ public class CardFactoryUtil {
|
||||
return neededDamage;
|
||||
}
|
||||
|
||||
/**
|
||||
* getWorstLand
|
||||
* <p/>
|
||||
* This function finds the worst land a player has in play based on: worst
|
||||
* 1. tapped, basic land 2. tapped, non-basic land 3. untapped, basic land
|
||||
* 4. untapped, non-basic land best
|
||||
* <p/>
|
||||
* This is useful when the AI needs to find one of its lands to sacrifice
|
||||
*
|
||||
* @param player
|
||||
* - AllZone.getHumanPlayer() or AllZone.getComputerPlayer()
|
||||
* @return the worst land found based on the description above
|
||||
*/
|
||||
public static Card getWorstLand(final Player player) {
|
||||
final List<Card> lands = player.getLandsInPlay();
|
||||
return CardFactoryUtil.getWorstLand(lands);
|
||||
} // end getWorstLand
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getWorstLand.
|
||||
* </p>
|
||||
*
|
||||
* @param lands
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstLand(final List<Card> lands) {
|
||||
Card worstLand = null;
|
||||
int maxScore = 0;
|
||||
// first, check for tapped, basic lands
|
||||
for (Card tmp : lands) {
|
||||
int score = tmp.isTapped() ? 2 : 0;
|
||||
score += tmp.isBasicLand() ? 1 : 0;
|
||||
if (score >= maxScore) {
|
||||
worstLand = tmp;
|
||||
maxScore = score;
|
||||
}
|
||||
}
|
||||
return worstLand;
|
||||
} // end getWorstLand
|
||||
|
||||
// may return null
|
||||
/**
|
||||
* <p>
|
||||
* getRandomCard.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getRandomCard(final List<Card> list) {
|
||||
if (list.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int index = CardFactoryUtil.random.nextInt(list.size());
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -4068,10 +3173,10 @@ public class CardFactoryUtil {
|
||||
} else {
|
||||
// AI choosing what to haunt
|
||||
final List<Card> oppCreats = CardLists.filterControlledBy(creats, card.getController().getOpponent());
|
||||
if (oppCreats.size() != 0) {
|
||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(oppCreats));
|
||||
if (!oppCreats.isEmpty()) {
|
||||
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(oppCreats));
|
||||
} else {
|
||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(creats));
|
||||
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(creats));
|
||||
}
|
||||
Singletons.getModel().getGame().getStack().add(haunterDiesWork);
|
||||
}
|
||||
@@ -4759,7 +3864,7 @@ public class CardFactoryUtil {
|
||||
}
|
||||
});
|
||||
if (choices.size() != 0) {
|
||||
ability.setTargetCard(CardFactoryUtil.getBestCreatureAI(choices));
|
||||
ability.setTargetCard(ComputerUtilCard.getBestCreatureAI(choices));
|
||||
|
||||
if (ability.getTargetCard() != null) {
|
||||
ability.setStackDescription("Put " + card.getCounters(CounterType.P1P1)
|
||||
|
||||
@@ -25,10 +25,10 @@ import forge.CardLists;
|
||||
import forge.CounterType;
|
||||
import forge.Singletons;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -223,9 +223,9 @@ public class CostPutCounter extends CostPartWithList {
|
||||
|
||||
Card card = null;
|
||||
if (this.getType().equals("Creature.YouCtrl")) {
|
||||
card = CardFactoryUtil.getWorstCreatureAI(typeList);
|
||||
card = ComputerUtilCard.getWorstCreatureAI(typeList);
|
||||
} else {
|
||||
card = CardFactoryUtil.getWorstPermanentAI(typeList, false, false, false, false);
|
||||
card = ComputerUtilCard.getWorstPermanentAI(typeList, false, false, false, false);
|
||||
}
|
||||
this.addToList(card);
|
||||
}
|
||||
|
||||
@@ -6,14 +6,13 @@ import java.util.List;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardColor;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.CardUtil;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
import forge.card.ability.effects.CharmEffect;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostPayment;
|
||||
import forge.card.mana.ManaCostBeingPaid;
|
||||
@@ -26,6 +25,7 @@ import forge.card.spellability.TargetSelection;
|
||||
import forge.card.staticability.StaticAbility;
|
||||
import forge.control.input.InputControl;
|
||||
import forge.control.input.InputPayManaSimple;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -196,7 +196,7 @@ public class GameActionPlay {
|
||||
}
|
||||
while (tapForConvoke != null && untappedCreats.size() != 0) {
|
||||
final Card workingCard = (Card) tapForConvoke;
|
||||
usableColors = CardUtil.getConvokableColors(workingCard, newCost);
|
||||
usableColors = GameActionPlay.getConvokableColors(workingCard, newCost);
|
||||
|
||||
if (usableColors.size() != 0) {
|
||||
String chosenColor = usableColors.get(0);
|
||||
@@ -317,7 +317,7 @@ public class GameActionPlay {
|
||||
}
|
||||
}
|
||||
if (chosen == null) {
|
||||
chosen = CardFactoryUtil.getWorstCreatureAI(grave);
|
||||
chosen = ComputerUtilCard.getWorstCreatureAI(grave);
|
||||
}
|
||||
|
||||
if (chosen == null) {
|
||||
@@ -503,4 +503,33 @@ public class GameActionPlay {
|
||||
final String costCuttingGetMultiKickerManaCostPaidColored0) {
|
||||
this.costCuttingGetMultiKickerManaCostPaidColored = costCuttingGetMultiKickerManaCostPaidColored0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the convokable colors.
|
||||
*
|
||||
* @param cardToConvoke
|
||||
* the card to convoke
|
||||
* @param cost
|
||||
* the cost
|
||||
* @return the convokable colors
|
||||
*/
|
||||
public static ArrayList<String> getConvokableColors(final Card cardToConvoke, final ManaCostBeingPaid cost) {
|
||||
final ArrayList<String> usableColors = new ArrayList<String>();
|
||||
|
||||
if (cost.getColorlessManaAmount() > 0) {
|
||||
usableColors.add("colorless");
|
||||
}
|
||||
for (final CardColor col : cardToConvoke.getColor()) {
|
||||
for (final String strCol : col.toStringList()) {
|
||||
if (strCol.equals("colorless")) {
|
||||
continue;
|
||||
}
|
||||
if (cost.toString().contains(MagicColor.toShortString(strCol))) {
|
||||
usableColors.add(strCol.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usableColors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import forge.CardLists;
|
||||
import forge.CounterType;
|
||||
import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.trigger.Trigger;
|
||||
import forge.card.trigger.TriggerType;
|
||||
import forge.game.GameState;
|
||||
@@ -909,7 +908,7 @@ public class AiAttackController {
|
||||
// see if the defending creature is of higher or lower
|
||||
// value. We don't want to attack only to lose value
|
||||
if (isWorthLessThanAllKillers && attacker.getSVar("SacMe").equals("")
|
||||
&& CardFactoryUtil.evaluateCreature(defender) <= CardFactoryUtil.evaluateCreature(attacker)) {
|
||||
&& ComputerUtilCard.evaluateCreature(defender) <= ComputerUtilCard.evaluateCreature(attacker)) {
|
||||
isWorthLessThanAllKillers = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,7 +596,7 @@ public class AiController {
|
||||
discardList.add(hand.get(0));
|
||||
hand.remove(hand.get(0));
|
||||
} else { //Discard worst card
|
||||
Card worst = CardFactoryUtil.getWorstAI(hand);
|
||||
Card worst = ComputerUtilCard.getWorstAI(hand);
|
||||
discardList.add(worst);
|
||||
hand.remove(worst);
|
||||
}
|
||||
@@ -606,14 +606,64 @@ public class AiController {
|
||||
return discardList;
|
||||
}
|
||||
|
||||
// These methods might be moved into matching SpellAbilityAi classes just without all these switches here
|
||||
public Card chooseSingleCardForEffect(List<Card> options, SpellAbility sa, String title, boolean isOptional) {
|
||||
ApiType api = sa.getApi();
|
||||
if ( null == api ) {
|
||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||
}
|
||||
|
||||
|
||||
Card choice = null;
|
||||
Card host = sa.getSourceCard();
|
||||
String logic = sa.getParam("AILogic");
|
||||
|
||||
switch(api) {
|
||||
case Bond: return CardFactoryUtil.getBestCreatureAI(options);
|
||||
case Bond:
|
||||
return ComputerUtilCard.getBestCreatureAI(options);
|
||||
|
||||
case ChooseCard:
|
||||
if (logic == null) {
|
||||
// Base Logic is choose "best"
|
||||
choice = ComputerUtilCard.getBestAI(options);
|
||||
} else if ("WorstCard".equals(logic)) {
|
||||
choice = ComputerUtilCard.getWorstAI(options);
|
||||
} else if (logic.equals("BestBlocker")) {
|
||||
if (!CardLists.filter(options, Presets.UNTAPPED).isEmpty()) {
|
||||
options = CardLists.filter(options, Presets.UNTAPPED);
|
||||
}
|
||||
choice = ComputerUtilCard.getBestCreatureAI(options);
|
||||
} else if (logic.equals("Clone")) {
|
||||
if (!CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
||||
options = CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
||||
}
|
||||
choice = ComputerUtilCard.getBestAI(options);
|
||||
} else if (logic.equals("Untap")) {
|
||||
if (!CardLists.getValidCards(options, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host).isEmpty()) {
|
||||
options = CardLists.getValidCards(options, "Permanent.YouCtrl,Permanent.tapped", host.getController(), host);
|
||||
}
|
||||
choice = ComputerUtilCard.getBestAI(options);
|
||||
}
|
||||
return choice;
|
||||
|
||||
case Encode:
|
||||
if (logic == null) {
|
||||
// Base Logic is choose "best"
|
||||
choice = ComputerUtilCard.getBestAI(options);
|
||||
} else if ("WorstCard".equals(logic)) {
|
||||
choice = ComputerUtilCard.getWorstAI(options);
|
||||
} else if (logic.equals("BestBlocker")) {
|
||||
if (!CardLists.filter(options, Presets.UNTAPPED).isEmpty()) {
|
||||
options = CardLists.filter(options, Presets.UNTAPPED);
|
||||
}
|
||||
choice = ComputerUtilCard.getBestCreatureAI(options);
|
||||
} else if (logic.equals("Clone")) {
|
||||
if (!CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host).isEmpty()) {
|
||||
options = CardLists.getValidCards(options, "Permanent.YouDontCtrl,Permanent.nonLegendary", host.getController(), host);
|
||||
}
|
||||
choice = ComputerUtilCard.getBestAI(options);
|
||||
}
|
||||
return choice;
|
||||
|
||||
default: throw new InvalidParameterException("AI chooseSingleCard does not know how to choose card for " + api);
|
||||
}
|
||||
}
|
||||
@@ -627,11 +677,14 @@ public class AiController {
|
||||
|
||||
switch(api) {
|
||||
case Discard:
|
||||
if ( mode.equals("Random") ) { //
|
||||
if ( mode.startsWith("Random") ) { //
|
||||
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Encode:
|
||||
return true;
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ public class ComputerUtil {
|
||||
if (unless != null && !unless.endsWith(">")) {
|
||||
final int amount = AbilityUtils.calculateAmount(source, unless, sa);
|
||||
|
||||
final int usableManaSources = CardFactoryUtil.getUsableManaSources(ai.getOpponent());
|
||||
final int usableManaSources = ComputerUtilCard.getUsableManaSources(ai.getOpponent());
|
||||
|
||||
// If the Unless isn't enough, this should be less likely to be used
|
||||
if (amount > usableManaSources) {
|
||||
@@ -384,7 +384,7 @@ public class ComputerUtil {
|
||||
if (landsInPlay.size() >= highestCMC
|
||||
|| (landsInPlay.size() + landsInHand.size() > 6 && landsInHand.size() > 1)) {
|
||||
// Don't need more land.
|
||||
return CardFactoryUtil.getWorstLand(landsInHand);
|
||||
return ComputerUtilCard.getWorstLand(landsInHand);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -678,11 +678,11 @@ public class ComputerUtil {
|
||||
Card c;
|
||||
|
||||
if (CardLists.getNotType(remaining, "Creature").size() == 0) {
|
||||
c = CardFactoryUtil.getWorstCreatureAI(remaining);
|
||||
c = ComputerUtilCard.getWorstCreatureAI(remaining);
|
||||
} else if (CardLists.getNotType(remaining, "Land").size() == 0) {
|
||||
c = CardFactoryUtil.getWorstLand(CardLists.filter(remaining, CardPredicates.Presets.LANDS));
|
||||
c = ComputerUtilCard.getWorstLand(CardLists.filter(remaining, CardPredicates.Presets.LANDS));
|
||||
} else {
|
||||
c = CardFactoryUtil.getWorstPermanentAI(remaining, false, false, false, false);
|
||||
c = ComputerUtilCard.getWorstPermanentAI(remaining, false, false, false, false);
|
||||
}
|
||||
|
||||
final ArrayList<Card> auras = c.getEnchantedBy();
|
||||
|
||||
@@ -29,7 +29,6 @@ import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.CounterType;
|
||||
import forge.GameEntity;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.game.phase.Combat;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.player.Player;
|
||||
@@ -360,9 +359,9 @@ public class ComputerUtilBlock {
|
||||
// destroyed
|
||||
killingBlockers = ComputerUtilBlock.getKillingBlockers(ai, attacker, safeBlockers, combat);
|
||||
if (killingBlockers.size() > 0) {
|
||||
blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
||||
blocker = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
|
||||
} else if (!attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||
blocker = CardFactoryUtil.getWorstCreatureAI(safeBlockers);
|
||||
blocker = ComputerUtilCard.getWorstCreatureAI(safeBlockers);
|
||||
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
||||
}
|
||||
} // no safe blockers
|
||||
@@ -378,9 +377,9 @@ public class ComputerUtilBlock {
|
||||
}
|
||||
// 4.Blockers that can destroy the attacker and are worth less
|
||||
if (blocker == null && killingBlockers.size() > 0) {
|
||||
final Card worst = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
||||
final Card worst = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
|
||||
|
||||
if ((CardFactoryUtil.evaluateCreature(worst) + ComputerUtilBlock.getDiff()) < CardFactoryUtil
|
||||
if ((ComputerUtilCard.evaluateCreature(worst) + ComputerUtilBlock.getDiff()) < ComputerUtilCard
|
||||
.evaluateCreature(attacker)) {
|
||||
blocker = worst;
|
||||
}
|
||||
@@ -471,7 +470,7 @@ public class ComputerUtilBlock {
|
||||
&& !(c.hasKeyword("First Strike") || c.hasKeyword("Double Strike"))) {
|
||||
return false;
|
||||
}
|
||||
return lifeInDanger || (CardFactoryUtil.evaluateCreature(c) + ComputerUtilBlock.getDiff()) < CardFactoryUtil
|
||||
return lifeInDanger || (ComputerUtilCard.evaluateCreature(c) + ComputerUtilBlock.getDiff()) < ComputerUtilCard
|
||||
.evaluateCreature(attacker);
|
||||
}
|
||||
});
|
||||
@@ -479,11 +478,11 @@ public class ComputerUtilBlock {
|
||||
return combat;
|
||||
}
|
||||
|
||||
final Card leader = CardFactoryUtil.getBestCreatureAI(usableBlockers);
|
||||
final Card leader = ComputerUtilCard.getBestCreatureAI(usableBlockers);
|
||||
blockGang.add(leader);
|
||||
usableBlockers.remove(leader);
|
||||
absorbedDamage = ComputerUtilCombat.getEnoughDamageToKill(leader, attacker.getNetCombatDamage(), attacker, true);
|
||||
currentValue = CardFactoryUtil.evaluateCreature(leader);
|
||||
currentValue = ComputerUtilCard.evaluateCreature(leader);
|
||||
|
||||
for (final Card blocker : usableBlockers) {
|
||||
// Add an additional blocker if the current blockers are not
|
||||
@@ -491,7 +490,7 @@ public class ComputerUtilBlock {
|
||||
final int currentDamage = ComputerUtilCombat.totalDamageOfBlockers(attacker, blockGang);
|
||||
final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker);
|
||||
final int absorbedDamage2 = ComputerUtilCombat.getEnoughDamageToKill(blocker, attacker.getNetCombatDamage(), attacker, true);
|
||||
final int addedValue = CardFactoryUtil.evaluateCreature(blocker);
|
||||
final int addedValue = ComputerUtilCard.evaluateCreature(blocker);
|
||||
final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
|
||||
if ((damageNeeded > currentDamage || CombatUtil.needsBlockers(attacker) > blockGang.size())
|
||||
@@ -499,7 +498,7 @@ public class ComputerUtilBlock {
|
||||
// The attacker will be killed
|
||||
&& (absorbedDamage2 + absorbedDamage > attacker.getNetCombatDamage()
|
||||
// only one blocker can be killed
|
||||
|| currentValue + addedValue - 50 <= CardFactoryUtil.evaluateCreature(attacker)
|
||||
|| currentValue + addedValue - 50 <= ComputerUtilCard.evaluateCreature(attacker)
|
||||
// or attacker is worth more
|
||||
|| (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)))
|
||||
// or life is in danger
|
||||
@@ -545,7 +544,7 @@ public class ComputerUtilBlock {
|
||||
ComputerUtilBlock.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true),
|
||||
combat);
|
||||
if ((killingBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||
final Card blocker = CardFactoryUtil.getWorstCreatureAI(killingBlockers);
|
||||
final Card blocker = ComputerUtilCard.getWorstCreatureAI(killingBlockers);
|
||||
combat.addBlocker(attacker, blocker);
|
||||
currentAttackers.remove(attacker);
|
||||
}
|
||||
@@ -579,7 +578,7 @@ public class ComputerUtilBlock {
|
||||
chumpBlockers = ComputerUtilBlock
|
||||
.getPossibleBlockers(attacker, ComputerUtilBlock.getBlockersLeft(), combat, true);
|
||||
if ((chumpBlockers.size() > 0) && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||
final Card blocker = CardFactoryUtil.getWorstCreatureAI(chumpBlockers);
|
||||
final Card blocker = ComputerUtilCard.getWorstCreatureAI(chumpBlockers);
|
||||
combat.addBlocker(attacker, blocker);
|
||||
currentAttackers.remove(attacker);
|
||||
ComputerUtilBlock.getBlockedButUnkilled().add(attacker);
|
||||
@@ -697,7 +696,7 @@ public class ComputerUtilBlock {
|
||||
final int additionalDamage = ComputerUtilCombat.dealsDamageAsBlocker(attacker, blocker);
|
||||
if ((damageNeeded > currentDamage)
|
||||
&& !(damageNeeded > (currentDamage + additionalDamage))
|
||||
&& ((CardFactoryUtil.evaluateCreature(blocker) + ComputerUtilBlock.getDiff()) < CardFactoryUtil
|
||||
&& ((ComputerUtilCard.evaluateCreature(blocker) + ComputerUtilBlock.getDiff()) < ComputerUtilCard
|
||||
.evaluateCreature(attacker)) && CombatUtil.canBlock(attacker, blocker, combat)) {
|
||||
combat.addBlocker(attacker, blocker);
|
||||
ComputerUtilBlock.getBlockersLeft().remove(blocker);
|
||||
|
||||
917
src/main/java/forge/game/ai/ComputerUtilCard.java
Normal file
917
src/main/java/forge/game/ai/ComputerUtilCard.java
Normal file
@@ -0,0 +1,917 @@
|
||||
package forge.game.ai;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
|
||||
import com.esotericsoftware.minlog.Log;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.CardUtil;
|
||||
import forge.Constant;
|
||||
import forge.card.CardType;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
*
|
||||
*/
|
||||
public class ComputerUtilCard {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostExpensivePermanentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getMostExpensivePermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
List<Card> all = list;
|
||||
if (targeted) {
|
||||
all = CardLists.filter(all, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.canBeTargetedBy(spell);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return ComputerUtilCard.getMostExpensivePermanentAI(all);
|
||||
}
|
||||
|
||||
// The AI doesn't really pick the best artifact, just the most expensive.
|
||||
/**
|
||||
* <p>
|
||||
* getBestArtifactAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestArtifactAI(final List<Card> list) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ARTIFACTS);
|
||||
if (all.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
// get biggest Artifact
|
||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
||||
}
|
||||
|
||||
// The AI doesn't really pick the best enchantment, just the most expensive.
|
||||
/**
|
||||
* <p>
|
||||
* getBestEnchantmentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestEnchantmentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS);
|
||||
if (targeted) {
|
||||
all = CardLists.filter(all, new Predicate<Card>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.canBeTargetedBy(spell);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// get biggest Enchantment
|
||||
return Aggregates.itemWithMax(all, CardPredicates.Accessors.fnGetCmc);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getBestLandAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestLandAI(final List<Card> list) {
|
||||
final List<Card> land = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
||||
if (!(land.size() > 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// prefer to target non basic lands
|
||||
final List<Card> nbLand = CardLists.filter(land, Predicates.not(CardPredicates.Presets.BASIC_LANDS));
|
||||
|
||||
if (nbLand.size() > 0) {
|
||||
// TODO - Rank non basics?
|
||||
return Aggregates.random(nbLand);
|
||||
}
|
||||
|
||||
// if no non-basic lands, target the least represented basic land type
|
||||
String sminBL = "";
|
||||
int iminBL = 20000; // hopefully no one will ever have more than 20000
|
||||
// lands of one type....
|
||||
int n = 0;
|
||||
for (String name : Constant.Color.BASIC_LANDS) {
|
||||
n = CardLists.getType(land, name).size();
|
||||
if ((n < iminBL) && (n > 0)) {
|
||||
// if two or more are tied, only the
|
||||
// first
|
||||
// one checked will be used
|
||||
iminBL = n;
|
||||
sminBL = name;
|
||||
}
|
||||
}
|
||||
if (iminBL == 20000) {
|
||||
return null; // no basic land was a minimum
|
||||
}
|
||||
|
||||
final List<Card> bLand = CardLists.getType(land, sminBL);
|
||||
|
||||
for (Card ut : Iterables.filter(bLand, CardPredicates.Presets.UNTAPPED)) {
|
||||
return ut;
|
||||
}
|
||||
|
||||
|
||||
return Aggregates.random(bLand); // random tapped land of least represented type
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getCheapestPermanentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getCheapestPermanentAI(final List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
List<Card> all = list;
|
||||
if (targeted) {
|
||||
all = CardLists.filter(all, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.canBeTargetedBy(spell);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (all.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// get cheapest card:
|
||||
Card cheapest = null;
|
||||
cheapest = all.get(0);
|
||||
|
||||
for (int i = 0; i < all.size(); i++) {
|
||||
if (cheapest.getManaCost().getCMC() <= cheapest.getManaCost().getCMC()) {
|
||||
cheapest = all.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
return cheapest;
|
||||
|
||||
}
|
||||
|
||||
// for Sarkhan the Mad
|
||||
/**
|
||||
* <p>
|
||||
* getCheapestCreatureAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param spell
|
||||
* a {@link forge.Card} object.
|
||||
* @param targeted
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getCheapestCreatureAI(List<Card> list, final SpellAbility spell, final boolean targeted) {
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.isCreature();
|
||||
}
|
||||
});
|
||||
return getCheapestPermanentAI(list, spell, targeted);
|
||||
}
|
||||
|
||||
// returns null if list.size() == 0
|
||||
/**
|
||||
* <p>
|
||||
* getBestAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestAI(final List<Card> list) {
|
||||
// Get Best will filter by appropriate getBest list if ALL of the list
|
||||
// is of that type
|
||||
if (CardLists.getNotType(list, "Creature").size() == 0) {
|
||||
return ComputerUtilCard.getBestCreatureAI(list);
|
||||
}
|
||||
|
||||
if (CardLists.getNotType(list, "Land").size() == 0) {
|
||||
return getBestLandAI(list);
|
||||
}
|
||||
|
||||
// TODO - Once we get an EvaluatePermanent this should call
|
||||
// getBestPermanent()
|
||||
return ComputerUtilCard.getMostExpensivePermanentAI(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* getBestCreatureAI.
|
||||
*
|
||||
* @param list
|
||||
* the list
|
||||
* @return the card
|
||||
*/
|
||||
public static Card getBestCreatureAI(final List<Card> list) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||
return Aggregates.itemWithMax(all, ComputerUtilCard.fnEvaluateCreature);
|
||||
}
|
||||
|
||||
// This selection rates tokens higher
|
||||
/**
|
||||
* <p>
|
||||
* getBestCreatureToBounceAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getBestCreatureToBounceAI(final List<Card> list) {
|
||||
final int tokenBonus = 40;
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||
Card biggest = null; // returns null if list.size() == 0
|
||||
int biggestvalue = 0;
|
||||
int newvalue = 0;
|
||||
|
||||
if (all.size() != 0) {
|
||||
biggest = all.get(0);
|
||||
|
||||
for (int i = 0; i < all.size(); i++) {
|
||||
biggestvalue = ComputerUtilCard.evaluateCreature(biggest);
|
||||
if (biggest.isToken()) {
|
||||
biggestvalue += tokenBonus; // raise the value of tokens
|
||||
}
|
||||
newvalue = ComputerUtilCard.evaluateCreature(all.get(i));
|
||||
if (all.get(i).isToken()) {
|
||||
newvalue += tokenBonus; // raise the value of tokens
|
||||
}
|
||||
if (biggestvalue < newvalue) {
|
||||
biggest = all.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return biggest;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getWorstAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstAI(final List<Card> list) {
|
||||
return ComputerUtilCard.getWorstPermanentAI(list, false, false, false, false);
|
||||
}
|
||||
|
||||
// returns null if list.size() == 0
|
||||
/**
|
||||
* <p>
|
||||
* getWorstCreatureAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstCreatureAI(final List<Card> list) {
|
||||
List<Card> all = CardLists.filter(list, CardPredicates.Presets.CREATURES);
|
||||
// get smallest creature
|
||||
return Aggregates.itemWithMin(all, ComputerUtilCard.fnEvaluateCreature);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getWorstPermanentAI.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @param biasEnch
|
||||
* a boolean.
|
||||
* @param biasLand
|
||||
* a boolean.
|
||||
* @param biasArt
|
||||
* a boolean.
|
||||
* @param biasCreature
|
||||
* a boolean.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstPermanentAI(final List<Card> list, final boolean biasEnch, final boolean biasLand,
|
||||
final boolean biasArt, final boolean biasCreature) {
|
||||
if (list.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (biasEnch && Iterables.any(list, CardPredicates.Presets.ENCHANTMENTS)) {
|
||||
return getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ENCHANTMENTS), null, false);
|
||||
}
|
||||
|
||||
if (biasArt && Iterables.any(list, CardPredicates.Presets.ARTIFACTS)) {
|
||||
return getCheapestPermanentAI(CardLists.filter(list, CardPredicates.Presets.ARTIFACTS), null, false);
|
||||
}
|
||||
|
||||
if (biasLand && Iterables.any(list, CardPredicates.Presets.LANDS)) {
|
||||
return ComputerUtilCard.getWorstLand(CardLists.filter(list, CardPredicates.Presets.LANDS));
|
||||
}
|
||||
|
||||
if (biasCreature && Iterables.any(list, CardPredicates.Presets.CREATURES)) {
|
||||
return getWorstCreatureAI(CardLists.filter(list, CardPredicates.Presets.CREATURES));
|
||||
}
|
||||
|
||||
List<Card> lands = CardLists.filter(list, CardPredicates.Presets.LANDS);
|
||||
if (lands.size() > 6) {
|
||||
return ComputerUtilCard.getWorstLand(lands);
|
||||
}
|
||||
|
||||
if ((CardLists.getType(list, "Artifact").size() > 0) || (CardLists.getType(list, "Enchantment").size() > 0)) {
|
||||
return getCheapestPermanentAI(CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.isArtifact() || c.isEnchantment();
|
||||
}
|
||||
}), null, false);
|
||||
}
|
||||
|
||||
if (CardLists.getType(list, "Creature").size() > 0) {
|
||||
return getWorstCreatureAI(CardLists.getType(list, "Creature"));
|
||||
}
|
||||
|
||||
// Planeswalkers fall through to here, lands will fall through if there
|
||||
// aren't very many
|
||||
return getCheapestPermanentAI(list, null, false);
|
||||
}
|
||||
|
||||
public static final Function<Card, Integer> fnEvaluateCreature = new Function<Card, Integer>() {
|
||||
@Override
|
||||
public Integer apply(Card a) {
|
||||
return ComputerUtilCard.evaluateCreature(a);
|
||||
}
|
||||
};
|
||||
public static final Comparator<Card> EvaluateCreatureComparator = new Comparator<Card>() {
|
||||
@Override
|
||||
public int compare(final Card a, final Card b) {
|
||||
return ComputerUtilCard.evaluateCreature(b) - ComputerUtilCard.evaluateCreature(a);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* <p>
|
||||
* evaluateCreature.
|
||||
* </p>
|
||||
*
|
||||
* @param c
|
||||
* a {@link forge.Card} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int evaluateCreature(final Card c) {
|
||||
|
||||
int value = 100;
|
||||
if (c.isToken()) {
|
||||
value = 80; // tokens should be worth less than actual cards
|
||||
}
|
||||
int power = c.getNetCombatDamage();
|
||||
final int toughness = c.getNetDefense();
|
||||
for (String keyword : c.getKeyword()) {
|
||||
if (keyword.equals("Prevent all combat damage that would be dealt by CARDNAME.")
|
||||
|| keyword.equals("Prevent all damage that would be dealt by CARDNAME.")
|
||||
|| keyword.equals("Prevent all combat damage that would be dealt to and dealt by CARDNAME.")
|
||||
|| keyword.equals("Prevent all damage that would be dealt to and dealt by CARDNAME.")) {
|
||||
power = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
value += power * 15;
|
||||
value += toughness * 10;
|
||||
value += c.getCMC() * 5;
|
||||
|
||||
// Evasion keywords
|
||||
if (c.hasKeyword("Flying")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (c.hasKeyword("Horsemanship")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (c.hasKeyword("Unblockable")) {
|
||||
value += power * 10;
|
||||
} else {
|
||||
if (c.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")) {
|
||||
value += power * 6;
|
||||
}
|
||||
if (c.hasKeyword("Fear")) {
|
||||
value += power * 6;
|
||||
}
|
||||
if (c.hasKeyword("Intimidate")) {
|
||||
value += power * 6;
|
||||
}
|
||||
if (c.hasStartOfKeyword("CARDNAME can't be blocked except by")) {
|
||||
value += power * 5;
|
||||
}
|
||||
if (c.hasStartOfKeyword("CARDNAME can't be blocked by")) {
|
||||
value += power * 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Other good keywords
|
||||
if (power > 0) {
|
||||
if (c.hasKeyword("Double Strike")) {
|
||||
value += 10 + (power * 15);
|
||||
} else if (c.hasKeyword("First Strike")) {
|
||||
value += 10 + (power * 5);
|
||||
}
|
||||
if (c.hasKeyword("Deathtouch")) {
|
||||
value += 25;
|
||||
}
|
||||
if (c.hasKeyword("Lifelink")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (power > 1 && c.hasKeyword("Trample")) {
|
||||
value += (power - 1) * 5;
|
||||
}
|
||||
if (c.hasKeyword("Vigilance")) {
|
||||
value += (power * 5) + (toughness * 5);
|
||||
}
|
||||
if (c.hasKeyword("Wither")) {
|
||||
value += power * 10;
|
||||
}
|
||||
if (c.hasKeyword("Infect")) {
|
||||
value += power * 15;
|
||||
}
|
||||
value += c.getKeywordMagnitude("Rampage");
|
||||
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
||||
+ "put into a graveyard, put a +1/+1 counter on CARDNAME.")) {
|
||||
value += 2;
|
||||
}
|
||||
if (c.hasKeyword("Whenever a creature dealt damage by CARDNAME this turn is "
|
||||
+ "put into a graveyard, put a +2/+2 counter on CARDNAME.")) {
|
||||
value += 3;
|
||||
}
|
||||
}
|
||||
|
||||
value += c.getKeywordMagnitude("Bushido") * 16;
|
||||
value += c.getAmountOfKeyword("Flanking") * 15;
|
||||
value += c.getAmountOfKeyword("Exalted") * 15;
|
||||
value += c.getKeywordMagnitude("Annihilator") * 50;
|
||||
|
||||
|
||||
// Defensive Keywords
|
||||
if (c.hasKeyword("Reach") && !c.hasKeyword("Flying")) {
|
||||
value += 5;
|
||||
}
|
||||
if (c.hasKeyword("CARDNAME can block creatures with shadow as though they didn't have shadow.")) {
|
||||
value += 3;
|
||||
}
|
||||
|
||||
// Protection
|
||||
if (c.hasKeyword("Indestructible")) {
|
||||
value += 70;
|
||||
}
|
||||
if (c.hasKeyword("Prevent all damage that would be dealt to CARDNAME.")) {
|
||||
value += 60;
|
||||
} else if (c.hasKeyword("Prevent all combat damage that would be dealt to CARDNAME.")) {
|
||||
value += 50;
|
||||
}
|
||||
if (c.hasKeyword("Hexproof")) {
|
||||
value += 35;
|
||||
} else if (c.hasKeyword("Shroud")) {
|
||||
value += 30;
|
||||
}
|
||||
if (c.hasStartOfKeyword("Protection")) {
|
||||
value += 20;
|
||||
}
|
||||
if (c.hasStartOfKeyword("PreventAllDamageBy")) {
|
||||
value += 10;
|
||||
}
|
||||
value += c.getKeywordMagnitude("Absorb") * 11;
|
||||
|
||||
// Bad keywords
|
||||
if (c.hasKeyword("Defender") || c.hasKeyword("CARDNAME can't attack.")) {
|
||||
value -= (power * 9) + 40;
|
||||
} else if (c.getSVar("SacrificeEndCombat").equals("True")) {
|
||||
value -= 40;
|
||||
}
|
||||
if (c.hasKeyword("CARDNAME can't block.")) {
|
||||
value -= 10;
|
||||
} else if (c.hasKeyword("CARDNAME attacks each turn if able.")) {
|
||||
value -= 10;
|
||||
} else if (c.hasKeyword("CARDNAME can block only creatures with flying.")) {
|
||||
value -= toughness * 5;
|
||||
}
|
||||
|
||||
if (c.hasStartOfKeyword("When CARDNAME is dealt damage, destroy it.")) {
|
||||
value -= (toughness - 1) * 9;
|
||||
}
|
||||
|
||||
if (c.hasKeyword("CARDNAME can't attack or block.")) {
|
||||
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
||||
}
|
||||
if (c.hasKeyword("CARDNAME doesn't untap during your untap step.")) {
|
||||
if (c.isTapped()) {
|
||||
value = 50 + (c.getCMC() * 5); // reset everything - useless
|
||||
} else {
|
||||
value -= 50;
|
||||
}
|
||||
}
|
||||
if (c.hasKeyword("At the beginning of the end step, destroy CARDNAME.")
|
||||
|| c.hasKeyword("At the beginning of the end step, exile CARDNAME.")
|
||||
|| c.hasKeyword("At the beginning of the end step, sacrifice CARDNAME.")) {
|
||||
value -= 50;
|
||||
} else if (c.hasStartOfKeyword("Cumulative upkeep")) {
|
||||
value -= 30;
|
||||
} else if (c.hasStartOfKeyword("At the beginning of your upkeep, destroy CARDNAME unless you pay")
|
||||
|| c.hasStartOfKeyword("At the beginning of your upkeep, sacrifice CARDNAME unless you pay")
|
||||
|| c.hasStartOfKeyword("Upkeep:")) {
|
||||
value -= 20;
|
||||
} else if (c.hasStartOfKeyword("(Echo unpaid)")) {
|
||||
value -= 10;
|
||||
}
|
||||
|
||||
if (c.hasStartOfKeyword("At the beginning of your upkeep, CARDNAME deals")) {
|
||||
value -= 20;
|
||||
}
|
||||
if (c.hasStartOfKeyword("Fading")) {
|
||||
value -= 20;
|
||||
}
|
||||
if (c.hasStartOfKeyword("Vanishing")) {
|
||||
value -= 20;
|
||||
}
|
||||
if (c.getSVar("Targeting").equals("Dies")) {
|
||||
value -= 25;
|
||||
}
|
||||
|
||||
for (final SpellAbility sa : c.getSpellAbilities()) {
|
||||
if (sa.isAbility()) {
|
||||
value += 10;
|
||||
}
|
||||
}
|
||||
if (!c.getManaAbility().isEmpty()) {
|
||||
value += 10;
|
||||
}
|
||||
|
||||
if (c.isUntapped()) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
// paired creatures are more valuable because they grant a bonus to the other creature
|
||||
if (c.isPaired()) {
|
||||
value += 14;
|
||||
}
|
||||
|
||||
return value;
|
||||
|
||||
} // evaluateCreature
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* evaluatePermanentList.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int evaluatePermanentList(final List<Card> list) {
|
||||
int value = 0;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
value += list.get(i).getCMC() + 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* evaluateCreatureList.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int evaluateCreatureList(final List<Card> list) {
|
||||
int value = 0;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
value += evaluateCreature(list.get(i));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* doesCreatureAttackAI.
|
||||
* </p>
|
||||
*
|
||||
* @param ai
|
||||
* the AI player
|
||||
* @param card
|
||||
* a {@link forge.Card} object.
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean doesCreatureAttackAI(final Player ai, final Card card) {
|
||||
final List<Card> att = new AiAttackController(ai, ai.getOpponent()).getAttackers().getAttackers();
|
||||
|
||||
return att.contains(card);
|
||||
}
|
||||
|
||||
// may return null
|
||||
/**
|
||||
* <p>
|
||||
* getRandomCard.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getRandomCard(final List<Card> list) {
|
||||
if (list.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int index = ComputerUtilCard.random.nextInt(list.size());
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
public static Random random = MyRandom.getRandom();
|
||||
/**
|
||||
* getMostExpensivePermanentAI.
|
||||
*
|
||||
* @param all
|
||||
* the all
|
||||
* @return the card
|
||||
*/
|
||||
public static Card getMostExpensivePermanentAI(final List<Card> all) {
|
||||
if (all.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
Card biggest = null;
|
||||
biggest = all.get(0);
|
||||
|
||||
int bigCMC = 0;
|
||||
for (int i = 0; i < all.size(); i++) {
|
||||
final Card card = all.get(i);
|
||||
int curCMC = card.getCMC();
|
||||
|
||||
// Add all cost of all auras with the same controller
|
||||
final List<Card> auras = CardLists.filterControlledBy(card.getEnchantedBy(), card.getController());
|
||||
curCMC += Aggregates.sum(auras, CardPredicates.Accessors.fnGetCmc) + auras.size();
|
||||
|
||||
if (curCMC >= bigCMC) {
|
||||
bigCMC = curCMC;
|
||||
biggest = all.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
return biggest;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostProminentCardName.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getMostProminentCardName(final List<Card> list) {
|
||||
|
||||
if (list.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
|
||||
for (final Card c : list) {
|
||||
final String name = c.getName();
|
||||
Integer currentCnt = map.get(name);
|
||||
map.put(name, currentCnt == null ? Integer.valueOf(1) : Integer.valueOf(1 + currentCnt));
|
||||
} // for
|
||||
|
||||
int max = 0;
|
||||
String maxName = "";
|
||||
|
||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||
final String type = entry.getKey();
|
||||
// Log.debug(type + " - " + entry.getValue());
|
||||
|
||||
if (max < entry.getValue()) {
|
||||
max = entry.getValue();
|
||||
maxName = type;
|
||||
}
|
||||
}
|
||||
return maxName;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostProminentCreatureType.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getMostProminentCreatureType(final List<Card> list) {
|
||||
|
||||
if (list.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
|
||||
for (final Card c : list) {
|
||||
final ArrayList<String> typeList = c.getType();
|
||||
|
||||
for (final String var : typeList) {
|
||||
if (CardType.isACreatureType(var)) {
|
||||
if (!map.containsKey(var)) {
|
||||
map.put(var, 1);
|
||||
} else {
|
||||
map.put(var, map.get(var) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for
|
||||
|
||||
int max = 0;
|
||||
String maxType = "";
|
||||
|
||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||
final String type = entry.getKey();
|
||||
// Log.debug(type + " - " + entry.getValue());
|
||||
|
||||
if (max < entry.getValue()) {
|
||||
max = entry.getValue();
|
||||
maxType = type;
|
||||
}
|
||||
}
|
||||
|
||||
return maxType;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getMostProminentColor.
|
||||
* </p>
|
||||
*
|
||||
* @param list
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link java.lang.String} object.
|
||||
*/
|
||||
public static String getMostProminentColor(final List<Card> list) {
|
||||
|
||||
final Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
|
||||
for (final Card c : list) {
|
||||
for (final String color : CardUtil.getColors(c)) {
|
||||
if (color.equals("colorless")) {
|
||||
// nothing to do
|
||||
} else if (!map.containsKey(color)) {
|
||||
map.put(color, 1);
|
||||
} else {
|
||||
map.put(color, map.get(color) + 1);
|
||||
}
|
||||
}
|
||||
} // for
|
||||
|
||||
int max = 0;
|
||||
String maxColor = "";
|
||||
|
||||
for (final Entry<String, Integer> entry : map.entrySet()) {
|
||||
final String color = entry.getKey();
|
||||
Log.debug(color + " - " + entry.getValue());
|
||||
|
||||
if (max < entry.getValue()) {
|
||||
max = entry.getValue();
|
||||
maxColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
return maxColor;
|
||||
}
|
||||
|
||||
public static List<String> getColorByProminence(final List<Card> list) {
|
||||
final HashMap<String, Integer> counts = new HashMap<String, Integer>();
|
||||
for (String color : Constant.Color.ONLY_COLORS) {
|
||||
counts.put(color, 0);
|
||||
}
|
||||
for (Card c : list) {
|
||||
List<String> colors = c.determineColor().toStringList();
|
||||
for (String col : colors) {
|
||||
if (counts.containsKey(col)) {
|
||||
counts.put(col.toString(), counts.get(col.toString()) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayList<String> res = new ArrayList<String>(counts.keySet());
|
||||
Collections.sort(res, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(final String a, final String b) {
|
||||
return counts.get(b) - counts.get(a);
|
||||
}
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getUsableManaSources.
|
||||
* </p>
|
||||
*
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
* @return a int.
|
||||
*/
|
||||
public static int getUsableManaSources(final Player player) {
|
||||
List<Card> list = CardLists.filter(player.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
for (final SpellAbility am : c.getAIPlayableMana()) {
|
||||
if (am.canPlay()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getWorstLand.
|
||||
* </p>
|
||||
*
|
||||
* @param lands
|
||||
* a {@link forge.CardList} object.
|
||||
* @return a {@link forge.Card} object.
|
||||
*/
|
||||
public static Card getWorstLand(final List<Card> lands) {
|
||||
Card worstLand = null;
|
||||
int maxScore = 0;
|
||||
// first, check for tapped, basic lands
|
||||
for (Card tmp : lands) {
|
||||
int score = tmp.isTapped() ? 2 : 0;
|
||||
score += tmp.isBasicLand() ? 1 : 0;
|
||||
if (score >= maxScore) {
|
||||
worstLand = tmp;
|
||||
maxScore = score;
|
||||
}
|
||||
}
|
||||
return worstLand;
|
||||
} // end getWorstLand
|
||||
|
||||
}
|
||||
@@ -17,7 +17,6 @@ import forge.Singletons;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostPayment;
|
||||
import forge.card.mana.ManaCostBeingPaid;
|
||||
@@ -748,7 +747,7 @@ public class ComputerUtilMana {
|
||||
}
|
||||
}
|
||||
// check if combo mana can produce most common color in hand
|
||||
String commonColor = CardFactoryUtil.getMostProminentColor(ai.getCardsIn(
|
||||
String commonColor = ComputerUtilCard.getMostProminentColor(ai.getCardsIn(
|
||||
ZoneType.Hand));
|
||||
if (!commonColor.isEmpty() && abMana.getComboColors().contains(MagicColor.toShortString(commonColor))) {
|
||||
choice = MagicColor.toShortString(commonColor);
|
||||
|
||||
@@ -50,6 +50,7 @@ import forge.game.GameState;
|
||||
import forge.game.GlobalRuleChange;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilBlock;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
@@ -1573,7 +1574,7 @@ public class CombatUtil {
|
||||
enchantment = ((Card) check);
|
||||
}
|
||||
} else {
|
||||
enchantment = CardFactoryUtil.getBestEnchantmentAI(enchantments, this, false);
|
||||
enchantment = ComputerUtilCard.getBestEnchantmentAI(enchantments, this, false);
|
||||
}
|
||||
if ((enchantment != null) && attacker.isInPlay()) {
|
||||
Singletons.getModel().getGame().getAction().changeZone(Singletons.getModel().getGame().getZoneOf(enchantment),
|
||||
|
||||
@@ -30,9 +30,9 @@ import forge.CardPredicates;
|
||||
import forge.CounterType;
|
||||
import forge.GameEntity;
|
||||
import forge.Singletons;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.control.input.Input;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -246,7 +246,7 @@ public class Untap extends Phase {
|
||||
artList = CardLists.filter(artList, Presets.ARTIFACTS);
|
||||
artList = CardLists.filter(artList, tappedCanUntap);
|
||||
if (artList.size() > 0) {
|
||||
CardFactoryUtil.getBestArtifactAI(artList).untap();
|
||||
ComputerUtilCard.getBestArtifactAI(artList).untap();
|
||||
}
|
||||
} else {
|
||||
final Input target = new Input() {
|
||||
|
||||
@@ -44,6 +44,7 @@ import forge.control.input.InputSelectManyCards;
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCombat;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
@@ -501,7 +502,7 @@ public class Upkeep extends Phase {
|
||||
if (indestruct.size() > 0) {
|
||||
game.getAction().destroyNoRegeneration(indestruct.get(0));
|
||||
} else if (targets.size() > 0) {
|
||||
final Card target = CardFactoryUtil.getWorstCreatureAI(targets);
|
||||
final Card target = ComputerUtilCard.getWorstCreatureAI(targets);
|
||||
if (null == target) {
|
||||
// must be nothing valid to destroy
|
||||
} else {
|
||||
@@ -632,7 +633,7 @@ public class Upkeep extends Phase {
|
||||
if (c.getController().isComputer()) {
|
||||
target = GuiChoose.one("Select a card to sacrifice", playerLand);
|
||||
} else {
|
||||
target = CardFactoryUtil.getBestLandAI(playerLand);
|
||||
target = ComputerUtilCard.getBestLandAI(playerLand);
|
||||
}
|
||||
game.getAction().sacrifice(target, null);
|
||||
} // end resolve()
|
||||
@@ -1027,7 +1028,7 @@ public class Upkeep extends Phase {
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (player.isComputer()) {
|
||||
Card toTap = CardFactoryUtil.getWorstPermanentAI(list, false, false, false, false);
|
||||
Card toTap = ComputerUtilCard.getWorstPermanentAI(list, false, false, false, false);
|
||||
// try to find non creature cards without tap abilities
|
||||
List<Card> betterList = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
|
||||
@@ -25,10 +25,10 @@ import forge.Card;
|
||||
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.AiController;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.MyRandom;
|
||||
@@ -175,7 +175,7 @@ public class AIPlayer extends Player {
|
||||
public final void sacrificePermanent(final String prompt, final List<Card> choices) {
|
||||
if (choices.size() > 0) {
|
||||
// TODO - this could probably use better AI
|
||||
final Card c = CardFactoryUtil.getWorstPermanentAI(choices, false, false, false, false);
|
||||
final Card c = ComputerUtilCard.getWorstPermanentAI(choices, false, false, false, false);
|
||||
game.getAction().sacrificeDestroy(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import forge.control.input.InputPayManaExecuteCommands;
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.event.SpellResolvedEvent;
|
||||
import forge.game.phase.PhaseType;
|
||||
@@ -901,9 +902,9 @@ public class MagicStack extends MyObservable {
|
||||
// AI choosing what to haunt
|
||||
final List<Card> oppCreats = CardLists.filterControlledBy(creats, source.getController().getOpponents());
|
||||
if (oppCreats.size() != 0) {
|
||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(oppCreats));
|
||||
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(oppCreats));
|
||||
} else {
|
||||
haunterDiesWork.setTargetCard(CardFactoryUtil.getWorstCreatureAI(creats));
|
||||
haunterDiesWork.setTargetCard(ComputerUtilCard.getWorstCreatureAI(creats));
|
||||
}
|
||||
this.add(haunterDiesWork);
|
||||
}
|
||||
|
||||
@@ -107,4 +107,22 @@ public class GuiDownloadPicturesLQ extends GuiDownloader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the ideal filename.
|
||||
*
|
||||
* @param cardName
|
||||
* the card name
|
||||
* @param artIndex
|
||||
* the art index
|
||||
* @param artIndexMax
|
||||
* the art index max
|
||||
* @return the string
|
||||
*/
|
||||
public static String buildIdealFilename(final String cardName, final int artIndex, final int artIndexMax) {
|
||||
final String nn = artIndexMax > 1 ? Integer.toString(artIndex + 1) : "";
|
||||
final String mwsCardName = GuiDisplayUtil.cleanStringMWS(cardName);
|
||||
// 3 letter set code with MWS filename format
|
||||
return String.format("%s%s.full.jpg", mwsCardName, nn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloader {
|
||||
|
||||
if (!foundSetImage) {
|
||||
final int artsCnt = c.getRules().getEditionInfo(setCode3).getCopiesCount();
|
||||
final String filename = CardUtil.buildIdealFilename(cardName, c.getArtIndex(), artsCnt);
|
||||
final String filename = GuiDownloadPicturesLQ.buildIdealFilename(cardName, c.getArtIndex(), artsCnt);
|
||||
String url = urlBase + setCode2 + "/" + Base64Coder.encodeString(filename, true);
|
||||
cList.add(new DownloadObject(url, new File(this.picturesPath + File.separator + setCode3, filename)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user