Automate deck creation

I am working on a module that requires two decks to be created at the beginning of a scenario by distributing one deck of Neutral cards evenly into an existing deck for each player. Then, each player deck – containing an even number of Neutral cards and their own ‘home’ cards – should be shuffled/randomized. I’d like to have a button in the card window that can do this.

I have kind of hit a wall on how to implement this. Is there a way to build a while loop that will send a Neutral card to each player deck while the deck.length > 0?

Or is there a module in the library that has similar functionality that I can look at?

Just looking for a nudge in the right direction. I appreciate any insight you guys could provide.

Thanks.

You can use a Trigger Action trait in an individual piece to loop until {<deck name>_numPieces == 0} (or while {<deck name>_numPieces != 0}, if you prefer), triggering a Global Key Command (GKC) Trait targeted at the right deck to trigger a Return to Deck trait on the individual cards; you can use the expression <deck name>_numPieces % 2) to alternate which deck the RTD actually targets.

E.g., you could set the Return to Deck Deck Name target to something like {<deck name>_numPieces % 2) == 0 ? <player 1 deck> : <player 2 deck>}. This will send the card to the first player’s deck if there are currently an even number of cards in the initial deck, or to the second player’s deck otherwise.

Obviously, you will want to replace all those deck names (including the <> I put around them) with the actual names of your decks.

Edit: The ability to use an expression for the Return to Deck target may have been added with VASSAL 3.6–I point this out since you tagged the initial post with “3.5”.

4 Likes

Thank you for the reply. I will try this out.

Okay, that function looks like exactly what I need. I might have to upgrade to 3.6.

This module was built in 3.5.8. Is it generally pretty safe to just continue working on a newer version of Vassal?

Yes, and I recommend giving it serious consideration. On top of dozens and dozens of bug fixes, a surprising number of new features and enhancements went into 3.6. You might be able to get a sense from reviewing that if you’d make use of any of them.

The approach that @jrwatts offered is markedly more compact and elegant than I’d have come up with, but you could still accomplish your goal in 3.5.8 by other methods without the 3.6-only RTD enhancement he leverages.

2 Likes

If you want to look at another example of a module that does that, pull down the “All Bridges Burning” module, and in the Game Piece Prototypes section search for the “SetupButton” prototype. The game’s algorithm is e.g. “4 random cards from this set + a Propaganda card, shuffled together + 4 more random cards” and then eventually interleaving from a different deck. It starts the initial cards in decks (that are later emptied – some people put these off the screen) and uses the “draw fixed number of pieces from deck” setting (e.g. 4 at a time) in a Global Key Command, and the fact that the deck it’s pulling from is set to “shuffle always” so every card is picked randomly.

I’ve attached a screenshot of some of the innards.

Brian

3 Likes

Sorry for the late reply to this. Real life got in the way and I haven’t been able to put much work into my module over the last few months. Getting back to it now.

Anyhow, I appreciate the answers given. I’ve looked through All Bridges Burning and some other COIN modules to get a feel but I’m still getting lost somewhere. Here are the steps I’ve taken:

  1. I added a property to the “Neutral Command Card” Prototype definition to alternate the deck to which it will be going. The expression is: {("Neutral Command Cards".length % 2) == 0 ? "German Command Cards" : "Soviet Command Cards"}

  1. Added the Action Button, Trigger Action, and Global Key Command properties to the “Create Command Deck” button.

  1. The Trigger Action property is set up so…

  1. The Global Key Command for this is set up so (I know I have repeated the expression from the prototype definition here, but I’m not sure which one it’s supposed to go to)…

Generally, I am just kind of confused how to chain along the Key Commands or Global Key Commands to get them to work.

Also, am getting an error message when I add either "Neutral Command Cards"_numPieces != 0 or "Neutral Command Cards".length != 0'. The full error message is:

-the Bad Data in Module: Source: Expression={"Neutral Command Cards".length != 0}, Error=: reflection error: bsh.ReflectError: No such field: length Error: Expression evaluation error. See the errorlog for more details.

Is there a list of the programming attributes somewhere that the pieces have? I always thought Java was dot notation, so I assume expressions would be written with a period instead of underscore.

And just for visual reference, here is the window I am working with. The middle Neutral deck should be evenly distributed between the German and Soviet deck when that button is pressed and then the decks should be shuffled.

Thank you for any pointers you can provide on this…

You are trying to do something based on the length of a fixed string “Neutral Command Cards”. Perhaps you meant “Neutral Command Cards_numPieces” ?

If you are indeed trying to get the number of cards currently in a Deck called “Neutral Command Cards”, then your expression should instead be:
{(GetProperty("Neutral Command Cards_numPieces") == 0 ? "German Command Cards" : "Soviet Command Cards"}

The <DeckName>_numPieces property is only available on the map where the Deck resides. If you need to reference the property from a different map, use GetMapProperty(<DeckName>_numPieces, <mapName>).

Does this help?

2 Likes

Java uses dot notation to access members of an object, yes, but VASSAL properties are not their own type of object; they are basic java String objects, and can be automatically converted to Integer objects (so you can use String.length(), Math.max(), etc.).

There are certain automatically-created properties: each map has <deck name>_numPieces for every deck on that map, every card in a deck will have DeckName and DeckPosition properties, etc. Because you included spaces in your deck names, you need to use GetProperty() to access the _numPieces property, as Mark just showed in his previous post; if you got rid of the spaces, you could just use NeutralCommandCards_numPieces, instead.

There is a list of most of the automatic properties for pieces here: Basic Piece.
Other automatic properties are described under the components they are associated with (<deck name>_numPieces in the documentation for Decks, for example).

1 Like

Yes, thanks for that. That expression is fixed…I’m getting an infinite loop on my button click now. Gonna keep tinkering…

This is helpful. Thank you.

Okay, I have messed around with this some more. Instead of writing Java expression to choose which deck to send to, I made two separate “Return to Deck” traits in the Neutral Command Card prototype with key commands, for the German and Soviet decks respectively. A Trigger Action button is then clicked to loop between these two Return to Deck key commands.

I have gotten the Trigger Action button to work, however it is sending the whole Neutral Card deck to the first player on the first “Return to Deck” global key command being invoked. So the German player is ending up with all the Neutral cards, instead of them being distributed evenly.

I don’t understand why this isn’t basically doing a “for loop” for each of the cards in the Neutral deck.

Also, the COIN modules got a lot more going on in them when deck building and I’m getting a bit lost when trying to copy the functionality. Does anyone know of a game out there that has a similar, simple deck building?

I just saw this thread for the first time today. Why in the world are you dealing one card at a time to each deck? You like making things hard for yourself? Who don’t you send half to one deck and half to the other, and then be done with it?

Can you show us your Trigger Action and GKC definitions?

Why in the world are you dealing one card at a time to each deck? You like making things hard for yourself?

Why? In case you haven’t been able to discern from this thread, I don’t really know what I’m doing.

However, your suggestion makes sense and would probably simplify the whole thing. Thank you.

Here are what my Trigger Action and GKC look like.

First is the Action Button:

Next are the two GKC for German and Soviet sides:


These both call back on a Key command (ShuffleCmd[side]) for Return to Deck that’s defined in the card prototype.

Lastly, here is the Trigger Action:

Interested to hear your thoughts. Although, the suggestion made by silinkski above is worth a look.

Sorry. Sometimes people try too hard to mimic what the game does instead of using the power of their computer, something a designer can’t do with just wood and paper.

I think your problem is "Within a Deck, apply to All Pieces"; you want it to only apply to 1 piece, don’t you?

1 Like

Yes, that fixed the problem. I misunderstood what the All Pieces setting meant. I thought I had to leave that checked in order for all the cards in the stack to be distributed. I unchecked it, made it loop through twice, and gave each side half the deck (using silinkski’s suggestion). It is not functioning how I would like.

Thank you to guys. I can now stop banging my head on the desk. :crazy_face:

1 Like