*
* NOT checked if fitting targets are available for cards!
*/
Vector<CardAndMana> generatePossibleActionsGeneral(boolean restrictMana, Vector<EAIAction> stack)
{
ManaCollection possibleMana = E.helper.getMaxAvailableMana(vMatch);
CardSimList hand = (CardSimList) vMatch.getHand(E.pNumber).clone();
// list of all cards, that can be played with mana available
CardSimList possiblePlayableCards;
// do different optimizations of "possible" playable cards
// LAND Play
// should be in phase 1
// and only one land of a type
boolean landPlay = true;
boolean removeDebufs = false;
if (isMyTurn())
{
if (E.aiPlayer.getEAIConfig().getLandForceMain1())
{
if (vMatch.getPhase() != MatchConstants.PHASE_MAIN1)
{
landPlay = false;
}
}
if (landPlay)
{
if (!decidePlayLand())
{
landPlay = false;
}
else
{
}
}
// this one should ensure land play when a land was got in attacking phase
// like tapping tales researcher...
if (vMatch.getPhase() == MatchConstants.PHASE_MAIN2)
{
if (decidePlayLand())
{
if (!(vMatch.isLandPlayed(E.pNumber)))
{
if (E.aiPlayer.getEAIConfig().getLandForceMain1())
{
landPlay = true;
}
}
}
}
}
else
{
landPlay = false;
}
boolean willPlayLand = false;
if ((vMatch.isLandPlayed(E.pNumber)) || (!landPlay))
{
// remove all lands, apart from land that is about to be played
for (int i = hand.size()-1; i >= 0 ; i--)
{
CardSim card = hand.getCard(i);
if (card.isLand())
{
hand.remove(card);
}
}
possiblePlayableCards = hand;
}
else
{
possiblePlayableCards = hand;
// reduce to one land per type
for (int i=0; i <possiblePlayableCards.size(); i++)
{
CardSim c = possiblePlayableCards.getCard(i);
if (c.getType().equals("Basic Land"))
{
removeButOneLandTypeAndFirstInList(possiblePlayableCards, c);
willPlayLand = true;
}
}
}
if (willPlayLand)
{
// reduce land play options to the one we think is best
CardSimList landsOnly = possiblePlayableCards.getSubListByType("Basic Land");
possiblePlayableCards = possiblePlayableCards.removeTypes("Basic Land");
CardSim goodLand = getBestPlayableLand(landsOnly);
if (goodLand != null)
possiblePlayableCards.addCard(goodLand);
}
if (isMyTurn())
{
// and without additional buf/debuf/damage stuff
// all of them should only be played in Main 2
if (vMatch.getPhase() == MatchConstants.PHASE_MAIN1)
{
// if we can / should not attack
// than there is no need to try buffing our creatures
if (!canAttack())
{
// dont consider one turn only Buffs
possiblePlayableCards = EAIHelper.removeOneRoundBufs(HintAll.HINT_SITUATION_CARD_PLAYED, possiblePlayableCards);
// dont consider one turn only Debufs for opponent Buffs
possiblePlayableCards = EAIHelper.removeOneRoundDeBufs(HintAll.HINT_SITUATION_CARD_PLAYED, possiblePlayableCards);
removeDebufs = true;
}
}
else if (vMatch.getPhase() == MatchConstants.PHASE_MAIN2)
{
// dont consider one turn only Buffs
possiblePlayableCards = EAIHelper.removeOneRoundBufs(HintAll.HINT_SITUATION_CARD_PLAYED, possiblePlayableCards);
// dont consider one turn only Debufs for opponent Buffs
possiblePlayableCards = EAIHelper.removeOneRoundDeBufs(HintAll.HINT_SITUATION_CARD_PLAYED, possiblePlayableCards);
removeDebufs = true;
}
}
// wenn keine Gegner da sind, keine Debuf / Damage Creature Cards
if (vMatch.getBattlefield((E.pNumber+1)%2 ).size() == 0)
{
if (!removeDebufs)
{
possiblePlayableCards = EAIHelper.removeOneRoundDeBufs(HintAll.HINT_SITUATION_CARD_PLAYED, possiblePlayableCards);
}
possiblePlayableCards = EAIHelper.removeCreatureOnlyDamages(HintAll.HINT_SITUATION_CARD_PLAYED, possiblePlayableCards);
}
if ((vMatch.getPhase() == MatchConstants.PHASE_MAIN1) || (vMatch.getPhase() == MatchConstants.PHASE_MAIN2))
{
// remove buf / debug instants
// this can and will be played in attack / block
possiblePlayableCards = EAIHelper.removeDeBufInstants(possiblePlayableCards);
}
CardSimList field = vMatch.getBattlefield(E.pNumber);
if (restrictMana)
possiblePlayableCards = EAIHelper.onlyEnoughMana(possiblePlayableCards, possibleMana);
// in general for all phases
// only relevant in stacking... but doesnt hurt anything if not stack
boolean isFinalCall = E.match.isFinalStackCall();
possiblePlayableCards = EAIHelper.onlyAllowedToPlay(possiblePlayableCards, vMatch.getPhase(), myTurn, stack, isFinalCall);
if (mDoStacking)
{
if ((!myTurn) && ((vMatch.getPhase() == MatchConstants.PHASE_COMBAT_DECLARE_ATTACKERS)))
{
// remove activatables
// that are also activateable in Blocker Phase!
CardSimList alsoInBlocker = EAIHelper.onlyAllowedToPlay(possiblePlayableCards, MatchConstants.PHASE_COMBAT_DECLARE_BLOCKERS, myTurn, new Vector<EAIAction>(), false);
possiblePlayableCards.removeListDirect(alsoInBlocker);
if (vMatch.getAttacker().size()==0)
{
possiblePlayableCards = EAIHelper.removeDeBufInstants(possiblePlayableCards);
}
}
}
field = field.onlyActivatable(); // possibly add land here
field = field.removeSick();
// list of all cards, that can be activated with mana availbal
CardSimList possibleActivateableCards = field;
if (restrictMana)
possibleActivateableCards = EAIHelper.onlyEnoughManaActivate(possibleActivateableCards, possibleMana);
// in general for all phases
possibleActivateableCards = EAIHelper.onlyAllowedToActivate(possibleActivateableCards, vMatch.getPhase(), myTurn, vMatch);
possibleActivateableCards = EAIHelper.onlyUntappedToActivate(possibleActivateableCards);
if (E.aiPlayer.getEAIConfig().getReducedActivationEvaluation())
{
if (!mDoStacking)
possibleActivateableCards = EAIHelper.reduceActivationEvaluation(possibleActivateableCards, vMatch.getPhase(), myTurn, vMatch);
}
if (mDoStacking)
{
if ((!myTurn) && ((vMatch.getPhase() == MatchConstants.PHASE_COMBAT_DECLARE_ATTACKERS)))
{
// remove activatables
// that are also activateable in Blocker Phase!
CardSimList alsoInBlocker = EAIHelper.onlyAllowedToActivate(possibleActivateableCards, MatchConstants.PHASE_COMBAT_DECLARE_BLOCKERS, myTurn, vMatch);
possibleActivateableCards.removeListDirect(alsoInBlocker);
if (vMatch.getAttacker().size()==0)
{
possibleActivateableCards = EAIHelper.removeDeBufActivations(possibleActivateableCards);
}
}
}
possiblePlayableCards = EAIHelper.removeRestrictedCards(HintAll.HINT_SITUATION_CARD_PLAYED, possiblePlayableCards, vMatch.getPhase(), myTurn, vMatch);
// TODO: Limit activateable Cards to same extend as playable cards
boolean NEW_CSA = true;
// For Play cards
if (mDoStacking)
{
// if we are in stack reaction
if (vMatch.getStack().isEmpty())
{
// and there is nothing on stack
// we assume, that all is right, and nothing instant to be done!
// if not in block phase
if (vMatch.getPhase() != MatchConstants.PHASE_COMBAT_DECLARE_BLOCKERS)
{
for(int c=possiblePlayableCards.size()-1; c>=0; c--)
{
CardSim card = possiblePlayableCards.getCard(c);
if (card.isInstant())
{
if (EAIHelper.hasPlayRestriction(card, HintAll.HINT_SITUATION_INSTANT))
continue;
if (EAIHelper.isBufCard(card, HintAll.HINT_SITUATION_INSTANT))
possiblePlayableCards.remove(card);
}
}
}
if (NEW_CSA)
{
// if not in block phase
if (vMatch.getPhase() != MatchConstants.PHASE_COMBAT_DECLARE_BLOCKERS)
{
for(int c=possibleActivateableCards.size()-1; c>=0; c--)
{
CardSim card = possibleActivateableCards.getCard(c);
if (EAIHelper.hasPlayRestriction(card, HintAll.HINT_SITUATION_ACTIVATION))
continue;
// this is ok here, since we come here only on empty stack
if (EAIHelper.isBufCard(card, HintAll.HINT_SITUATION_ACTIVATION))
possibleActivateableCards.remove(card);
}
}
}
}
else // stack is not empty
{
if (NEW_CSA)
{
// TODO CSA
// check if stack is creature damage card, if yes allow
// bufs
// if instant is stack influence card -> allow it
// if instant is player health card -> allow it
boolean stackIsPlayerDamage = EAIHelper.isStackPlayerDamage(player, stack);
boolean stackIsCreatureDamage = EAIHelper.isStackCreatureDamage(player, stack);
for(int c=possiblePlayableCards.size()-1; c>=0; c--)
{
CardSim card = possiblePlayableCards.getCard(c);
if (!card.isInstant())
{
possiblePlayableCards.remove(card);
continue;
}
if (stackIsPlayerDamage)
{
// remove player heals
if (!EAIHelper.isHealCard(card, HintAll.HINT_SITUATION_INSTANT))
{
possiblePlayableCards.remove(card);
continue;
}
}
if (stackIsCreatureDamage)
{
// remove creature bufs
if (!EAIHelper.isBufCard(card, HintAll.HINT_SITUATION_INSTANT))
{
possiblePlayableCards.remove(card);
continue;
}
}
}
for(int c=possibleActivateableCards.size()-1; c>=0; c--)
{
CardSim card = possibleActivateableCards.getCard(c);
if (!EAIHelper.hasPlayRestriction(card, HintAll.HINT_SITUATION_ACTIVATION))
{
possibleActivateableCards.remove(card);
continue;
}
if (stackIsPlayerDamage)
{
// remove player heals
if (!EAIHelper.isHealCard(card, HintAll.HINT_SITUATION_ACTIVATION))
{
possibleActivateableCards.remove(card);
continue;
}
}
if (stackIsCreatureDamage)
{
// remove creature bufs
if (!EAIHelper.isBufCard(card, HintAll.HINT_SITUATION_ACTIVATION))
{
possibleActivateableCards.remove(card);
continue;
}
}
}
}
}
}
Vector<CardAndMana> cam = new Vector<CardAndMana>();
for(int c=0; c< possiblePlayableCards.size(); c++)
{
CardSim card = possiblePlayableCards.getCard(c);
if (card.getCard().getManaCost()!=-1)
{
// non X Mana j
cam.addElement(new CardAndMana(CardAndMana.CAM_PLAY , card, ManaCollection.getPlayCost(card) ) );
}
else
{
//X card
// damagaing X cards only in Main1
if (EAIHelper.isCreatureDamageCard(card, HintAll.HINT_SITUATION_CARD_PLAYED))
{
if (!EAIHelper.isPlayerDamageCard(card, HintAll.HINT_SITUATION_CARD_PLAYED))
{
if (vMatch.getPhase() != MatchConstants.PHASE_MAIN1)
{
continue;
}
}
}
int maxX = MAX_X;
if (maxX==0)
{
ManaCollection baseCost = ManaCollection.getPlayCostBase(card);
ManaCollection rest = possibleMana.subMana(baseCost);
for (int m=0; m<rest. getManaItems().size(); m++)
{
baseCost.addMana(rest.getManaItems().elementAt(m));
cam.addElement(new CardAndMana(CardAndMana.CAM_PLAY , card, new ManaCollection(baseCost) ) );
}
}
else
{
int step = (possibleMana.subMana(ManaCollection.getPlayCostBase(card)).getManaItems().size())/maxX;
int currentMana = step;
while (maxX > 0)
{
ManaCollection baseCost = ManaCollection.getPlayCostBase(card);
ManaCollection rest = possibleMana.subMana(baseCost);
for (int m=0; m<currentMana; m++)
{
baseCost.addMana(rest.getManaItems().elementAt(m));
}
currentMana += step;
maxX--;
cam.addElement(new CardAndMana(CardAndMana.CAM_PLAY , card, new ManaCollection(baseCost) ) );
}
}
}
//count x
}