eqPump (was VanillaEquipment) keyword
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
49 posts
• Page 2 of 4 • 1, 2, 3, 4
Re: eqPump (was VanillaEquipment) keyword
by Chris H. » 07 Mar 2010, 15:14
I have finished the first stage revision of the VanilaEquipment keyword. The new format for the cards.txt entries are looking good. Here is an example of four of them:
The word "none" no longer appears in either cards.txt file or card detail panel. The keywords and the ampersand delimiter can be separated with a space character. This makes the cards.txt entries more readable. I am using the .trim() command and I think that we may want to add this to other keywords as time permits.
The new parsing code:
I will merge this work into the SVN and then start on the second stage revision, modifying the CardFactoryUtil.vanila_equip() methods to handle an array of strings containing the keywords.
- Bone Saw
0
Artifact Equipment
Equipped creature gets +1/+0.
eqPump 1:1/0
Fireshrieker
3
Artifact Equipment
Equipped creature has double strike.
eqPump 2:0/0/Double Strike
Lightning Greaves
2
Artifact Equipment
Equipped creature has haste and shroud.
eqPump 0:0/0/Haste & Shroud
Peregrine Mask
1
Artifact Equipment
Equipped creature has defender, flying, and first strike.
eqPump 2:0/0/Defender & Flying & First Strike
The word "none" no longer appears in either cards.txt file or card detail panel. The keywords and the ampersand delimiter can be separated with a space character. This makes the cards.txt entries more readable. I am using the .trim() command and I think that we may want to add this to other keywords as time permits.
The new parsing code:
- Code: Select all
if(shouldEquip(card) != -1) {
int n = shouldEquip(card);
if(n != -1) {
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
String kk[] = k[1].split("/");
String tmpCost;
tmpCost = k[0].substring(6);
final String manacost = tmpCost.trim();
final String P = kk[0].trim();
final String T = kk[1].trim();
final int Power = Integer.parseInt(P);
final int Tough = Integer.parseInt(T);
String tempAb1 = "none";
String tempAb2 = "none";
String tempAb3 = "none";
if (kk.length > 2) // then there is at least one keyword ability to assign
{
String kkk[] = kk[2].split("&");
tempAb1 = kkk[0].trim();
if (kkk.length > 1) tempAb2 = kkk[1].trim();
if (kkk.length > 2) tempAb3 = kkk[2].trim(); //quantity of keyword abilities could be modified
}
final String Ab1 = tempAb1;
final String Ab2 = tempAb2;
final String Ab3 = tempAb3;
card.addSpellAbility(CardFactoryUtil.vanila_equip(card, Power, Tough, Ab1, Ab2, Ab3, manacost));
card.addEquipCommand(CardFactoryUtil.vanila_onequip(card, Power, Tough, Ab1, Ab2, Ab3, manacost));
card.addUnEquipCommand(CardFactoryUtil.vanila_unequip(card, Power, Tough, Ab1, Ab2, Ab3, manacost));
}
}// eqPump (was VanillaEquipment)
I will merge this work into the SVN and then start on the second stage revision, modifying the CardFactoryUtil.vanila_equip() methods to handle an array of strings containing the keywords.
Last edited by Chris H. on 11 Mar 2010, 19:03, edited 1 time in total.
-
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: VanillaEquipment keyword
by zerker2000 » 07 Mar 2010, 18:37
I am confused: why not get rid of "none" altogether, and change the utils to use "String[] Abs"? Also, I am still confused as to why the commands need the cost(and the ability needs the values).
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: eqPump (was VanillaEquipment) keyword
by Chris H. » 07 Mar 2010, 19:35
`zerker2000 wrote:I am confused: why not get rid of "none" altogether, and change the utils to use "String[] Abs"? Also, I am still confused as to why the commands need the cost(and the ability needs the values).
I am taking this in stages as it helps to keep me focused. My wife had her wrist surgery this last Thursday and I find myself to be somewhat distracted.

The "none" is currently hidden from the end user ... a good thing.

Unfortunately, I can not for the life of me figure out how to implement the SVar into the system. That may come at a later date. I also looked at Rob's +- P/T parser and I do not understand that either ... at least not yet.
Some people can raise to the level of a lead programmer, others have to settle for jr. programmer.

Last edited by Chris H. on 11 Mar 2010, 19:04, edited 1 time in total.
-
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: VanillaEquipment keyword
by Rob Cashwalker » 08 Mar 2010, 06:16
You could also have performed the split on " & ".... But either way, you've got the right idea.
What zerker and I have been driving at is this:
Integer.parseInt doesn't like "+", but it does like "-" (negative number). Whenever applying the boost, adding a negative number is subtracting. When removing the boost, subtracting a negative number is adding.
What would the SVar be for again? Just for the "+X/+Y" type of stuff? Really should just be a cut and paste hack..
What zerker and I have been driving at is this:
- Code: Select all
CardFactoryUtil.vanila_equip(card, Power, Tough, Ab1, Ab2, Ab3, manacost)
- Code: Select all
CardFactoryUtil.vanila_equip(card, Power, Tough, Abilities[], manacost)
- Code: Select all
if(!(Ab1.equals ("none")) && (!crd.getKeyword().contains(Ab1))) crd.addExtrinsicKeyword(Ab1); //fixed, "none" will not be assigned as a keyword
if(!(Ab2.equals ("none")) && (!crd.getKeyword().contains(Ab2))) crd.addExtrinsicKeyword(Ab2); //prevent Flying, Flying
if(!(Ab3.equals ("none")) && (!crd.getKeyword().contains(Ab3))) crd.addExtrinsicKeyword(Ab3);
- Code: Select all
for (int i=0; i<Abilities.length(); i++
{
if(!(Abilities[i].equals ("none")) && (!crd.getKeyword().contains(Abilities[i]))) crd.addExtrinsicKeyword(Abilities[i]);
}
- Code: Select all
else if(ptk[0].matches("[\\+\\-][0-9]"))
NumAttack[0] = Integer.parseInt(ptk[0].replace("+", ""));
Integer.parseInt doesn't like "+", but it does like "-" (negative number). Whenever applying the boost, adding a negative number is subtracting. When removing the boost, subtracting a negative number is adding.
What would the SVar be for again? Just for the "+X/+Y" type of stuff? Really should just be a cut and paste hack..
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: VanillaEquipment keyword
by zerker2000 » 08 Mar 2010, 07:50
Also, make sure AI has checks: you generally don't want to Skullclamp a Kamahl, Pit Fighter.
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: VanillaEquipment keyword
by silly freak » 08 Mar 2010, 08:28
actually regexes in java are much more powerful. i think this is the current keyword format?
eqPump 2:P/T/Ability & Ability & Ability
it could be solved like that:
eqPump 2:P/T/Ability & Ability & Ability
it could be solved like that:
- Code: Select all
String word; //the keyword line
Matcher m = Pattern.compile("eqPump (.*?):(.*)").matcher(word);
if(m.matches()) {
//the first group is what matches the part in the first parentheses, aka the cost
String cost = m.group(1);
word = m.group(2);
Matcher m = Pattern.compile("+?(-?\\d+)/+?(-?\\d+)/(.*)").matcher(word);
if(m.matches()) {
int p = Integer.parseInt(m.group(1));
int t = Integer.parseInt(m.group(2));
word = m.group(3);
}
String[] ab = word.split(" & ");
}
___
where's the "trust me, that will work!" switch for the compiler?
Laterna Magica - blog, forum, project, 2010/09/06 release!
where's the "trust me, that will work!" switch for the compiler?
Laterna Magica - blog, forum, project, 2010/09/06 release!
- silly freak
- DEVELOPER
- Posts: 598
- Joined: 26 Mar 2009, 07:18
- Location: Vienna, Austria
- Has thanked: 93 times
- Been thanked: 25 times
Re: VanillaEquipment keyword
by Rob Cashwalker » 08 Mar 2010, 12:51
Sure... it could be done like that....
On the other hand, while Chris didn't understand a couple of the details of the normal parsing skeleton, the rest was straight-forward enough that he could. If I didn't know exactly what the result of your code was already, I wouldn't have a clue how it worked its magic, because of the extra complexity. Certainly wouldn't know how to adapt it for my own code.
On the other hand, while Chris didn't understand a couple of the details of the normal parsing skeleton, the rest was straight-forward enough that he could. If I didn't know exactly what the result of your code was already, I wouldn't have a clue how it worked its magic, because of the extra complexity. Certainly wouldn't know how to adapt it for my own code.
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: VanillaEquipment keyword
by Rob Cashwalker » 08 Mar 2010, 12:53
Normally, we just give the AI a Debit Mastercard and call it a day....zerker2000 wrote:Also, make sure AI has checks: you generally don't want to Skullclamp a Kamahl, Pit Fighter.
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: eqPump (was VanillaEquipment) keyword
by Chris H. » 09 Mar 2010, 20:48
Thank you for the pointers, guys.
I have the parsing code and the CardFactoryUtil method changed to use a String[]. The MakeToken method also needs an array of keywords and it uses "String[] intrinsicKeywords", so I decided to name mine "String[] extrinsicKeywords". Might as well travel down the well beaten path.
I also renamed the CardFactoryUtil methods. Initially Eclipse became confused when I changed the names. I finally realized that I needed to rebuild the project and Eclipse would then be able to make the associations.
I was not able to remove all traces of the "none". I see that abPump uses this as an initial array value which can be changed to the corresponding keyword during the parsing process. I have done something similar to the eqPump's parsing code. It works, but sometimes we have to compromise.
And I now see why the +- parsing code in abPump was confusing me … regex. My usenet news application offers regex filtering, but I find it easier to just use the normal filtering options.
I modified Rob's regex code and cards.txt and it looks good. I was not aware that parseInt can handle "-" but not "+". Interesting. I will merge this much into the SVN. Afterwards I will try modifying the util methods so that Skullclamp can be changed to a keyword'ed card.
Parsing code only:

I have the parsing code and the CardFactoryUtil method changed to use a String[]. The MakeToken method also needs an array of keywords and it uses "String[] intrinsicKeywords", so I decided to name mine "String[] extrinsicKeywords". Might as well travel down the well beaten path.
I also renamed the CardFactoryUtil methods. Initially Eclipse became confused when I changed the names. I finally realized that I needed to rebuild the project and Eclipse would then be able to make the associations.
I was not able to remove all traces of the "none". I see that abPump uses this as an initial array value which can be changed to the corresponding keyword during the parsing process. I have done something similar to the eqPump's parsing code. It works, but sometimes we have to compromise.
And I now see why the +- parsing code in abPump was confusing me … regex. My usenet news application offers regex filtering, but I find it easier to just use the normal filtering options.
I modified Rob's regex code and cards.txt and it looks good. I was not aware that parseInt can handle "-" but not "+". Interesting. I will merge this much into the SVN. Afterwards I will try modifying the util methods so that Skullclamp can be changed to a keyword'ed card.
Parsing code only:
- Code: Select all
if(shouldEquip(card) != -1) {
int n = shouldEquip(card);
if(n != -1) {
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
String kk[] = k[1].split("/");
String tmpCost;
tmpCost = k[0].substring(6);
final String manacost = tmpCost.trim();
for (int i = 0; i < 2; i ++)
{
if (kk[i].matches("[\\+\\-][0-9]")) kk[i] =kk[i].replace("+", "");
}
final int Power = Integer.parseInt(kk[0].trim());
final int Tough = Integer.parseInt(kk[1].trim());
String extrinsicKeywords[] = {"none"}; // for equips with no keywords to add
if (kk.length > 2) // then there is at least one extrinsic keyword to assign
{
String kkk[] = kk[2].split("&");
extrinsicKeywords = new String[kkk.length];
for (int i = 0; i < kkk.length; i ++)
{
extrinsicKeywords[i] = kkk[i].trim();
}
}
card.addSpellAbility(CardFactoryUtil.eqPump_Equip(card, Power, Tough, extrinsicKeywords, manacost));
card.addEquipCommand(CardFactoryUtil.eqPump_onEquip(card, Power, Tough, extrinsicKeywords, manacost));
card.addUnEquipCommand(CardFactoryUtil.eqPump_unEquip(card, Power, Tough, extrinsicKeywords, manacost));
}
}// eqPump (was VanillaEquipment)
-
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: eqPump (was VanillaEquipment) keyword
by Chris H. » 11 Mar 2010, 19:10
`zerker2000 wrote:Also, make sure AI has checks: you generally don't want to Skullclamp a Kamahl, Pit Fighter.
I think that I have finally figured out this last part. In CardFactoryUtil.eqPump_Equip I changed the CardList getCreature() (constructor?) to:
- Code: Select all
CardList getCreature() {
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter() {
public boolean addCard(Card c) {
return c.isCreature() && (!CardFactoryUtil.AI_doesCreatureAttack(c))
&& CardFactoryUtil.canTarget(sourceCard, c)
&& (!c.getKeyword().contains("Defender"))
&& (c.getNetDefense() + Tough > 0);
}
});
// list.remove(card); // if mana-only cost, allow self-target
return list;
}//getCreature()
and the computer will now not give the Skullclamp to a creature with a net toughness of only one.

And once again, thank you guys for your suggestions.
-
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: eqPump (was VanillaEquipment) keyword
by Huggybaby » 11 Mar 2010, 20:57
Way to stick with it Chris, good job.
-
Huggybaby - Administrator
- Posts: 3225
- Joined: 15 Jan 2006, 19:44
- Location: Finally out of Atlanta
- Has thanked: 737 times
- Been thanked: 601 times
Re: eqPump (was VanillaEquipment) keyword
by DennisBergkamp » 12 Mar 2010, 00:19
But wait, isn't it a smart thing to put Skullclamp on 1/1s? I do it all the time, since it gives me two cards
Then again, I'm not the greatest magic player...

Then again, I'm not the greatest magic player...
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: eqPump (was VanillaEquipment) keyword
by Chris H. » 12 Mar 2010, 00:27
`DennisBergkamp wrote:But wait, isn't it a smart thing to put Skullclamp on 1/1s? I do it all the time, since it gives me two cards![]()
Then again, I'm not the greatest magic player...

I remember when I first tried Skullclamp in Forge ... I wanted to attach it to the computer's 1/1 creature ... imagine killing it's creature and drawing two cards.

-
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: eqPump (was VanillaEquipment) keyword
by DennisBergkamp » 12 Mar 2010, 00:47
Now that would be even better 
Anyway, I could see how it would be useful to kill off some of your own 1/1 tokens to refill one's hand (I think my friend used to have an Elves deck running it, and he would just kill off his own Wirewood Hivemaster Insect tokens with Skullclamp to draw more elves). But it might be tricky to write AI code checks to determine a good time to use it on his own 1/1s.

Anyway, I could see how it would be useful to kill off some of your own 1/1 tokens to refill one's hand (I think my friend used to have an Elves deck running it, and he would just kill off his own Wirewood Hivemaster Insect tokens with Skullclamp to draw more elves). But it might be tricky to write AI code checks to determine a good time to use it on his own 1/1s.
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: eqPump (was VanillaEquipment) keyword
by Huggybaby » 12 Mar 2010, 01:02
If the AI has say 4 cards or less (IOW not a full hand, and few enough that adding two cards won't go over seven), and x number of lands (enough to pay for a nice draw), and it's after turn y (mid game), kill puny creatures.
-
Huggybaby - Administrator
- Posts: 3225
- Joined: 15 Jan 2006, 19:44
- Location: Finally out of Atlanta
- Has thanked: 737 times
- Been thanked: 601 times
49 posts
• Page 2 of 4 • 1, 2, 3, 4
Who is online
Users browsing this forum: No registered users and 30 guests