It is currently 09 Sep 2025, 04:45
   
Text Size

I'm trying to fix Funeral Charm

Post MTG Forge Related Programming Questions Here

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

I'm trying to fix Funeral Charm

Postby Chris H. » 17 Apr 2010, 23:43

I tried to fix this card some time ago and ran out of steam. I recently found my code additions/modifications. So I thought that I would try again. I have the third SpellAbility included in the code object. It works reasonably well for the human.

The AI will cause the human to discard a card but it will not choose either of the two pump abilities to buff it's attacking creature. I will post my code in the hopes that someone will see something that I must have missed.

Code: Select all
        //*************** START *********** START **************************
        else if (cardName.equals("Funeral Charm")) {
           
            //discard
            final SpellAbility spell_one = new Spell(card) {
                private static final long serialVersionUID = 8273875515630095127L;
               
                @Override
                public boolean canPlayAI() {
                   CardList computerCreatures = new CardList(AllZone.Computer_Play.getCards());
                   computerCreatures = computerCreatures.filter(new CardListFilter() {
                        public boolean addCard(Card c) {
                            return c.isCreature() && CardFactoryUtil.canTarget(card, c) &&
                                  !c.getKeyword().contains("Defender") && 1 < c.getNetDefense();
                        }
                    });
                   
                    setTargetPlayer(Constant.Player.Human);
                    PlayerZone humanHand = AllZone.getZone(Constant.Zone.Hand, Constant.Player.Human);
                   
                    return (humanHand.size() >= 1 && computerCreatures.size() < 1 &&
                           (MyRandom.random.nextBoolean() || MyRandom.random.nextBoolean())) ||
                           (humanHand.size() >= 1 && computerCreatures.size() > 0 && MyRandom.random.nextBoolean());
                }
               
                @Override
                public void resolve() {
                    if (Constant.Player.Computer.equals(getTargetPlayer())) AllZone.GameAction.discardRandom(getTargetPlayer());
                    else AllZone.InputControl.setInput(CardFactoryUtil.input_discard());
                }//resolve()
            };//SpellAbility
           
            spell_one.setDescription("Target player discards a card.");
            spell_one.setBeforePayMana(CardFactoryUtil.input_targetPlayer(spell_one));

            //creature gets +2/-1
            final SpellAbility spell_two = new Spell(card) {
                private static final long serialVersionUID = -4554812851052322555L;
               
                @Override
                public boolean canPlayAI() {
                    CardList list = new CardList(ComputerUtil.getAttackers().getAttackers());
                    list = list.filter(new CardListFilter() {
                        public boolean addCard(Card c) {
                            return c.getNetDefense() > 1 && CardFactoryUtil.canTarget(card, c) &&
                                  (!c.hasSickness() || (c.hasSickness() && c.getKeyword().contains("Haste")));
                        }
                    });
                   
                    //put biggest attack creatures first
                    if (list.size() > 0) {
                       CardListUtil.sortAttack(list);
                       setTargetCard(list.get(0));
                    }
                   
                    return list.size() > 0 && MyRandom.random.nextBoolean();
                }
               
                @Override
                public void resolve() {
                    final Card c = getTargetCard();
                   
                    if (AllZone.GameAction.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) {
                        c.addTempAttackBoost(2);
                        c.addTempDefenseBoost(-1);
                       
                        Command until = new Command() {
                            private static final long serialVersionUID = 4674846621452044251L;
                           
                            public void execute() {
                                c.addTempAttackBoost(-2);
                                c.addTempDefenseBoost(1);
                            }
                        };//Command
                        AllZone.EndOfTurn.addUntil(until);
                    }//if card in play?
                }//resolve()
            };//SpellAbility
            spell_two.setDescription("Target creature gets +2/-1 until end of turn.");
            spell_two.setBeforePayMana(CardFactoryUtil.input_targetCreature(spell_two));
           
            //creature gets swampwalk
            final SpellAbility spell_three = new Spell(card) {
            private static final long serialVersionUID = -8455677074284271852L;

            @Override
                public boolean canPlayAI() {

               CardList creatures = new CardList(ComputerUtil.getAttackers().getAttackers());
                    creatures = creatures.filter(new CardListFilter() {
                        public boolean addCard(Card c) {
                            return CardFactoryUtil.canTarget(card, c) && !c.getKeyword().contains("Swampwalk") &&
                                  (!c.hasSickness() || (c.hasSickness() && c.getKeyword().contains("Haste")));
                        }
                    });
                   
                    //put biggest attack creatures first
                    if (creatures.size() > 0) {
                       CardListUtil.sortAttack(creatures);
                       setTargetCard(creatures.get(0));
                    }
                   
                    CardList humanSwamp = new CardList(AllZone.Human_Play.getCards());
                    humanSwamp = humanSwamp.getType("Swamp");
               
               return creatures.size() > 0 && humanSwamp.size() > 0 && MyRandom.random.nextBoolean();
            }
            
            @Override
                public void resolve() {
               final Card c = getTargetCard();
               
               if (AllZone.GameAction.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c) && !c.getKeyword().contains("Swampwalk")) {
                  c.addExtrinsicKeyword("Swampwalk");
                  
                  Command until = new Command() {
                     private static final long serialVersionUID = 1452395016805444249L;

                     public void execute() {
                        if (AllZone.GameAction.isCardInPlay(c)) {
                           c.removeExtrinsicKeyword("Swampwalk");
                        }
                     }
                  };//Command
                  AllZone.EndOfTurn.addUntil(until);
               }//if card in play?
               }//resolve()
            };//SpellAbility
            spell_three.setDescription("Target creature gains swampwalk until end of turn.");
            spell_three.setBeforePayMana(CardFactoryUtil.input_targetCreature(spell_three));
           
            card.clearSpellAbility();
            card.addSpellAbility(spell_one);
            card.addSpellAbility(spell_two);
            card.addSpellAbility(spell_three);
        }//*************** END ************ END **************************
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: I'm trying to fix Funeral Charm

Postby DennisBergkamp » 18 Apr 2010, 01:17

Probably the reason the AI does not use its 2nd and 3rd abilities is because it finds the first ability first (and a true is returned for canPlayAI()). The next abilities won't even be considered... the planeswalkers have some of their abilities coded so that the AI will try to use the big abilities first, and this is achieved through including code in the earlier abilities' canPlayAI() method that looks something like this: "return !ability3.canPlay() && ... etc."
Otherwise Ajani wouldn't ever be able to use its third ability under the control of the AI, it would just keep gaining life. This approach would require to define the third and second ability before the first one though...
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: I'm trying to fix Funeral Charm

Postby Chris H. » 18 Apr 2010, 01:55

I see, I may figure it out yet some day. :wink:
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: I'm trying to fix Funeral Charm

Postby Rob Cashwalker » 18 Apr 2010, 06:38

I wonder if there's something that could be done where each canPlayAI is passed to an external method which is able to execute the logic for each part and then select randomly from the ones that return true.

Or put tht kind of logic further up the AI.... Somewhere, there's some code that iterates through each card in hand and in play executing canPlayAI... those that evaluate the game state and return true, get exceuted. However this code should become aware of when a card has multiple abilities, that it needs to execute canPlayAI for each of them and then select a result.
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: I'm trying to fix Funeral Charm

Postby Chris H. » 18 Apr 2010, 16:59

I looked at the planeswalker code but I could not figure out how it works. I also tried commenting out the first ability and playtested the card ... I was currious to see if the computer would then use the pump code in the second ability. The computer would not cast the card. :(

So, I decided that at this time I would strip out the AI code for the last two abilities and just have it return a false ... it is not being analyzed anyway. I added the third ability and the human can now cast swampwalk on a creature.

This is a small step in the right direction.
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: I'm trying to fix Funeral Charm

Postby DennisBergkamp » 18 Apr 2010, 17:06

Well, they should be considered if the first ability returns false.
Then again, as you said it still doesn't work even after removing the first ability. Strange...
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: I'm trying to fix Funeral Charm

Postby jim » 18 Apr 2010, 17:13

Chris H. wrote:I looked at the planeswalker code but I could not figure out how it works. I also tried commenting out the first ability and playtested the card ... I was currious to see if the computer would then use the pump code in the second ability. The computer would not cast the card. :(
I tried the same thing (making the first ability return false). Once I did that, the computer would use the swampwalk ability IF I added Funeral Charm to the computer's list of "Cards that must be cast during main 1". I couldn't make it use the other ability.
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: I'm trying to fix Funeral Charm

Postby mtgrares » 19 Apr 2010, 14:53

Chris H. wrote:I see, I may figure it out yet some day. :wink:
It is really hard understanding someone else's code. (Sometimes it is even hard to read your own code.) I've heard that "It is easier to write code than to read code".
mtgrares
DEVELOPER
 
Posts: 1352
Joined: 08 Sep 2008, 22:10
Has thanked: 3 times
Been thanked: 12 times


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 34 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 34 users online :: 0 registered, 0 hidden and 34 guests (based on users active over the past 10 minutes)
Most users ever online was 7303 on 15 Jul 2025, 20:46

Users browsing this forum: No registered users and 34 guests

Login Form