How to set the Max And Min Amount of a Variable

Started by SinSin, Tue 25/09/2018 11:51:45

Previous topic - Next topic

SinSin

Hello all, (my brain isn't at full speed yet as I haven't had my breakfast..  naughty me..)
I'm stuck trying to work out how to set the maximum value of a variable I have created.
Its probably so easy to do that this needs to be in a new section of the forums labelled Scripting For Power Newbs..   However I cant find an answer anywhere in the help file or in the forums.

Please help 

currently I have

Code: ags
 
int myint = 100 ; 


My guess is that it will be something like

Code: ags

int myint = 50 (max = 100(min = 0 )); 


How far off the mark am I?  I noticed that I cant set max and mins on global variables using the designated screen in the global variable menu.
(unless I overlooked it :-D)
Currently working on a project!

Crimson Wizard

#1
You cannot do that the way you typed above. What you may do, and which is a regular way of doing so in C-like languages, is hiding the variable behind functions that get and set its value. You may reduce that to one function that sets it and leave variable available for direct reading its value, but in such case you'll have to remember to not set its value directly, which I don't recommend (this is like an open door inviting random mistakes into your program)

The global functions solution:

In script header:
Code: ags

import int GetMyInt();
import void SetMyInt(int val);

In script body:
Code: ags

int myint;
int GetMyInt()
{
    return myint;
}
void SetMyInt(int val)
{
    myint = Maths.Min(100, Maths.Max(0, val));
}




Attributes solution:

If this variable is a part of struct you could use attributes (aka properties) to achieve similar effect (but that's not required):
http://www.adventuregamestudio.co.uk/wiki/Keyword:_attribute


Custom struct solution:

Finally, if you are planning to have a lot of global variables like these, you may consider writing your own struct to keep things more organized, for example (warning - not tested):
in header
Code: ags

struct Parameter
{
    // writeprotected means you cannot set this variable directly, but you may still get its value
    writeprotected int Min;
    writeprotected int Max;
    writeprotected int Val; 

    import void SetMinMax(int min, int max);
    import void SetValue(int val);
}

in script
Code: ags

void Parameter::SetMinMax(int min, int max)
{
    this.Min = min;
    this.Max = max;
    // reapply variable in case it is now beyond the range
    this.Val = SetValue(this.Val);
}
void Parameter::SetValue(int val)
{
    // Optionally you may even report error if value is out of range.
    // if (val < this.Min || val > this.Max)
    //    AbortGame("Parameter is out of range!");
    this.Val = Maths.Min(this.Max, Maths.Max(this.Min, val));
}


Example of use:
Code: ags

Parameter myParam;

function game_start()
{
    myParam.SetMinMax(0, 100);
    myParam.SetValue(50);
}

Snarky

#2
CW got there first, but here's the reply I was writing.

Quote from: SinSin on Tue 25/09/2018 11:51:45
Code: ags

int myint = 50 (max = 100(min = 0 )); 


How far off the mark am I?

Pretty far.

You can't set a max (or min) value of an int variable. An int is an int, and has no defined min or max other than the fixed, built-in INTEGER_MAX/MIN limits (based on the largest/smallest values that can be represented).

The usual way to ensure that a variable doesn't exceed a max is to always check it, either when it is set or when it is read. Most often this is done by comparison against a constant (e.g. check that the value is greater than or equal to 0). If you need the max/min values to be dynamic, you're going to need to store them as separate variables.

If you need to do this a lot, it might make sense to factor it out. The easiest is as a function:

Code: ags
int myint;

// Always use this function to set the value of myint
function setMyint(int value, int maxValue)
{
  myint = value;
  if(myint>maxValue) myint = maxValue;
}


You could also do it as a struct so that it happens automatically. (Probably the whole context where you're using it should then be a part of this struct.)

Edit: That last point is probably the main thing I would add to CW's answer: In most cases you wouldn't create a struct just for this behavior. Instead, you would build this behavior into a struct that also does other useful things related to your particular task. For example, as part of a slider it would make sure that the slider value is between the min and max, but it would also do a lot more than just that.

SinSin

Ok thanks very much for the replies guys. I won't be using the variable in question too many times. It's mainly for a shop, I'll just work some if statements into to function to check whether the player has enough money to make a purchase.

Handy to know though. Thanks again.
Currently working on a project!

Monsieur OUXX

#4
Quote from: SinSin on Tue 25/09/2018 16:12:34
Ok thanks very much for the replies guys. I won't be using the variable in question too many times. It's mainly for a shop, I'll just work some if statements into to function to check whether the player has enough money to make a purchase.

Handy to know though. Thanks again.

I know that this question is 2 weeks old now, but if it's for a shop, then you'd be better off implementing a function like "can purchase":

Code: ags

int playerFortune = 100;

struct ObjectToPurchase {
    int price;
    import bool CanBePurchased();
}
ObjectToPurchase objectsForSale[10];

bool ObjectToPurchase::CanBePurchased() {
    return (playerFortune - this.price > 0);
}



in your game :
Code: ags


//player tried to buy object #6
if (!objectsforSale[6].CanBePurchased()) {
    player.say("That trumpet is too expensive.");
}
 

SMF spam blocked by CleanTalk