Some help with building custom code

Howdy.

I’m turning my attention now to another upcoming problem I’ve got with my upcoming Wing Commander Armada PNP mod. Right now, I’m trying to see if it will be necessary to write a custom piece of Java code to handle what I want to do or if VASSAL can handle it natively. Problem I’ve got is that I’m not a Java programmer, though I do know Python and I’ve been around the block enough to know working in another language is a matter of just learning the necessary syntax.

Okay, so here’s the issue: I’ve got VASSAL handling four Global properties - Confederation Group Strength, Confederation Group Maneuver, Kilrathi Group Strength and Kilrathi Group Maneuver. What I’d like to do is tell the game which side is attacking and have it calculate the ratio of the Strengths and the difference of the maneuvers from the attacker’s point of view. I figure I can do this with a pair of buttons on the battle board. The return would be a text message which would then be displayed on the battle board.

Here’s how I’d do it in Python:

def sz_battleCalculate(self, ConStr, ConMan, KilStr, KilMan, Confed):
    strRatio = 0.0
    maneuver = 0
    ratioString = ""

    if (ConStr != 0) and (KilStr != 0):
        if ConStr > KilStr:
            strRatio = ConStr/KilStr
        elif Constr < Kilstr:
            strRatio = KilStr/Constr
        else:
            strRatio = 1.0

        if Confed == True:
            maneuver = ConMan - Kilman
            if ConStr > KilStr:
                ratioString = ("%.1f:1" % (strRatio))
            else:
                ratioString = ("1:%.1f" % (strRatio))
        else:
            maneuver = KilMan - Conman
            if KilStr > ConStr:
                ratioString = ("%.1f:1" % (strRatio))
            else:
                ratioString = ("1:%.1f" % (strRatio))

        return "Strength Ratio: " + ratioString + ", Maneuver Bonus :" + str(maneuver)
        
    else:
        return "At least one player does not have their forces on the Battle Board."

The routine accepts the four Global properties as arguments and a fifth argument, Confed, is a Boolean that asks whether the Confederation side is the attacker. After setting up dummy variables, the routine checks to see if one side has a Strength of zero (i.e. they have no pieces on the battle board), if that’s the case, it says so right away - this avoids the potential division by zero error. If both sides have pieces on the board, it then calculates the strength ratio as a floating point variable based on which side has the higher Strength value. It then builds the ratio string and calculates the difference in Maneuver scores based on who’s attacking, and finally builds the final message to return. Pretty straight forward.

So how about it? Can VASSAL do something like this natively? If so, how (I’ve yet to figure out how to do conditional statements like this in the engine)? If not, what’s the Java equivalent?

Let me ask this question - how does VASSAL handle numeric property values? Are they stored as ints for floats? My understanding is that a float division by zero in Java will return NaN, while an int division by zero in Java throws an exception.

And are there any guidelines out there for how to use Calculated Properties similar to what’s in the Designer’s Guide? The guide’s a few versions out of date, looks like.

Alright…so Calculated Properties is how you handle conditional statements. That’s quite good to know.

So, my mod now has a Ratio Calculator piece on the Battle Board. Its properties are:

  1. Basic Piece - simply names the piece

  2. Does not Stack - allows normal selection but disallows movement.

  3. Text Label - it says “High Side: $highSide$, Ratio: $strRatio$:1, Maneuver Difference: $manDiff$”

  4. Calculated Property - strRatio - which says…
    If(GetProperty(“Confederation Group Strength”)!=0 && GetProperty(“Kilrathi Group Strength”) !=0,If(GetProperty(“Confederation Group Strength”)>GetProperty(“Kilrathi Group Strength”),GetProperty(“Confederation Group Strength”)/GetProperty(“Kilrathi Group Strength”),GetProperty(“Kilrathi Group Strength”)/GetProperty(“Confederation Group Strength”)),NaN)

  5. Calculated Property - manDiff - which says…
    If(GetProperty(“Confederation Group Strength”)>GetProperty(“Kilrathi Group Strength”),GetProperty(“Confederation Group Maneuver”)-GetProperty(“Kilrathi Group Maneuver”),GetProperty(“Kilrathi Group Maneuver”)-GetProperty(“Confederation Group Maneuver”))

  6. Calculated Property - highSide - which says…
    If(GetProperty(“Confederation Group Strength”)>GetProperty(“Kilrathi Group Strength”),“Confederation”,If(GetProperty(“Confederation Group Strength”)<GetProperty(“Kilrathi Group Strength”),“Kilrathi”,“Sides Equal”))

strRatio is throwing an error when I open the Battle Board. The paraphrased message is:
Bad Data in Module: Expression evaluation error Ratio Calculator-Calculated Property[strRatio]=(what I typed above), Error= inline evaluation of: ``_xyzzy=_plugh();’’ internal Error: Unimplemented binary String operator.

I assume that what’s going on is that I’m dividing two integers and asking for a float. The only other thing I can think of is that it’s ignoring the initial conditional statement and going ahead with attempting to do the math, despite the fact it’s a division by zero.

I’ll search the site and see if I can figure out what’s going on; anyone feel free to jump in with the answer, though. This is the last piece of the mod; I get this figured out and I can go about releasing it.

EDIT: Okay. Looks like it’s time to update my version of VASSAL…

Alright, now it’s behaving properly but I’m still getting the error message.

Also, is there a way to tell VASSAL to return the ratio value as a single-point decimal, or am I stuck with the integer value?

Thus spake capi3101:

Alright, now it’s behaving properly but I’m still getting the error
message.

Also, is there a way to tell VASSAL to return the ratio value as a
single-point decimal, or am I stuck with the integer value?

If you’re doing this through BeanShell, you should be able to cast
the dividend or the divisor to a float.


J.

Okay…I’m not familiar with how BeanShell. works, but I’ll see if I can figure it out.

BeanShell is an interpreted implementation of Java, so if you know Java,
you know BeanShell.

On 11/09/2013 6:43 AM, capi3101 wrote:

Okay…I’m not familiar with how BeanShell. works, but I’ll see if I can
figure it out.


Brent Easton
Analyst/Programmer
University of Western Sydney
Email: b.easton@exemail.com.au

…and I don’t know Java either. I know Python, though, and I’ve got enough knowledge of programming to know that the big difference between programming languages is the syntax.

So in Python, I’d recast something to a float by saying (float); that would give then give me a number with a gazillion decimal points, which I would then narrow down a bit. Now, my understanding is that I could achieve what I wanted in Java - a number with a single decimal point - by multiplying one of the numbers by 0.1 first. Is that correct? I haven’t actually tried this…

Not necessarily.
0.1 is not exactly representable as a binary fraction, so you wouldn’t have
any guarantees as to the number of decimal places that a floating point
number will occupy. That can only really be done by formatting the
resulting numbers, which is not really something supported by Vassal, AFAIK.

Binary floating point can be really surprising in the way that it works.
In fact, it will likely have the same results as what you see in Python.
Now Java happens to have decimal numbers as well, which you may be able to
use in beanshell, although it would be less convenient than using int or
double floats.

On Tue, Sep 10, 2013 at 3:00 PM, capi3101 capi3101a@netscape.net wrote:

…and I don’t know Java either. I know Python, though, and I’ve got
enough knowledge of programming to know that the big difference between
programming languages is the syntax.

So in Python, I’d recast something to a float by saying (float); that
would give then give me a number with a gazillion decimal points, which
I would then narrow down a bit. Now, my understanding is that I could
achieve what I wanted in Java - a number with a single decimal point -
by multiplying one of the numbers by 0.1 first. Is that correct? I
haven’t actually tried this…

_____________**
Read this topic online here:
vassalengine.org/**forum/vie … 4#**p41994<https://forum.vassalengine.org/t/some-help-with-building-custom-code/6257/8

_____________**
messages mailing list
messages@vassalengine.org
vassalengine.org/**mailman/listinfo/messageshttp://www.vassalengine.org/mailman/listinfo/messages

Alright, I’ve done a bit of homework, so time to ask for a case. So what I have in VASSAL is two Strength values, both custom Global Properties, both integers. Let’s say the Global Properties are called P1 and P2. I’ve got the case where either of them has a value of zero covered already via a Trigger Action property, so the chance of a division by zero error is successfully avoided. Say P1=6 and P2=4; would the following expression give me a result of 1.5 or not?

(float)Math.round((P1/P2) * 10) / 10

I’m guessing it hinges on whether or not VASSAL loads up that Math library or not…I imagine it does, but I don’t know for sure. I also don’t know if VASSAL will allow the re-cast.

There’s a quick way to find out, I suppose…

Yep…that didn’t work, although I did get the impression that the reason it didn’t work is that I tried to recast the thing as a float afterI performed the division. VASSAL told me there was no Round(int) function or some such.

So I’ll try again, recasting one of the Strength values as a float first. Makes more sense anyway.

Well, I didn’t get it to round to one decimal point, but at least I did start getting it to throw decimals, and that’s good enough for me. Simple, too - just multiply one of the properties by 1.0. Forget about that whole “round” method bit.

I have one more thing I want to try; whether it works or not I’ll probably have a new version of the Armada PNP mod up later today.