Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: SinSin on Tue 25/09/2018 11:51:45

Title: How to set the Max And Min Amount of a Variable
Post by: SinSin on Tue 25/09/2018 11:51:45
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) Select

int myint = 100 ;


My guess is that it will be something like

Code (ags) Select

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)
Title: Re: How to set the Max And Min Amount of a Variable
Post by: Crimson Wizard on Tue 25/09/2018 12:12:08
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) Select

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

In script body:
Code (ags) Select

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) Select

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) Select

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) Select

Parameter myParam;

function game_start()
{
    myParam.SetMinMax(0, 100);
    myParam.SetValue(50);
}
Title: Re: How to set the Max And Min Amount of a Variable
Post by: Snarky on Tue 25/09/2018 12:14:00
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) Select

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) Select
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.
Title: Re: How to set the Max And Min Amount of a Variable
Post by: 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.
Title: Re: How to set the Max And Min Amount of a Variable
Post by: Monsieur OUXX on Fri 05/10/2018 13:55:19
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) Select

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) Select


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