I'm trying to fix Funeral Charm
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
8 posts
• Page 1 of 1
I'm trying to fix Funeral Charm
by 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.
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 **************************
-
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
by 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...
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...
-
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
by Chris H. » 18 Apr 2010, 01:55
I see, I may figure it out yet some day. 

-
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
by 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.
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.
-
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
by 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.

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.
-
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
by 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...
Then again, as you said it still doesn't work even after removing the first ability. Strange...
-
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
by jim » 18 Apr 2010, 17:13
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.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.![]()
- 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
by mtgrares » 19 Apr 2010, 14:53
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".Chris H. wrote:I see, I may figure it out yet some day.
- mtgrares
- DEVELOPER
- Posts: 1352
- Joined: 08 Sep 2008, 22:10
- Has thanked: 3 times
- Been thanked: 12 times
8 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 22 guests