How to toss coins into a random pile

Someone last week asked about how to simulate a random dump–like pouring a bag of coins onto a table. I thought about it because I considered it in the past but never figured out a way to do it. Cattlesquat proposed an idea based on drawing random cards, but I discovered an even simpler way, and I tested it in a sample module. Here is how it works. (If everybody already knows this or there is a trivial way I’ve missed, forgive me for being the fool.)

Suppose we have a coin and a coin prototype. I want to toss it on a spot but have land somewhere nearby and different each time. In the coin’s prototype, I add the “sendto” trait. I decided to send to a region on a target map because this (and send to pixel location) gives me the advanced option to offset from the base point. It’s then just a matter of generating random numbers to put in those offsets. But how to do that?

(As an aside, it would be really nice if the bean shell tool had a random() function that provided random integers. It would open the door for some simple AI in solo games among other things like my coin toss.)

So again, how do I do that? The way I did is is to add a Layer trait. In fact, I made two. I called them “randomX” and “randomY” and set to always active. The layer trait has a command to get a random level, so I added 10 null image levels, and I implemented only one command in it–randomize. I did not expose a right-click command, and I made the key code a string-- “randomizeX” in one and “randomizeY” in the other. Each time I call randomizeX, it stores a random number from 1-10 in the property randomX_Level (and the same for randomizeY).

Next, I just needed to use those random numbers in my sendto offsets. I needed a trigger trait that looked like this:
randomizeX !get a random x from the X layer trait
randomizeY
send

The send command sends the coin to region “Start” and offset by “drift”, a local property that I can set to taste. My pieces were 48 pixels a side, so I randomly set drift to 23, but I can change it widen or narrow the toss range. In the advanced section, it became these bean shell lines: {drift} times {randomX_Level - 1} and {drift} times {randomY_Level - 1}. (I subtract 1 to get the multiplier down to 0-9 from 1-10, but that doesn’t matter much.) And that’s it.

So that brings me to my second thing. I made a very simple module to demonstrate this plus something else where “tossed” pieces line themselves neatly without much work by me. It occurred that wouldn’t it be nice if there was a dedicated area in the Vassal module library for non-game-playing modules whose only purpose was to teach how to use a feature or two. All the complications would be stripped out, so no more looking at Twilight to figure out how a deck works. The admins would have to set this up, but I think it would be great.

This came up the other day

{Math.round(Math.random()*10)+1} will give you a random integer between 1 and 10. Agree though, it would be nice if we added a Bsh function randInt(10) which did the same thing.

I love the idea of a section of demo module ‘fragments’ highlighting individual features. It could be tied in with the ‘Tips and Tricks’ section of the wiki. Wouldn’t need the admins to set it up, you could just go ahead and create a module page for a ‘Tips and Tricks’ module and link to it from the Tips and Tricks page.

I had no idea math functions were available in vassal. Is this explained somewhere? Is there a list somewhere of all available functions?

My concern about submitting a module simply for the purpose of education is that it will get buried and lost in the thousands of game modules already available. I thought it would be nice that if you were looking at the alphabetical list of modules, there’d be a link to the cluster of all teaching modules so a person could look through them at their leisure. Of course, there would have to be some submissions to make it worthwhile. Also, I must admit I didn’t know there was a tips and tricks page either.

If I understand it correctly (50-50), the java Math class library functions are accessible within java beanshell expressions, so these:
docs.oracle.com/javase/8/docs/a … /Math.html

see post “Sending a piece to a zone with a random offset”

Yes those are the ones. Note that when you start trying to get them to behave with your named Global Properties, etc, in calculations, there are some “tricksy bits”, and you usually have to use GetProperty. My related post (on string functions) gives examples:

vassalengine.org/wiki/How_to … _in_VASSAL

I have found that page very helpful.

It’s been over 10 years since I’ve been in the software business, but I recall that the Math functions are reentrant, so I can use them without object instantiation, so I see why they could work. I started snooping around vassal and beanshell docs to see how vassal uses beanshell and what java methods were exposed in vassal, and it was tough sledding. The only java, non-vassal methods I found useful, btw, were round() and random(). I still think it would be nice if there was a random method returning integers.

On an unrelated note, I see that in vassal’s beanshell, there is an alert method that is suppose to show a dialog box. I haven’t tried it, but I couldn’t figure out how and when I would use it in a vassal module. Anybody use it?

Thus spake shilinski:

It’s been over 10 years since I’ve been in the software business,
but I recall that the Math functions are reentrant, so I can use them
without object instantiation,

“static” is the word you want there, not “reentrant”.


J.


messages mailing list
messages@vassalengine.org
vassalengine.org/mailman/listinfo/messages

Again it’s been almost 15 years, but doesn’t a static method need to be reentrant?

Thus spake shilinski:

Again it’s been almost 15 years, but doesn’t a static method need to be
reentrant?

A static method is just one which doesn’t require an object on which to
call it. A reentrant method is one which can (correctly) be run a second
time before the first call to it is complete (which can happen for various
reasons, among them: interrupts, multiple threads).

Here’s an example (in C++) of a non-reentrant static member function:

class A {
static int foo() {
static int x = 0;
return ++x;
}
};

All A.foo() does is return the number of times it’s been called. If you
call A.foo(), then execution is suspended for some reason, and something
else calls A.foo() and returns, the second call will return 1 and the
first call will return 2, which isn’t right. (This also happens to be
a case where being non-reentrant is the same as being thread-unsafe, but
there are cases where those are different as well…)

Anyway… everything in Math is static and thread-safe, so it’s safe to
call from beanshell.


J.

The Terraforming Mars module uses Alerts to warn about special placement restrictions for certain special tiles.

NOTE: Just an important word of warning for folks who’ve started using this:

{Math.[b]round/b+1}

You actually want this:

{Math.[b]floor/b+1}

Because Math.round does 5/4 rounding and you’ll sometimes roll an 11 (and half as many 1’s as you should).

(I’m working w/ a game designer on an official module, and he managed to roll a 7 on a 6-sided die, haha!)

The recommended way to generate random numbers in Beanshell is now to use the new Random() and IsRandom() functions which use the stronger SecureRandom class.

Correct. When I wrote the original message, much of this was unavailable, or I didn’t know what really existed. Thanks for your clarifying comment.

Hi Stan, no problem. Just trying to direct anyone looking in the forums or wiki for info to the latest. Since Random numbers is such a touchy subject :slight_smile: