- Restructured some code in ComputerAIGeneral to prevent duplicate checks.

This commit is contained in:
Sloth
2012-02-27 22:01:26 +00:00
parent 714b595d56
commit cd212e4a1e
3 changed files with 81 additions and 109 deletions

View File

@@ -89,9 +89,9 @@ public class ComputerAIGeneral implements Computer {
* a {@link java.lang.String} object. * a {@link java.lang.String} object.
*/ */
private void playCards(final String phase) { private void playCards(final String phase) {
final SpellAbility[] sp = phase.equals(Constant.Phase.MAIN1) ? this.getMain1() : this.getMain2(); final CardList list = phase.equals(Constant.Phase.MAIN1) ? this.getMain1() : this.getMain2();
final boolean nextPhase = ComputerUtil.playSpellAbilities(sp); final boolean nextPhase = ComputerUtil.playSpellAbilities(getSpellAbilities(list));
if (nextPhase) { if (nextPhase) {
AllZone.getPhaseHandler().passPriority(); AllZone.getPhaseHandler().passPriority();
@@ -105,14 +105,16 @@ public class ComputerAIGeneral implements Computer {
* *
* @return an array of {@link forge.card.spellability.SpellAbility} objects. * @return an array of {@link forge.card.spellability.SpellAbility} objects.
*/ */
private SpellAbility[] getMain1() { private CardList getMain1() {
final Player computer = AllZone.getComputerPlayer();
final Player human = AllZone.getHumanPlayer();
// Card list of all cards to consider // Card list of all cards to consider
CardList hand = AllZone.getComputerPlayer().getCardsIn(Zone.Hand); CardList hand = computer.getCardsIn(Zone.Hand);
final boolean hasACardGivingHaste = this.hasACardGivingHaste(); final boolean hasACardGivingHaste = this.hasACardGivingHaste();
// If mana pool is not empty try to play anything // If mana pool is not empty try to play anything
if (AllZone.getComputerPlayer().getManaPool().isEmpty()) { if (computer.getManaPool().isEmpty()) {
hand = hand.filter(new CardListFilter() { hand = hand.filter(new CardListFilter() {
@Override @Override
public boolean addCard(final Card c) { public boolean addCard(final Card c) {
@@ -131,7 +133,7 @@ public class ComputerAIGeneral implements Computer {
} }
// get all cards the computer controls with BuffedBy // get all cards the computer controls with BuffedBy
final CardList buffed = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield); final CardList buffed = computer.getCardsIn(Zone.Battlefield);
for (int j = 0; j < buffed.size(); j++) { for (int j = 0; j < buffed.size(); j++) {
final Card buffedcard = buffed.get(j); final Card buffedcard = buffed.get(j);
if (buffedcard.getSVar("BuffedBy").length() > 0) { if (buffedcard.getSVar("BuffedBy").length() > 0) {
@@ -144,7 +146,7 @@ public class ComputerAIGeneral implements Computer {
} // BuffedBy } // BuffedBy
// get all cards the human controls with AntiBuffedBy // get all cards the human controls with AntiBuffedBy
final CardList antibuffed = AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield); final CardList antibuffed = human.getCardsIn(Zone.Battlefield);
for (int k = 0; k < antibuffed.size(); k++) { for (int k = 0; k < antibuffed.size(); k++) {
final Card buffedcard = antibuffed.get(k); final Card buffedcard = antibuffed.get(k);
if (buffedcard.getSVar("AntiBuffedBy").length() > 0) { if (buffedcard.getSVar("AntiBuffedBy").length() > 0) {
@@ -160,9 +162,9 @@ public class ComputerAIGeneral implements Computer {
return false; return false;
} }
final CardList vengevines = AllZone.getComputerPlayer().getCardsIn(Zone.Graveyard, "Vengevine"); final CardList vengevines = computer.getCardsIn(Zone.Graveyard, "Vengevine");
if (vengevines.size() > 0) { if (vengevines.size() > 0) {
final CardList creatures = AllZone.getComputerPlayer().getCardsIn(Zone.Hand); final CardList creatures = computer.getCardsIn(Zone.Hand);
final CardList creatures2 = new CardList(); final CardList creatures2 = new CardList();
for (int i = 0; i < creatures.size(); i++) { for (int i = 0; i < creatures.size(); i++) {
if (creatures.get(i).isCreature() if (creatures.get(i).isCreature()
@@ -182,21 +184,17 @@ public class ComputerAIGeneral implements Computer {
} }
}); });
} }
final CardList all = AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield); final CardList all = computer.getCardsIn(Zone.Battlefield);
all.addAll(CardFactoryUtil.getExternalZoneActivationCards(AllZone.getComputerPlayer())); all.addAll(computer.getCardsIn(Zone.Exile));
all.addAll(computer.getCardsIn(Zone.Graveyard));
if (!computer.getCardsIn(Zone.Library).isEmpty()) {
all.add(computer.getCardsIn(Zone.Library).get(0));
}
all.addAll(human.getCardsIn(Zone.Battlefield));
all.addAll(human.getCardsIn(Zone.Exile));
all.addAll(hand); all.addAll(hand);
CardList humanPlayable = AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield); return all;
humanPlayable = humanPlayable.filter(new CardListFilter() {
@Override
public boolean addCard(final Card c) {
return (c.canAnyPlayerActivate());
}
});
all.addAll(humanPlayable);
return this.getPlayable(all);
} // getMain1() } // getMain1()
/** /**
@@ -240,49 +238,39 @@ public class ComputerAIGeneral implements Computer {
* *
* @return an array of {@link forge.card.spellability.SpellAbility} objects. * @return an array of {@link forge.card.spellability.SpellAbility} objects.
*/ */
private SpellAbility[] getMain2() { private CardList getMain2() {
final Player computer = AllZone.getComputerPlayer();
final Player human = AllZone.getHumanPlayer();
// Card list of all cards to consider // Card list of all cards to consider
CardList all = AllZone.getComputerPlayer().getCardsIn(Zone.Hand); CardList all = computer.getCardsIn(Zone.Hand);
// Don't play permanents with Flash before humans declare attackers step // Don't play permanents with Flash before humans declare attackers step
all = all.filter(new CardListFilter() { all = all.filter(new CardListFilter() {
@Override @Override
public boolean addCard(final Card c) { public boolean addCard(final Card c) {
if (c.isPermanent() if (c.isPermanent()
&& c.hasKeyword("Flash") && c.hasKeyword("Flash")
&& (AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) || AllZone.getPhaseHandler() && (AllZone.getPhaseHandler().isPlayerTurn(computer) || AllZone.getPhaseHandler()
.isBefore(Constant.Phase.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY))) { .isBefore(Constant.Phase.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY))) {
return false; return false;
} }
return true; return true;
} }
}); });
all.addAll(AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield)); all.addAll(computer.getCardsIn(Zone.Exile));
all.addAll(CardFactoryUtil.getExternalZoneActivationCards(AllZone.getComputerPlayer())); all.addAll(computer.getCardsIn(Zone.Graveyard));
if (!computer.getCardsIn(Zone.Library).isEmpty()) {
all.add(computer.getCardsIn(Zone.Library).get(0));
}
all.addAll(human.getCardsIn(Zone.Exile));
// Prevent the computer from summoning Ball Lightning type creatures // Prevent the computer from summoning Ball Lightning type creatures
// during main phase 2 // during main phase 2
all = all.getNotKeyword("At the beginning of the end step, sacrifice CARDNAME."); all = all.getNotKeyword("At the beginning of the end step, sacrifice CARDNAME.");
all = all.filter(new CardListFilter() { all.addAll(computer.getCardsIn(Zone.Battlefield));
@Override all.addAll(human.getCardsIn(Zone.Battlefield));
public boolean addCard(final Card c) {
if (c.isLand()) {
return false;
}
return true;
}
});
CardList humanPlayable = AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield); return all;
humanPlayable = humanPlayable.filter(new CardListFilter() {
@Override
public boolean addCard(final Card c) {
return (c.canAnyPlayerActivate());
}
});
all.addAll(humanPlayable);
return this.getPlayable(all);
} // getMain2() } // getMain2()
/** /**
@@ -293,7 +281,9 @@ public class ComputerAIGeneral implements Computer {
* @return a {@link forge.CardList} object. * @return a {@link forge.CardList} object.
*/ */
private CardList getAvailableSpellAbilities() { private CardList getAvailableSpellAbilities() {
CardList all = AllZone.getComputerPlayer().getCardsIn(Zone.Hand); final Player computer = AllZone.getComputerPlayer();
final Player human = AllZone.getHumanPlayer();
CardList all = computer.getCardsIn(Zone.Hand);
// Don't play permanents with Flash before humans declare attackers step // Don't play permanents with Flash before humans declare attackers step
all = all.filter(new CardListFilter() { all = all.filter(new CardListFilter() {
@Override @Override
@@ -301,24 +291,21 @@ public class ComputerAIGeneral implements Computer {
if (c.isPermanent() if (c.isPermanent()
&& c.hasKeyword("Flash") && c.hasKeyword("Flash")
&& !hasETBTrigger(c) && !hasETBTrigger(c)
&& (AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) || AllZone.getPhaseHandler() && (AllZone.getPhaseHandler().isPlayerTurn(computer) || AllZone.getPhaseHandler()
.isBefore(Constant.Phase.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY))) { .isBefore(Constant.Phase.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY))) {
return false; return false;
} }
return true; return true;
} }
}); });
all.addAll(AllZone.getComputerPlayer().getCardsIn(Zone.Battlefield)); all.addAll(computer.getCardsIn(Zone.Battlefield));
all.addAll(CardFactoryUtil.getExternalZoneActivationCards(AllZone.getComputerPlayer())); all.addAll(computer.getCardsIn(Zone.Exile));
all.addAll(computer.getCardsIn(Zone.Graveyard));
CardList humanPlayable = AllZone.getHumanPlayer().getCardsIn(Zone.Battlefield); if (!computer.getCardsIn(Zone.Library).isEmpty()) {
humanPlayable = humanPlayable.filter(new CardListFilter() { all.add(computer.getCardsIn(Zone.Library).get(0));
@Override }
public boolean addCard(final Card c) { all.addAll(human.getCardsIn(Zone.Exile));
return (c.canAnyPlayerActivate()); all.addAll(human.getCardsIn(Zone.Battlefield));
}
});
all.addAll(humanPlayable);
return all; return all;
} }
@@ -351,17 +338,6 @@ public class ComputerAIGeneral implements Computer {
return false; return false;
} }
/**
* <p>
* getOtherPhases.
* </p>
*
* @return an array of {@link forge.card.spellability.SpellAbility} objects.
*/
private SpellAbility[] getOtherPhases() {
return this.getPlayable(this.getAvailableSpellAbilities());
}
/** /**
* <p> * <p>
* getPossibleCounters. * getPossibleCounters.
@@ -381,25 +357,44 @@ public class ComputerAIGeneral implements Computer {
* @return a {@link java.util.ArrayList} object. * @return a {@link java.util.ArrayList} object.
*/ */
private ArrayList<SpellAbility> getPossibleETBCounters() { private ArrayList<SpellAbility> getPossibleETBCounters() {
return this.getETBCounters(this.getAvailableSpellAbilities()); final Player computer = AllZone.getComputerPlayer();
final Player human = AllZone.getHumanPlayer();
CardList all = computer.getCardsIn(Zone.Hand);
all.addAll(computer.getCardsIn(Zone.Exile));
all.addAll(computer.getCardsIn(Zone.Graveyard));
if (!computer.getCardsIn(Zone.Library).isEmpty()) {
all.add(computer.getCardsIn(Zone.Library).get(0));
}
all.addAll(human.getCardsIn(Zone.Exile));
final ArrayList<SpellAbility> spellAbilities = new ArrayList<SpellAbility>();
for (final Card c : all) {
for (final SpellAbility sa : c.getSpellAbility()) {
if (sa instanceof SpellPermanent) {
if (SpellPermanent.checkETBEffects(c, sa, "Counter")) {
spellAbilities.add(sa);
}
}
}
}
return spellAbilities;
} }
/** /**
* Returns the spellAbilities from the card list that the computer is able * Returns the spellAbilities from the card list
* to play.
* *
* @param l * @param l
* a {@link forge.CardList} object. * a {@link forge.CardList} object.
* @return an array of {@link forge.card.spellability.SpellAbility} objects. * @return an array of {@link forge.card.spellability.SpellAbility} objects.
*/ */
private SpellAbility[] getPlayable(final CardList l) { private ArrayList<SpellAbility> getSpellAbilities(final CardList l) {
final ArrayList<SpellAbility> spellAbility = new ArrayList<SpellAbility>(); final ArrayList<SpellAbility> spellAbilities = new ArrayList<SpellAbility>();
for (final Card c : l) { for (final Card c : l) {
for (final SpellAbility sa : c.getSpellAbility()) { for (final SpellAbility sa : c.getSpellAbility()) {
spellAbility.add(sa); spellAbilities.add(sa);
} }
} }
return spellAbility.toArray(new SpellAbility[spellAbility.size()]); return spellAbilities;
} }
/** /**
@@ -425,31 +420,6 @@ public class ComputerAIGeneral implements Computer {
return spellAbility; return spellAbility;
} }
/**
* <p>
* getETBCounters.
* </p>
*
* @param l
* a {@link forge.CardList} object.
* @return a {@link java.util.ArrayList} object.
*/
private ArrayList<SpellAbility> getETBCounters(final CardList l) {
final ArrayList<SpellAbility> spellAbility = new ArrayList<SpellAbility>();
for (final Card c : l) {
for (final SpellAbility sa : c.getSpellAbility()) {
// Or if this Permanent has an ETB ability with Counter
if (sa instanceof SpellPermanent) {
if (SpellPermanent.checkETBEffects(c, sa, "Counter")) {
spellAbility.add(sa);
}
}
}
}
return spellAbility;
}
/** /**
* <p> * <p>
* begin_combat. * begin_combat.
@@ -562,10 +532,10 @@ public class ComputerAIGeneral implements Computer {
*/ */
public final void stackResponse() { public final void stackResponse() {
// if top of stack is empty // if top of stack is empty
final SpellAbility[] sas = this.getOtherPhases(); final ArrayList<SpellAbility> sas = this.getSpellAbilities(this.getAvailableSpellAbilities());
if (AllZone.getStack().size() == 0) { if (AllZone.getStack().size() == 0) {
boolean pass = (sas.length == 0) boolean pass = (sas.size() == 0)
|| AllZone.getPhaseHandler().is(Constant.Phase.END_OF_TURN, AllZone.getComputerPlayer()); || AllZone.getPhaseHandler().is(Constant.Phase.END_OF_TURN, AllZone.getComputerPlayer());
if (!pass) { // Each AF should check the phase individually if (!pass) { // Each AF should check the phase individually
pass = ComputerUtil.playSpellAbilities(sas); pass = ComputerUtil.playSpellAbilities(sas);
@@ -597,13 +567,13 @@ public class ComputerAIGeneral implements Computer {
possibleCounters.clear(); possibleCounters.clear();
possibleCounters = this.getPossibleETBCounters(); possibleCounters = this.getPossibleETBCounters();
if ((possibleCounters.size() > 0) && !ComputerUtil.playAbilities(possibleCounters)) { if ((possibleCounters.size() > 0) && !ComputerUtil.playSpellAbilities(possibleCounters)) {
// Responding Permanent w/ ETB Counter is on the Stack // Responding Permanent w/ ETB Counter is on the Stack
// AllZone.getPhaseHandler().passPriority(); // AllZone.getPhaseHandler().passPriority();
return; return;
} }
if (sas.length > 0) { if (sas.size() > 0) {
// Spell not Countered // Spell not Countered
if (!ComputerUtil.playSpellAbilities(sas)) { if (!ComputerUtil.playSpellAbilities(sas)) {
return; return;

View File

@@ -63,10 +63,9 @@ public class ComputerUtil {
public static boolean playSpellAbilities(final SpellAbility[] all) { public static boolean playSpellAbilities(final SpellAbility[] all) {
// not sure "playing biggest spell" matters? // not sure "playing biggest spell" matters?
ComputerUtil.sortSpellAbilityByCost(all); ComputerUtil.sortSpellAbilityByCost(all);
// MyRandom.shuffle(all);
for (final SpellAbility sa : all) { for (final SpellAbility sa : all) {
// Don't add Counterspells to the "normal" playcard lookupss // Don't add Counterspells to the "normal" playcard lookups
final AbilityFactory af = sa.getAbilityFactory(); final AbilityFactory af = sa.getAbilityFactory();
if ((af != null) && af.getAPI().equals("Counter")) { if ((af != null) && af.getAPI().equals("Counter")) {
continue; continue;
@@ -141,7 +140,7 @@ public class ComputerUtil {
* a {@link java.util.ArrayList} object. * a {@link java.util.ArrayList} object.
* @return a boolean. * @return a boolean.
*/ */
public static boolean playAbilities(final ArrayList<SpellAbility> all) { public static boolean playSpellAbilities(final ArrayList<SpellAbility> all) {
final SpellAbility[] sas = new SpellAbility[all.size()]; final SpellAbility[] sas = new SpellAbility[all.size()];
for (int i = 0; i < sas.length; i++) { for (int i = 0; i < sas.length; i++) {
sas[i] = all.get(i); sas[i] = all.get(i);

View File

@@ -439,6 +439,9 @@ public class StaticAbility {
} }
if (this.mapParams.containsKey("TopCardOfLibraryIs")) { if (this.mapParams.containsKey("TopCardOfLibraryIs")) {
if (controller.getCardsIn(Zone.Library).isEmpty()) {
return false;
}
final Card topCard = controller.getCardsIn(Zone.Library).get(0); final Card topCard = controller.getCardsIn(Zone.Library).get(0);
if (!topCard.isValid(this.mapParams.get("TopCardOfLibraryIs").split(","), controller, this.hostCard)) { if (!topCard.isValid(this.mapParams.get("TopCardOfLibraryIs").split(","), controller, this.hostCard)) {
return false; return false;