private boolean phasesUnpreferredTargeting(
      final Game game, final SpellAbility sa, final boolean mandatory) {
    final Card source = sa.getHostCard();
    final TargetRestrictions tgt = sa.getTargetRestrictions();

    CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
    list =
        CardLists.getTargetableCards(
            CardLists.getValidCards(list, tgt.getValidTgts(), source.getController(), source), sa);

    return false;
  }
Beispiel #2
0
  boolean pumpAgainstRemoval(Player ai, SpellAbility sa) {
    final List<GameObject> objects =
        ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
    final List<Card> threatenedTargets = new ArrayList<Card>();
    final TargetRestrictions tgt = sa.getTargetRestrictions();

    if (tgt == null) {
      // For pumps without targeting restrictions, just return immediately until this is fleshed
      // out.
      return false;
    }

    List<Card> targetables =
        CardLists.getValidCards(
            ai.getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard());
    targetables = CardLists.getTargetableCards(targetables, sa);
    targetables = ComputerUtil.getSafeTargets(ai, sa, targetables);
    for (final Card c : targetables) {
      if (objects.contains(c)) {
        threatenedTargets.add(c);
      }
    }
    if (!threatenedTargets.isEmpty()) {
      ComputerUtilCard.sortByEvaluateCreature(threatenedTargets);
      for (Card c : threatenedTargets) {
        sa.getTargets().add(c);
        if (sa.getTargets().getNumTargeted() >= tgt.getMaxTargets(sa.getHostCard(), sa)) {
          break;
        }
      }
      if (sa.getTargets().getNumTargeted() > tgt.getMaxTargets(sa.getHostCard(), sa)
          || sa.getTargets().getNumTargeted() < tgt.getMinTargets(sa.getHostCard(), sa)) {
        sa.resetTargets();
        return false;
      }
      return true;
    }
    return false;
  }
Beispiel #3
0
  private boolean pumpMandatoryTarget(
      final Player ai, final SpellAbility sa, final boolean mandatory) {
    final Game game = ai.getGame();
    List<Card> list = game.getCardsIn(ZoneType.Battlefield);
    final TargetRestrictions tgt = sa.getTargetRestrictions();
    final Player opp = ai.getOpponent();
    list =
        CardLists.getValidCards(
            list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getHostCard());
    list = CardLists.getTargetableCards(list, sa);

    if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
      sa.resetTargets();
      return false;
    }

    // Remove anything that's already been targeted
    for (final Card c : sa.getTargets().getTargetCards()) {
      list.remove(c);
    }

    List<Card> pref;
    List<Card> forced;
    final Card source = sa.getHostCard();

    if (sa.isCurse()) {
      pref = CardLists.filterControlledBy(list, opp);
      forced = CardLists.filterControlledBy(list, ai);
    } else {
      pref = CardLists.filterControlledBy(list, ai);
      forced = CardLists.filterControlledBy(list, opp);
    }

    while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
      if (pref.isEmpty()) {
        break;
      }

      Card c;
      if (CardLists.getNotType(pref, "Creature").isEmpty()) {
        c = ComputerUtilCard.getBestCreatureAI(pref);
      } else {
        c = ComputerUtilCard.getMostExpensivePermanentAI(pref, sa, true);
      }

      pref.remove(c);

      sa.getTargets().add(c);
    }

    while (sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) {
      if (forced.isEmpty()) {
        break;
      }

      Card c;
      if (CardLists.getNotType(forced, "Creature").isEmpty()) {
        c = ComputerUtilCard.getWorstCreatureAI(forced);
      } else {
        c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, true);
      }

      forced.remove(c);

      sa.getTargets().add(c);
    }

    if (sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa)) {
      sa.resetTargets();
      return false;
    }

    return true;
  } // pumpMandatoryTarget()
Beispiel #4
0
  private boolean pumpTgtAI(
      final Player ai,
      final SpellAbility sa,
      final int defense,
      final int attack,
      final boolean mandatory) {
    final List<String> keywords =
        sa.hasParam("KW") ? Arrays.asList(sa.getParam("KW").split(" & ")) : new ArrayList<String>();
    final Game game = ai.getGame();
    final Card source = sa.getHostCard();

    if (!mandatory
        && !sa.isTrigger()
        && game.getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS)
        && !(sa.isCurse() && defense < 0)
        && !this.containsNonCombatKeyword(keywords)
        && !sa.hasParam("UntilYourNextTurn")) {
      return false;
    }

    final Player opp = ai.getOpponent();
    final TargetRestrictions tgt = sa.getTargetRestrictions();
    sa.resetTargets();
    if (sa.hasParam("TargetingPlayer") && sa.getActivatingPlayer().equals(ai) && !sa.isTrigger()) {
      Player targetingPlayer =
          AbilityUtils.getDefinedPlayers(source, sa.getParam("TargetingPlayer"), sa).get(0);
      sa.setTargetingPlayer(targetingPlayer);
      return targetingPlayer.getController().chooseTargetsFor(sa);
    }

    List<Card> list = new ArrayList<Card>();
    if (sa.hasParam("AILogic")) {
      if (sa.getParam("AILogic").equals("HighestPower")) {
        list =
            CardLists.getValidCards(
                CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES),
                tgt.getValidTgts(),
                ai,
                source);
        list = CardLists.getTargetableCards(list, sa);
        CardLists.sortByPowerDesc(list);
        if (!list.isEmpty()) {
          sa.getTargets().add(list.get(0));
          return true;
        } else {
          return false;
        }
      }
      if (sa.getParam("AILogic").equals("Fight") || sa.getParam("AILogic").equals("PowerDmg")) {
        final AbilitySub tgtFight = sa.getSubAbility();
        List<Card> aiCreatures = ai.getCreaturesInPlay();
        aiCreatures = CardLists.getTargetableCards(aiCreatures, sa);
        aiCreatures = ComputerUtil.getSafeTargets(ai, sa, aiCreatures);
        ComputerUtilCard.sortByEvaluateCreature(aiCreatures);
        // sort is suboptimal due to conflicting needs depending on game state:
        //  -deathtouch for deal damage
        //  -max power for damage to player
        //  -survivability for generic "fight"
        //  -no support for "heroic"

        List<Card> humCreatures = ai.getOpponent().getCreaturesInPlay();
        humCreatures = CardLists.getTargetableCards(humCreatures, tgtFight);
        ComputerUtilCard.sortByEvaluateCreature(humCreatures);
        if (humCreatures.isEmpty() || aiCreatures.isEmpty()) {
          return false;
        }
        int buffedAtk = attack, buffedDef = defense;
        for (Card humanCreature : humCreatures) {
          for (Card aiCreature : aiCreatures) {
            if (sa.isSpell()) { // heroic triggers adding counters
              for (Trigger t : aiCreature.getTriggers()) {
                if (t.getMode() == TriggerType.SpellCast) {
                  final Map<String, String> params = t.getMapParams();
                  if ("Card.Self".equals(params.get("TargetsValid"))
                      && "You".equals(params.get("ValidActivatingPlayer"))
                      && params.containsKey("Execute")) {
                    SpellAbility heroic =
                        AbilityFactory.getAbility(
                            aiCreature.getSVar(params.get("Execute")), aiCreature);
                    if ("Self".equals(heroic.getParam("Defined"))
                        && "P1P1".equals(heroic.getParam("CounterType"))) {
                      int amount =
                          AbilityUtils.calculateAmount(
                              aiCreature, heroic.getParam("CounterNum"), heroic);
                      buffedAtk += amount;
                      buffedDef += amount;
                    }
                    break;
                  }
                }
              }
            }
            if (sa.getParam("AILogic").equals("PowerDmg")) {
              if (FightAi.canKill(aiCreature, humanCreature, buffedAtk)) {
                sa.getTargets().add(aiCreature);
                tgtFight.getTargets().add(humanCreature);
                return true;
              }
            } else {
              if (FightAi.shouldFight(aiCreature, humanCreature, buffedAtk, buffedDef)) {
                sa.getTargets().add(aiCreature);
                tgtFight.getTargets().add(humanCreature);
                return true;
              }
            }
          }
        }
      }
      return false;
    } else if (sa.isCurse()) {
      if (sa.canTarget(opp)) {
        sa.getTargets().add(opp);
        return true;
      }
      list = this.getCurseCreatures(ai, sa, defense, attack, keywords);
    } else {
      if (!tgt.canTgtCreature()) {
        ZoneType zone = tgt.getZone().get(0);
        list = game.getCardsIn(zone);
      } else {
        list = this.getPumpCreatures(ai, sa, defense, attack, keywords);
      }
      if (sa.canTarget(ai)) {
        sa.getTargets().add(ai);
        return true;
      }
    }

    list = CardLists.getValidCards(list, tgt.getValidTgts(), ai, source);
    if (game.getStack().isEmpty()) {
      // If the cost is tapping, don't activate before declare
      // attack/block
      if (sa.getPayCosts() != null && sa.getPayCosts().hasTapCost()) {
        if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
            && game.getPhaseHandler().isPlayerTurn(ai)) {
          list.remove(sa.getHostCard());
        }
        if (game.getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS)
            && game.getPhaseHandler().isPlayerTurn(opp)) {
          list.remove(sa.getHostCard());
        }
      }
    }

    if (list.isEmpty()) {
      return mandatory && this.pumpMandatoryTarget(ai, sa, mandatory);
    }

    if (!sa.isCurse()) {
      // Don't target cards that will die.
      list = ComputerUtil.getSafeTargets(ai, sa, list);
    }

    while (sa.getTargets().getNumTargeted() < tgt.getMaxTargets(source, sa)) {
      Card t = null;
      // boolean goodt = false;

      if (list.isEmpty()) {
        if ((sa.getTargets().getNumTargeted() < tgt.getMinTargets(source, sa))
            || (sa.getTargets().getNumTargeted() == 0)) {
          if (mandatory) {
            return this.pumpMandatoryTarget(ai, sa, mandatory);
          }

          sa.resetTargets();
          return false;
        } else {
          // TODO is this good enough? for up to amounts?
          break;
        }
      }

      t = ComputerUtilCard.getBestAI(list);
      // option to hold removal instead only applies for single targeted removal
      if (!sa.isTrigger() && tgt.getMaxTargets(source, sa) == 1 && sa.isCurse()) {
        if (!ComputerUtilCard.useRemovalNow(sa, t, -defense, ZoneType.Graveyard)) {
          return false;
        }
      }
      sa.getTargets().add(t);
      list.remove(t);
    }

    return true;
  } // pumpTgtAI()