From 3e325d243a738c5efc8d7b0faec94e5d7e8bc769 Mon Sep 17 00:00:00 2001 From: Agetian Date: Mon, 30 Jan 2017 17:48:39 +0000 Subject: [PATCH] - Basic and conservative prediction of the total number of available blockers with vehicles in mind for the purpose of AI alpha-strike: the AI will try to acknowledge the fact that for the vehicle to become active, generally at least one other creature will need to tap. This should allow the AI to somewhat better predict when it can alpha strike for lethal in presence of vehicles. - Crew prediction needs to be somehow expanded in general: in all other attack routines the AI assumes that each vehicle on the battlefield will activate and the human will not tap anything to activate them, which leads to the AI becoming very "scared" of inactive vehicles on the battlefield. --- .../java/forge/ai/AiAttackController.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index 0df42d21ab5..2778bf87abb 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -25,12 +25,14 @@ import com.google.common.base.Predicate; import com.google.common.collect.Lists; import forge.ai.ability.AnimateAi; +import forge.card.CardTypeView; import forge.game.GameEntity; import forge.game.ability.ApiType; import forge.game.ability.effects.ProtectEffect; import forge.game.card.Card; import forge.game.card.CardCollectionView; import forge.game.card.CardLists; +import forge.game.card.CardPredicates; import forge.game.card.CounterType; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; @@ -399,6 +401,25 @@ public class AiAttackController { final List remainingAttackers = new ArrayList(this.attackers); final List remainingBlockers = new ArrayList(this.blockers); final List blockedAttackers = new ArrayList(); + + // Conservative prediction for vehicles: the AI tries to acknowledge the fact that + // at least one creature will tap to crew a blocking vehicle when predicting if an + // alpha strike for lethal is viable + int maxBlockersAfterCrew = remainingBlockers.size(); + for (Card c : this.blockers) { + CardTypeView cardType = c.getCurrentState().getType(); + boolean oppControlsPW = !CardLists.filter(c.getController().getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.PLANEWALKERS).isEmpty(); + + if (c.getName().equals("Heart of Kirin") && oppControlsPW) { + continue; + } else if (c.getName().equals("Peacewalker Colossus")) { + // TODO: the AI should probably predict if the human can actually use its activated ability + continue; + } else if (cardType.hasSubtype("Vehicle") && !cardType.isCreature()) { + maxBlockersAfterCrew--; + } + } + final Player opp = this.defendingOpponent; for (Card attacker : attackers) { @@ -423,18 +444,20 @@ public class AiAttackController { // presumes the Human will block for (Card blocker : remainingBlockers) { - if (remainingAttackers.isEmpty()) { + if (remainingAttackers.isEmpty() || maxBlockersAfterCrew == 0) { break; } if (blocker.hasKeyword("CARDNAME can block an additional creature.")) { blockedAttackers.add(remainingAttackers.get(0)); remainingAttackers.remove(0); + maxBlockersAfterCrew--; if (remainingAttackers.isEmpty()) { break; } } blockedAttackers.add(remainingAttackers.get(0)); remainingAttackers.remove(0); + maxBlockersAfterCrew--; } unblockedAttackers.addAll(remainingAttackers);