§15.8. Units
Suppose we want to talk about how tall people are. We could just create a "number" property, like this:
A person has a number called height.
But then we would have to write lines like "Isabella has height 68", which nobody would naturally say. What we want is to be able to write "Isabella is 5 foot 8." Perhaps the computer will need to store that measurement as the number 68 in some register or other, but we don't want to know about that.
"5 foot 8" is a complicated notation in a way - it involves both feet and inches - so let's start with a simpler example:
A weight is a kind of value. 10kg specifies a weight.
This is a little different to the kinds of value seen so far, which were all created like so:
A colour is a kind of value. The colours are red, green and blue.
We can't mix the two styles: a new kind of value will either be numerical at heart ("10kg") or verbal at heart ("blue").
The effect of "10kg specifies a weight" is to tell Inform that this is the notation for writing a constant "weight". So, for instance,
The maximum load is a weight that varies. The maximum load is 8000kg.
if the maximum load is greater than 8000kg, ...
Inform is then careful not to allow weights to be mixed up with other numerical values. For instance, it won't allow "if the maximum load is 400", because 400 is a number, not a weight.
More or less anything we can do with numbers, we can now do with weights. For instance, we can write:
The Weighbridge is a room. "A sign declares that the maximum load is [maximum load]."
...which will produce the text "A sign declares that the maximum load is 8000kg."
Numerical kinds of value are sometimes called "units", because one of their main uses is to allow us to write quantities using scientific units such as kilograms. But they have other uses too. We have a great deal of freedom in creating notations like "10kg", or "4 foot 10" - the main thing is that new notations must not already mean a value. So "10 specifies a weight" will not be allowed, because 10 specifies a number already.
By default we can only write whole-number values. As we've seen, Inform can handle both integer (whole-number) and real arithmetic, and they each have their advantages. The default here is to use whole numbers, so
10 kg specifies a weight.
will store only whole numbers of kilograms (unless clever scaling tricks are used: see the next section). That may be fine, but if we need to handle a wider range of weights, or do scientific calculations that need to be more accurate, this is better:
1.0 kg specifies a weight.
Here Inform can see from the decimal point in the prototype number that real numbers will be involved. We can still write "8000kg", but we can now also write "1.9891 x 10^30 kg" (the mass of the Sun) or "9.109383 x 10^−31 kg" (the mass of an electron). On the other hand, any calculations we do will be limited in accuracy to about 6 to 9 decimal places, exactly as for real numbers.
By default we can only write positive values when whole numbers are used. Sometimes it is unnatural to write negative values, and so Inform will issue a Problem message if this is tried - for instance, Inform would not allow us to write a weight of -4 kg. (This doesn't mean that arithmetic on units is forbidden to get a negative result: we may want to work out the difference between two weights. Inform's Problem message is simply to try to prevent the accidental writing of incorrect values.) If we do want the ability to write negative values in the source text, we signal that in the notation itself:
-10 kg specifies a weight.
That alerts Inform that both positive and negative values for this unit make sense.
If we set up a spread of multiple notations (see the next section) then this is automatically enabled, because then we're clearly dealing with proper physics, where negative values are common; and similarly if we use real numbers (as above).
| ExamplerBGH The player character's height is selected randomly at the start of play.
|
|
|  ExampleLethal Concentration 1 A poisonous gas that spreads from room to room, incapacitating or killing the player when it reaches sufficient levels.
|
|
|  ExampleWonderland Hiking Mount Rainier, with attention to which locations are higher and which lower than the present location.
|
|
This is a slight variation on the previous gas diffusion example: the main difference is that gas preferentially moves towards lower rooms, and will gradually settle in the bottom floor. We do this by calculating the probability of movement separately for each pair of rooms.
"Lethal Concentration"
A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration.
A room has a concentration called current concentration. A room has a concentration called former concentration.
To decide what number is the probability inverse between (space - a room) and (second space - a room):
let guess be 20;
let way be the best route from space to second space;
if way is up, let guess be 50;
if way is down, let guess be 10;
if the guess is less than 10, decide on 10;
decide on guess.
If we wanted, we could introduce other concerns into the calculation here: open and closed doors, windows between rooms, rooms that are outdoors vs. those that are indoors, and so on. The possibilities are numerous, so we will stick with the simple principle that our poison gas sinks.
Every turn:
follow the diffusion rules.
The diffusion rules are a rulebook.
A diffusion rule (this is the gas movement rule):
repeat with space running through rooms:
let sum be 0.0 ppm;
repeat with way running through directions:
let second space be the room way from the space;
if second space is a room:
let incoming be the former concentration of the second space divided by the probability inverse between second space and space;
let outgoing be the former concentration of the space divided by the probability inverse between space and second space;
let difference be incoming minus outgoing;
increase sum by the difference;
now current concentration of the space is the former concentration of the space plus the sum.
A diffusion rule (this is the resetting concentration rule):
repeat with space running through rooms:
now the former concentration of the space is the current concentration of the space.
The last diffusion rule (this is the lethal dosage rule):
if the current concentration of the location is greater than LC50:
say "The concentration in the air overpowers you...";
end the story;
otherwise:
if the current concentration of the location is greater than TLV-STEL:
say "You feel extremely uncomfortable in this environment."
Instead of doing something when the current concentration of the location is greater than TLV-STEL:
if going, continue the action;
say "You can't work in this environment: your eyes and nose sting and it hurts to breathe."
Room 1A is west of Room 1B. Room 1B is west of Room 1C. Room 1C is west of Room 1D. Room 1D is west of Room 1E.
Room 2A is west of Room 2B and below room 1A. Room 2B is west of Room 2C and below Room 1B. Room 2C is west of Room 2D and below Room 1C. Room 2D is west of Room 2E and below Room 1D. Room 2E is south of Room 1E and below Room 1E.
The former concentration of Room 1C is 800.0 ppm.
The status grid is a device carried by the player. The status grid is switched on.
And just for fun, this time we'll make the grid prettier, too; but this will work only on the Z-machine setting, not Glulx.
Every turn:
try examining the grid.
Instead of examining the status grid:
say "[unicode box drawings light down and right][top bar][unicode box drawings light down and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 1A][state of room 1B][state of room 1C][state of room 1D][state of room 1E] upstairs[line break]";
say "[unicode box drawings light vertical and right][middle bar][unicode box drawings light vertical and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 2A][state of room 2B][state of room 2C][state of room 2D][state of room 2E] downstairs[line break]";
say "[unicode box drawings light up and right][bottom bar][unicode box drawings light up and left][variable letter spacing][line break]"
Include Unicode Character Names by Graham Nelson.
To say top bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light down and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
To say middle bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light vertical and horizontal]";
otherwise say "[unicode box drawings light triple dash horizontal]".
To say bottom bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light up and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
TLV is a concentration that varies. TLV is 30.0ppm. [Long-term exposure maximum, safe for 8 hours a day.]
TLV-STEL is a concentration that varies. TLV-STEL is 50.0ppm. [Short-term exposure maximum, safe for fifteen minutes max.]
TLV-C is a concentration that varies. TLV-C is 150.0ppm. [Absolute exposure ceiling.]
LC50 is a concentration that varies. LC50 is 300.0ppm. [Concentration at which 50 percent of test subjects die of exposure, usually expressed in terms of time and body weight; in our LC50 these are factored in for the player's weight for one minute.]
Include Basic Screen Effects by Emily Short.
To say state of (space - a room):
if the current concentration of space is less than TLV, say blue letters;
if the current concentration of space is TLV, say blue letters;
if the current concentration of space is greater than TLV, say green letters;
if the current concentration of space is greater than TLV-STEL, say yellow letters;
if the current concentration of space is greater than TLV-C, say red letters;
say "[unicode square with diagonal crosshatch fill]";
say default letters;
say "[unicode box drawings light vertical]".
Test me with "z / z / z / z / z / z / z / z".
|   ExampleLethal Concentration 2 Poisonous gas again, only this time it sinks.
|
This is a slight variation on the previous gas diffusion example: the main difference is that gas preferentially moves towards lower rooms, and will gradually settle in the bottom floor. We do this by calculating the probability of movement separately for each pair of rooms.
"Lethal Concentration"
A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration.
A room has a concentration called current concentration. A room has a concentration called former concentration.
To decide what number is the probability inverse between (space - a room) and (second space - a room):
let guess be 20;
let way be the best route from space to second space;
if way is up, let guess be 50;
if way is down, let guess be 10;
if the guess is less than 10, decide on 10;
decide on guess.
If we wanted, we could introduce other concerns into the calculation here: open and closed doors, windows between rooms, rooms that are outdoors vs. those that are indoors, and so on. The possibilities are numerous, so we will stick with the simple principle that our poison gas sinks.
Every turn:
follow the diffusion rules.
The diffusion rules are a rulebook.
A diffusion rule (this is the gas movement rule):
repeat with space running through rooms:
let sum be 0.0 ppm;
repeat with way running through directions:
let second space be the room way from the space;
if second space is a room:
let incoming be the former concentration of the second space divided by the probability inverse between second space and space;
let outgoing be the former concentration of the space divided by the probability inverse between space and second space;
let difference be incoming minus outgoing;
increase sum by the difference;
now current concentration of the space is the former concentration of the space plus the sum.
A diffusion rule (this is the resetting concentration rule):
repeat with space running through rooms:
now the former concentration of the space is the current concentration of the space.
The last diffusion rule (this is the lethal dosage rule):
if the current concentration of the location is greater than LC50:
say "The concentration in the air overpowers you...";
end the story;
otherwise:
if the current concentration of the location is greater than TLV-STEL:
say "You feel extremely uncomfortable in this environment."
Instead of doing something when the current concentration of the location is greater than TLV-STEL:
if going, continue the action;
say "You can't work in this environment: your eyes and nose sting and it hurts to breathe."
Room 1A is west of Room 1B. Room 1B is west of Room 1C. Room 1C is west of Room 1D. Room 1D is west of Room 1E.
Room 2A is west of Room 2B and below room 1A. Room 2B is west of Room 2C and below Room 1B. Room 2C is west of Room 2D and below Room 1C. Room 2D is west of Room 2E and below Room 1D. Room 2E is south of Room 1E and below Room 1E.
The former concentration of Room 1C is 800.0 ppm.
The status grid is a device carried by the player. The status grid is switched on.
And just for fun, this time we'll make the grid prettier, too; but this will work only on the Z-machine setting, not Glulx.
Every turn:
try examining the grid.
Instead of examining the status grid:
say "[unicode box drawings light down and right][top bar][unicode box drawings light down and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 1A][state of room 1B][state of room 1C][state of room 1D][state of room 1E] upstairs[line break]";
say "[unicode box drawings light vertical and right][middle bar][unicode box drawings light vertical and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 2A][state of room 2B][state of room 2C][state of room 2D][state of room 2E] downstairs[line break]";
say "[unicode box drawings light up and right][bottom bar][unicode box drawings light up and left][variable letter spacing][line break]"
Include Unicode Character Names by Graham Nelson.
To say top bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light down and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
To say middle bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light vertical and horizontal]";
otherwise say "[unicode box drawings light triple dash horizontal]".
To say bottom bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light up and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
TLV is a concentration that varies. TLV is 30.0ppm. [Long-term exposure maximum, safe for 8 hours a day.]
TLV-STEL is a concentration that varies. TLV-STEL is 50.0ppm. [Short-term exposure maximum, safe for fifteen minutes max.]
TLV-C is a concentration that varies. TLV-C is 150.0ppm. [Absolute exposure ceiling.]
LC50 is a concentration that varies. LC50 is 300.0ppm. [Concentration at which 50 percent of test subjects die of exposure, usually expressed in terms of time and body weight; in our LC50 these are factored in for the player's weight for one minute.]
Include Basic Screen Effects by Emily Short.
To say state of (space - a room):
if the current concentration of space is less than TLV, say blue letters;
if the current concentration of space is TLV, say blue letters;
if the current concentration of space is greater than TLV, say green letters;
if the current concentration of space is greater than TLV-STEL, say yellow letters;
if the current concentration of space is greater than TLV-C, say red letters;
say "[unicode square with diagonal crosshatch fill]";
say default letters;
say "[unicode box drawings light vertical]".
Test me with "z / z / z / z / z / z / z / z".
This is a slight variation on the previous gas diffusion example: the main difference is that gas preferentially moves towards lower rooms, and will gradually settle in the bottom floor. We do this by calculating the probability of movement separately for each pair of rooms.
"Lethal Concentration"
A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration.
A room has a concentration called current concentration. A room has a concentration called former concentration.
To decide what number is the probability inverse between (space - a room) and (second space - a room):
let guess be 20;
let way be the best route from space to second space;
if way is up, let guess be 50;
if way is down, let guess be 10;
if the guess is less than 10, decide on 10;
decide on guess.
If we wanted, we could introduce other concerns into the calculation here: open and closed doors, windows between rooms, rooms that are outdoors vs. those that are indoors, and so on. The possibilities are numerous, so we will stick with the simple principle that our poison gas sinks.
Every turn:
follow the diffusion rules.
The diffusion rules are a rulebook.
A diffusion rule (this is the gas movement rule):
repeat with space running through rooms:
let sum be 0.0 ppm;
repeat with way running through directions:
let second space be the room way from the space;
if second space is a room:
let incoming be the former concentration of the second space divided by the probability inverse between second space and space;
let outgoing be the former concentration of the space divided by the probability inverse between space and second space;
let difference be incoming minus outgoing;
increase sum by the difference;
now current concentration of the space is the former concentration of the space plus the sum.
A diffusion rule (this is the resetting concentration rule):
repeat with space running through rooms:
now the former concentration of the space is the current concentration of the space.
The last diffusion rule (this is the lethal dosage rule):
if the current concentration of the location is greater than LC50:
say "The concentration in the air overpowers you...";
end the story;
otherwise:
if the current concentration of the location is greater than TLV-STEL:
say "You feel extremely uncomfortable in this environment."
Instead of doing something when the current concentration of the location is greater than TLV-STEL:
if going, continue the action;
say "You can't work in this environment: your eyes and nose sting and it hurts to breathe."
Room 1A is west of Room 1B. Room 1B is west of Room 1C. Room 1C is west of Room 1D. Room 1D is west of Room 1E.
Room 2A is west of Room 2B and below room 1A. Room 2B is west of Room 2C and below Room 1B. Room 2C is west of Room 2D and below Room 1C. Room 2D is west of Room 2E and below Room 1D. Room 2E is south of Room 1E and below Room 1E.
The former concentration of Room 1C is 800.0 ppm.
The status grid is a device carried by the player. The status grid is switched on.
And just for fun, this time we'll make the grid prettier, too; but this will work only on the Z-machine setting, not Glulx.
Every turn:
try examining the grid.
Instead of examining the status grid:
say "[unicode box drawings light down and right][top bar][unicode box drawings light down and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 1A][state of room 1B][state of room 1C][state of room 1D][state of room 1E] upstairs[line break]";
say "[unicode box drawings light vertical and right][middle bar][unicode box drawings light vertical and left][line break]";
say "[unicode box drawings light vertical]";
say "[state of room 2A][state of room 2B][state of room 2C][state of room 2D][state of room 2E] downstairs[line break]";
say "[unicode box drawings light up and right][bottom bar][unicode box drawings light up and left][variable letter spacing][line break]"
Include Unicode Character Names by Graham Nelson.
To say top bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light down and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
To say middle bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light vertical and horizontal]";
otherwise say "[unicode box drawings light triple dash horizontal]".
To say bottom bar:
repeat with N running from 1 to 9:
if the remainder after dividing N by 2 is 0, say "[unicode box drawings light up and horizontal]";
otherwise say "[unicode box drawings light horizontal]".
TLV is a concentration that varies. TLV is 30.0ppm. [Long-term exposure maximum, safe for 8 hours a day.]
TLV-STEL is a concentration that varies. TLV-STEL is 50.0ppm. [Short-term exposure maximum, safe for fifteen minutes max.]
TLV-C is a concentration that varies. TLV-C is 150.0ppm. [Absolute exposure ceiling.]
LC50 is a concentration that varies. LC50 is 300.0ppm. [Concentration at which 50 percent of test subjects die of exposure, usually expressed in terms of time and body weight; in our LC50 these are factored in for the player's weight for one minute.]
Include Basic Screen Effects by Emily Short.
To say state of (space - a room):
if the current concentration of space is less than TLV, say blue letters;
if the current concentration of space is TLV, say blue letters;
if the current concentration of space is greater than TLV, say green letters;
if the current concentration of space is greater than TLV-STEL, say yellow letters;
if the current concentration of space is greater than TLV-C, say red letters;
say "[unicode square with diagonal crosshatch fill]";
say default letters;
say "[unicode box drawings light vertical]".
Test me with "z / z / z / z / z / z / z / z".
|