Repeat - getting the nth item from a list

Hello! Seems like i’ve hit today’s learning curve wall.

i can see some documentation examples of setting up lists and looping through them, but they seem to stop short of explaining how to actually extract items from lists.

Let’s say i have five dogs, and a list of dog names. i want to iterate through the dogs, and apply a name from the list to each dog.

OR i want to loop through the list of dog names, and on each iteration, dynamically create a new dog and give it a name from the list.

OR i want to start with five dogs, loop through the list of dog names, and apply a name to each dog.

i’m not concerned with how it happens, and i can’t figure out which of these three methods is preferred.

i also can’t quite wrap my head around how to reference the nth item in a list.

[spoiler][code]A dog is a type of thing. A dog has some text called the dogName.

L is a list of that varies.
L is {“Rover”,“Fido”,“Rex”,“Spanky”,“Carl”}.

When play begins:
repeat with someDog running through L:
[somehow make a new dog];
the dogName of the dog is L[n] [… how do i say nth item in the list?]
the description of the dog is “This is [dogName]. He’s a good boy.”;[/code][/spoiler]

Thanks, as always, for your help.

To answer just this bit: you can refer to “entry 3 of L”, where L is a list. Or “entry N of L”, if N is a number.

You can refer to “entry X” in a list.

[code]Test Chamber is a room.

After jumping:
let L be {2, 3, 5, 7, 11, 13, 17, 19};
let X be entry 3 in L;
say “Entry 3 is [X].”
[/code]

Why not just create the dogs directly?

Rover, Fido, Rex, Spanky, and Carl are dogs.

For the most part, the number of objects you can have is set at compile-time. Making more at run-time is difficult.

Here’s a working version of your dog example:

[code]A dog is a kind of thing. A dog has some text called the dogName.

The Kennel is a room. The Kennel contains 5 dogs.

Understand the dogName property as describing a dog.
[This allows you to refer to each dog by its name. Otherwise, you would only be able to call them “dog”, and the game has no way to determine which dog you mean.]

Rule for printing the name of a dog (called D): say “[dogName of D]”.
[This tells the game to refer to the dogs by name. Otherwise, it would say “There is a dog, a dog, a dog, a dog and a dog here.”]

A dog is usually proper-named.
[This tells the game to drop the indefinite article, so it will call Fido “Fido,” instead of “a Fido.”]

Definition: a dog is unnamed if the dogName of it is “”.
[This sets up a handy definition so the rule below can quickly figure out which dogs haven’t been named yet.]

L is initially {“Rover”,“Fido”,“Rex”,“Spanky”,“Carl”}.
[The “initially” keyword initializes the variable L with the appropriate type.]

When play begins:
repeat with X running from 1 to 5:
let D be a random unnamed dog;
now the dogName of D is entry X in L;
now the description of D is “This is [dogName of D]. He’s a good boy.”

Test me with “x rover / x fido / x rex / x spanky / x dog / carl”[/code]

Thanks so much for your help everyone. And mikegentry: thanks a million for this example. There are a number of things in here that i wouldn’t have been able to guess at or cobble together from the recipe book.

A new problem has emerged, though: the dogs were a bit of a smokescreen. i’m actually dealing with objects called “A,” “B,” and “C.” But of course, i’m running into problems whenever i try to (for example) take A box. (i’m not just being difficult for the sake of it … this is, like, a box with a big letter “A” carved into the side of it)

i tried variations on this:

Understand “[the boxName property] box” as describing a box.

But alas…

You might also find the idea of defining things from a table useful for your purposes. See WWI 16.16 for details.

How would i have the player refer to something that is named [the letter A][some word], like an A frame? (WWI 16.16 says that a/the are interpreted from the table as articles). How do i avoid Inform confusion when i’m talking about the literal letter A?

Right now, i say something like “take A Box,” and Inform says “You take the C box,” because it thinks “a” is just an article.

Understand “a box” and “a-box” and “box a” and “box-a” as boxa. The printed name of boxa is “Box A”

Or give them more distinctive names.

A box is a kind of container. alpha box is a box. beta box is a box.

Yeah, that is going to be tough. I’m not certain you can do it without explicitly creating an “A box” in your code (as opposed to making five generic instances of “box” and then labeling them during runtime).

You could use an “after reading a command” rule and some regex matching to replace the text “a box” in the player’s command with something less ambiguous, like “a-box”, and then make “a-box” a synonym for the A box. However, you will need to weigh that against the possibility that a player might actually type TAKE A BOX with the intent to take a random box. If only the B box and the C box are in the room, the command won’t work.

You might also consider referring to them in the game as “box A”, “box B”, “box C”, etc. instead of the other way around. This should encourage the player to refer to them similarly. Inform can understand TAKE BOX A without ambiguity.

I’m pretty sure that (creating an object with source name “A box”) will only make the situation worse. Keep the source code names unambiguous; use parsing rules and synonyms for everything else.

I agree with the rest of Mike’s post. This is one of those situations where it really is best to surrender to the parser and rethink your game design.

(In Delightful Wallpaper I wanted characters with single-letter names. They wound up named R, C, J, F, P, M, and V… notice that I avoided the hell out of directions N, S, E, W, U, D; single-letter verbs I, X, L, Z, Q; meta-abbreviations G and O; and the article A.)

How about intercepting at the level of reading a players command, matching against a regexp, and changing “a box” to something like “aa box”?

Mike Gentry suggested that above, and noted the drawback:

There was a similarish problem involving Numbered Disambiguation Choices, where (to sum it up roughly) an object was supposed to be labeled with the number 1, but when you had a command that wound up getting processed as TAKE 1 BOX it was just understood as “take one box,” and defaulted to the first available choice. Along the lines of what I tried there, maybe you could try this:

Does the player mean doing something with box-a when the player's command includes "a": it is very likely.

That might direct the player’s command to box-a when the player types “take box a” in the presence of box-a, without crashing things when the player types “take a box” when only box C is present. But really, do what Mike and zarf are saying, especially calling it Box A rather than A Box (which sounds more natural to me anyway). And if you want an A-frame use a hyphen. (There aren’t B-frames anyway, are there?)

It occurred to me that you could handle that caveat by checking to see if the A-box is in scope, and only making the text substitution if it is, which allows the parser to interpret “a box” as “any box” if only B-box and C-box are present.

That leaves the (slim, I should think) possibility that the player might type TAKE A BOX while all boxes, including the A-box, are present, and the parser will interpret it as “take the A-box” even when the player meant “take any box”. But since the only two possible interpretations of the command are “give me the A-box” and “give me any box, I don’t care which,” then receiving the A-box should satisfy in either case.

Also, this would be the point where I would throw away my original design notes and just make the boxes blue, green, and yellow instead.

No problem referring to them as “box A,” box B" etc. But right now, they’re being dynamically named from a list {“A”,“B”,“C”}.

i presume the list should look like this instead: {“box A”, “box B”, “box C”}

But i’d still like the individual letters A, B, and C (in another programming language, i would say “string literals”) referenceable later, so that something like this can happen:

Smash box A.

You shatter it. Tiny bits of the red A go flying everywhere.

(where “A” is dynamically printed)

I would just use the letter in the list, and store it to a property like “boxLetter”. That way you can you can use the letter in various ways:

[code]The printed name of a box is usually “box [boxLetter of the item described]”.

The description of a box is usually “This box has a big red [‘][boxLetter of the item described][’] on one side.”

Understand the boxLetter property as describing a box.

After attacking a box: say “You smash it. Tiny bits of the letter [‘][boxLetter of the noun][’] go flying everywhere.”[/code]

etc.