mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
confirmAction - added a enum parameter for cases when no API is avaliable
ChooseTypeEffect - moved choose logic into ComputerUtil
This commit is contained in:
@@ -4,21 +4,13 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.Constant;
|
||||
import forge.card.CardType;
|
||||
import forge.card.ability.SpellAbilityEffect;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.GameState;
|
||||
import forge.game.ai.ComputerUtilCard;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
|
||||
public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
|
||||
@@ -38,12 +30,9 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
public void resolve(SpellAbility sa) {
|
||||
final Card card = sa.getSourceCard();
|
||||
final String type = sa.getParam("Type");
|
||||
final ArrayList<String> invalidTypes = new ArrayList<String>();
|
||||
if (sa.hasParam("InvalidTypes")) {
|
||||
invalidTypes.addAll(Arrays.asList(sa.getParam("InvalidTypes").split(",")));
|
||||
}
|
||||
final List<String> invalidTypes = sa.hasParam("InvalidTypes") ? Arrays.asList(sa.getParam("InvalidTypes").split(",")) : new ArrayList<String>();
|
||||
|
||||
final ArrayList<String> validTypes = new ArrayList<String>();
|
||||
final List<String> validTypes = new ArrayList<String>();
|
||||
if (sa.hasParam("ValidTypes")) {
|
||||
validTypes.addAll(Arrays.asList(sa.getParam("ValidTypes").split(",")));
|
||||
}
|
||||
@@ -52,174 +41,25 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
||||
|
||||
for (final Player p : tgtPlayers) {
|
||||
final GameState game = p.getGame();
|
||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
|
||||
if (type.equals("Card")) {
|
||||
if (validTypes.isEmpty()) {
|
||||
validTypes.addAll(Constant.CardTypes.CARD_TYPES);
|
||||
}
|
||||
boolean valid = false;
|
||||
while (!valid) {
|
||||
if (p.isHuman()) {
|
||||
final Object o = GuiChoose.one("Choose a card type", validTypes);
|
||||
if (null == o) {
|
||||
return;
|
||||
}
|
||||
final String choice = (String) o;
|
||||
if (CardType.isACardType(choice) && !invalidTypes.contains(choice)) {
|
||||
valid = true;
|
||||
card.setChosenType(choice);
|
||||
}
|
||||
} else {
|
||||
// TODO
|
||||
// computer will need to choose a type
|
||||
// based on whether it needs a creature or land,
|
||||
// otherwise, lib search for most common type left
|
||||
// then, reveal chosenType to Human
|
||||
}
|
||||
}
|
||||
if (validTypes.isEmpty()) validTypes.addAll(Constant.CardTypes.CARD_TYPES);
|
||||
} else if (type.equals("Creature")) {
|
||||
String chosenType = "";
|
||||
boolean valid = false;
|
||||
while (!valid) {
|
||||
if (p.isHuman()) {
|
||||
final ArrayList<String> validChoices = CardType.getCreatureTypes();
|
||||
for (final String s : invalidTypes) {
|
||||
validChoices.remove(s);
|
||||
}
|
||||
chosenType = GuiChoose.one("Choose a creature type", validChoices);
|
||||
} else {
|
||||
Player ai = p;
|
||||
Player opp = ai.getOpponent();
|
||||
String chosen = "";
|
||||
if (sa.hasParam("AILogic")) {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
if (logic.equals("MostProminentOnBattlefield")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(game.getCardsIn(ZoneType.Battlefield));
|
||||
}
|
||||
else if (logic.equals("MostProminentComputerControls")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
||||
}
|
||||
else if (logic.equals("MostProminentHumanControls")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), opp));
|
||||
}
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerDeck")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
||||
}
|
||||
}
|
||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||
chosen = "Sliver";
|
||||
}
|
||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
||||
chosenType = chosen;
|
||||
}
|
||||
|
||||
if (CardType.isACreatureType(chosenType) && !invalidTypes.contains(chosenType)) {
|
||||
valid = true;
|
||||
card.setChosenType(chosenType);
|
||||
}
|
||||
}
|
||||
if (validTypes.isEmpty()) validTypes.addAll(CardType.getCreatureTypes());
|
||||
} else if (type.equals("Basic Land")) {
|
||||
boolean valid = false;
|
||||
while (!valid) {
|
||||
if (p.isHuman()) {
|
||||
final String choice = GuiChoose.one("Choose a basic land type", CardType.getBasicTypes());
|
||||
if (null == choice) {
|
||||
return;
|
||||
}
|
||||
if (CardType.isABasicLandType(choice) && !invalidTypes.contains(choice)) {
|
||||
valid = true;
|
||||
card.setChosenType(choice);
|
||||
}
|
||||
} else {
|
||||
Player ai = p;
|
||||
String chosen = "";
|
||||
if (sa.hasParam("AILogic")) {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
if (logic.equals("MostNeededType")) {
|
||||
// Choose a type that is in the deck, but not in hand or on the battlefield
|
||||
final ArrayList<String> basics = new ArrayList<String>();
|
||||
basics.addAll(Constant.CardTypes.BASIC_TYPES);
|
||||
List<Card> presentCards = ai.getCardsIn(ZoneType.Battlefield);
|
||||
presentCards.addAll(ai.getCardsIn(ZoneType.Hand));
|
||||
List<Card> possibleCards = ai.getAllCards();
|
||||
|
||||
for (String b : basics) {
|
||||
if(!Iterables.any(presentCards, CardPredicates.isType(b)) && Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
||||
chosen = b;
|
||||
}
|
||||
}
|
||||
if (chosen.equals("")) {
|
||||
for (String b : basics) {
|
||||
if(Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
||||
chosen = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (logic.equals("ChosenLandwalk")) {
|
||||
final List<Card> lands = p.getOpponent().getLandsInPlay();
|
||||
for (Card c : lands) {
|
||||
for (String t : c.getType()) {
|
||||
if (!invalidTypes.contains(t)
|
||||
&& CardType.isABasicLandType(t)) {
|
||||
chosen = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CardType.isABasicLandType(chosen) || invalidTypes.contains(chosen)) {
|
||||
chosen = "Island";
|
||||
}
|
||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
||||
card.setChosenType(chosen);
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
if (validTypes.isEmpty()) validTypes.addAll(CardType.getBasicTypes());
|
||||
} else if (type.equals("Land")) {
|
||||
boolean valid = false;
|
||||
while (!valid) {
|
||||
if (p.isHuman()) {
|
||||
final String choice = GuiChoose
|
||||
.one("Choose a land type", CardType.getLandTypes());
|
||||
if (null == choice) {
|
||||
return;
|
||||
}
|
||||
if (!invalidTypes.contains(choice)) {
|
||||
valid = true;
|
||||
card.setChosenType(choice);
|
||||
}
|
||||
} else {//AI
|
||||
String choice = null;
|
||||
if (sa.hasParam("AILogic")) {
|
||||
final String logic = sa.getParam("AILogic");
|
||||
if (logic.equals("ChosenLandwalk")) {
|
||||
final List<Card> lands = p.getOpponent().getLandsInPlay();
|
||||
for (Card c : lands) {
|
||||
for (String t : c.getType()) {
|
||||
if (!invalidTypes.contains(t)
|
||||
&& CardType.getLandTypes().contains(t)) {
|
||||
choice = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
card.setChosenType(choice != null ? choice :"Island");
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
if (validTypes.isEmpty()) validTypes.addAll(CardType.getLandTypes());
|
||||
} // end if-else if
|
||||
|
||||
if( !validTypes.isEmpty()) {
|
||||
for (final String s : invalidTypes) {
|
||||
validTypes.remove(s);
|
||||
}
|
||||
String choice = p.getController().chooseSomeType(type, sa.getParam("AILogic"), validTypes, invalidTypes);
|
||||
card.setChosenType(choice);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import forge.card.cardfactory.CardFactoryUtil;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
@@ -141,7 +142,7 @@ public class DiscardEffect extends RevealEffectBase {
|
||||
|
||||
if (mode.equals("Random")) {
|
||||
String message = "Would you like to discard " + numCards + " random card(s)?";
|
||||
boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, mode, message);
|
||||
boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message);
|
||||
|
||||
if (runDiscard) {
|
||||
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
||||
|
||||
@@ -47,6 +47,7 @@ import forge.game.GameState;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.Expressions;
|
||||
@@ -699,15 +700,18 @@ public class AiController {
|
||||
}
|
||||
|
||||
|
||||
public boolean confirmAction(SpellAbility sa, String mode, String message) {
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||
ApiType api = sa.getApi();
|
||||
|
||||
// Abilities without api may also use this routine, However they should provide a unique mode value
|
||||
if ( null == api ) {
|
||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||
}
|
||||
|
||||
switch(api) {
|
||||
if( mode != null ) switch (mode) {
|
||||
case BraidOfFire: return true;
|
||||
}
|
||||
} else switch(api) {
|
||||
case Discard:
|
||||
if ( mode.startsWith("Random") ) { //
|
||||
if ( mode == PlayerActionConfirmMode.Random ) { //
|
||||
// TODO For now AI will always discard Random used currently with: Balduvian Horde and similar cards
|
||||
return true;
|
||||
}
|
||||
@@ -718,7 +722,7 @@ public class AiController {
|
||||
|
||||
default:
|
||||
}
|
||||
String exMsg = String.format("AI confirmAction does not know what to decide about %s with %s mode.", api, mode);
|
||||
String exMsg = String.format("AI confirmAction does not know what to decide about %s API with %s mode.", api, mode);
|
||||
throw new InvalidParameterException(exMsg);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,18 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.Card;
|
||||
import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.Constant;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.CardUtil;
|
||||
import forge.card.CardType;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
@@ -658,6 +662,12 @@ public class ComputerUtil {
|
||||
|
||||
// Precondition it wants: remaining are reverse-sorted by CMC
|
||||
private static Card chooseCardToSacrifice(final List<Card> remaining, final Player ai, final boolean destroy) {
|
||||
// If somehow ("Drop of Honey") they suggest to destroy opponent's card - use the chance!
|
||||
for(Card c : remaining) { // first compare is fast, second is precise
|
||||
if (c.getController() != ai && ai.getOpponents().contains(c.getController()) )
|
||||
return c;
|
||||
}
|
||||
|
||||
if (destroy) {
|
||||
final List<Card> indestructibles = CardLists.getKeyword(remaining, "Indestructible");
|
||||
if (!indestructibles.isEmpty()) {
|
||||
@@ -1420,4 +1430,99 @@ public class ComputerUtil {
|
||||
// no special options for human or remote friends
|
||||
return getCardsToDiscardFromOpponent(aiChooser, p, sa, validCards, min, max);
|
||||
}
|
||||
|
||||
public static String chooseSomeType(Player ai, String kindOfType, String logic, List<String> invalidTypes) {
|
||||
final GameState game = ai.getGame();
|
||||
String chosen = "";
|
||||
if( kindOfType.equals("Card")) {
|
||||
// TODO
|
||||
// computer will need to choose a type
|
||||
// based on whether it needs a creature or land,
|
||||
// otherwise, lib search for most common type left
|
||||
// then, reveal chosenType to Human
|
||||
} else if (kindOfType.equals("Creature")) {
|
||||
Player opp = ai.getOpponent();
|
||||
if (logic != null ) {
|
||||
if (logic.equals("MostProminentOnBattlefield")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(game.getCardsIn(ZoneType.Battlefield));
|
||||
}
|
||||
else if (logic.equals("MostProminentComputerControls")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Battlefield));
|
||||
}
|
||||
else if (logic.equals("MostProminentHumanControls")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(opp.getCardsIn(ZoneType.Battlefield));
|
||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), opp));
|
||||
}
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerDeck")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(CardLists.filterControlledBy(game.getCardsInGame(), ai));
|
||||
}
|
||||
else if (logic.equals("MostProminentInComputerGraveyard")) {
|
||||
chosen = ComputerUtilCard.getMostProminentCreatureType(ai.getCardsIn(ZoneType.Graveyard));
|
||||
}
|
||||
}
|
||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||
chosen = "Sliver";
|
||||
}
|
||||
|
||||
} else if ( kindOfType.equals("Basic Land")) {
|
||||
if (logic != null) {
|
||||
if (logic.equals("MostNeededType")) {
|
||||
// Choose a type that is in the deck, but not in hand or on the battlefield
|
||||
final ArrayList<String> basics = new ArrayList<String>();
|
||||
basics.addAll(Constant.CardTypes.BASIC_TYPES);
|
||||
List<Card> presentCards = ai.getCardsIn(ZoneType.Battlefield);
|
||||
presentCards.addAll(ai.getCardsIn(ZoneType.Hand));
|
||||
List<Card> possibleCards = ai.getAllCards();
|
||||
|
||||
for (String b : basics) {
|
||||
if(!Iterables.any(presentCards, CardPredicates.isType(b)) && Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
||||
chosen = b;
|
||||
}
|
||||
}
|
||||
if (chosen.equals("")) {
|
||||
for (String b : basics) {
|
||||
if(Iterables.any(possibleCards, CardPredicates.isType(b))) {
|
||||
chosen = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (logic.equals("ChosenLandwalk")) {
|
||||
for (Card c : ai.getOpponent().getLandsInPlay()) {
|
||||
for (String t : c.getType()) {
|
||||
if (!invalidTypes.contains(t) && CardType.isABasicLandType(t)) {
|
||||
chosen = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CardType.isABasicLandType(chosen) || invalidTypes.contains(chosen)) {
|
||||
chosen = "Island";
|
||||
}
|
||||
|
||||
} else if( kindOfType.equals("Land") ) {
|
||||
if (logic != null) {
|
||||
if (logic.equals("ChosenLandwalk")) {
|
||||
for (Card c : ai.getOpponent().getLandsInPlay()) {
|
||||
for (String t : c.getType()) {
|
||||
if (!invalidTypes.contains(t) && CardType.isALandType(t)) {
|
||||
chosen = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( StringUtils.isEmpty(chosen))
|
||||
chosen = "Island";
|
||||
}
|
||||
|
||||
|
||||
GuiChoose.one("Computer picked: ", new String[]{chosen});
|
||||
return chosen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import forge.game.ai.ComputerUtilCost;
|
||||
import forge.game.ai.ComputerUtilMana;
|
||||
import forge.game.player.HumanPlay;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.GuiChoose;
|
||||
@@ -133,9 +134,7 @@ public class Upkeep extends Phase {
|
||||
Map<String, String> produced = new HashMap<String, String>();
|
||||
produced.put("Produced", rs.toString());
|
||||
final AbilityManaPart abMana = new AbilityManaPart(c, produced);
|
||||
if (player.isComputer()) {
|
||||
abMana.produceMana(this);
|
||||
} else if (GuiDialog.confirm(c, sb.toString())) {
|
||||
if( player.getController().confirmAction(this, PlayerActionConfirmMode.BraidOfFire, sb.toString())) {
|
||||
abMana.produceMana(this);
|
||||
} else {
|
||||
game.getAction().sacrifice(c, null);
|
||||
@@ -493,48 +492,17 @@ public class Upkeep extends Phase {
|
||||
final List<Card> creatures = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.CREATURES);
|
||||
if (creatures.size() > 0) {
|
||||
CardLists.sortByPowerAsc(creatures);
|
||||
final List<Card> lowest = new ArrayList<Card>();
|
||||
final int power = creatures.get(0).getNetAttack();
|
||||
if (player.isHuman()) {
|
||||
InputSelectCards inp = new InputSelectCardsFromList(1,1,this.getLowestPowerList(creatures));
|
||||
inp.setMessage("Select creature with power: " + power + " to sacrifice.");
|
||||
FThreads.setInputAndWait(inp);
|
||||
if(!inp.hasCancelled())
|
||||
game.getAction().destroyNoRegeneration(inp.getSelected().get(0), this);
|
||||
|
||||
} else { // computer
|
||||
final Card compyTarget = this.getCompyCardToDestroy(creatures);
|
||||
game.getAction().destroyNoRegeneration(compyTarget, this);
|
||||
for(Card c : creatures) {
|
||||
if (c.getNetAttack() > power) break;
|
||||
lowest.add(c);
|
||||
}
|
||||
|
||||
List<Card> toSac = player.getController().choosePermanentsToSacrifice(lowest, "Select creature with power: " + power + " to destroy.", 1, this, true, false);
|
||||
game.getAction().destroyNoRegeneration(toSac.get(0), this);
|
||||
}
|
||||
} // resolve
|
||||
|
||||
private List<Card> getLowestPowerList(final List<Card> original) {
|
||||
final List<Card> lowestPower = new ArrayList<Card>();
|
||||
final int power = original.get(0).getNetAttack();
|
||||
int i = 0;
|
||||
while ((i < original.size()) && (original.get(i).getNetAttack() == power)) {
|
||||
lowestPower.add(original.get(i));
|
||||
i++;
|
||||
}
|
||||
return lowestPower;
|
||||
}
|
||||
|
||||
private Card getCompyCardToDestroy(final List<Card> original) {
|
||||
final List<Card> options = this.getLowestPowerList(original);
|
||||
final List<Card> humanCreatures = CardLists.filter(options, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
return c.getController().isHuman();
|
||||
}
|
||||
});
|
||||
if (humanCreatures.isEmpty()) {
|
||||
CardLists.shuffle(options);
|
||||
return options.get(0);
|
||||
} else {
|
||||
CardLists.shuffle(humanCreatures);
|
||||
return humanCreatures.get(0);
|
||||
}
|
||||
}
|
||||
}; // Ability
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
11
src/main/java/forge/game/player/PlayerActionConfirmMode.java
Normal file
11
src/main/java/forge/game/player/PlayerActionConfirmMode.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package forge.game.player;
|
||||
|
||||
/**
|
||||
* Used by PlayerController.confirmAction - to avoid a lot of hardcoded strings for mode
|
||||
*
|
||||
*/
|
||||
public enum PlayerActionConfirmMode {
|
||||
Random,
|
||||
BraidOfFire,
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.game.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -35,11 +34,11 @@ public abstract class PlayerController {
|
||||
private PhaseType autoPassUntil = null;
|
||||
private final Input autoPassPriorityInput;
|
||||
protected final Player player;
|
||||
|
||||
|
||||
public PlayerController(GameState game0, Player p) {
|
||||
game = game0;
|
||||
player = p;
|
||||
autoPassPriorityInput = new InputAutoPassPriority(getPlayer());
|
||||
autoPassPriorityInput = new InputAutoPassPriority(player);
|
||||
}
|
||||
|
||||
public abstract Input getDefaultInput();
|
||||
@@ -66,6 +65,16 @@ public abstract class PlayerController {
|
||||
return false; // human has it's overload
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*/
|
||||
public void passPriority() {
|
||||
PhaseHandler handler = game.getPhaseHandler();
|
||||
|
||||
if ( handler.getPriorityPlayer() == player )
|
||||
game.getPhaseHandler().passPriority();
|
||||
}
|
||||
|
||||
// Triggers preliminary choice: ask, decline or play
|
||||
private Map<Integer, Boolean> triggersAlwaysAccept = new HashMap<Integer, Boolean>();
|
||||
|
||||
@@ -84,16 +93,6 @@ public abstract class PlayerController {
|
||||
*/
|
||||
public abstract SpellAbility getAbilityToPlay(List<SpellAbility> abilities);
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*/
|
||||
public void passPriority() {
|
||||
PhaseHandler handler = game.getPhaseHandler();
|
||||
|
||||
if ( handler.getPriorityPlayer() == getPlayer() )
|
||||
game.getPhaseHandler().passPriority();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param c
|
||||
@@ -101,11 +100,8 @@ public abstract class PlayerController {
|
||||
public abstract void playFromSuspend(Card c);
|
||||
public abstract boolean playCascade(Card cascadedCard, Card sourceCard);
|
||||
public abstract void playSpellAbilityForFree(SpellAbility copySA);
|
||||
/**
|
||||
* @return the player
|
||||
*/
|
||||
protected final Player getPlayer(){ return player; }
|
||||
|
||||
|
||||
|
||||
|
||||
public abstract Deck sideboard(final Deck deck, GameType gameType);
|
||||
|
||||
@@ -118,7 +114,7 @@ public abstract class PlayerController {
|
||||
|
||||
public Card chooseSingleCardForEffect(List<Card> sourceList, SpellAbility sa, String title) { return chooseSingleCardForEffect(sourceList, sa, title, false); }
|
||||
public abstract Card chooseSingleCardForEffect(List<Card> sourceList, SpellAbility sa, String title, boolean isOptional);
|
||||
public abstract boolean confirmAction(SpellAbility sa, String mode, String message);
|
||||
public abstract boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message);
|
||||
public abstract boolean getWillPlayOnFirstTurn(String message);
|
||||
public abstract boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message);
|
||||
|
||||
@@ -139,4 +135,6 @@ public abstract class PlayerController {
|
||||
public abstract List<Card> chooseCardsToDelve(int colorLessAmount, List<Card> grave);
|
||||
public abstract List<Card> chooseCardsToDiscardUnlessType(int min, List<Card> hand, String param, SpellAbility sa);
|
||||
public abstract Mana chooseManaFromPool(List<Mana> manaChoices);
|
||||
|
||||
public abstract String chooseSomeType(String kindOfType, String aiLogic, List<String> validTypes, List<String> invalidTypes);
|
||||
}
|
||||
|
||||
@@ -46,22 +46,32 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
private final AiController brains;
|
||||
|
||||
|
||||
|
||||
public final Input getDefaultInput() {
|
||||
return defaultInput;
|
||||
}
|
||||
|
||||
public PlayerControllerAi(GameState game, Player p) {
|
||||
super(game, p);
|
||||
|
||||
brains = new AiController(p, game);
|
||||
|
||||
defaultInput = new AiInputCommon(brains);
|
||||
blockInput = new AiInputBlock(getPlayer());
|
||||
blockInput = new AiInputBlock(player);
|
||||
cleanupInput = getDefaultInput();
|
||||
}
|
||||
|
||||
public final Input getDefaultInput() {
|
||||
return defaultInput;
|
||||
}
|
||||
|
||||
/** Input to use when player has to declare blockers */
|
||||
public Input getBlockInput() {
|
||||
return blockInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cleanupInput
|
||||
*/
|
||||
public Input getCleanupInput() {
|
||||
return cleanupInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses GUI to learn which spell the player (human in our case) would like to play
|
||||
*/
|
||||
@@ -75,19 +85,6 @@ public class PlayerControllerAi extends PlayerController {
|
||||
}
|
||||
}
|
||||
|
||||
/** Input to use when player has to declare blockers */
|
||||
public Input getBlockInput() {
|
||||
return blockInput;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the cleanupInput
|
||||
*/
|
||||
public Input getCleanupInput() {
|
||||
return cleanupInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param c
|
||||
@@ -123,11 +120,11 @@ public class PlayerControllerAi extends PlayerController {
|
||||
if (copySA instanceof Spell) {
|
||||
Spell spell = (Spell) copySA;
|
||||
if (spell.canPlayFromEffectAI(true, true)) {
|
||||
ComputerUtil.playStackFree(getPlayer(), copySA);
|
||||
ComputerUtil.playStackFree(player, copySA);
|
||||
}
|
||||
} else {
|
||||
copySA.canPlayAI();
|
||||
ComputerUtil.playStackFree(getPlayer(), copySA);
|
||||
ComputerUtil.playStackFree(player, copySA);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +156,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmAction(SpellAbility sa, String mode, String message) {
|
||||
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||
return getAi().confirmAction(sa, mode, message);
|
||||
}
|
||||
|
||||
@@ -215,7 +212,7 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min, int max) {
|
||||
boolean isTargetFriendly = !p.isOpponentOf(getPlayer());
|
||||
boolean isTargetFriendly = !p.isOpponentOf(player);
|
||||
|
||||
return isTargetFriendly
|
||||
? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min, max)
|
||||
@@ -274,5 +271,13 @@ public class PlayerControllerAi extends PlayerController {
|
||||
return manaChoices.get(0); // no brains used
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.PlayerController#ChooseSomeType(java.lang.String, java.util.List, java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public String chooseSomeType(String kindOfType, String aiLogic, List<String> validTypes, List<String> invalidTypes) {
|
||||
return ComputerUtil.chooseSomeType(player, kindOfType, aiLogic, invalidTypes);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -50,18 +50,30 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
private final Input blockInput;
|
||||
private final Input cleanupInput;
|
||||
|
||||
public final Input getDefaultInput() {
|
||||
return defaultInput;
|
||||
}
|
||||
|
||||
public PlayerControllerHuman(GameState game0, Player p) {
|
||||
super(game0, p);
|
||||
defaultInput = new InputPassPriority(player);
|
||||
blockInput = new InputBlock(getPlayer(), game0);
|
||||
cleanupInput = new InputCleanup(getPlayer());
|
||||
blockInput = new InputBlock(player, game0);
|
||||
cleanupInput = new InputCleanup(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Input getDefaultInput() {
|
||||
return defaultInput;
|
||||
}
|
||||
|
||||
/** Input to use when player has to declare blockers */
|
||||
public Input getBlockInput() {
|
||||
return blockInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cleanupInput
|
||||
*/
|
||||
public Input getCleanupInput() {
|
||||
return cleanupInput;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
||||
return !CMatchUI.SINGLETON_INSTANCE.stopAtPhase(turn, phase);
|
||||
}
|
||||
@@ -79,18 +91,6 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
}
|
||||
|
||||
/** Input to use when player has to declare blockers */
|
||||
public Input getBlockInput() {
|
||||
return blockInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cleanupInput
|
||||
*/
|
||||
public Input getCleanupInput() {
|
||||
return cleanupInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param c
|
||||
@@ -260,7 +260,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
* @see forge.game.player.PlayerController#confirmAction(forge.card.spellability.SpellAbility, java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean confirmAction(SpellAbility sa, String mode, String message) {
|
||||
public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) {
|
||||
return GuiDialog.confirm(sa.getSourceCard(), message);
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
@Override
|
||||
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int min, int max) {
|
||||
if ( p != getPlayer() ) {
|
||||
if ( p != player ) {
|
||||
int cntToKeepInHand = min == 0 ? -1 : valid.size() - min;
|
||||
return GuiChoose.order("Choose cards to Discard", "Discarded", cntToKeepInHand, valid, null, null);
|
||||
}
|
||||
@@ -450,4 +450,12 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
return manaChoices.get(Integer.parseInt(idx)-1);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.game.player.PlayerController#chooseSomeType(java.lang.String, java.lang.String, java.util.List, java.util.List, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String chooseSomeType(String kindOfType, String aiLogic, List<String> validTypes, List<String> invalidTypes) {
|
||||
return GuiChoose.one("Choose a " + kindOfType.toLowerCase() + " type", validTypes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,9 +33,7 @@ import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.CardUtil;
|
||||
import forge.Singletons;
|
||||
import forge.card.spellability.SpellAbilityStackInstance;
|
||||
import forge.control.FControl;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.game.zone.MagicStack;
|
||||
|
||||
Reference in New Issue
Block a user