mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Code that chooses cards to be discarded moved to PlayerController and ComputerUtil
This commit is contained in:
@@ -24,6 +24,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
@@ -90,6 +91,8 @@ public class CardLists {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final List<Card> emptyList = ImmutableList.of();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Sorts a List<Card> by "best" using the EvaluateCreature function.
|
* Sorts a List<Card> by "best" using the EvaluateCreature function.
|
||||||
|
|||||||
@@ -1,26 +1,18 @@
|
|||||||
package forge.card.ability.effects;
|
package forge.card.ability.effects;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
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.cardfactory.CardFactoryUtil;
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.game.ai.ComputerUtilCard;
|
|
||||||
import forge.game.player.AIPlayer;
|
|
||||||
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.util.Aggregates;
|
|
||||||
|
|
||||||
public class DiscardEffect extends RevealEffectBase {
|
public class DiscardEffect extends RevealEffectBase {
|
||||||
@Override
|
@Override
|
||||||
@@ -87,44 +79,6 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
} // discardStackDescription()
|
} // discardStackDescription()
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for this method.
|
|
||||||
* @param sa
|
|
||||||
* @param opponentHand
|
|
||||||
* @param list
|
|
||||||
*/
|
|
||||||
private Card chooseCardToDiscardFromOpponent(SpellAbility sa, List<Card> opponentHand) {
|
|
||||||
List<Card> goodChoices = CardLists.filter(opponentHand, new Predicate<Card>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final Card c) {
|
|
||||||
if (!c.getSVar("DiscardMeByOpp").equals("") || !c.getSVar("DiscardMe").equals("")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (goodChoices.isEmpty()) {
|
|
||||||
goodChoices = opponentHand;
|
|
||||||
}
|
|
||||||
final List<Card> dChoices = new ArrayList<Card>();
|
|
||||||
if (sa.hasParam("DiscardValid")) {
|
|
||||||
final String validString = sa.getParam("DiscardValid");
|
|
||||||
if (validString.contains("Creature") && !validString.contains("nonCreature")) {
|
|
||||||
final Card c = ComputerUtilCard.getBestCreatureAI(goodChoices);
|
|
||||||
if (c != null) {
|
|
||||||
dChoices.add(ComputerUtilCard.getBestCreatureAI(goodChoices));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(goodChoices, CardLists.TextLenComparator);
|
|
||||||
|
|
||||||
CardLists.sortByCmcDesc(goodChoices);
|
|
||||||
dChoices.add(goodChoices.get(0));
|
|
||||||
|
|
||||||
return Aggregates.random(goodChoices);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
@@ -194,11 +148,7 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
// Reveal
|
// Reveal
|
||||||
final List<Card> dPHand = p.getCardsIn(ZoneType.Hand);
|
final List<Card> dPHand = p.getCardsIn(ZoneType.Hand);
|
||||||
|
|
||||||
if (p.isHuman()) {
|
p.getOpponent().getController().reveal("Reveal " + p + " hand" , dPHand, ZoneType.Hand, p);
|
||||||
// "reveal to computer" for information gathering
|
|
||||||
} else {
|
|
||||||
GuiChoose.oneOrNone("Revealed computer hand", dPHand);
|
|
||||||
}
|
|
||||||
|
|
||||||
String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
||||||
|
|
||||||
@@ -215,7 +165,7 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
} else if (mode.equals("RevealYouChoose") || mode.equals("RevealOppChoose") || mode.equals("TgtChoose")) {
|
} else if (mode.equals("RevealYouChoose") || mode.equals("RevealOppChoose") || mode.equals("TgtChoose")) {
|
||||||
// Is Reveal you choose right? I think the wrong player is
|
// Is Reveal you choose right? I think the wrong player is
|
||||||
// being used?
|
// being used?
|
||||||
List<Card> dPHand = new ArrayList<Card>(p.getCardsIn(ZoneType.Hand));
|
List<Card> dPHand = p.getCardsIn(ZoneType.Hand);
|
||||||
if (dPHand.isEmpty())
|
if (dPHand.isEmpty())
|
||||||
continue; // for loop over players
|
continue; // for loop over players
|
||||||
|
|
||||||
@@ -224,11 +174,9 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
int amount = StringUtils.isNumeric(amountString) ? Integer.parseInt(amountString) : CardFactoryUtil.xCount(source, source.getSVar(amountString));
|
int amount = StringUtils.isNumeric(amountString) ? Integer.parseInt(amountString) : CardFactoryUtil.xCount(source, source.getSVar(amountString));
|
||||||
dPHand = getRevealedList(p, dPHand, amount, false);
|
dPHand = getRevealedList(p, dPHand, amount, false);
|
||||||
}
|
}
|
||||||
List<Card> dPChHand = new ArrayList<Card>(dPHand);
|
|
||||||
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
final String valid = sa.hasParam("DiscardValid") ? sa.getParam("DiscardValid") : "Card";
|
||||||
String[] dValid = ArrayUtils.EMPTY_STRING_ARRAY;
|
String[] dValid = valid.split(",");
|
||||||
dValid = valid.split(",");
|
List<Card> validCards = CardLists.getValidCards(dPHand, dValid, source.getController(), source);
|
||||||
dPChHand = CardLists.getValidCards(dPHand, dValid, source.getController(), source);
|
|
||||||
|
|
||||||
Player chooser = p;
|
Player chooser = p;
|
||||||
if (mode.equals("RevealYouChoose")) {
|
if (mode.equals("RevealYouChoose")) {
|
||||||
@@ -237,60 +185,16 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
chooser = source.getController().getOpponent();
|
chooser = source.getController().getOpponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Card> toBeDiscarded = new ArrayList<Card>();
|
if (mode.startsWith("Reveal") && p != chooser)
|
||||||
if (chooser.isComputer()) {
|
chooser.getController().reveal("Revealed " + p + " hand", dPHand, ZoneType.Hand, p);
|
||||||
List<Card> dPChHand1 = new ArrayList<Card>(p.getCardsIn(ZoneType.Hand));
|
|
||||||
dPChHand1 = CardLists.getValidCards(dPChHand1, dValid, source.getController(), source);
|
|
||||||
|
|
||||||
int max = Math.min(dPChHand1.size(), numCards);
|
int minDiscardAmount = sa.hasParam("AnyNumber") || sa.hasParam("Optional") ? 0 : numCards;
|
||||||
List<Card> list = new ArrayList<Card>();
|
int max = Math.min(validCards.size(), minDiscardAmount);
|
||||||
|
|
||||||
if (!p.isOpponentOf(chooser) && p instanceof AIPlayer) { // discard AI cards
|
List<Card> toBeDiscarded = validCards.isEmpty() ? CardLists.emptyList : chooser.getController().chooseCardsToDiscardFrom(p, sa, validCards, max);
|
||||||
toBeDiscarded = ((AIPlayer) p).getAi().getCardsToDiscard(max, dValid, sa);
|
|
||||||
} else {
|
|
||||||
// discard hostile or human opponent
|
|
||||||
for (int i = 0; i < max; i++) {
|
|
||||||
Card dC = chooseCardToDiscardFromOpponent(sa, dPChHand1);
|
|
||||||
dPChHand1.remove(dC);
|
|
||||||
toBeDiscarded.add(dC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode.startsWith("Reveal")) {
|
if (mode.startsWith("Reveal") ) {
|
||||||
GuiChoose.oneOrNone("Computer has chosen", list);
|
p.getController().reveal(chooser + " has chosen", toBeDiscarded, ZoneType.Hand, p);
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// human
|
|
||||||
if (mode.startsWith("Reveal")) {
|
|
||||||
GuiChoose.oneOrNone("Revealed " + p + " hand", dPHand);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sa.hasParam("AnyNumber")) {
|
|
||||||
List<Card> chosen = getDiscardedList(p, dPChHand);
|
|
||||||
|
|
||||||
for (Card c : chosen) {
|
|
||||||
dPChHand.remove(c);
|
|
||||||
toBeDiscarded.add(c);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
for (int i = 0; i < numCards; i++) {
|
|
||||||
if (dPChHand.isEmpty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Card dC = null;
|
|
||||||
if (sa.hasParam("Optional")) {
|
|
||||||
dC = GuiChoose.oneOrNone("Choose a card to be discarded", dPChHand);
|
|
||||||
} else {
|
|
||||||
dC = GuiChoose.one("Choose a card to be discarded", dPChHand);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dC != null) {
|
|
||||||
dPChHand.remove(dC);
|
|
||||||
toBeDiscarded.add(dC);
|
|
||||||
}
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toBeDiscarded != null) {
|
if (toBeDiscarded != null) {
|
||||||
@@ -311,34 +215,4 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // discardResolve()
|
} // discardResolve()
|
||||||
|
|
||||||
public static List<Card> getDiscardedList(final Player player, final List<Card> valid) {
|
|
||||||
final List<Card> chosen = new ArrayList<Card>();
|
|
||||||
final int validamount = Math.min(valid.size(), valid.size());
|
|
||||||
|
|
||||||
if (player.isHuman() && validamount > 0) {
|
|
||||||
final List<Card> selection = GuiChoose.order("Choose Which Cards to Discard", "Discarded", -1, valid, null, null);
|
|
||||||
for (final Object o : selection) {
|
|
||||||
if (o != null && o instanceof Card) {
|
|
||||||
chosen.add((Card) o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < validamount; i++) {
|
|
||||||
if (player.isHuman()) {
|
|
||||||
final Card o = GuiChoose.one("Choose card(s) to discard", valid);
|
|
||||||
if (o != null) {
|
|
||||||
chosen.add(o);
|
|
||||||
valid.remove(o);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else { // Computer
|
|
||||||
chosen.add(valid.get(0));
|
|
||||||
valid.remove(valid.get(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chosen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -473,11 +473,9 @@ public class CardFactorySorceries {
|
|||||||
int s = h.size();
|
int s = h.size();
|
||||||
min = Math.min(min, s);
|
min = Math.min(min, s);
|
||||||
}
|
}
|
||||||
Iterator<List<Card>> hh = hands.iterator();
|
|
||||||
for (Player p : Singletons.getModel().getGame().getPlayers()) {
|
|
||||||
|
|
||||||
List<Card> h = hh.next();
|
for (Player p : Singletons.getModel().getGame().getPlayers()) {
|
||||||
int sac = h.size() - min;
|
int sac = p.getCardsIn(ZoneType.Hand).size() - min;
|
||||||
if (sac == 0) {
|
if (sac == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -525,16 +525,21 @@ public class AiController {
|
|||||||
*/
|
*/
|
||||||
public List<Card> getCardsToDiscard(final int numDiscard, final String[] uTypes, final SpellAbility sa) {
|
public List<Card> getCardsToDiscard(final int numDiscard, final String[] uTypes, final SpellAbility sa) {
|
||||||
List<Card> hand = new ArrayList<Card>(player.getCardsIn(ZoneType.Hand));
|
List<Card> hand = new ArrayList<Card>(player.getCardsIn(ZoneType.Hand));
|
||||||
Card sourceCard = null;
|
|
||||||
|
|
||||||
if ((uTypes != null) && (sa != null)) {
|
if ((uTypes != null) && (sa != null)) {
|
||||||
hand = CardLists.getValidCards(hand, uTypes, sa.getActivatingPlayer(), sa.getSourceCard());
|
hand = CardLists.getValidCards(hand, uTypes, sa.getActivatingPlayer(), sa.getSourceCard());
|
||||||
}
|
}
|
||||||
|
return getCardsToDiscard(numDiscard, hand, sa);
|
||||||
|
}
|
||||||
|
|
||||||
if (hand.size() < numDiscard) {
|
public List<Card> getCardsToDiscard(final int numDiscard, final List<Card> validCards, final SpellAbility sa) {
|
||||||
|
|
||||||
|
if (validCards.size() < numDiscard) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Card sourceCard = null;
|
||||||
final List<Card> discardList = new ArrayList<Card>();
|
final List<Card> discardList = new ArrayList<Card>();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
if (sa != null) {
|
if (sa != null) {
|
||||||
@@ -545,7 +550,7 @@ public class AiController {
|
|||||||
while (count < numDiscard) {
|
while (count < numDiscard) {
|
||||||
Card prefCard = null;
|
Card prefCard = null;
|
||||||
if (sa != null && sa.getActivatingPlayer() != null && sa.getActivatingPlayer().isOpponentOf(player)) {
|
if (sa != null && sa.getActivatingPlayer() != null && sa.getActivatingPlayer().isOpponentOf(player)) {
|
||||||
for (Card c : hand) {
|
for (Card c : validCards) {
|
||||||
if (c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME,"
|
if (c.hasKeyword("If a spell or ability an opponent controls causes you to discard CARDNAME,"
|
||||||
+ " put it onto the battlefield instead of putting it into your graveyard.")) {
|
+ " put it onto the battlefield instead of putting it into your graveyard.")) {
|
||||||
prefCard = c;
|
prefCard = c;
|
||||||
@@ -554,11 +559,11 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (prefCard == null) {
|
if (prefCard == null) {
|
||||||
prefCard = ComputerUtil.getCardPreference(player, sourceCard, "DiscardCost", hand);
|
prefCard = ComputerUtil.getCardPreference(player, sourceCard, "DiscardCost", validCards);
|
||||||
}
|
}
|
||||||
if (prefCard != null) {
|
if (prefCard != null) {
|
||||||
discardList.add(prefCard);
|
discardList.add(prefCard);
|
||||||
hand.remove(prefCard);
|
validCards.remove(prefCard);
|
||||||
count++;
|
count++;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -569,11 +574,11 @@ public class AiController {
|
|||||||
|
|
||||||
// choose rest
|
// choose rest
|
||||||
for (int i = 0; i < discardsLeft; i++) {
|
for (int i = 0; i < discardsLeft; i++) {
|
||||||
if (hand.isEmpty()) {
|
if (validCards.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final int numLandsInPlay = Iterables.size(Iterables.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS));
|
final int numLandsInPlay = Iterables.size(Iterables.filter(player.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.LANDS));
|
||||||
final List<Card> landsInHand = CardLists.filter(hand, CardPredicates.Presets.LANDS);
|
final List<Card> landsInHand = CardLists.filter(validCards, CardPredicates.Presets.LANDS);
|
||||||
final int numLandsInHand = landsInHand.size();
|
final int numLandsInHand = landsInHand.size();
|
||||||
|
|
||||||
// Discard a land
|
// Discard a land
|
||||||
@@ -582,21 +587,21 @@ public class AiController {
|
|||||||
|
|
||||||
if (canDiscardLands) {
|
if (canDiscardLands) {
|
||||||
discardList.add(landsInHand.get(0));
|
discardList.add(landsInHand.get(0));
|
||||||
hand.remove(landsInHand.get(0));
|
validCards.remove(landsInHand.get(0));
|
||||||
} else { // Discard other stuff
|
} else { // Discard other stuff
|
||||||
CardLists.sortByCmcDesc(hand);
|
CardLists.sortByCmcDesc(validCards);
|
||||||
int numLandsAvailable = numLandsInPlay;
|
int numLandsAvailable = numLandsInPlay;
|
||||||
if (numLandsInHand > 0) {
|
if (numLandsInHand > 0) {
|
||||||
numLandsAvailable++;
|
numLandsAvailable++;
|
||||||
}
|
}
|
||||||
//Discard unplayable card
|
//Discard unplayable card
|
||||||
if (hand.get(0).getCMC() > numLandsAvailable) {
|
if (validCards.get(0).getCMC() > numLandsAvailable) {
|
||||||
discardList.add(hand.get(0));
|
discardList.add(validCards.get(0));
|
||||||
hand.remove(hand.get(0));
|
validCards.remove(validCards.get(0));
|
||||||
} else { //Discard worst card
|
} else { //Discard worst card
|
||||||
Card worst = ComputerUtilCard.getWorstAI(hand);
|
Card worst = ComputerUtilCard.getWorstAI(validCards);
|
||||||
discardList.add(worst);
|
discardList.add(worst);
|
||||||
hand.remove(worst);
|
validCards.remove(worst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1001,21 +1001,7 @@ public class ComputerUtil {
|
|||||||
|
|
||||||
for (final Card c : all) {
|
for (final Card c : all) {
|
||||||
for (final SpellAbility sa : c.getSpellAbility()) {
|
for (final SpellAbility sa : c.getSpellAbility()) {
|
||||||
|
if (sa.getApi() == ApiType.Pump && sa.hasParam("KW") && sa.getParam("KW").contains("Haste")) {
|
||||||
if (sa.getApi() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ????
|
|
||||||
// if ( sa.isAbility() || sa.isSpell() && sa.getApi() != ApiType.Pump ) continue
|
|
||||||
if (sa.hasParam("AB") && !sa.getParam("AB").equals("Pump")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (sa.hasParam("SP") && !sa.getParam("SP").equals("Pump")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sa.hasParam("KW") && sa.getParam("KW").contains("Haste")) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1239,4 +1225,62 @@ public class ComputerUtil {
|
|||||||
}
|
}
|
||||||
return bottom;
|
return bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param chooser
|
||||||
|
* @param discarder
|
||||||
|
* @param sa
|
||||||
|
* @param validCards
|
||||||
|
* @param min
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<Card> getCardsToDiscardFromOpponent(AIPlayer chooser, Player discarder, SpellAbility sa, List<Card> validCards, int min) {
|
||||||
|
List<Card> goodChoices = CardLists.filter(validCards, new Predicate<Card>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Card c) {
|
||||||
|
if (!c.getSVar("DiscardMeByOpp").equals("") || !c.getSVar("DiscardMe").equals("")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (goodChoices.isEmpty()) {
|
||||||
|
goodChoices = validCards;
|
||||||
|
}
|
||||||
|
final List<Card> dChoices = new ArrayList<Card>();
|
||||||
|
if (sa.hasParam("DiscardValid")) {
|
||||||
|
final String validString = sa.getParam("DiscardValid");
|
||||||
|
if (validString.contains("Creature") && !validString.contains("nonCreature")) {
|
||||||
|
final Card c = ComputerUtilCard.getBestCreatureAI(goodChoices);
|
||||||
|
if (c != null) {
|
||||||
|
dChoices.add(ComputerUtilCard.getBestCreatureAI(goodChoices));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(goodChoices, CardLists.TextLenComparator);
|
||||||
|
|
||||||
|
CardLists.sortByCmcDesc(goodChoices);
|
||||||
|
dChoices.add(goodChoices.get(0));
|
||||||
|
|
||||||
|
return Aggregates.random(goodChoices, min);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param aiChoser
|
||||||
|
* @param p
|
||||||
|
* @param sa
|
||||||
|
* @param validCards
|
||||||
|
* @param min
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<Card> getCardsToDiscardFromFriend(AIPlayer aiChooser, Player p, SpellAbility sa, List<Card> validCards, int min) {
|
||||||
|
if (p instanceof AIPlayer) { // ask that ai player what he would like to discard
|
||||||
|
return ((AIPlayer) p).getAi().getCardsToDiscard(min, validCards, sa);
|
||||||
|
}
|
||||||
|
// no special options for human or remote friends
|
||||||
|
return getCardsToDiscardFromOpponent(aiChooser, p, sa, validCards, min);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public class AIPlayer extends Player {
|
|||||||
public final void discard(final int num, final SpellAbility sa) {
|
public final void discard(final int num, final SpellAbility sa) {
|
||||||
int max = this.getCardsIn(ZoneType.Hand).size();
|
int max = this.getCardsIn(ZoneType.Hand).size();
|
||||||
max = Math.min(max, num);
|
max = Math.min(max, num);
|
||||||
final List<Card> toDiscard = this.getAi().getCardsToDiscard(max, null, sa);
|
final List<Card> toDiscard = this.getAi().getCardsToDiscard(max, (String[])null, sa);
|
||||||
for (int i = 0; i < toDiscard.size(); i++) {
|
for (int i = 0; i < toDiscard.size(); i++) {
|
||||||
this.doDiscard(toDiscard.get(i), sa);
|
this.doDiscard(toDiscard.get(i), sa);
|
||||||
}
|
}
|
||||||
@@ -125,8 +125,7 @@ public class AIPlayer extends Player {
|
|||||||
|
|
||||||
if (tHand.size() > 0) {
|
if (tHand.size() > 0) {
|
||||||
Card toDiscard = Aggregates.itemWithMin(tHand, CardPredicates.Accessors.fnGetCmc);
|
Card toDiscard = Aggregates.itemWithMin(tHand, CardPredicates.Accessors.fnGetCmc);
|
||||||
toDiscard.getController().discard(toDiscard, sa); // this got changed
|
discard(toDiscard, sa); // this got changed to doDiscard basically
|
||||||
// to doDiscard basically
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.discard(num, sa);
|
this.discard(num, sa);
|
||||||
|
|||||||
@@ -108,4 +108,7 @@ public abstract class PlayerController {
|
|||||||
public abstract void reveal(String string, List<Card> cards, ZoneType zone, Player owner);
|
public abstract void reveal(String string, List<Card> cards, ZoneType zone, Player owner);
|
||||||
public abstract ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN);
|
public abstract ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN);
|
||||||
public abstract boolean willPutCardOnTop(Card c);
|
public abstract boolean willPutCardOnTop(Card c);
|
||||||
|
|
||||||
|
/** p = target player, validCards - possible discards, min cards to discard */
|
||||||
|
public abstract List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,4 +255,16 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
return true; // AI does not know what will happen next (another clash or that would become his topdeck)
|
return true; // AI does not know what will happen next (another clash or that would become his topdeck)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.game.player.PlayerController#chooseCardsToDiscardFrom(forge.game.player.Player, java.util.List, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> validCards, int min) {
|
||||||
|
boolean isTargetFriendly = !p.isOpponentOf(getPlayer());
|
||||||
|
|
||||||
|
return isTargetFriendly
|
||||||
|
? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min)
|
||||||
|
: ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,4 +318,12 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
public boolean willPutCardOnTop(Card c) {
|
public boolean willPutCardOnTop(Card c) {
|
||||||
return GuiDialog.confirm(c, "Where will you put " + c.getName() + " in your library", new String[]{"Top", "Bottom"} );
|
return GuiDialog.confirm(c, "Where will you put " + c.getName() + " in your library", new String[]{"Top", "Bottom"} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see forge.game.player.PlayerController#chooseCardsToDiscardFrom(forge.game.player.Player, java.util.List, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Card> chooseCardsToDiscardFrom(Player p, SpellAbility sa, List<Card> valid, int minDiscard) {
|
||||||
|
return GuiChoose.order("Choose cards to Discard", "Discarded", minDiscard == 0 ? -1 : minDiscard, valid, null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user