It is currently 30 Oct 2025, 15:37
   
Text Size

new keyword: spBounceAll

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins

new keyword: spBounceAll

Postby Sloth » 16 Aug 2010, 09:58

I've added a new keyword: spBounceAll

spBounceAll:<AffectedType>:<Destination>

<AffectedType>: takes all the restrictions of spDestroyTgt. (uses getValidCards)

<Destination>: Hand, BottomofLibrary, TopofLibrary, ShuffleIntoLibrary and Exile.

The AI will use these spells if at least 2 more human permanents will be bounced.

Here is the code:
Code: Select all
                // Generic bounce all card
        if(hasKeyword(card, "spBounceAll") != -1) {
            int n = hasKeyword(card, "spBounceAll");
           
            String parse = card.getKeyword().get(n).toString();
            card.removeIntrinsicKeyword(parse);
           
            String k[] = parse.split(":");
            String Targets = k[1]; // Artifact, Creature, Enchantment, Land, Permanent, White, Blue, Black, Red, Green, Colorless, MultiColor
            // non-Artifact, non-Creature, non-Enchantment, non-Land, non-Permanent,
            //non-White, non-Blue, non-Black, non-Red, non-Green, non-Colorless, non-MultiColor
            final String Tgts[] = Targets.split(",");
           
            final String Destination = k[2];
           
            card.clearSpellAbility();
           
            final SpellAbility spBnceAll = new Spell(card) {
                private static final long serialVersionUID = 897326872601L;
               
                @Override
                public boolean canPlayAI() {
                    CardList human = new CardList(AllZone.Human_Play.getCards());
                    CardList computer = new CardList(AllZone.Computer_Play.getCards());
                   
                    human = human.getValidCards(Tgts);
                    computer = computer.getValidCards(Tgts);
                   
                    // the computer will at least bounce 2 more human permanents
                    return  AllZone.Phase.getPhase().equals(Constant.Phase.Main2) &&
                          (computer.size() < human.size() - 1);
                }

                @Override
                public void resolve() {
                    CardList all = new CardList();
                    all.addAll(AllZone.Human_Play.getCards());
                    all.addAll(AllZone.Computer_Play.getCards());
                    all = all.getValidCards(Tgts);
                   
                    for(int i = 0; i < all.size(); i++) {
                        Card c = all.get(i);
                        if(c.isToken()) AllZone.getZone(c).remove(c);
                        else { 
               if(Destination.equals("TopofLibrary")) AllZone.GameAction.moveToTopOfLibrary(c);
               else if(Destination.equals("ShuffleIntoLibrary")) {
                     AllZone.GameAction.moveToTopOfLibrary(c);
                     AllZone.GameAction.shuffle(c.getOwner());
                  }
               else if(Destination.equals("Exile")) AllZone.GameAction.removeFromGame(c);
               else if(Destination.equals("Hand")) {
                                     PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, c.getOwner());
                                     AllZone.GameAction.moveTo(hand, c);
                  }
            }
                    }
                }// resolve()

            }; //SpBnceAll
           
            card.addSpellAbility(spBnceAll);           

        }//spBounceAll
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: new keyword: spBounceAll

Postby Rob Cashwalker » 16 Aug 2010, 13:41

Damn.... Let the keywords keep rolling!

Might also want the AI to consider the total number of perms affected - maybe something along the lines of total >= CMC of BounceAll spell. This also applies to DestroyAll, I'd guess.

Edit - Actually, maybe that should only be for lands and creatures... if it's more restrictive, like say only enchantments, then blowing up even just 2 Propaganda 's would be well worth nearly any cost....

(Yeah, playing against Barney Rubble last night for an hour (only 1 match) really bummed me out, even though I eventually won.)
The Force will be with you, Always.
User avatar
Rob Cashwalker
Programmer
 
Posts: 2167
Joined: 09 Sep 2008, 15:09
Location: New York
Has thanked: 5 times
Been thanked: 40 times

Re: new keyword: spBounceAll

Postby Sloth » 16 Aug 2010, 14:01

Rob Cashwalker wrote:Might also want the AI to consider the total number of perms affected - maybe something along the lines of total >= CMC of BounceAll spell. This also applies to DestroyAll, I'd guess.

Edit - Actually, maybe that should only be for lands and creatures... if it's more restrictive, like say only enchantments, then blowing up even just 2 Propaganda 's would be well worth nearly any cost....
I thought about X = number of permanents + total CMC + number of lands.
The AI would play the card, if X is at least 3 more for the human card list.

Example: The AI would play the spell if the boards are the same, but for

- One Glory Seeker, or
- Two Lands, or
- Three Crookshank Kobolds on the human side.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: new keyword: spBounceAll

Postby Rob Cashwalker » 16 Aug 2010, 14:22

It's got my gears turning... trying to come up with a way to evaluate board position is tough.

For example, the AllPump keywords use this routine:
Code: Select all

                   CardList sl = getScopeList();
                   int NumScope = sl.size();
                   
                   int defense = getNumDefense();
                   int attack = getNumAttack();
                   int key = getNumKeyword();
                   int th = (attack + defense + key) / 2; // Benefit Threshold
                   
                   if (NumScope > th) // have enough creatures in play
                   {
                      Combat c = ComputerUtil.getAttackers();
                      if (c.getAttackers().length >= th) // have enough creatures that will attack
                      {
                         int ndead = 0;
                         for (int i=0; i<sl.size(); i++) // check to see if this will kill any creatures
                            if ((sl.get(i).getNetDefense() + defense) < 1)
                               ndead++;
                         if (!(ndead > (sl.size() / 2))) // don't kill more than half of the creatures
                               return true;
                      }
                   }
A +1/+1/Flying pump spell wants to affect at least 3 creatures
(1 + 1 + 1) / 2 = 1.5 --> 2
Overrun (3 + 3 + 1) wants to affect at least 5 creatures.

It's not perfect.. but it's scaleable.... Bigger spells need to wait for better situations. The biggest limitation is ComputerUtil.getAttackers which of course doesn't know anything about the boost that could be applied. This may need to be addressed at some point... adding
ComputerUtil.getAttackersIfPumped(int power, int toughness, String keywords)

As to evaluating destroying or bouncing all ___ -

When affecting just creatures, comparing total power/toughness between the players may be an option.
For lands, compare not just the number of lands between, but also the ratio of basic to nonbasic. (favoring the destruction of nonbasics...)
For all other permanent types, compare total CMC.
For all permanents, just the number difference would suffice.
The Force will be with you, Always.
User avatar
Rob Cashwalker
Programmer
 
Posts: 2167
Joined: 09 Sep 2008, 15:09
Location: New York
Has thanked: 5 times
Been thanked: 40 times

Re: new keyword: spBounceAll

Postby Sloth » 16 Aug 2010, 15:55

Rob Cashwalker wrote:As to evaluating destroying or bouncing all ___ -

When affecting just creatures, comparing total power/toughness between the players may be an option.
For lands, compare not just the number of lands between, but also the ratio of basic to nonbasic. (favoring the destruction of nonbasics...)
For all other permanent types, compare total CMC.
For all permanents, just the number difference would suffice.
The best thing of course, would be to have a function that evaluates a board situation. But this needs a lot of tactical analysis first.

For now, I will implement my single value check. Special targets can be added later.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: new keyword: spBounceAll

Postby Chris H. » 17 Aug 2010, 00:23

Nice work, indeed. Thank you.
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: new keyword: spBounceAll

Postby Sloth » 17 Aug 2010, 07:49

For spBounceAll the AI now uses the following criteria:

X = total CMC + number of lands + 3 * number of tokens.

The AI would play the card, if X is at least 3 more for the human card list.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 14 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 14 users online :: 0 registered, 0 hidden and 14 guests (based on users active over the past 10 minutes)
Most users ever online was 9298 on 10 Oct 2025, 12:54

Users browsing this forum: No registered users and 14 guests

Login Form