refactored 10+ calls to isComputer/isHuman

This commit is contained in:
Maxmtg
2013-06-21 22:46:00 +00:00
parent 69c36da984
commit 4c40598c79
14 changed files with 89 additions and 78 deletions

View File

@@ -4,13 +4,12 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import org.apache.commons.lang.math.RandomUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.ability.effects.CharmEffect; import forge.card.ability.effects.CharmEffect;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.player.Player; import forge.game.player.Player;
import forge.util.Aggregates;
import forge.util.MyRandom; import forge.util.MyRandom;
public class CharmAi extends SpellAbilityAi { public class CharmAi extends SpellAbilityAi {
@@ -68,8 +67,12 @@ public class CharmAi extends SpellAbilityAi {
return chosenList.size() >= min ? chosenList : null; return chosenList.size() >= min ? chosenList : null;
} }
public static Player determineOpponentChooser(Player ai, SpellAbility sa, List<Player> opponents) { /* (non-Javadoc)
return opponents.get(RandomUtils.nextInt(opponents.size())); * @see forge.card.ability.SpellAbilityAi#chooseSinglePlayer(forge.game.player.Player, forge.card.spellability.SpellAbility, java.util.List)
*/
@Override
public Player chooseSinglePlayer(Player ai, SpellAbility sa, List<Player> opponents) {
return Aggregates.random(opponents);
} }
} }

View File

@@ -11,6 +11,7 @@ import forge.game.Game;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
public class CloneAi extends SpellAbilityAi { public class CloneAi extends SpellAbilityAi {
@@ -143,5 +144,14 @@ public class CloneAi extends SpellAbilityAi {
// good job of picking a good target // good job of picking a good target
return false; return false;
} }
/* (non-Javadoc)
* @see forge.card.ability.SpellAbilityAi#confirmAction(forge.game.player.Player, forge.card.spellability.SpellAbility, forge.game.player.PlayerActionConfirmMode, java.lang.String)
*/
@Override
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
// Didn't confirm in the original code
return false;
}
} }

View File

@@ -121,5 +121,14 @@ public class CopyPermanentAi extends SpellAbilityAi {
//TODO: add logic here //TODO: add logic here
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.ability.SpellAbilityAi#chooseSingleCard(forge.game.player.Player, forge.card.spellability.SpellAbility, java.util.List, boolean)
*/
@Override
public Card chooseSingleCard(Player ai, SpellAbility sa, List<Card> options, boolean isOptional) {
// Select a card to attach to
return ComputerUtilCard.getBestAI(options);
}
} }

View File

@@ -4,16 +4,20 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import com.google.common.base.Predicate;
import forge.Card; import forge.Card;
import forge.CardLists; import forge.CardLists;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityAi; import forge.card.ability.SpellAbilityAi;
import forge.card.cost.Cost; import forge.card.cost.Cost;
import forge.card.spellability.Spell;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.TargetRestrictions; import forge.card.spellability.TargetRestrictions;
import forge.game.ai.ComputerUtilCard; import forge.game.ai.ComputerUtilCard;
import forge.game.ai.ComputerUtilCost; import forge.game.ai.ComputerUtilCost;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.MyRandom; import forge.util.MyRandom;
@@ -94,4 +98,35 @@ public class PlayAi extends SpellAbilityAi {
return true; return true;
} }
/* (non-Javadoc)
* @see forge.card.ability.SpellAbilityAi#confirmAction(forge.game.player.Player, forge.card.spellability.SpellAbility, forge.game.player.PlayerActionConfirmMode, java.lang.String)
*/
@Override
public boolean confirmAction(Player player, SpellAbility sa, PlayerActionConfirmMode mode, String message) {
// as called from PlayEffect:173
return true;
}
/* (non-Javadoc)
* @see forge.card.ability.SpellAbilityAi#chooseSingleCard(forge.game.player.Player, forge.card.spellability.SpellAbility, java.util.List, boolean)
*/
@Override
public Card chooseSingleCard(final Player ai, SpellAbility sa, List<Card> options, boolean isOptional) {
List<Card> tgtCards = CardLists.filter(options, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
for (SpellAbility s : c.getBasicSpells()) {
Spell spell = (Spell) s;
s.setActivatingPlayer(ai);
// timing restrictions still apply
if (s.getRestrictions().checkTimingRestrictions(c, s) && spell.canPlayFromEffectAI(false, true)) {
return true;
}
}
return false;
}
});
return ComputerUtilCard.getBestAI(tgtCards);
}
} }

View File

@@ -57,18 +57,10 @@ public class CharmEffect extends SpellAbilityEffect {
if (sa.hasParam("Chooser")) { if (sa.hasParam("Chooser")) {
// Three modal cards require you to choose a player to make the modal choice' // Three modal cards require you to choose a player to make the modal choice'
// Two of these also reference the chosen player during the spell effect // Two of these also reference the chosen player during the spell effect
String choose = sa.getParam("Chooser");
List<Player> opponents = activator.getOpponents(); //String choosers = sa.getParam("Chooser");
int numOpps = opponents.size(); List<Player> opponents = activator.getOpponents(); // all cards have Choser$ Opponent, so it's hardcoded here
if (numOpps == 1) { chooser = activator.getController().chooseSinglePlayerForEffect(opponents, sa, "Choose an opponent");
chooser = opponents.get(0);
} else {
if (activator.isComputer()) {
chooser = CharmAi.determineOpponentChooser(activator, sa, opponents);
} else {
chooser = GuiChoose.one("Choose an opponent", opponents);
}
}
source.setChosenPlayer(chooser); source.setChosenPlayer(chooser);
} }

View File

@@ -19,7 +19,6 @@ import forge.card.spellability.TargetRestrictions;
import forge.card.trigger.Trigger; import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerHandler;
import forge.game.Game; import forge.game.Game;
import forge.gui.GuiDialog;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
public class CloneEffect extends SpellAbilityEffect { public class CloneEffect extends SpellAbilityEffect {
@@ -74,11 +73,8 @@ public class CloneEffect extends SpellAbilityEffect {
return; return;
} }
final StringBuilder sb = new StringBuilder();
sb.append("Do you want to copy " + cardToCopy + "?");
boolean optional = sa.hasParam("Optional"); boolean optional = sa.hasParam("Optional");
if (host.getController().isHuman() && optional if (optional && !host.getController().getController().confirmAction(sa, null, "Do you want to copy " + cardToCopy + "?")) {
&& !GuiDialog.confirm(host, sb.toString())) {
return; return;
} }

View File

@@ -27,10 +27,8 @@ import forge.card.spellability.Ability;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.TargetRestrictions; import forge.card.spellability.TargetRestrictions;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.util.Aggregates; import forge.util.Aggregates;
import forge.util.PredicateString.StringOp; import forge.util.PredicateString.StringOp;
@@ -219,16 +217,7 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), copy.getController(), copy); list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), copy.getController(), copy);
} }
if (!list.isEmpty()) { if (!list.isEmpty()) {
Card attachedTo = null; Card attachedTo = sa.getActivatingPlayer().getController().chooseSingleCardForEffect(list, sa, copy + " - Select a card to attach to.");
if (sa.getActivatingPlayer().isHuman()) {
if (list.size() > 1) {
attachedTo = GuiChoose.one(copy + " - Select a card to attach to.", list);
} else {
attachedTo = list.get(0);
}
} else { // AI player
attachedTo = ComputerUtilCard.getBestAI(list);
}
if (copy.isAura()) { if (copy.isAura()) {
if (attachedTo.canBeEnchantedBy(copy)) { if (attachedTo.canBeEnchantedBy(copy)) {
copy.enchantEntity(attachedTo); copy.enchantEntity(attachedTo);

View File

@@ -179,21 +179,21 @@ public class DigEffect extends SpellAbilityEffect {
movedCards = CardLists.getRandomSubList(valid, numChanging); movedCards = CardLists.getRandomSubList(valid, numChanging);
} else if (allButOne) { } else if (allButOne) {
movedCards.addAll(valid); movedCards.addAll(valid);
Card chosen = null;
if (choser.isHuman()) { if (choser.isHuman()) {
Card chosen = null;
String prompt = "Choose a card to leave in "; String prompt = "Choose a card to leave in ";
if (destZone2.equals(ZoneType.Library) && (libraryPosition2 == 0)) { if (destZone2.equals(ZoneType.Library) && (libraryPosition2 == 0)) {
prompt = "Leave which card on top of the "; prompt = "Leave which card on top of the ";
} }
chosen = GuiChoose.one(prompt + destZone2, valid); chosen = GuiChoose.one(prompt + destZone2, valid);
movedCards.remove(chosen);
} else { // Computer } else { // Computer
Card chosen = ComputerUtilCard.getBestAI(valid); chosen = ComputerUtilCard.getBestAI(valid);
if (sa.getActivatingPlayer().isHuman() && p.isHuman()) { if (sa.getActivatingPlayer().isOpponentOf(choser) && p.isOpponentOf(choser)) {
chosen = ComputerUtilCard.getWorstAI(valid); chosen = ComputerUtilCard.getWorstAI(valid);
} }
movedCards.remove(chosen);
} }
movedCards.remove(chosen);
if (sa.hasParam("RandomOrder")) { if (sa.hasParam("RandomOrder")) {
final Random random = MyRandom.getRandom(); final Random random = MyRandom.getRandom();
Collections.shuffle(movedCards, random); Collections.shuffle(movedCards, random);

View File

@@ -12,7 +12,6 @@ import com.google.common.collect.Lists;
import forge.Card; import forge.Card;
import forge.CardCharacteristicName; import forge.CardCharacteristicName;
import forge.CardLists;
import forge.card.CardDb; import forge.card.CardDb;
import forge.card.CardRulesPredicates; import forge.card.CardRulesPredicates;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
@@ -22,12 +21,10 @@ import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityRestriction; import forge.card.spellability.SpellAbilityRestriction;
import forge.game.Game; import forge.game.Game;
import forge.game.ai.ComputerUtil; import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCard;
import forge.game.player.HumanPlay; import forge.game.player.HumanPlay;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.gui.GuiDialog;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.util.Aggregates; import forge.util.Aggregates;
@@ -136,42 +133,17 @@ public class PlayEffect extends SpellAbilityEffect {
} }
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
if (tgtCards.isEmpty()) { Card tgtCard = controller.getController().chooseSingleCardForEffect(tgtCards, sa, "Select a card to play");
if (tgtCard == null) {
return; return;
} }
Card tgtCard = tgtCards.get(0);
if (tgtCards.size() > 1) {
if (controller.isHuman()) {
tgtCard = GuiChoose.one("Select a card to play", tgtCards);
} else {
// AI
tgtCards = CardLists.filter(tgtCards, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
for (SpellAbility s : c.getBasicSpells()) {
Spell spell = (Spell) s;
s.setActivatingPlayer(controller);
// timing restrictions still apply
if (s.getRestrictions().checkTimingRestrictions(c, s) && spell.canPlayFromEffectAI(false, true)) {
return true;
}
}
return false;
}
});
tgtCard = ComputerUtilCard.getBestAI(tgtCards);
if (tgtCard == null) {
return;
}
}
}
if (tgtCard.isFaceDown()) { if (tgtCard.isFaceDown()) {
tgtCard.setState(CardCharacteristicName.Original); tgtCard.setState(CardCharacteristicName.Original);
wasFaceDown = true; wasFaceDown = true;
} }
final StringBuilder sb = new StringBuilder();
sb.append("Do you want to play " + tgtCard + "?"); if (optional && !controller.getController().confirmAction(sa, null, "Do you want to play " + tgtCard + "?")) {
if (controller.isHuman() && optional && !GuiDialog.confirm(source, sb.toString())) {
// i--; // This causes an infinite loop (ArsenalNut) // i--; // This causes an infinite loop (ArsenalNut)
if (wasFaceDown) { if (wasFaceDown) {
tgtCard.setState(CardCharacteristicName.FaceDown); tgtCard.setState(CardCharacteristicName.FaceDown);

View File

@@ -57,6 +57,7 @@ import forge.game.ai.AiController;
import forge.game.player.HumanPlay; import forge.game.player.HumanPlay;
import forge.game.event.GameEventLifeLoss; import forge.game.event.GameEventLifeLoss;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerActionConfirmMode;
import forge.game.player.PlayerControllerAi; import forge.game.player.PlayerControllerAi;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
@@ -297,9 +298,10 @@ public final class GameActionUtil {
void doRipple(final Card c, final int rippleCount, final Player controller) { void doRipple(final Card c, final int rippleCount, final Player controller) {
final Card rippleCard = c; final Card rippleCard = c;
if (controller.isComputer() || GuiDialog.confirm(c, "Activate Ripple for " + c + "?")) { final Ability ability = new RippleAbility(c, ManaCost.ZERO, controller, rippleCount, rippleCard);
if (controller.getController().confirmAction(ability, PlayerActionConfirmMode.Ripple, "Activate Ripple for " + c + "?")) {
final Ability ability = new RippleAbility(c, ManaCost.ZERO, controller, rippleCount, rippleCard);
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append(c).append(" - Ripple."); sb.append(c).append(" - Ripple.");
ability.setStackDescription(sb.toString()); ability.setStackDescription(sb.toString());

View File

@@ -643,6 +643,7 @@ public class AiController {
if ( null == api ) { if ( null == api ) {
if( mode != null ) switch (mode) { if( mode != null ) switch (mode) {
case BraidOfFire: return true; case BraidOfFire: return true;
case Ripple: return true;
} }
String exMsg = String.format("AI confirmAction does not know what to decide about %s mode (api is null).", mode); String exMsg = String.format("AI confirmAction does not know what to decide about %s mode (api is null).", mode);

View File

@@ -7,6 +7,7 @@ package forge.game.player;
public enum PlayerActionConfirmMode { public enum PlayerActionConfirmMode {
Random, Random,
BraidOfFire, BraidOfFire,
FromOpeningHand; FromOpeningHand,
Ripple;
} }

View File

@@ -266,14 +266,15 @@ public class PlayerControllerHuman extends PlayerController {
@Override @Override
public Card chooseSingleCardForEffect(List<Card> options, SpellAbility sa, String title, boolean isOptional) { public Card chooseSingleCardForEffect(List<Card> options, SpellAbility sa, String title, boolean isOptional) {
// Human is supposed to read the message and understand from it what to choose // Human is supposed to read the message and understand from it what to choose
if (options.isEmpty())
return null;
if ( isOptional ) if ( isOptional )
return GuiChoose.oneOrNone(title, options); return GuiChoose.oneOrNone(title, options);
else if ( options.size() > 1 ) else if ( options.size() > 1 )
return GuiChoose.one(title, options); return GuiChoose.one(title, options);
else if (options.size() == 1)
return options.get(0);
else else
return null; return options.get(0);
} }
@Override @Override

View File

@@ -145,7 +145,7 @@ public class ControlWinLose {
if( !fromGame.hasWon()) continue; // not a loser if( !fromGame.hasWon()) continue; // not a loser
// offer to winner, if he is local human // offer to winner, if he is local human
if (fromGame.isHuman()) { if (fromGame.getController().getLobbyPlayer() == Singletons.getControl().getLobby().getGuiPlayer()) {
List<PaperCard> chosen = GuiChoose.noneOrMany("Select cards to add to your deck", losses); List<PaperCard> chosen = GuiChoose.noneOrMany("Select cards to add to your deck", losses);
if (null != chosen) { if (null != chosen) {
RegisteredPlayer psc = match.getPlayers().get(i); RegisteredPlayer psc = match.getPlayers().get(i);