Max and Min

Is there a Max and Min function in Inform? Let’s say I have three variables: A, B, and C. How would I find the largest? The smallest?

I use these:

[code]To decide which number is the greater/max of/-- (X - a number) or (Y - a number):
if Y > X, decide on Y;
decide on X.

To decide which number is the lesser/min of/-- (X - a number) or (Y - a number):
if Y < X, decide on Y;
decide on X.

To decide what number is ABS/absolute value/-- of/-- (N - a number):
if N < 0, decide on 0 - N;
decide on N.[/code]

You can use like so:

let N be max (X or Y); let N be the lesser of X or Y; let N be the absolute value of Y;

…etc.

–Erik

This is a great start, but would it work with more than two variables? How would I get the Max of an indefinite set of numbers? Perhaps I could iterate through the list of variables, testing to see which of a pair is larger. The larger value stays, while the smaller one is discarded. This is iterated until there’s only one value left. I’m having trouble figuring out how to implement this, but I’ll keep thinking.

You can iterate through a list like this:

[code]Every turn:
say the max of {4, 6, 10, 25, 8}.

To decide which number is the max of (L - a list of numbers):
let maximum be entry 1 of L;
repeat with X running through L:
if X is greater than maximum, now maximum is X;
decide on maximum.[/code]

Juhana beat me to it, but since my solution is slightly different:

[code]To decide which number is the greater/max of/-- (L - a list of numbers):
sort L in reverse order;
decide on entry 1 of L.

To decide which number is the lesser/min of/-- (L - a list of numbers):
sort L;
decide on entry 1 of L.

When play begins:
let N be max {12, 21, 88, 7};
say “[N].”
[/code]

The main annoyance with using lists is that you have to put digits–not variables–into the list. That is, “{score, max_score}” is not legal. Instead, you have to build the list first, e.g. “let L be a list of numbers; add score to L; add max_score to L; let N be max L.”

–Erik

These are both far more elegant that what I had envisioned. Thank you both!

On closer examination, it turns out these won’t work–at least for what I’m trying to accomplish. They can find the max number, which is great, but my goal is actually to find out which variable is the largest. For instance, of A, B, and C, which contains the biggest number?

If it’s not possible to this, I’ve found a work-around, but it’s not very elegant.

I explained how you’d have to do that:

Rather than use a list, you could also just extend the original two-term phrases to use three terms, e.g.:

To decide which number is the greater/max of/-- (X - a number) or (Y - a number) or (Z - a number): let N be X; if Y > X, let N be Y; if N > Z, decide on N; decide on Z.

This will allow you to use variables for any or all of the terms.

–Erik

Sorry, either I’m missing your point, or I’m not explaining my own very well. So I’m not looking for the largest number, but rather the largest variable. Let say that the variables were cat, dog, and lizard. I want to know, is cat the largest? Dog? Lizard? Perhaps I could extend the current code by adding:

if cat is N: <response>; else if dog is N: <response>; otherwise: <response>;

This isn’t very elegant, but it looks like it will work. Have a better idea?

I think I get what you’re looking for now, but I admit I’m a bit thrown by your use of cat and dog as variable names–wouldn’t you implement cats and dogs as objects (persons), not variables? Anyway, assuming that we are talking about number variables here, then yes, the way to find out which variable contains the number returned from a max/min routine would be to compare back to the inputs, as you suggested. However, if what you’re trying to do is print a different message depending on whether a given variable is greater than a set of others, wouldn’t it make more sense to just compare them directly, rather than use a min/max function? Something like this:

If cat is greater than or equal to dog and cat is greater than or equal to lizard: say "Cat is top dog."; if dog is greater than or equal to cat and dog is greater than or equal to lizard: say "Dog is out front."; if lizard is greater than or equal to cat and lizard is greater than or equal to dog: say "Lizard is the leader."

Or am I still missing something?

–Erik

You got it this time!

As for why I’m not just comparing the variables directly, it’s because I’m actually working with sets with 4 to 12 variables. Typing out 12 greater-than statements per line is a bit much.

Oh, and don’t worry, I’m not actually comparing cats and dogs. This is part of a decision making process during NPC conversation. Depending on the mood set by prior conversation choices, the NPC will respond in various ways. The real variables are things like trust, boredom, servility, and familiarity.

Hm, that sounds like a lot to try to juggle with simple variables. You might want to consider simplifying your scheme for your own sanity’s sake…

But in the event that you don’t want to simplify the scheme, you might take advantage of object properties to manage things a little more sanely. For example, you could store your values as number properties inside objects representing your 12 traits; you could then write “max” and “min” routines that compare the values of the properties, but return the corresponding object name rather than the number. Here’s a bit of code that illustrates how this might work (note that this also allows you to divide your traits into subgroups for easier comparison:

[code]There is a room.

A trait is a kind of thing. A trait has a number called the quantity. The quantity of a trait is usually 3.

Interest is a kind of trait.

The engagement is a kind of interest. Engagement is a part of every person. The quantity of engagement is usually 2.
The boredom is a kind of interest. Boredom is a part of every person. The quantity of boredom is usually 4.

To decide what thing is predominant of/-- (L - a list of things):
sort L in reverse quantity order;
decide on entry 1 of L.

When play begins:
let quality be the predominant of the list of interests that are part of the player;
say “Your most salient interest is [quality] ([quantity of quality]).”;
let N be the quantified engagement of the player;
say “Your engagement is [N].”

To decide which number is the quantified (V - name of kind of value K) of (P - a person):
let X be a random K that is part of P;
decide on the quantity of X.[/code]

There are other ways to approach this kind of thing, of course. Other folks might chime in with totally different solutions.

–Erik

Erik’s solution is beautiful.

Depending on what else you want to to with this, another option would be to have a table which you fill with (column 1) the emotions, and (column 2) the associated numbers. You can then sort the table by the number, and check out which emotion corresponds to that.

There are definitely too many variables. I’ve been working on this segment of NPC code for about two weeks, and it’s finally coming to a close. Hopefully I’ll be done before the weekend. Anyway, I now see cleaner ways to handle it, but I’m so deep in that it doesn’t make sense to rewrite. I’ll keep your suggestion in mind for my next game, though. It would have made coding this one go by a lot faster.