"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.
Probability inverse is a number that varies. [This is expressed as an inverse of the actual probability of diffusion from one room to another, to avoid error.] Probability inverse is 20. [That is, any given molecule of gas has a 5% chance of leaving by a given doorway at any given minute. Probability inverse should never drop below 10, the maximum number of exits from the room.]
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 difference be the former concentration of the second space minus the former concentration of the space;
increase sum by the difference;
let sum be sum divided by probability inverse;
now current concentration of the space is the former concentration of the space plus the sum.
A technical note: it would be possible to write "repeat with space running through rooms... repeat with second space running through rooms adjacent to the space" instead, but in practice this loops through all the rooms * all the rooms again * all the directions (to determine adjacency). Phrasing the loop this way omits the second multiplier. For a map of 25 rooms, this means that the loop runs 25 times faster than it would otherwise, and of course for a larger map the effect would be even more dramatic.
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."
And, for testing purposes, a square grid of rooms:
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 south of room 1A and west of Room 2B. Room 2B is west of Room 2C and south of Room 1B. Room 2C is west of Room 2D and south of Room 1C. Room 2D is west of Room 2E and south of Room 1D. Room 2E is south of Room 1E.
Room 3A is south of room 2A and west of Room 3B. Room 3B is west of Room 3C and south of Room 2B. Room 3C is west of Room 3D and south of Room 2C. Room 3D is west of Room 3E and south of Room 2D. Room 3E is south of Room 2E.
Room 4A is south of room 3A and west of Room 4B. Room 4B is west of Room 4C and south of Room 3B. Room 4C is west of Room 4D and south of Room 3C. Room 4D is west of Room 4E and south of Room 3D. Room 4E is south of Room 3E.
Room 5A is south of room 4A and west of Room 5B. Room 5B is west of Room 5C and south of Room 4B. Room 5C is west of Room 5D and south of Room 4C. Room 5D is west of Room 5E and south of Room 4D. Room 5E is south of Room 4E.
The former concentration of room 3C is 800.0 ppm.
For variety of testing, here is another room set-up, this time with some corridors and walls within; uncommenting it, and commenting out the connected grid, will let us explore what would happen in alternative cases, to prove to ourselves that the model works consistently.
[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. Room 2B is west of Room 2C. Room 2C is west of Room 2D. Room 2D is west of Room 2E. Room 2E is south of Room 1E.
Room 3A is south of room 2A and west of Room 3B. Room 3B is west of Room 3C. Room 3C is west of Room 3D. Room 3D is west of Room 3E.
Room 4A is west of Room 4B. Room 4B is west of Room 4C. Room 4C is west of Room 4D. Room 4D is west of Room 4E. Room 4E is south of Room 3E.
Room 5A is south of room 4A and west of Room 5B. Room 5B is west of Room 5C and south of Room 4B. Room 5C is west of Room 5D and south of Room 4C. Room 5D is west of Room 5E and south of Room 4D. Room 5E is south of Room 4E.]
For the sake at least of seeing what's going on in the example, let's also provide the player with the means to view the gas diffusion graphically:
The status grid is a device carried by the player. The status grid is switched on.
Every turn:
try examining the grid.
Instead of examining the status grid:
say "[fixed letter spacing][bar][line break]";
say "|[state of room 1A]|[state of room 1B]|[state of room 1C]|[state of room 1D]|[state of room 1E]|[line break]";
say "[bar][line break]";
say "|[state of room 2A]|[state of room 2B]|[state of room 2C]|[state of room 2D]|[state of room 2E]|[line break]";
say "[bar][line break]";
say "|[state of room 3A]|[state of room 3B]|[state of room 3C]|[state of room 3D]|[state of room 3E]|[line break]";
say "[bar][line break]";
say "|[state of room 4A]|[state of room 4B]|[state of room 4C]|[state of room 4D]|[state of room 4E]|[line break]";
say "[bar][line break]";
say "|[state of room 5A]|[state of room 5B]|[state of room 5C]|[state of room 5D]|[state of room 5E]|[line break]";
say "[bar][variable letter spacing][line break]".
To say bar:
say "----------------------------------------------".
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.]
The values set for these would depend on the type of poisonous gas in question; we'd want to adjust appropriately.
To say state of (space - a room):
if the space is the location, say bold type;
if current concentration of space is less than 10.0ppm, say " ";
if current concentration of space is less than 100.0ppm, say " ";
say current concentration of space;
say roman type.
Now, in theory we might also want to account for sources and sinks, items that either inject poisonous gas into the environment or remove it again. For simplicity, we will assume that these contributions can also be calculated in ppm and that the total number of inert and poisonous gas molecules in a room never changes (so if poison gas molecules are added, an equal number of inert molecules are removed). If room pressure were able to change, our model would have to be improved, so let us assume for now that that never happens. We want this sink/source business to calculate before any other portion of the diffusion rulebook, so set it as a first diffusion rule.
A gas source is a kind of thing. A gas source has a concentration called the contribution. The contribution of a gas source is usually 30.0ppm.
Room 2B contains a gas source called a spigot. The contribution of the spigot is 50.0ppm. Room 5A contains a gas source.
A gas sink is a kind of thing. A gas sink has a concentration called the contribution. The contribution of a gas sink is usually 30.0ppm.
Room 5E contains a gas sink called a fan. The contribution of the fan is 80.0ppm.
The first diffusion rule (this is the sources and sinks rule):
follow the sources rule;
follow the sinks rule.
This is the sinks rule:
repeat with item running through gas sinks:
let space be the location of the item;
decrease the former concentration of the space by the contribution of the item;
if the former concentration of the space is less than 0.0ppm, now the former concentration of the space is 0.0ppm.
This is the sources rule:
repeat with second item running through gas sources:
let space be the location of the second item;
increase the former concentration of the space by the contribution of the second item;
if the former concentration of the space is less than 0.0ppm, now the former concentration of the space is 0.0ppm.
Test me with "z / z / z / z / z / z / z / z".
Suppose we want to have smoke that spreads from room to room, gradually filling the entire map with a clogging smoke. Having it spread every single turn would make for a pretty rapid diffusion, so we temper this by having it spread only on even-numbered turns, instead. Conveniently, Inform by default already knows about even and odd numbers, so we can write:
"Only You..."
Section 1 - The Procedure
Every turn when the turn count is even:
if every room is smoky, make no decision;
let previously smoky be whether or not the location is smoky;
repeat with area running through smoky rooms:
now every room which is adjacent to the area is smoky;
if previously smoky is false and the location is smoky:
say "[The location] is filling rapidly with smoke."
A room can be smoky or unsmoky.
Some air is a backdrop. Air is everywhere. Instead of doing something other than examining or smelling to air: say "It's just air." Understand "smoke" as the air when the location is smoky.
Instead of examining the air in a smoky room: say "A thick layer of smoke lies just under the ceiling."
Instead of smelling the air in a smoky room: say "Agh, acrid." Instead of smelling a smoky room: try smelling the air.
After looking in a smoky room: say "A thick layer of smoke has gathered under the ceiling."
Section 2 - The Scenario
The Guide Lodge is a room. "A very spacious room capable of containing several hundred girls while they eat, talk, or do crafts. It is constructed in a not-unappealing rustic style, with floor-to-ceiling windows overlooking the lake below, and a fieldstone hearth at the center." The Guide Lodge is smoky.
The Kitchen is north of the Guide Lodge. "Multiple eight-burner ranges, ovens, and a walk-in refrigerator: you know the sort of thing."
The Industrial Pantry is east of the Kitchen. "Awe-inspiring quantities of food line every shelf, from the three-gallon tub of mayonnaise to the 50-pound tub of rice. Perhaps the most astonishing item is a bag of marshmallows big enough to double as a futon."
The player is in the Pantry.
The Hallway is west of the Guide Lodge. The description of the Hallway is "A perpetually-crammed hallway which has to handle the overflow line for the toilets." A singed sign is fixed in place in the Hallway. The description of the sign is "Where the edge of the sign has not been burnt, the legible words are '...Can Prevent Forest Fires'."
The Toilets are north of the Hallway. "Always in full use, at least when the 12-to-15s are here."
The Coat Closet is south of the Hallway. "Muddy boots may not be worn inside the lodge; instead, about 250 pair are piled here, along with their owners' damp parkas and umbrellas."
The Craft Supply Room is west of the Hallway. "A holding-depot for jugs of white glue and popsicle sticks."
Test me with "x smoke / z / z / z / z / x smoke / look".
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".