Esempio n. 1
0
  public static boolean isValidBand(List<Card> band, boolean shareDamage) {
    if (band.isEmpty()) {
      // An empty band is not a valid band
      return false;
    }

    int bandingCreatures = CardLists.getKeyword(band, "Banding").size();
    int neededBandingCreatures = shareDamage ? 1 : band.size() - 1;
    if (neededBandingCreatures <= bandingCreatures) {
      // For starting a band, only one can be non-Banding
      // For sharing damage, only one needs to be Banding
      return true;
    }

    // Legends lands, Master of the Hunt, Old Fogey (just in case)
    // Since Bands With Other is a dead keyword, no major reason to make this more generic
    // But if someone is super motivated, feel free to do it. Just make sure you update Tolaria and
    // Shelkie Brownie
    String[] bandsWithString = {
      "Bands with Other Legendary Creatures",
      "Bands with Other Creatures named Wolves of the Hunt",
      "Bands with Other Dinosaurs"
    };
    String[] validString = {"Legendary.Creature", "Creature.namedWolves of the Hunt", "Dinosaur"};

    Card source = band.get(0);
    for (int i = 0; i < bandsWithString.length; i++) {
      String keyword = bandsWithString[i];
      String valid = validString[i];

      // Check if a bands with other keyword exists in band, and each creature in the band fits the
      // valid quality
      if (!CardLists.getKeyword(band, keyword).isEmpty()
          && CardLists.getValidCards(band, valid, source.getController(), source).size()
              == band.size()) {
        return true;
      }
    }

    return false;
  }
Esempio n. 2
0
  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;
  }