- Restructured the way alternative costs of spells are handled for the computer player.

This commit is contained in:
Sloth
2012-03-06 18:36:08 +00:00
parent 461beb9e00
commit cbc61cddc9
4 changed files with 25 additions and 86 deletions

View File

@@ -75,7 +75,7 @@ public class ComputerAIGeneral implements Computer {
* a {@link java.lang.String} object. * a {@link java.lang.String} object.
*/ */
private void playCards() { private void playCards() {
final CardList list = getAvailableSpellAbilities(); final CardList list = getAvailableCards();
final boolean nextPhase = ComputerUtil.playSpellAbilities(getSpellAbilities(list)); final boolean nextPhase = ComputerUtil.playSpellAbilities(getSpellAbilities(list));
@@ -125,7 +125,7 @@ public class ComputerAIGeneral implements Computer {
* *
* @return a {@link forge.CardList} object. * @return a {@link forge.CardList} object.
*/ */
private CardList getAvailableSpellAbilities() { private CardList getAvailableCards() {
final Player computer = AllZone.getComputerPlayer(); final Player computer = AllZone.getComputerPlayer();
final Player human = AllZone.getHumanPlayer(); final Player human = AllZone.getHumanPlayer();
CardList all = computer.getCardsIn(Zone.Hand); CardList all = computer.getCardsIn(Zone.Hand);
@@ -351,7 +351,7 @@ 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 CardList cards = getAvailableSpellAbilities(); final CardList cards = getAvailableCards();
if (AllZone.getStack().size() == 0) { if (AllZone.getStack().size() == 0) {
final ArrayList<SpellAbility> sas = this.getSpellAbilities(cards); final ArrayList<SpellAbility> sas = this.getSpellAbilities(cards);
boolean pass = (sas.size() == 0) boolean pass = (sas.size() == 0)

View File

@@ -63,64 +63,21 @@ 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);
final ArrayList<SpellAbility> abilities = new ArrayList<SpellAbility>();
for (final SpellAbility sa : all) { for (SpellAbility sa : all) {
//add alternative costs as additional spell abilities
abilities.addAll(GameAction.getAlternativeCosts(sa));
abilities.add(sa);
}
for (final SpellAbility sa : abilities) {
// Don't add Counterspells to the "normal" playcard lookups // 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;
} }
sa.setActivatingPlayer(AllZone.getComputerPlayer()); sa.setActivatingPlayer(AllZone.getComputerPlayer());
final Card source = sa.getSourceCard();
boolean flashb = false; if (ComputerUtil.canBePlayedAndPayedByAI(sa)) {
if (source.hasStartOfKeyword("May be played without paying its mana cost")) {
final SpellAbility newSA = sa.copy();
final Cost cost = sa.getPayCosts();
for (final CostPart part : cost.getCostParts()) {
if (part instanceof CostMana) {
((CostMana) part).setMana("0");
}
}
cost.setNoManaCostChange(true);
newSA.setManaCost("0");
final StringBuilder sb = new StringBuilder();
sb.append(sa.getDescription()).append(" (without paying its mana cost)");
newSA.setDescription(sb.toString());
if (ComputerUtil.canBePlayedAndPayedByAI(newSA)) {
ComputerUtil.handlePlayingSpellAbility(newSA);
return false;
}
}
// Flashback
if (source.isInZone(Constant.Zone.Graveyard) && sa.isSpell() && (source.isInstant() || source.isSorcery())) {
for (final String keyword : source.getKeyword()) {
if (keyword.startsWith("Flashback")) {
final SpellAbility flashback = sa.copy();
flashback.setActivatingPlayer(AllZone.getComputerPlayer());
flashback.setFlashBackAbility(true);
if (!keyword.equals("Flashback")) { // there is a
// flashback cost
// (and not the
// cards
// cost)
final Cost fbCost = new Cost(keyword.substring(10), source.getName(), false);
flashback.setPayCosts(fbCost);
}
if (ComputerUtil.canBePlayedAndPayedByAI(flashback)) {
ComputerUtil.handlePlayingSpellAbility(flashback);
return false;
}
flashb = true;
}
}
}
if ((!flashb || source.hasStartOfKeyword("May be played")) && ComputerUtil.canBePlayedAndPayedByAI(sa)) {
ComputerUtil.handlePlayingSpellAbility(sa); ComputerUtil.handlePlayingSpellAbility(sa);
if (!(sa instanceof AbilityStatic)) { if (!(sa instanceof AbilityStatic)) {
@@ -277,35 +234,17 @@ public class ComputerUtil {
public static boolean playCounterSpell(final ArrayList<SpellAbility> possibleCounters) { public static boolean playCounterSpell(final ArrayList<SpellAbility> possibleCounters) {
SpellAbility bestSA = null; SpellAbility bestSA = null;
int bestRestriction = Integer.MIN_VALUE; int bestRestriction = Integer.MIN_VALUE;
final ArrayList<SpellAbility> abilities = new ArrayList<SpellAbility>();
for (final SpellAbility sa : possibleCounters) { for (SpellAbility sa : possibleCounters) {
//add alternative costs as additional spell abilities
abilities.addAll(GameAction.getAlternativeCosts(sa));
abilities.add(sa);
}
for (final SpellAbility sa : abilities) {
SpellAbility currentSA = sa; SpellAbility currentSA = sa;
sa.setActivatingPlayer(AllZone.getComputerPlayer()); sa.setActivatingPlayer(AllZone.getComputerPlayer());
final Card source = sa.getSourceCard(); // check everything necessary
if (ComputerUtil.canBePlayedAndPayedByAI(currentSA)) {
// Flashback
if (source.isInZone(Constant.Zone.Graveyard) && sa.isSpell() && (source.isInstant() || source.isSorcery())) {
for (final String keyword : source.getKeyword()) {
if (keyword.startsWith("Flashback")) {
final SpellAbility flashback = sa.copy();
flashback.setActivatingPlayer(AllZone.getComputerPlayer());
flashback.setFlashBackAbility(true);
if (!keyword.equals("Flashback")) { // there is a
// flashback cost
// (and not the
// cards
// cost)
final Cost fbCost = new Cost(keyword.substring(10), source.getName(), false);
flashback.setPayCosts(fbCost);
}
currentSA = flashback;
}
}
}
if (ComputerUtil.canBePlayedAndPayedByAI(currentSA)) { // checks
// everything
// nescessary
if (bestSA == null) { if (bestSA == null) {
bestSA = currentSA; bestSA = currentSA;
bestRestriction = ComputerUtil.counterSpellRestriction(currentSA); bestRestriction = ComputerUtil.counterSpellRestriction(currentSA);

View File

@@ -1339,7 +1339,7 @@ public class GameAction {
* @return an ArrayList<SpellAbility>. * @return an ArrayList<SpellAbility>.
* get alternative costs as additional spell abilities * get alternative costs as additional spell abilities
*/ */
public final ArrayList<SpellAbility> getAlternativeCosts(SpellAbility sa) { public static final ArrayList<SpellAbility> getAlternativeCosts(SpellAbility sa) {
ArrayList<SpellAbility> alternatives = new ArrayList<SpellAbility>(); ArrayList<SpellAbility> alternatives = new ArrayList<SpellAbility>();
Card source = sa.getSourceCard(); Card source = sa.getSourceCard();
if (!sa.isBasicSpell()) { if (!sa.isBasicSpell()) {

View File

@@ -269,10 +269,6 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
return false; return false;
} }
if (!checkZoneRestrictions(c, sa)) {
return false;
}
Player activator = sa.getActivatingPlayer(); Player activator = sa.getActivatingPlayer();
if (activator == null) { if (activator == null) {
activator = c.getController(); activator = c.getController();
@@ -292,6 +288,10 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
return false; return false;
} }
if (!checkZoneRestrictions(c, sa)) {
return false;
}
if ((this.getActivationLimit() != -1) && (this.getNumberTurnActivations() >= this.getActivationLimit())) { if ((this.getActivationLimit() != -1) && (this.getNumberTurnActivations() >= this.getActivationLimit())) {
return false; return false;
} }