- Complete the basic implementation of AI optional cost choice, remove getOptionalCosts.

This commit is contained in:
Agetian
2018-12-16 09:11:54 +03:00
parent 7a53a0fb36
commit 14799ccd62
4 changed files with 32 additions and 156 deletions

View File

@@ -849,20 +849,22 @@ public class AiController {
int neededMana = 0;
boolean dangerousRecurringCost = false;
for (SpellAbility sa2 : GameActionUtil.getOptionalCosts(sa)) {
if (sa2.isOptionalCostPaid(OptionalCost.Buyback)) {
Cost sac = sa2.getPayCosts();
CostAdjustment.adjust(sac, sa2);
if (sac.getCostMana() != null) {
neededMana = sac.getCostMana().getMana().getCMC();
}
if (sac.hasSpecificCostType(CostPayLife.class)
|| sac.hasSpecificCostType(CostDiscard.class)
|| sac.hasSpecificCostType(CostSacrifice.class)) {
dangerousRecurringCost = true;
}
Cost costWithBuyback = sa.getPayCosts().copy();
for (OptionalCostValue opt : GameActionUtil.getOptionalCostValues(sa)) {
if (opt.getType() == OptionalCost.Buyback) {
costWithBuyback.add(opt.getCost());
}
}
CostAdjustment.adjust(costWithBuyback, sa);
if (costWithBuyback.getCostMana() != null) {
neededMana = costWithBuyback.getCostMana().getMana().getCMC();
}
if (costWithBuyback.hasSpecificCostType(CostPayLife.class)
|| costWithBuyback.hasSpecificCostType(CostDiscard.class)
|| costWithBuyback.hasSpecificCostType(CostSacrifice.class)) {
dangerousRecurringCost = true;
}
// won't be able to afford buyback any time soon
// if Buyback cost includes sacrifice, life, discard
@@ -1568,7 +1570,7 @@ public class AiController {
sa.setActivatingPlayer(player);
sa.setLastStateBattlefield(game.getLastStateBattlefield());
sa.setLastStateGraveyard(game.getLastStateGraveyard());
AiPlayDecision opinion = canPlayAndPayFor(sa);
// PhaseHandler ph = game.getPhaseHandler();
// System.out.printf("Ai thinks '%s' of %s -> %s @ %s %s >>> \n", opinion, sa.getHostCard(), sa, Lang.getPossesive(ph.getPlayerTurn().getName()), ph.getPhase());

View File

@@ -105,17 +105,22 @@ public class ComputerUtilAbility {
final List<SpellAbility> result = Lists.newArrayList();
for (SpellAbility sa : newAbilities) {
sa.setActivatingPlayer(player);
// TODO: remove this once all optional costs are ported over to chooseOptionalCosts
result.addAll(GameActionUtil.getOptionalCosts(sa));
// Optional cost selection through the AI controller
boolean choseOptCost = false;
List<OptionalCostValue> list = GameActionUtil.getOptionalCostValues(sa);
if (!list.isEmpty()) {
list = player.getController().chooseOptionalCosts(sa, list);
if (!list.isEmpty()) {
choseOptCost = true;
result.add(GameActionUtil.addOptionalCosts(sa, list));
}
}
// Add only one ability: either the one with preferred optional costs, or the original one if there are none
if (!choseOptCost) {
result.add(sa);
}
}
return result;

View File

@@ -1147,19 +1147,20 @@ public class PlayerControllerAi extends PlayerController {
public List<OptionalCostValue> chooseOptionalCosts(SpellAbility chosen,
List<OptionalCostValue> optionalCostValues) {
List<OptionalCostValue> chosenOptCosts = Lists.newArrayList();
Cost cost = chosen.getPayCosts();
Cost costSoFar = chosen.getPayCosts() != null ? chosen.getPayCosts().copy() : Cost.Zero;
for (OptionalCostValue opt : optionalCostValues) {
if (opt.getType() == OptionalCost.Entwine) {
// Test implementation: just always choose Entwine
Cost fullCost = opt.getCost().copy().add(cost);
SpellAbility fullCostSa = chosen.copyWithDefinedCost(fullCost);
if (ComputerUtilCost.canPayCost(fullCostSa, player)) {
chosenOptCosts.add(opt);
}
// Specific code for optional costs should be made conditional here
}
else {
System.out.println("Skipping unported optional cost: " + opt.getType());
// Generic code: for now, chooses the optional cost if it can be paid (and later - played)
Cost fullCost = opt.getCost().copy().add(costSoFar);
SpellAbility fullCostSa = chosen.copyWithDefinedCost(fullCost);
if (ComputerUtilCost.canPayCost(fullCostSa, player)) {
chosenOptCosts.add(opt);
costSoFar.add(opt.getCost());
System.out.println("Chosen: " + opt + " for total cost of " + costSoFar.toSimpleString());
}
}