It is currently 29 Oct 2025, 13:16
   
Text Size

Kinship cards

Post MTG Forge Related Programming Questions Here

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

Kinship cards

Postby Chris H. » 30 Sep 2010, 01:30

I have spent a little time recently looking at the existing Kinship cards. I added a new one and did a little work on another.

It strikes me now that these cards are just an approximation of the real card. I am now trying to modify one of these to be more rules compliant but am not sure if the additional mouse clicks will be welcome to the user base.

I got it working well for the computer but the human was generating the new version of the computer is thinking bug. It still worked but it was not fun to see the message.

I have some more work to do before I have some code to show. I am starting to think that I may need some help to figure this out. :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: Kinship cards

Postby friarsol » 30 Sep 2010, 01:58

Well once your ready just create a patch of your work and post it up on the forums for some fresh eyes. I know a lot of times you work on something for a few days and it all gets blurred together.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Kinship cards

Postby Chris H. » 30 Sep 2010, 02:29

Thank you Sol.

At this moment I think that we do not have to ask the human if they want to look at the top card of the Library at the beginning of the upkeep. In real life we would always look at the top card until we had gained the advantage and at that time we are ready to win the game and start the next match.

I guess that with forge things are different. We can assume that the answer is always yes. Can anyone think of a reason why we should give the human a choice at this point?

If top card of the Library matches the criteria, then give a choice to reveal the card and resolve the effect. The current kinship card implementation reveals the card if the criteria matches or not. Some cards give you the choice to resolve the effect.
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: Kinship cards

Postby friarsol » 30 Sep 2010, 03:30

Chris H. wrote:Thank you Sol.

At this moment I think that we do not have to ask the human if they want to look at the top card of the Library at the beginning of the upkeep. In real life we would always look at the top card until we had gained the advantage and at that time we are ready to win the game and start the next match.

I guess that with forge things are different. We can assume that the answer is always yes. Can anyone think of a reason why we should give the human a choice at this point?

If top card of the Library matches the criteria, then give a choice to reveal the card and resolve the effect. The current kinship card implementation reveals the card if the criteria matches or not. Some cards give you the choice to resolve the effect.
I can't see many times not wanting to actually look at the top card. Sometimes I wouldn't want to reveal based on what the advantage the card gives.
Maybe the first time it occurs we could have a third option "always yes" or something, which will set a variable in the spell ability so you won't ask them after that. This would be useful for a lot of abilities (like the Ally triggers).
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Kinship cards

Postby Chris H. » 30 Sep 2010, 11:16

For those who are curious, this is the original code block for Wolf-Skull Shaman. It works well and is fairly brief.

It does not give us a choice to reveal the top card of the library if the criteria matches. The name of the card appears on the stack whether the card matches the criteria or not.

Code: Select all
    private static void upkeep_Wolf_Skull_Shaman() {
        final String player = AllZone.Phase.getActivePlayer();
        PlayerZone playZone = AllZone.getZone(Constant.Zone.Play, player);
        PlayerZone library = AllZone.getZone(Constant.Zone.Library, player);

        CardList list = new CardList(playZone.getCards());
        list = list.getName("Wolf-Skull Shaman");

        Ability ability;
        for(int i = 0; i < list.size(); i++) {
            if(library.size() <= 0) {
                return;
            }
            // System.out.println("top of deck: " + library.get(i).getName());
            String creatureType = library.get(0).getType().toString();
            String cardName = library.get(0).getName();

            final Card crd = list.get(i);
            ability = new Ability(list.get(i), "0") {
                @Override
                public void resolve() {
                    PlayerZone library = AllZone.getZone(Constant.Zone.Library, player);

                    String creatureType = library.get(0).getType().toString();

                    if(creatureType.contains("Elf") || creatureType.contains("Shaman")
                            || library.get(0).getKeyword().contains("Changeling")) {
                        CardFactoryUtil.makeToken("Wolf", "G 2 2 Wolf", crd, "G",
                                new String[] {"Creature", "Wolf"}, 2, 2, new String[] {""});
                    }

                }// resolve()
            };// Ability
            if(creatureType.contains("Elf") || creatureType.contains("Shaman")) ability.setStackDescription("Wolf-Skull Shaman - "
                    + player + " reveals: " + cardName + ", and puts 2/2 Wolf into play.");
            else ability.setStackDescription("Wolf-Skull Shaman - " + player + " reveals top card: " + cardName
                    + ".");

            AllZone.Stack.add(ability);
        }// for
    }// upkeep_Wolf_Skull_Shaman()
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: Kinship cards

Postby Chris H. » 30 Sep 2010, 11:17

This is an edited version and has a couple of minor improvements.

The setStackDescription() now uses StringBuilder and includes a test for changeling. We give the human a choice to put a token into play via a nice looking JOptionPane.showConfirmDialog() using yes/no buttons.

This version still displays the name of the card and it appears on the stack whether the card matches the criteria or not.

Code: Select all
    private static void upkeep_Wolf_Skull_Shaman() {
        final String player = AllZone.Phase.getActivePlayer();
        PlayerZone playZone = AllZone.getZone(Constant.Zone.Play, player);
        PlayerZone library = AllZone.getZone(Constant.Zone.Library, player);

        CardList list = new CardList(playZone.getCards());
        list = list.getName("Wolf-Skull Shaman");

        Ability ability;
        for (int i = 0; i < list.size(); i++) {
            if (library.size() <= 0) return;
           
            String creatureType = library.get(0).getType().toString();
            String cardName = library.get(0).getName();
            final Card crd = list.get(i);
           
            ability = new Ability(list.get(i), "0") {
                @Override
                public void resolve() {
                   
                    PlayerZone library = AllZone.getZone(Constant.Zone.Library, player);
                    String creatureType = library.get(0).getType().toString();

                    if (creatureType.contains("Elf")
                            || creatureType.contains("Shaman")
                            || library.get(0).getKeyword().contains("Changeling")) {
                       
                        if (player.equals(Constant.Player.Human)) {
                           
                            String title = "Wolf-Skull Shaman - Ability";
                            Object message = "Put a 2/2 green Wolf creature token into play?";
                           
                            int choice = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
                           
                            if (choice == JOptionPane.YES_OPTION) {
                                CardFactoryUtil.makeToken("Wolf", "G 2 2 Wolf", crd, "G",
                                        new String[] {"Creature", "Wolf"}, 2, 2, new String[] {""});
                            }
                        } else {
                           
                            CardFactoryUtil.makeToken("Wolf", "G 2 2 Wolf", crd, "G",
                                    new String[] {"Creature", "Wolf"}, 2, 2, new String[] {""});
                        }
                    }
                }// resolve()
            };// Ability
           
            StringBuilder sb = new StringBuilder();
            sb.append("Wolf-Skull Shaman - ").append(player);
           
            if (creatureType.contains("Elf")
                    || creatureType.contains("Shaman")
                    || library.get(0).getKeyword().contains("Changeling")) {
               
                sb.append(" reveals: ").append(cardName).append(", and puts 2/2 Wolf into play.");
               
            } else {
               
                sb.append(" reveals top card: ").append(cardName).append(".");
            }
            ability.setStackDescription(sb.toString());
            AllZone.Stack.add(ability);
        }// for
    }// upkeep_Wolf_Skull_Shaman()
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: Kinship cards

Postby Chris H. » 30 Sep 2010, 11:20

The next version that I am working on attempts to move most of the code out of the

Code: Select all
ability = new Ability(list.get(i), "0")
`
method.

I think that I can place the test for types + changeling and the option dialog outside of the ability. If we choose yes, then the ability would resolve. The ability would make a token, place the ability on the stack and this would reveal the info to the opponent.

I hope to have this code ready later today or tomorrow. :D
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: Kinship cards

Postby Rob Cashwalker » 30 Sep 2010, 14:17

I think I can create an activated ability keyword like "abSetOption" or simply "abSetSVar"... so you can click on the card to turn on/off the "may" default.
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: Kinship cards

Postby Chris H. » 30 Sep 2010, 14:21

This is the next version. The AI will always choose to reveal the top card if the criteria matches and the effect will always go onto the stack.

The Human gets a JOptionPane.showConfirmDialog() only if the criteria matches. The pic below shows both the JOptionPane.showConfirmDialog() and the possible error condition in the message window. The game can be continued and no error exception is generated.

Code: Select all
    private static void upkeep_Wolf_Skull_Shaman() {
        final String player = AllZone.Phase.getActivePlayer();
        PlayerZone playZone = AllZone.getZone(Constant.Zone.Play, player);
        PlayerZone playerLibrary = AllZone.getZone(Constant.Zone.Library, player);
       
        CardList list = new CardList(playZone.getCards());
        list = list.getName("Wolf-Skull Shaman");
       
        for (int i = 0; i < list.size(); i++) {
            if (playerLibrary.size() <= 0) return;
           
            PlayerZone library = AllZone.getZone(Constant.Zone.Library, player);
            String creatureType = library.get(0).getType().toString();
            String cardName = library.get(0).getName();
            final Card crd = list.get(i);
            final int choice[] = {JOptionPane.NO_OPTION};
           
            if (creatureType.contains("Elf")
                    || creatureType.contains("Shaman")
                    || library.get(0).getKeyword().contains("Changeling")) {
               
                if (player.equals(Constant.Player.Human)) {
                   
                    String title = "Wolf-Skull Shaman - Ability";
                    Object message = "Put a 2/2 green Wolf creature token into play?";
                    choice[0] = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
                }
               
                if (choice[0] == JOptionPane.YES_OPTION
                        || player.equals(Constant.Player.Computer)) {
                   
                    Ability ability = new Ability(crd, "0") {
                        @Override
                        public void resolve() {
                           
                            CardFactoryUtil.makeToken("Wolf", "G 2 2 Wolf", crd, "G",
                                    new String[] {"Creature", "Wolf"}, 2, 2, new String[] {""});
                           
                        }// resolve()
                    };// ability
                   
                    StringBuilder sb = new StringBuilder();
                    sb.append("Wolf-Skull Shaman - ").append(player);
                    sb.append(" reveals: ").append(cardName).append(", and puts a 2/2 Wolf into play.");
                    ability.setStackDescription(sb.toString());
                    AllZone.Stack.add(ability);
                }
            }
        }// for
    }// upkeep_Wolf_Skull_Shaman()
`
Attachments
An error may have occured.jpg
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: Kinship cards

Postby Chris H. » 30 Sep 2010, 21:33

I spent far too much time trying to track down the possible error that is displayed in the message window today. The "Phase: Until End of Turn" has sidelined me.

The Kinship card code blocks are located in the upkeep section of the GameActionUtil.java file and I just can not figure out how my last mods would trigger such an error message. Two different phases and all of that.

I thought that adding a

Code: Select all
AllZone.Display.showMessage("Top card in Library: " + cardName);
`
might overwrite the error message, but I was wrong. I am a little stuck at this time. I will wait on this and see if anyone has any ideas. Worst case, we can keep the kinship cards the way they are and I can add the yes/no option to them.
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: Kinship cards

Postby Chris H. » 04 Oct 2010, 00:16

I spent some time trying a few things to fix the error message that appears in the message panel (see jpg picture above.) As far as I can tell, this code section is causing the problem, but I can not figure out how to fix it:

Code: Select all
String title = "Wolf-Skull Shaman - Ability";
Object message = "Put a 2/2 green Wolf creature token into play?";
choice[0] = JOptionPane.showConfirmDialog(null, message, title, JOptionPane.YES_NO_OPTION);
`
The error message does not hang the game and we can select the yes or no button and proceed. The error message does not appear in the message panel if I place this and the rest of the code inside of the spell ability. The error message only appears when this code is outside of the spell ability.
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: Kinship cards

Postby Chris H. » 06 Nov 2010, 19:51

With the recent work done by Sol on the phases I decided to try my updated Wolf Skull Shaman code. I think that the code is a better representation of the real card. I also included a test deck for testing this code block. The original code and the new code can be found at CardFactoryUtil.upkeep_Wolf_Skull_Shaman() and was merged into the SVN at r3346.

The original code is commented out and my new code is the active code block. It is ready to go for testing. :mrgreen:

For some reason, the code outside of the Ability appears to be taking place at end of turn while the ability takes place during upkeep. I realize that Sol is very busy but I thought he might want to take a quick look at this while his phase work is still fresh in his mind.

.
Attachments
test.dck.zip
Wolf Skull Shaman test deck
(272 Bytes) Downloaded 201 times
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: Kinship cards

Postby friarsol » 06 Nov 2010, 21:19

Technically all the choices need to be inside of the Triggered Ability. It's weird about the stuff outside happening at end of the turn.

I moved everything into the Ability and it seems to be working properly for me. I added a small section where the AI will properly reveal to the player as well.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Kinship cards

Postby Chris H. » 07 Nov 2010, 14:10

Thank you Sol. I see that I was mistaken about at which point the ability triggers. The ability triggers when we peek at the top card and not when we decide to create the token.

We have to assume that the human will always peek and the ability then triggers. We can't ask the player if they want to peek since that question will appear during the prior end of turn phase. I agree that this is weird.

I have a question that should be fairly easy for the people that know the rules far better than myself. Should the computer reveal cards that do not match the creature types of the Wolf Skull Shaman?

Currently, the original code and this newest version causes the computer to reveal the Wall of Vines, the Mox Emerald and the Mox Jet that are in my test deck.

I have this feeling, right or wrong, that we only reveal cards that match the creature types of the Wolf Skull Shaman. :)
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: Kinship cards

Postby Hellfish » 07 Nov 2010, 16:40

As far as I understand, your feeling is correct.
Oracle:
...If it shares a creature type with Wolf-Skull Shaman, you may reveal it....
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Next

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 18 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 18 users online :: 0 registered, 0 hidden and 18 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 18 guests

Login Form