sitting as a relationship

I want to place a random number from 1 to 4 at each of three tables in the Inn. Then I want to print the customers at the tables ordered by table, so that for each table, I say who is sitting at each table. I tried using RELATIONS for this, but it is clear I don’t understand how to use it.

Inn-table is a kind of thing. 
Table 1, Table 2, Table 3 and Table 4 are inn-tables in the Inn. 
Understand "table" as inn-table.

A customer is a kind of person.
Ahaz is a customer. Printed name of Ahaz is "A tall man in a monk's robe ".
Boaz is a customer. Printed name of Boaz is "A short man in a monk's robe".
Charles is a customer. Printed name of Charles is "A man with a scruffy beard in a monk's robe ".
Delia is a customer. Printed name of Delia is "A woman, tall and beautiful with platinum blond hair ".
Emmanuelle is a customer. Printed name of Emmanuelle is "A short woman with piggish features ".
Frieda is a customer. Printed name of Frieda is "A yound girl with a head of blazing red hair ".
Greta is a customer. Printed name of Greta is "A young woman, perky, cute, and doesn't seem to stop talking, ".
Hermann is a customer. Printed name of Hermann is "A young man wearing leather armor ".
Roberta is a customer. Printed name of Roberta is "An middle-aged woman bears herself like a leader ".
Tyrone is a customer. Printed name of Tyrone is "A dark-haired man with a three-day beard ".

Sitting relates various customers to one inn-table. 
The verb to sit at means the sitting relationship. 

After going to the Inn:
	let L be {Ahaz, Boaz, Charles, Delia, Emmanuelle, Frieda, Greta, Hermann, Roberta, Tyrone};
	populate table 1 with L;			
	populate table 2 with L;			
	populate table 3 with L;		

[Put 1 - 4 random customers at a particular table.]
To populate (tbl - inn-table) with (L - list of customers):
	repeat with R running from 1 to 4:
		if number of entries in L is 0:
			break;
		if a random chance of 1 in 4 succeeds:    [25% chance]
			let P be a random customer;
			say "[P] sits at [tbl][line break]"; 
			now P sits at tbl;
			remove P from L;

Very little of this is about relations, but I include the whole section for completeness. I get the error
Problem. In the sentence ‘now P sits at tbl’, I was expecting to read a condition, but instead found some text that I couldn’t understand - ‘P sits at tbl’.

1 Like

I can’t see your full project, but this compiles.

I added “inn is a room” and changed "The verb to sit at means the sitting relationship. " to "The verb to sit at means the sitting relation. "

inn is a room

Inn-table is a kind of thing. 
Table 1, Table 2, Table 3 and Table 4 are inn-tables in the Inn. 
Understand "table" as inn-table.

A customer is a kind of person.
Ahaz is a customer. Printed name of Ahaz is "A tall man in a monk's robe ".
Boaz is a customer. Printed name of Boaz is "A short man in a monk's robe".
Charles is a customer. Printed name of Charles is "A man with a scruffy beard in a monk's robe ".
Delia is a customer. Printed name of Delia is "A woman, tall and beautiful with platinum blond hair ".
Emmanuelle is a customer. Printed name of Emmanuelle is "A short woman with piggish features ".
Frieda is a customer. Printed name of Frieda is "A yound girl with a head of blazing red hair ".
Greta is a customer. Printed name of Greta is "A young woman, perky, cute, and doesn't seem to stop talking, ".
Hermann is a customer. Printed name of Hermann is "A young man wearing leather armor ".
Roberta is a customer. Printed name of Roberta is "An middle-aged woman bears herself like a leader ".
Tyrone is a customer. Printed name of Tyrone is "A dark-haired man with a three-day beard ".

Sitting relates various customers to one inn-table. 
The verb to sit at means the sitting relation. 

After going to the Inn:
	let L be {Ahaz, Boaz, Charles, Delia, Emmanuelle, Frieda, Greta, Hermann, Roberta, Tyrone};
	populate table 1 with L;			
	populate table 2 with L;			
	populate table 3 with L;		

[Put 1 - 4 random customers at a particular table.]
To populate (tbl - inn-table) with (L - list of customers):
	repeat with R running from 1 to 4:
		if number of entries in L is 0:
			break;
		if a random chance of 1 in 4 succeeds:    [25% chance]
			let P be a random customer;
			say "[P] sits at [tbl][line break]"; 
			now P sits at tbl;
			remove P from L;
``

That one word made a big difference. Thanks.
After compiling, the problem I’m having is trying to list the customers by table.
This doesn’t work but I think it’s close.

After looking in the Inn:
	say "There are people sitting at the various tables.";
	say "[list of customers which relate to table 1 by the sitting relation][line break]";
	say "[list of customers which relate to table 2 by the sitting relation][line break]";
	say "[list of customers which relate to table 3 by the sitting relation][line break]";

This code gives me out no output at all (including the first text line) but it does compile. Totally mystified.

You populate the tables with customers “after going to the Inn”, but at least in the example you’ve given, the Inn is the only room and so there’s no way to go there (implied: from somewhere else). Therefore you never populate L with customers, so in the end you only prints empty lists.

Change “After going to the Inn” to “When play begins”, and it works.

3 Likes

Thanks for considering my example, but it is within an 8K words of source code. There are plenty of rooms. The set of rules I posted is the only relevant ones.

Adding a room to the beginning of Drew’s code, appending your code to the end, and then moving into the Inn works as intended. The issue may lie outside of your example.

Welcome
An Interactive Fiction
Release 1 / Serial number 260317 / Inform 7 v10.1.2 / D

street

>
e
A dark-haired man with a three-day beard  sits at Table 2

>
restart
Are you sure you want to restart? 
y

Welcome
An Interactive Fiction
Release 1 / Serial number 260317 / Inform 7 v10.1.2 / D

street

> e
An middle-aged woman bears herself like a leader  sits at Table 1
A man with a scruffy beard in a monk's robe  sits at Table 2

> restart
Are you sure you want to restart? y

Welcome
An Interactive Fiction
Release 1 / Serial number 260317 / Inform 7 v10.1.2 / D

street

> e
A woman, tall and beautiful with platinum blond hair  sits at Table 1
A short man in a monk's robe sits at Table 2
A woman, tall and beautiful with platinum blond hair  sits at Table 2

Okay, but your example is the only code I had to consider. More crucially, your example did indeed exhibit the problem you mentioned, and by making the change I proposed (ie. changing “After going to the Inn” to “When play begins”), your example then worked fine. So I’m fairly sure the problem is the “After going to the Inn” condition not triggering.

3 Likes

I have solved the problem somewhat.

After looking in  Inn:
	let L be {Ahaz, Boaz, Charles, Delia, Emmanuelle, Finnigan, Frieda, Greta, Hermann, Malcolm, Roberta, Tyrone};
	populate table 1 with L;			
	populate table 2 with L;			
	populate table 3 with L;		
	say "There are four tables here, with a few people sitting at some of them.[line break]";
	let Patrons be list of customers which relate to table 1 by the sitting relation;
	describe Table 1 with Patrons;		
	let Patrons be list of customers which relate to table 2 by the sitting relation;
	describe Table 2 with Patrons;		
	let Patrons be list of customers which relate to table 3 by the sitting relation;
	describe Table 3 with Patrons;		
	say "The unseated NPC's are [L][line break]";

To describe (Tbl - inn-table) with (Patrons - list of customers):
	let N be the number of entries in Patrons;
	if N is not 0:
		say "At [tbl]: ";
		repeat with P running through Patrons:
			say "[P] ([initial appearance of P]), ";
			now P is in the Inn;
		say "[paragraph break]";
	otherwise:
		say "[tbl] is empty. [line break]";
		
[Put 1 - 4 random customers at a particular table.]
To populate (tbl - inn-table) with (L - list of customers):
	repeat with R running from 1 to 4:
		if number of entries in L is 0:
			break;
		if a random chance of 1 in 4 succeeds:
			let N be the number of entries in L;
			let K be a random number from 1 to N;
			let P be entry K in L;
			now P sits at tbl;
			remove P from L;

This produces the output:


The only problem is that although L is changed within the populate rule, it does not change it in the After looking in Inn: rule that calls it.

Does someone know how to declare a list outside a rule (like the Customers are declared) or how to pass the changed L back to the caller? I want L to not sit customers that have already been sat at a table.

Yes, this is explained here (perhaps confusingly, because what you’re after is a variable list, as opposed to a constant list – but it is L itself that is constant and global, while its contents can vary; perhaps the documentation should simply call this “list literals”):

So you can declare L as a variable list (ie. a list that varies), at the top level of the program, outside the rule:

L is a list of customers that varies.
L is {Ahaz, Boaz, Charles, Delia, Emmanuelle, Finnigan, Frieda, Greta, Hermann, Malcolm, Roberta, Tyrone}.

This makes L a global variable list. You now don’t need to pass the list into the populate rule at all:

To populate (tbl - inn-table):

In other words, the L in the rule body will now refer to the global L, and when you alter L it will be affected globally. And then just say:

After looking in  Inn:
	populate table 1;			
	populate table 2;			
	populate table 3;		

For the record, let creates a temporary variable for the purposes of the rule, so you can’t use it elsewhere.

Yes, that works great! Thanks.