I7 semi-random (one of/or) modifications

I have code that works to do what I want. But what I am wondering is if there is a way to do it simpler. I want to be able to not just shuffle a list, but keep consecutive items together. For instance, this would allow for sensible ongoing conversations.

To do this I define the following and operate on it.

[code]a talkgroup is a kind of thing. a talkgroup has a number called cur-row. a talkgroup has a table-name called cur-table.

jokes is a talkgroup. cur-row of jokes is 0. cur-table of jokes is table of cc-blather.
complaints is a talkgroup. cur-row of jokes is 0. cur-table of complaints is table of bar-blather.
[/code]

This works okay, but two tries with tables or lists didn’t. And it’s no problem if they don’t, but I don’t understand why & sense I’m missing something important about Inform in general. Code-tries are below.

[spoiler][code]“tablenum” by Andrew Schultz

room 1 is a room. room 2 is west of room 1.

temp-table is a table-name that varies. a table has a number called x.

when play begins:
now temp-table is table of not very random talk;
sort table of not very random talk in random order;

every turn:
if player is in room 1:
now temp-table is table of not very random talk;
if player is in room 2:
now temp-table is table of boring talk;
increment x of temp-table;
if x of temp-table > number of rows in temp-table:
now x is 1;
choose row x of temp-table in temp-table;
say “[blah entry]”;

to say minus:
decrement x of temp-table;

table of not very random talk
blah
“[one of]Hi![minus][or]How are you?[minus][or]My, the weather![cycling]”
“I like lamp.”

table of boring talk
blah
“[one of]yawn[minus][or]yawn again[cycling]”
“zzz”[/code][/spoiler]

[spoiler][code]“tablenum” by Andrew Schultz

room 1 is a room. room 2 is west of room 1.

temp-list is a list of text variable that varies.

a list has a number called x.

when play begins:
now temp-list is list of not very random talk;
sort list of not very random talk in random order;

every turn:
if player is in room 1:
now temp-list is list of not very random talk;
if player is in room 2:
now temp-list is list of boring talk;
increment x of temp-list;
if x of temp-list > number of entries in temp-list:
now x is 1;
say “[entry x of temp-list in temp-list]”;

to say minus:
decrement x of temp-list;

list of not very random talk is a list of text variable. list of not very random talk is { “[one of]Hi![minus][or]How are you?[minus][or]My, the weather![cycling]”, “I like lamp.” }

list of boring talk is a list of text variable. list of boring talk is { “[one of]yawn[minus][or]yawn again[cycling]”, “zzz” }[/code][/spoiler]

This says “In the sentence ‘increment x of temp-list’ , you seem to be looking up the ‘x’ property, but ‘list of k’ is not allowed to have that property.”

So, am I missing syntax, or the big picture? Thanks!

For number 2, I bet you can’t give lists properties for the same reason you can’t give numbers properties. But I’m pretty sure that you could achieve the same stuff that you want to achieve using “x” by rotating the list and rotating the list backwards (see 20.8 of Writing with Inform), and then choosing the first entry of the list.

Not quite sure what you’re wanting to accomplish. Could you use to say statements?

[code]To say jokes:
if the location is Comedy Club:
say “The guy onstage says, ‘[one of]Hey, how about that airline food…[or]Man, kids today…[or]My wife, I tell ya…[cycling]’[line break]”;
otherwise if the location is Lobby:
say “’[one of]Seriously , I can tell jokes better than these people,’ your friend says. ‘Hey–Knock knock!’[or]Who’s there?’ you respond.[or]Interrupting cow,’ your friend says.[or]Interrupting cow wh-’[paragraph break]‘MOOOO!’ your friend interrupts.[cycling]”;
say “[heckle]”.

To say heckle:
if the location is Comedy Club:
if a random chance of 1 in 2 succeeds:
say “‘Hey! You suck!’ yells someone from the audience.”

Every turn:
say “[jokes]”.

Lobby is a room. “The entrance to the comedy club is north.”

Comedy Club is north of Lobby.

Test me with “n/z/z/s/z/z/z”

[/code]

Okay, I’m a dumbass, you know how to do that. I didn’t see your name on this post Andrew! I don’t suppose you could put comments and responses (with their respective variations) in the same table? I guess you’re trying to get responses and comments to line up but still shuffle the table?

That would almost work, except that when you assign a list to a variable, Inform seems to make a copy of the list. So rotating “temp-list” won’t actually change the original list it was copied from. If you only have a limited number of lists, you could still make it work by manipulating each of them directly, but I don’t see any obvious way to generalize it to an arbitrary number of lists.

Edit: You could probably do it by writing a “speak a line from [list]” routine in I6, since I6 allows you to pass lists by reference. That’s how the standard phrases like “rotate [list]” are defined.

Yes, this is it, thanks! To you and the others who responded. (Delayed thanks due to not clicking “Notify when reply is posted.”)

It looks like there is no simple way to do this. So I will just post my code, because quite frankly I think I’ve done it wrong and have no clue how to do it better. This works. But it doesn’t feel right at all. I mean, I don’t insist on perfect code but I genuinely feel I’m totally missing something here.

[spoiler][code]“semi-random” by Andrew Schultz

comedy club is a room. “You can go west to the bar, which is no more fun.”

bar is west of club. “You can go east to the comedy club, which is no more fun.”

a talkgroup is a kind of thing. a talkgroup has a number called cur-row. a talkgroup has a table-name called cur-table.

jokes is a talkgroup. cur-row of jokes is 0. cur-table of jokes is table of cc-blather.
complaints is a talkgroup. cur-row of jokes is 0. cur-table of complaints is table of bar-blather.

when play begins:
sort table of cc-blather in random order;
sort table of bar-blather in random order;

every turn:
if player is in comedy club:
convocrank jokes;
else if player is in bar:
convocrank complaints;

temp-table is a table-name that varies.

temp-group is a talkgroup that varies.

to convocrank (tg - a talkgroup):
now temp-table is cur-table of tg;
now temp-group is tg;
increment cur-row of tg;
if cur-row of tg > number of rows in temp-table:
now cur-row of tg is 1;
sort cur-table of tg in random order;
choose row cur-row of tg in temp-table;
say “[blah entry]”;

to say minus:
decrement cur-row of temp-group;

table of bar-blather
blah
“‘Who ate all the peanuts?’”
“‘There’s a fly in my martini!’”
“‘I’m not too think to drunk!’”
“‘Boy, bartender, I got problems.’”
“[one of]‘Is this guy boring you?’[minus][or]‘Yeah, he should throw his drink in your face to be more exciting.’[cycling]”

table of cc-blather
blah
“[one of]Knock knock[minus].[or]Who’s there? Orange[minus].[or]Orange who[minus]?[or]Orange you glad I didn’t say banana.[cycling]”
“A man walks into a bar and another ducks.”
“How many (your favorite profession) does it take to screw in a lightbulb?”
“What’s the deal with airline food?”
“I flew in from Cleveland, and boy, are my arms tired.”[/code][/spoiler]

I still haven’t figured out what you’re trying to do. As far as I understand it, you have a number of multi-line conversations that you want to be said, one line per turn, playing the conversations in random order but keeping each individual conversation intact. For example, you have 5 3-line knock-knock jokes, a few one-liners, and a 6-line shaggy dog story, and you want to play random jokes 1 line per turn, choosing a new joke at random whenever you finished the last one. If this is not an accurate description of your problem, skip the remainder of this suggestion.

Here is how I would do it. I would make a table listing all the lines, where each line optionally specifies a successor line. Keep a global of “this is the next line I need to print”. Then, when you’re printing a joke line, if you have a line you need to print, then do so and set the next line to its successor; otherwise, choose randomly among the lines labeled “initial” in the table.

"Jokes" by Paul Zagieboylo

A joke-line is a kind of thing. A joke-line is usually privately-named. [Probably won't matter, but just in case.] Some joke-lines are defined by the Table of Jokes. 

Table of Jokes
joke-line    quip    successor   initial
banana-1    "Knock knock."    banana-2    true
banana-2    "'Who's there?' 'Banana.'"    banana-3    false
banana-3    "'Banana who?' 'Banana banana. Knock knock.'"    banana-4    false
banana-4    "'Who's there?' 'Banana banana.'"    banana-5    false
banana-5    "'Banana banana who?' 'Banana banana banana. Knock knock.'"    banana-6    false
banana-6    "'Who's there?' 'Orange.'"    banana-7    false
banana-7    "'Orange who?' 'Orange you glad I didn[']t say banana?'"    --    false
bar-duck    "'A man walks into a bar and another ducks.'"    --    true
Q-1    "'Ok, whenever I say 1-Q you say 2-Q. Ready? 1-Q!'"    Q-2    true
Q-2    "'2-Q.' '3-Q!'"    Q-3    false
Q-3    "'4-Q.' '5-Q!'"    Q-4    false
Q-4    "'6-Q.' '7-Q!'"    Q-5    false
Q-5    "'8-Q.' '9-Q!'"    Q-6    false
Q-6    "'10-Q.' 'You're welcome.'"    --    false    [This was my favorite joke when I was 4.]
flying    "'I just flew in from Cleveland, and boy, are my arms tired!'"    --    true

The next line is a joke-line that varies. The next line is nothing.

A joke-line is joke-starting if the initial of it is true.

To tell a joke begin;
if the next line is nothing, now the next line is a random joke-starting joke-line;
say the quip of the next line;
now the next line is the successor of the next line;
end.

Comedy Club is a room.

Every turn when in Comedy Club: tell a joke.

Please note: I have not tested this code, so it is probably kind of broken. The table will probably need to be reformatted. I don’t know if I’m dealing with the no-successor case properly. But you should be able to fix it up, and it’s a different approach than what you were doing. I don’t know if it’s better or not.

I suppose you could try to nest say phrases and control them with flags. Something like this (not sure if it’s easier than doing it with tables in the long run, though):


comedy club is a room. "You can go west to the bar, which is no more fun."

bar is west of club. "You can go east to the comedy club, which is no more fun."

sticky is a truth state that varies.
sticky 1 is a truth state that varies.
Sticky 2 is a truth state that varies.

every turn:
	if player is in comedy club:
		if sticky is false:
			say jokes;
		else if sticky 1 is true:
			say sticky joke 1;
		else if sticky 2 is true:
			say sticky joke 2;
	else if player is in bar:
		if sticky is false, say complaints;
		else say sticky complaint.


to say sticky: now sticky is true.
to say sticky 1: now sticky 1 is true.
To say sticky 2: now sticky 2 is true.
to say unstick: now sticky is false; now sticky 1 is false; now sticky 2 is false.

to say complaints:
say "[one of]'Who ate all the peanuts?'
[or]'There's a fly in my martini!'
[or]'I'm not too think to drunk!'
[or]'Boy, bartender, I got problems.'
[or][sticky complaint]
[in random order]".

to say sticky complaint: say "[one of][sticky complaint 1][or][sticky complaint 2][in random order]".

To say sticky complaint 1:
say "[one of][sticky][sticky 1]'Is this guy boring you?'[or]'Yeah, he should throw his drink in your face to be more exciting.'[unstick][cycling]".

To say sticky complaint 2:
say "[one of][sticky][sticky 2]'You're my best friend. I hope you live to be a hundred. Plus three months or so'[or]'You're my best friend, too. Why's the three months'[or]'You're my best friend – I wouldn't want you to die suddenly!'[unstick][cycling]".

To say jokes:
say "[one of]'I flew in from Cleveland, and boy, are my arms tired.'
[or]'A man walks into a bar and another ducks.'
[or]'How many (your favorite profession) does it take to screw in a lightbulb?'
[or]'What's the deal with airline food?'
[or][sticky joke]
[in random order]".

To say sticky joke: say "[one of][sticky joke 1][or][sticky joke 2][in random order]".

To say sticky joke 1:
say "[one of][sticky][sticky 1]'Knock knock.'[or]'Who's there?' 'Orange.'[or]'Orange who?'[or]'Orange you glad I didn't say banana.'[unstick][cycling]".

To say sticky joke 2:
say "[one of][sticky][sticky 2]'Why is an elephant big, grey, and wrinkled?'[or]'Because if he was small, round, and white, he'd be an aspirin.'[unstick][cycling]".

This is really cool–it’s what I was looking for! The details can be sorted out later. Thanks! I think the tables are easiest in the long run, too.