It is currently 17 Jun 2025, 21:38
   
Text Size

eqPump (was VanillaEquipment) keyword

Post MTG Forge Related Programming Questions Here

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

Re: eqPump (was VanillaEquipment) keyword

Postby 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:

    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.
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: VanillaEquipment keyword

Postby 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
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

Postby 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. 8-[ My previous message refers to my revision 1st stage.

The "none" is currently hidden from the end user ... a good thing. :D I will change the utils to a String[] Abs as part of the revision 2nd stage and this will get rid of the last remnants of that pesky word.

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. :wink:
Last edited by Chris H. on 11 Mar 2010, 19:04, edited 1 time in total.
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: VanillaEquipment keyword

Postby 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:
Code: Select all
CardFactoryUtil.vanila_equip(card, Power, Tough, Ab1, Ab2, Ab3, manacost)
should become something like
Code: Select all
CardFactoryUtil.vanila_equip(card, Power, Tough, Abilities[], manacost)
Then modify vanila_equip's code: (BTW, might as well fix the spelling at some point...)
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);
to something like this:
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]);
}
the + - PT stuff??
Code: Select all
else if(ptk[0].matches("[\\+\\-][0-9]"))
                       NumAttack[0] = Integer.parseInt(ptk[0].replace("+", ""));
The .matches part that I added as part of the X revision is just a formality here, ensuring that we follow the pattern in the future if another type of boost value is to be added.... (the regular expression is looking to match either +0 through +9 or -0 through -9)
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.
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: VanillaEquipment keyword

Postby 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
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

Postby 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:

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(" & ");
}
note that the if for power and toughness allows for simply skipping it
___

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

Postby 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.
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: VanillaEquipment keyword

Postby Rob Cashwalker » 08 Mar 2010, 12:53

zerker2000 wrote:Also, make sure AI has checks: you generally don't want to Skullclamp a Kamahl, Pit Fighter.
Normally, we just give the AI a Debit Mastercard and call it a day....
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: eqPump (was VanillaEquipment) keyword

Postby Chris H. » 09 Mar 2010, 20:48

Thank you for the pointers, guys. :D

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)
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: eqPump (was VanillaEquipment) keyword

Postby 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. =D> I will merge my work into the SVN.

And once again, thank you guys for your suggestions.
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: eqPump (was VanillaEquipment) keyword

Postby Huggybaby » 11 Mar 2010, 20:57

Way to stick with it Chris, good job.
User avatar
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

Postby 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 =D>
Then again, I'm not the greatest magic player...
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: eqPump (was VanillaEquipment) keyword

Postby 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 =D>
Then again, I'm not the greatest magic player...
`
:lol:
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. :mrgreen:
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: eqPump (was VanillaEquipment) keyword

Postby 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.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: eqPump (was VanillaEquipment) keyword

Postby 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.
User avatar
Huggybaby
Administrator
 
Posts: 3225
Joined: 15 Jan 2006, 19:44
Location: Finally out of Atlanta
Has thanked: 737 times
Been thanked: 601 times

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 30 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 30 users online :: 0 registered, 0 hidden and 30 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 30 guests

Login Form