@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(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(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(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(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); }
@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; }