- Fixed a little loophole in the MustBlock code.

- First steps towards an AI for AF MustBlock.
This commit is contained in:
Sloth
2011-10-17 21:10:21 +00:00
parent d968d28352
commit 234e791158
3 changed files with 44 additions and 11 deletions

View File

@@ -651,7 +651,8 @@ public class ComputerUtil_Block2 {
if (!blocker.getMustBlockCards().isEmpty()) {
ArrayList<Card> blocks = blocker.getMustBlockCards();
for (Card attacker : blocks) {
if (attacker.isAttacking() && CombatUtil.canBlock(attacker, blocker)) {
if (attacker.isAttacking() && CombatUtil.canBlock(attacker, blocker, combat)
&& getBlockersLeft().contains(blocker)) {
combat.addBlocker(attacker, blocker);
getBlockersLeft().remove(blocker);
}

View File

@@ -5,10 +5,13 @@ import java.util.HashMap;
import forge.AllZone;
import forge.Card;
import forge.CardList;
import forge.CardListFilter;
import forge.CombatUtil;
import forge.ComputerUtil;
import forge.Constant;
import forge.Player;
import forge.Constant.Zone;
import forge.card.cardFactory.CardFactoryUtil;
import forge.card.spellability.Ability_Activated;
import forge.card.spellability.Ability_Sub;
@@ -835,17 +838,46 @@ public final class AbilityFactory_Combat {
}
private static boolean mustBlockDoTriggerAI(final AbilityFactory af, final SpellAbility sa,
final boolean mandatory)
{
final boolean mandatory) {
final Card source = sa.getSourceCard();
Target abTgt = sa.getTarget();
// If there is a cost payment it's usually not mandatory
if (!ComputerUtil.canPayCost(sa) && !mandatory) {
return false;
}
//only use on creatures that attack
if (!source.isAttacking())
return false;
boolean chance;
boolean chance = false;
//TODO - implement AI
chance = false;
CardList list = AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield).getType("Creature");
list = list.getTargetableCards(source);
if (abTgt != null) {
list = list.getValidCards(abTgt.getValidTgts(), source.getController(), source);
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
if (!CombatUtil.canBlock(source, c, AllZone.getCombat()))
return false;
if (CombatUtil.canDestroyAttacker(source, c, AllZone.getCombat(), false))
return false;
if (!CombatUtil.canDestroyBlocker(c, source, AllZone.getCombat(), false))
return false;
return true;
}
});
if (!list.isEmpty()) {
Card blocker = CardFactoryUtil.AI_getBestCreature(list);
if (blocker == null)
return false;
abTgt.addTarget(CardFactoryUtil.AI_getBestCreature(list));
chance = false; //TODO:change this to true, once the human input takes mustblocks into account
}
} else
return false;
// check SubAbilities DoTrigger?
Ability_Sub abSub = sa.getSubAbility();

View File

@@ -4973,13 +4973,13 @@ public class CardFactoryUtil {
}
if(card.hasKeyword("Provoke")) {
String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Execute$ UntapAbility | Secondary$ True | TriggerDescription$ When this attacks, you may have target creature defending player controls untap and block it if able.";
String abString = "AB$ Untap | Cost$ 0 | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature defending player controls | SubAbility$ DBProvoke";
String dbString = "DB$ MustBlock | Defined$ Targeted";
String actualTrigger = "Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Execute$ ProvokeAbility | Secondary$ True | TriggerDescription$ When this attacks, you may have target creature defending player controls untap and block it if able.";
String abString = "DB$ MustBlock | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature defending player controls | SubAbility$ DBUntap";
String dbString = "DB$ Untap | Defined$ Targeted";
Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, false);
card.addTrigger(parsedTrigger);
card.setSVar("UntapAbility", abString);
card.setSVar("DBProvoke", dbString);
card.setSVar("ProvokeAbility", abString);
card.setSVar("DBUntap", dbString);
}
return card;