@Override
  public PaymentDecision visit(CostSacrifice cost) {
    if (cost.payCostFromSource()) {
      return PaymentDecision.card(source);
    }
    if (cost.getAmount().equals("All")) {
      /*List<Card> typeList = new ArrayList<Card>(activator.getCardsIn(ZoneType.Battlefield));
      typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), activator, source);
      if (activator.hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) {
          typeList = CardLists.getNotType(typeList, "Creature");
      }*/
      // Does the AI want to use Sacrifice All?
      return null;
    }

    Integer c = cost.convertAmount();
    if (c == null) {
      if (ability.getSVar(cost.getAmount()).equals("XChoice")) {
        return null;
      }

      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }
    List<Card> list =
        ComputerUtil.chooseSacrificeType(
            player, cost.getType(), source, ability.getTargetCard(), c);
    return PaymentDecision.card(list);
  }
  @Override
  public PaymentDecision visit(CostReveal cost) {

    final String type = cost.getType();
    List<Card> hand = new ArrayList<Card>(player.getCardsIn(ZoneType.Hand));

    if (cost.payCostFromSource()) {
      if (!hand.contains(source)) {
        return null;
      }
      return PaymentDecision.card(source);
    }

    if (cost.getType().equals("Hand"))
      return PaymentDecision.card(player.getCardsIn(ZoneType.Hand));

    if (cost.getType().equals("SameColor")) {
      return null;
    }

    hand = CardLists.getValidCards(hand, type.split(";"), player, source);
    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      if (sVar.equals("XChoice")) {
        c = hand.size();
      } else {
        c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
      }
    }

    final AiController aic = ((PlayerControllerAi) player.getController()).getAi();
    return PaymentDecision.card(aic.getCardsToDiscard(c, type.split(";"), ability));
  }
  @Override
  public PaymentDecision visit(CostGainControl cost) {
    if (cost.payCostFromSource()) return PaymentDecision.card(source);

    Integer c = cost.convertAmount();
    if (c == null) {
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    final List<Card> typeList =
        CardLists.getValidCards(
            player.getGame().getCardsIn(ZoneType.Battlefield),
            cost.getType().split(";"),
            player,
            source);

    if (typeList.size() < c) {
      return null;
    }

    CardLists.sortByPowerAsc(typeList);
    final List<Card> res = new ArrayList<Card>();

    for (int i = 0; i < c; i++) {
      res.add(typeList.get(i));
    }
    return res.isEmpty() ? null : PaymentDecision.card(res);
  }
  @Override
  public PaymentDecision visit(CostExile cost) {
    if (cost.payCostFromSource()) {
      return PaymentDecision.card(source);
    }

    if (cost.getType().equals("All")) {
      return PaymentDecision.card(player.getCardsIn(cost.getFrom()));
    } else if (cost.getType().contains("FromTopGrave")) {
      return null;
    }

    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      // Generalize cost
      if (sVar.equals("XChoice")) {
        return null;
      }
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    if (cost.getFrom().equals(ZoneType.Library)) {
      return PaymentDecision.card(player.getCardsIn(ZoneType.Library, c));
    } else if (cost.sameZone) {
      // TODO Determine exile from same zone for AI
      return null;
    } else {
      List<Card> chosen =
          ComputerUtil.chooseExileFrom(
              player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
      return null == chosen ? null : PaymentDecision.card(chosen);
    }
  }
  @Override
  public PaymentDecision visit(CostReturn cost) {
    if (cost.payCostFromSource()) return PaymentDecision.card(source);

    Integer c = cost.convertAmount();
    if (c == null) {
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    List<Card> res =
        ComputerUtil.chooseReturnType(player, cost.getType(), source, ability.getTargetCard(), c);
    return res.isEmpty() ? null : PaymentDecision.card(res);
  }
  @Override
  public PaymentDecision visit(CostUntapType cost) {
    final String amount = cost.getAmount();
    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(amount);
      if (sVar.equals("XChoice")) {
        List<Card> typeList = player.getGame().getCardsIn(ZoneType.Battlefield);
        typeList =
            CardLists.getValidCards(
                typeList, cost.getType().split(";"), player, ability.getHostCard());
        if (!cost.canUntapSource) {
          typeList.remove(source);
        }
        typeList = CardLists.filter(typeList, Presets.TAPPED);
        c = typeList.size();
        source.setSVar("ChosenX", "Number$" + Integer.toString(c));
      } else {
        c = AbilityUtils.calculateAmount(source, amount, ability);
      }
    }

    List<Card> list =
        ComputerUtil.chooseUntapType(player, cost.getType(), source, cost.canUntapSource, c);

    if (list == null) {
      System.out.println("Couldn't find a valid card to untap for: " + source.getName());
      return null;
    }

    return PaymentDecision.card(list);
  }
  @Override
  public PaymentDecision visit(CostExiledMoveToGrave cost) {
    Integer c = cost.convertAmount();
    List<Card> chosen = new ArrayList<Card>();

    if (c == null) {
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    List<Card> typeList = player.getGame().getCardsIn(ZoneType.Exile);

    typeList = CardLists.getValidCards(typeList, cost.getType().split(";"), player, source);

    if (typeList.size() < c) {
      return null;
    }

    CardLists.sortByPowerAsc(typeList);
    Collections.reverse(typeList);

    for (int i = 0; i < c; i++) {
      chosen.add(typeList.get(i));
    }

    return chosen.isEmpty() ? null : PaymentDecision.card(chosen);
  }
  @Override
  public PaymentDecision visit(CostTapType cost) {
    final String amount = cost.getAmount();
    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(amount);
      if (sVar.equals("XChoice")) {
        List<Card> typeList =
            CardLists.getValidCards(
                player.getCardsIn(ZoneType.Battlefield),
                cost.getType().split(";"),
                ability.getActivatingPlayer(),
                ability.getHostCard());
        typeList = CardLists.filter(typeList, Presets.UNTAPPED);
        c = typeList.size();
        source.setSVar("ChosenX", "Number$" + Integer.toString(c));
      } else {
        c = AbilityUtils.calculateAmount(source, amount, ability);
      }
    }
    if (cost.getType().contains("sharesCreatureTypeWith")
        || cost.getType().contains("withTotalPowerGE")) {
      return null;
    }

    List<Card> totap =
        ComputerUtil.chooseTapType(player, cost.getType(), source, !cost.canTapSource, c);

    if (totap == null) {
      System.out.println("Couldn't find a valid card to tap for: " + source.getName());
      return null;
    }

    return PaymentDecision.card(totap);
  }
 @Override
 public PaymentDecision visit(CostUnattach cost) {
   Card cardToUnattach = cost.findCardToUnattach(source, (Player) player, ability);
   if (cardToUnattach == null) {
     // We really shouldn't be able to get here if there's nothing to unattach
     return null;
   }
   return PaymentDecision.card(cardToUnattach);
 }
Exemple #10
0
  @Override
  public PaymentDecision visit(CostAddMana cost) {
    Integer c = cost.convertAmount();

    if (c == null) {
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    return PaymentDecision.number(c);
  }
Exemple #11
0
 @Override
 public PaymentDecision visit(CostChooseCreatureType cost) {
   String choice =
       player
           .getController()
           .chooseSomeType(
               "Creature",
               ability,
               new ArrayList<String>(CardType.getCreatureTypes()),
               new ArrayList<String>());
   return PaymentDecision.type(choice);
 }
Exemple #12
0
  @Override
  public PaymentDecision visit(CostRemoveCounter cost) {
    final String amount = cost.getAmount();
    Integer c = cost.convertAmount();
    final String type = cost.getType();

    if (c == null) {
      final String sVar = ability.getSVar(amount);
      if (sVar.equals("XChoice")) {
        c = AbilityUtils.calculateAmount(source, "ChosenX", ability);
      } else if (amount.equals("All")) {
        c = source.getCounters(cost.counter);
      } else {
        c = AbilityUtils.calculateAmount(source, amount, ability);
      }
    }

    if (!cost.payCostFromSource()) {
      List<Card> typeList;
      if (type.equals("OriginalHost")) {
        typeList = Lists.newArrayList(ability.getOriginalHost());
      } else {
        typeList =
            CardLists.getValidCards(player.getCardsIn(cost.zone), type.split(";"), player, source);
      }
      for (Card card : typeList) {
        if (card.getCounters(cost.counter) >= c) {
          return PaymentDecision.card(card, c);
        }
      }
      return null;
    }

    if (c > source.getCounters(cost.counter)) {
      System.out.println("Not enough " + cost.counter + " on " + source.getName());
      return null;
    }

    return PaymentDecision.card(source, c);
  }
Exemple #13
0
  @Override
  public PaymentDecision visit(CostPutCounter cost) {

    if (cost.payCostFromSource()) {
      return PaymentDecision.card(source);
    }

    final List<Card> typeList =
        CardLists.getValidCards(
            player.getGame().getCardsIn(ZoneType.Battlefield),
            cost.getType().split(";"),
            player,
            source);

    Card card = null;
    if (cost.getType().equals("Creature.YouCtrl")) {
      card = ComputerUtilCard.getWorstCreatureAI(typeList);
    } else {
      card = ComputerUtilCard.getWorstPermanentAI(typeList, false, false, false, false);
    }
    return PaymentDecision.card(card);
  }
Exemple #14
0
  @Override
  public PaymentDecision visit(CostDiscard cost) {
    final String type = cost.getType();

    final List<Card> hand = player.getCardsIn(ZoneType.Hand);
    if (type.equals("LastDrawn")) {
      if (!hand.contains(player.getLastDrawnCard())) {
        return null;
      }
      return PaymentDecision.card(player.getLastDrawnCard());
    } else if (cost.payCostFromSource()) {
      if (!hand.contains(source)) {
        return null;
      }

      return PaymentDecision.card(source);
    } else if (type.equals("Hand")) {
      return PaymentDecision.card(hand);
    }

    if (type.contains("WithSameName")) {
      return null;
    }
    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      if (sVar.equals("XChoice")) {
        return null;
      }
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    if (type.equals("Random")) {
      return PaymentDecision.card(CardLists.getRandomSubList(hand, c));
    } else {
      final AiController aic = ((PlayerControllerAi) player.getController()).getAi();
      return PaymentDecision.card(aic.getCardsToDiscard(c, type.split(";"), ability));
    }
  }
Exemple #15
0
 @Override
 public PaymentDecision visit(CostFlipCoin cost) {
   Integer c = cost.convertAmount();
   if (c == null) {
     final String sVar = ability.getSVar(cost.getAmount());
     // Generalize cost
     if (sVar.equals("XChoice")) {
       return null;
     }
     c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
   }
   return PaymentDecision.number(c);
 }
Exemple #16
0
  @Override
  public PaymentDecision visit(CostRemoveAnyCounter cost) {
    final String amount = cost.getAmount();
    final int c = AbilityUtils.calculateAmount(source, amount, ability);
    final String type = cost.getType();

    List<Card> typeList =
        CardLists.getValidCards(
            player.getCardsIn(ZoneType.Battlefield), type.split(";"), player, source);
    List<Card> hperms =
        CardLists.filter(
            typeList,
            new Predicate<Card>() {
              @Override
              public boolean apply(final Card crd) {
                for (final CounterType c1 : CounterType.values()) {
                  if (crd.getCounters(c1) >= c && ComputerUtil.isNegativeCounter(c1, crd)) {
                    return true;
                  }
                }
                return false;
              }
            });

    if (hperms.isEmpty()) return null;

    PaymentDecision result = PaymentDecision.card(hperms);
    Card valid = hperms.get(0);
    for (CounterType c1 : valid.getCounters().keySet()) {
      if (valid.getCounters(c1) >= c && ComputerUtil.isNegativeCounter(c1, valid)) {
        result.ct = c1;
        break;
      }
    }
    // Only find cards with enough negative counters
    // TODO: add ai for Chisei, Heart of Oceans
    return result;
  }
Exemple #17
0
  @Override
  public PaymentDecision visit(CostGainLife cost) {
    final List<Player> oppsThatCanGainLife = new ArrayList<Player>();

    for (final Player opp : cost.getPotentialTargets(player, source)) {
      if (opp.canGainLife()) {
        oppsThatCanGainLife.add(opp);
      }
    }

    if (oppsThatCanGainLife.size() == 0) {
      return null;
    }

    return PaymentDecision.players(oppsThatCanGainLife);
  }
Exemple #18
0
  @Override
  public PaymentDecision visit(CostMill cost) {
    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      // Generalize cost
      if (sVar.equals("XChoice")) {
        return null;
      }

      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    List<Card> topLib = player.getCardsIn(ZoneType.Library, c);
    return topLib.size() < c ? null : PaymentDecision.card(topLib);
  }
Exemple #19
0
 @Override
 public PaymentDecision visit(CostPayLife cost) {
   Integer c = cost.convertAmount();
   if (c == null) {
     final String sVar = ability.getSVar(cost.getAmount());
     // Generalize cost
     if (sVar.equals("XChoice")) {
       return null;
     } else {
       c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
     }
   }
   if (!player.canPayLife(c)) {
     return null;
   }
   // activator.payLife(c, null);
   return PaymentDecision.number(c);
 }
Exemple #20
0
  @Override
  public PaymentDecision visit(CostPutCardToLib cost) {
    Integer c = cost.convertAmount();
    final Game game = player.getGame();
    List<Card> chosen = new ArrayList<Card>();
    List<Card> list;

    if (cost.isSameZone()) {
      list = new ArrayList<Card>(game.getCardsIn(cost.getFrom()));
    } else {
      list = new ArrayList<Card>(player.getCardsIn(cost.getFrom()));
    }

    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      // Generalize cost
      if (sVar.equals("XChoice")) {
        return null;
      }

      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    list = CardLists.getValidCards(list, cost.getType().split(";"), player, source);

    if (cost.isSameZone()) {
      // Jotun Grunt
      // TODO: improve AI
      final List<Player> players = game.getPlayers();
      for (Player p : players) {
        List<Card> enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
        if (enoughType.size() >= c) {
          chosen.addAll(enoughType);
          break;
        }
      }
      chosen = chosen.subList(0, c);
    } else {
      chosen =
          ComputerUtil.choosePutToLibraryFrom(
              player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
    }
    return chosen.isEmpty() ? null : PaymentDecision.card(chosen);
  }
Exemple #21
0
  @Override
  public PaymentDecision visit(CostExileFromStack cost) {

    Integer c = cost.convertAmount();
    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      // Generalize cost
      if (sVar.equals("XChoice")) {
        return null;
      }
      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }
    List<SpellAbility> chosen = new ArrayList<SpellAbility>();
    for (SpellAbilityStackInstance si : source.getGame().getStack()) {
      SpellAbility sp = si.getSpellAbility().getRootAbility();
      if (si.getSourceCard().isValid(cost.getType().split(";"), source.getController(), source)) {
        chosen.add(sp);
      }
    }
    return chosen.isEmpty() ? null : PaymentDecision.spellabilities(chosen);
  }
Exemple #22
0
 @Override
 public PaymentDecision visit(CostUntap cost) {
   return PaymentDecision.number(0);
 }
Exemple #23
0
 @Override
 public PaymentDecision visit(CostPartMana cost) {
   return PaymentDecision.number(0);
 }