public static boolean destroyAllCanPlayAI( final AbilityFactory af, final SpellAbility sa, final boolean noRegen) { // AI needs to be expanded, since this function can be pretty complex based on what the expected // targets could be Random r = MyRandom.random; Cost abCost = sa.getPayCosts(); final Card source = sa.getSourceCard(); final HashMap<String, String> params = af.getMapParams(); String Valid = ""; if (params.containsKey("ValidCards")) Valid = params.get("ValidCards"); if (Valid.contains("X") && source.getSVar("X").equals("Count$xPaid")) { // Set PayX here to maximum value. int xPay = ComputerUtil.determineLeftoverMana(sa); source.setSVar("PayX", Integer.toString(xPay)); Valid = Valid.replace("X", Integer.toString(xPay)); } CardList humanlist = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer); CardList computerlist = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer); humanlist = humanlist.getValidCards(Valid.split(","), source.getController(), source); computerlist = computerlist.getValidCards(Valid.split(","), source.getController(), source); humanlist = humanlist.getNotKeyword("Indestructible"); computerlist = computerlist.getNotKeyword("Indestructible"); if (abCost != null) { // AI currently disabled for some costs if (abCost.getSacCost()) { // OK } if (abCost.getLifeCost()) { if (AllZone.ComputerPlayer.getLife() - abCost.getLifeAmount() < 4) return false; } if (abCost.getDiscardCost()) ; // OK if (abCost.getSubCounter()) { // OK } } if (!ComputerUtil.canPayCost(sa)) return false; // prevent run-away activations - first time will always return true boolean chance = r.nextFloat() <= Math.pow(.6667, source.getAbilityUsed()); // if only creatures are affected evaluate both lists and pass only if human creatures are more // valuable if (humanlist.getNotType("Creature").size() == 0 && computerlist.getNotType("Creature").size() == 0) { if (CardFactoryUtil.evaluateCreatureList(computerlist) + 200 >= CardFactoryUtil.evaluateCreatureList(humanlist)) return false; } // only lands involved else if (humanlist.getNotType("Land").size() == 0 && computerlist.getNotType("Land").size() == 0) { if (CardFactoryUtil.evaluatePermanentList(computerlist) + 1 >= CardFactoryUtil.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.evaluatePermanentList(humanlist)) return false; Ability_Sub subAb = sa.getSubAbility(); if (subAb != null) chance &= subAb.chkAI_Drawback(); return ((r.nextFloat() < .9667) && chance); }
public static boolean destroyCanPlayAI(final AbilityFactory af, final SpellAbility sa) { // AI needs to be expanded, since this function can be pretty complex based on what the expected // targets could be Random r = MyRandom.random; Cost abCost = sa.getPayCosts(); Target abTgt = sa.getTarget(); final Card source = sa.getSourceCard(); final boolean noRegen = af.getMapParams().containsKey("NoRegen"); CardList list; list = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer); list = list.getTargetableCards(source); if (abTgt != null) { list = list.getValidCards(abTgt.getValidTgts(), source.getController(), source); list = list.getNotKeyword("Indestructible"); // If NoRegen is not set, filter out creatures that have a regeneration shield if (!noRegen) { // TODO: filter out things that could regenerate in response? might be tougher? list = list.filter( new CardListFilter() { public boolean addCard(Card c) { return (c.getShield() == 0 && !ComputerUtil.canRegenerate(c)); } }); } if (list.size() == 0) return false; } if (abCost != null) { // AI currently disabled for some costs if (abCost.getSacCost() && !abCost.getSacThis()) { // only sacrifice something that's supposed to be sacrificed String sacType = abCost.getSacType(); CardList typeList = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer); typeList = typeList.getValidCards(sacType.split(","), source.getController(), source); if (ComputerUtil.getCardPreference(source, "SacCost", typeList) == null) return false; } if (abCost.getLifeCost()) { if (AllZone.ComputerPlayer.getLife() - abCost.getLifeAmount() < 4) return false; } if (abCost.getDiscardCost()) return false; if (abCost.getSubCounter()) { // OK } } if (!ComputerUtil.canPayCost(sa)) return false; // prevent run-away activations - first time will always return true boolean chance = r.nextFloat() <= Math.pow(.6667, source.getAbilityUsed()); // Targeting if (abTgt != null) { abTgt.resetTargets(); // target loop while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { if (list.size() == 0) { if (abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa) || abTgt.getNumTargeted() == 0) { abTgt.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? break; } } Card choice = null; if (list.getNotType("Creature").size() == 0) choice = CardFactoryUtil.AI_getBestCreature( list); // if the targets are only creatures, take the best else choice = CardFactoryUtil.AI_getMostExpensivePermanent(list, af.getHostCard(), true); if (choice == null) { // can't find anything left if (abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa) || abTgt.getNumTargeted() == 0) { abTgt.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? break; } } list.remove(choice); abTgt.addTarget(choice); } } else { return false; } Ability_Sub subAb = sa.getSubAbility(); if (subAb != null) chance &= subAb.chkAI_Drawback(); return ((r.nextFloat() < .6667) && chance); }