mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
- Restructured the way alternative costs of spells are handled for the computer player.
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user