I would like to have a generic phrase that updates an enumerated value with the value after or the value before. Generic meaning that it doesn’t work with a single kind of value, but with any enumerated value. For example, if I have these two kinds of value:
The strengths are feeble, weak, strong and superstrong.
The accuracies are terrible shooter, bad shooter, good shooter and sharpshooter.
I’d like a phrase that works like this:
Boost the strength of Pat. Lessen the accuracy of Bob.
This is as far as I’ve been able to go, and it doesn’t work:
To boost (var - enumerated value of kind K):
say "// boost - value to boost: [var] // [line break]";
unless var is the last value of K:
now var is K after var;
say "// boost - resulting value: [var] // [line break]".
The value of var at the end of boost is correct. However, the actual property I want to update stays the same.
Shooting is an action applying to nothing. Understand "shoot" as shooting.
Instead of shooting:
boost the accuracy of the player;
say "You practise your shooting. Now you are a [accuracy of the player]. ".
Then…
>shoot
// boost - value to boost: regular shooter //
// boost - resulting value: good shooter //
You practise your shooting. Now you are a regular shooter.
I guess that the phrase gets accuracy of the player as a separate value (if that makes sense), not as a reference to the property I want to update. Any ideas? Thanks.
Rationale: I’ve noticed that if the value is the last in the enumeration then something like the accuracy after the accuracy of the player cycles to the first (if a sharpshooter practices, they become a terrible shooter). So I need to include an extra condition line and I’m willing to make it a bit more concise since I’m going to have a ton of these.
Correct. Inform doesn’t have the “pass by reference” semantics that you’d need for this to work as written. At the I6 level, it’s possible to have a generic “read/write this property of that object” feature, but this quickly goes into mad science territory.
It’s easier if you don’t need a single phrase to cover all properties. For example, you could have a bunch of phrases like “boost strength of a person” and “boost accuracy of a person” that encapsulate the steps of getting the current property value, computing the new value, and update the property to this new value. The middle step can still delegate to a kind-generic phrase like your current “to boost” phrase, it just has to return the new value as result. This is more phrases in total and slightly different syntax for using them, but each phrase is dead simple to write and understand because it doesn’t involve any deep wizardry.
Yeah, there are special kinds “storage”, “existing variable”, and “nonexisting variable” which can be used to pass things by reference, but I can’t find any documentation on how to use these even in I6—the times they’re used in Basic Inform (to define phrases like “increase _ by _”) are hardcoded into the compiler. The {-lvalue-by-reference:VAR} syntax only works for block values (i.e. values that exist on the heap), so not arithmetic properties.
lab is a room.
A strength is a kind of value.
The strengths are feeble, weak, strong and superstrong.
an accuracy is a kind of value.
The accuracies are terrible shooter, bad shooter, good shooter and sharpshooter.
a person has a strength.
a person has an accuracy.
To set (p - property) property of (o - object) to (v - value):
(- WriteGProperty(OBJECT_TY, {o}, {p}, {v}); -).
To decide what K is (P - a value of kind K valued property)
property of (O - object): (- {O}.{P} -)
To boost (p - an enumerated value of kind K valued property)
of (obj - object):
let x be p property of obj;
if x is not the last value of K, set p property of obj to the K after x;
when play begins:
boost accuracy of player;
say "[accuracy of player] ";
boost accuracy of player;
say "[accuracy of player] ";
boost accuracy of player;
say "[accuracy of player] ";
boost accuracy of player;
say "[accuracy of player] ";