/*
   * (non-Javadoc)
   *
   * @see
   * forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility,
   * forge.Card, forge.Player, forge.card.cost.Cost)
   */
  @Override
  public final boolean canPay(final SpellAbility ability) {
    final Player activator = ability.getActivatingPlayer();
    final Card source = ability.getHostCard();
    CardCollectionView validCards = activator.getCardsIn(ZoneType.Battlefield);
    validCards = CardLists.getValidCards(validCards, this.getType().split(";"), activator, source);
    validCards =
        CardLists.filter(
            validCards,
            new Predicate<Card>() {
              @Override
              public boolean apply(final Card c) {
                return c.hasCounters();
              }
            });
    if (validCards.isEmpty()) {
      return false;
    }
    Integer i = this.convertAmount();

    if (i == null) {
      i = AbilityUtils.calculateAmount(source, this.getAmount(), ability);
    }
    int allCounters = 0;
    for (Card c : validCards) {
      final Map<CounterType, Integer> tgtCounters = c.getCounters();
      for (Integer value : tgtCounters.values()) {
        allCounters += value;
      }
    }

    return i <= allCounters;
  }
 @Override
 public Player chooseSinglePlayer(Player ai, SpellAbility sa, Iterable<Player> choices) {
   Player chosen = null;
   if ("Curse".equals(sa.getParam("AILogic"))) {
     for (Player pc : choices) {
       if (pc.isOpponentOf(ai)) {
         chosen = pc;
         break;
       }
     }
     if (chosen == null) {
       chosen = Iterables.getFirst(choices, null);
       System.out.println("No good curse choices. Picking first available: " + chosen);
     }
   } else if ("Pump".equals(sa.getParam("AILogic"))) {
     chosen = Iterables.contains(choices, ai) ? ai : Iterables.getFirst(choices, null);
   } else if ("BestAllyBoardPosition".equals(sa.getParam("AILogic"))) {
     List<Player> prefChoices = Lists.newArrayList(choices);
     prefChoices.removeAll(ai.getOpponents());
     if (!prefChoices.isEmpty()) {
       chosen = ComputerUtil.evaluateBoardPosition(prefChoices);
     }
     if (chosen == null) {
       chosen = Iterables.getFirst(choices, null);
       System.out.println("No good curse choices. Picking first available: " + chosen);
     }
   } else if ("MostCardsInHand".equals(sa.getParam("AILogic"))) {
     int cardsInHand = 0;
     for (final Player p : choices) {
       int hand = p.getCardsIn(ZoneType.Hand).size();
       if (hand >= cardsInHand) {
         chosen = p;
         cardsInHand = hand;
       }
     }
   } else if ("LeastCreatures".equals(sa.getParam("AILogic"))) {
     int creats = 50;
     for (final Player p : choices) {
       int curr = p.getCreaturesInPlay().size();
       if (curr <= creats) {
         chosen = p;
         creats = curr;
       }
     }
   } else {
     System.out.println("Default player choice logic.");
     chosen = Iterables.contains(choices, ai) ? ai : Iterables.getFirst(choices, null);
   }
   return chosen;
 }
  /* (non-Javadoc)
   * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, forge.card.spellability.SpellAbility)
   */
  @Override
  protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
    String logic = sa.getParam("AILogic");
    Game game = aiPlayer.getGame();

    if ("ZeroToughness".equals(logic)) {
      // If Creature has Zero Toughness, make sure some static ability is in play
      // That will grant a toughness bonus

      final List<Card> list = aiPlayer.getCardsIn(ZoneType.Battlefield);
      if (!Iterables.any(
          list,
          Predicates.or(
              CardPredicates.nameEquals("Glorious Anthem"),
              CardPredicates.nameEquals("Gaea's Anthem")))) {
        return false;
      }

      // TODO See if card ETB will survive after Static Effects
      /*
      List<Card> cards = game.getCardsIn(ZoneType.Battlefield);

      for(Card c : cards) {
          ArrayList<StaticAbility> statics = c.getStaticAbilities();
          for(StaticAbility s : statics) {
              final Map<String, String> stabMap = s.parseParams();

              if (!stabMap.get("Mode").equals("Continuous")) {
                  continue;
              }

              final String affected = stabMap.get("Affected");

              if (affected == null) {
                  continue;
              }
          }
      }
      */
    }

    // Wait for Main2 if possible
    if (game.getPhaseHandler().is(PhaseType.MAIN1)
        && !ComputerUtil.castPermanentInMain1(aiPlayer, sa)) {
      return false;
    }

    // AI shouldn't be retricted all that much for Creatures for now
    return true;
  }
Exemple #4
0
  /*
   * (non-Javadoc)
   *
   * @see
   * forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility,
   * forge.Card, forge.Player, forge.card.cost.Cost)
   */
  @Override
  public final boolean canPay(final SpellAbility ability) {
    final Player activator = ability.getActivatingPlayer();
    final Card source = ability.getHostCard();
    if (!this.payCostFromSource()) {
      boolean needsAnnoucement =
          ability.hasParam("Announce") && this.getType().contains(ability.getParam("Announce"));

      CardCollectionView typeList = activator.getCardsIn(ZoneType.Battlefield);
      typeList = CardLists.getValidCards(typeList, this.getType().split(";"), activator, source);

      final Integer amount = this.convertAmount();
      if (!needsAnnoucement && amount != null && typeList.size() < amount) {
        return false;
      }
    } else if (!source.isInPlay()) {
      return false;
    }

    return true;
  }
Exemple #5
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;
  }
  protected boolean revealHandTargetAI(final Player ai, final SpellAbility sa) {
    final TargetRestrictions tgt = sa.getTargetRestrictions();

    Player opp = ai.getOpponent();
    final int humanHandSize = opp.getCardsIn(ZoneType.Hand).size();

    if (tgt != null) {
      // ability is targeted
      sa.resetTargets();

      final boolean canTgtHuman = opp.canBeTargetedBy(sa);

      if (!canTgtHuman || (humanHandSize == 0)) {
        return false;
      } else {
        sa.getTargets().add(opp);
      }
    } else {
      // if it's just defined, no big deal
    }

    return true;
  } // revealHandTargetAI()
Exemple #7
0
 /* (non-Javadoc)
  * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, java.util.Map, forge.card.spellability.SpellAbility)
  */
 @Override
 protected boolean canPlayAI(Player ai, final SpellAbility sa) {
   Card object1 = null;
   Card object2 = null;
   final Card source = sa.getHostCard();
   final String type = sa.getParam("Type");
   if (sa.hasParam("Object")) {
     object1 = AbilityUtils.getDefinedCards(source, sa.getParam("Object"), sa).get(0);
   } else {
     object1 = source;
   }
   final ZoneType zone1 =
       sa.hasParam("Zone1") ? ZoneType.smartValueOf(sa.getParam("Zone1")) : ZoneType.Battlefield;
   final ZoneType zone2 =
       sa.hasParam("Zone2") ? ZoneType.smartValueOf(sa.getParam("Zone2")) : ZoneType.Hand;
   CardCollection list = new CardCollection(ai.getCardsIn(zone2));
   if (type != null) {
     list = CardLists.getValidCards(list, type, ai, source);
   }
   object2 = ComputerUtilCard.getBestAI(list);
   if (object1 == null
       || object2 == null
       || !object1.isInZone(zone1)
       || !object1.getOwner().equals(ai)) {
     return false;
   }
   if (type.equals("Aura")) {
     Card c = object1.getEnchantingCard();
     if (!c.canBeEnchantedBy(object2)) {
       return false;
     }
   }
   if (object2.getCMC() > object1.getCMC()) {
     return MyRandom.getRandom().nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
   }
   return false;
 }
  private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) {

    final Card source = sa.getHostCard();
    final TargetRestrictions tgt = sa.getTargetRestrictions();
    final boolean destroy = sa.hasParam("Destroy");

    Player opp = ai.getOpponent();
    if (tgt != null) {
      sa.resetTargets();
      if (!opp.canBeTargetedBy(sa)) {
        return false;
      }
      sa.getTargets().add(opp);
      final String valid = sa.getParam("SacValid");
      String num = sa.getParam("Amount");
      num = (num == null) ? "1" : num;
      final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa);

      List<Card> list =
          CardLists.getValidCards(
              ai.getOpponent().getCardsIn(ZoneType.Battlefield),
              valid.split(","),
              sa.getActivatingPlayer(),
              sa.getHostCard());
      for (Card c : list) {
        if (c.hasSVar("SacMe") && Integer.parseInt(c.getSVar("SacMe")) > 3) {
          return false;
        }
      }
      if (!destroy) {
        list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(sa));
      } else {
        if (!CardLists.getKeyword(list, "Indestructible").isEmpty()) {
          // human can choose to destroy indestructibles
          return false;
        }
      }

      if (list.isEmpty()) {
        return false;
      }

      if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
        // Set PayX here to maximum value.
        final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
        source.setSVar("PayX", Integer.toString(xPay));
      }

      final int half = (amount / 2) + (amount % 2); // Half of amount
      // rounded up

      // If the Human has at least half rounded up of the amount to be
      // sacrificed, cast the spell
      if (!sa.isTrigger() && list.size() < half) {
        return false;
      }
    }

    final String defined = sa.getParam("Defined");
    final String valid = sa.getParam("SacValid");
    if (defined == null) {
      // Self Sacrifice.
    } else if (defined.equals("Each") || (defined.equals("Opponent") && !sa.isTrigger())) {
      // If Sacrifice hits both players:
      // Only cast it if Human has the full amount of valid
      // Only cast it if AI doesn't have the full amount of Valid
      // TODO: Cast if the type is favorable: my "worst" valid is
      // worse than his "worst" valid
      final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1";
      int amount = AbilityUtils.calculateAmount(source, num, sa);

      if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
        // Set PayX here to maximum value.
        amount = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
      }

      List<Card> humanList =
          CardLists.getValidCards(
              opp.getCardsIn(ZoneType.Battlefield),
              valid.split(","),
              sa.getActivatingPlayer(),
              sa.getHostCard());

      // Since all of the cards have remAIDeck:True, I enabled 1 for 1
      // (or X for X) trades for special decks
      if (humanList.size() < amount) {
        return false;
      }
    } else if (defined.equals("You")) {
      List<Card> computerList =
          CardLists.getValidCards(
              ai.getCardsIn(ZoneType.Battlefield),
              valid.split(","),
              sa.getActivatingPlayer(),
              sa.getHostCard());
      for (Card c : computerList) {
        if (c.hasSVar("SacMe") || ComputerUtilCard.evaluateCreature(c) <= 135) {
          return true;
        }
      }
      return false;
    }

    return true;
  }