Diary Part 2: Is there an elegant way to select a page?

Thank you for all the help I received on my previous diary post, especially to Wade.

I have managed to create a diary and for posterity I’ve included it below, credit to @severedhand . Note: I still have to make the entries contextually relevant to my story.

This is exactly what I wanted but, as with these things, once you have what you want you learn it wasn’t exactly what you wanted after all. I loved the exercise of learning this though, which, to me, is the coding equivalent of “The real treasure is the friends you made along the way”.

So let’s say I wanted to make it so that when someone types “read diary” it does a bit of chat about reading diaries and ends with the prompt “which date would you like to read?”.

I’ve tried a few things but this is where my lack of skill and experience shows through. I can’t seem to link ideas together with the correct syntax.

Is it even possible to bring up a command prompt “what page would you like to turn it to?” like entering a name in *415 “Identity Theft” and, even so, can you catch two separate things at the same time without having to collect both separately like “what month would you like?” “what day would you like”?

This would allow me to write significant dates with actual entries, and randomly generate the vast majority.

(This, of course, raises a second issue which is that if you went to a non-significant day more than once it would not read the same. I bet there’s a way to set an entry forever but now I’m really in the tall grass for something that was initially a flight of fancy, so I’ll leave that wrinkle alone).

the Garden is a room.

a table is a fixed in place supporter in the garden.

a diary is on the table.
page of diary is initially 19.
month of diary is  initially 1.


mname is a text that varies.

When play begins:
	now the mname is "December".


Rule for writing a paragraph about table:
	say "An open [diary] sits here on the table.";

Instead of examining diary:
	[if the table of fragment one is empty:
		say "Riveting! You've read the whole thing!!!";
	otherwise:]
	print a diary entry;


To print a diary entry:
	increment page of diary;[get the next date in the diary]
	if page of diary is 20 and month of diary is 1:
		say "There are almost a year of entries in this diary. You feel sort of bad reading it but, judging by the carnage outside the door, this person likely needs your help:[paragraph break]";
	say "'[mname] [page of diary]: ";
	if a random number between 1 and 2 is 1:
		choose a random row in the table of intro-fragments;
		say "[prose entry]. ";
		[blank out the whole row;]
 	say "[one of]Today[or]This morning[or]This evening[or]This afternoon[or]Tonight[or]In the morning[or]In the evening[or]In the afternoon[at random] ";
	[print a sentence beginning]
	choose a random row in the table of fragment one;
	say "[prose entry] ";
	[blank out the whole row;]
	[print a plant name]
	choose a random row in the table of plants;
	say "[prose entry]. ";
	[blank out the whole row;]
	[print a final comment]
	choose a random row in the table of fragment two;
	say "[prose entry]";
	[blank out the whole row;]
	[extra comment made 1 in 3 times:]
	if a random number between 1 and 3 is 1:
		choose a random row in the table of fragment three;
		say ". [prose entry]";
		[blank out the whole row;]
	say ".'";
	if page of diary is 31 and month of diary is 1:
		now page of diary is 0;
		now month of diary is 2;
		now mname is "January";
	if page of diary is 31 and month of diary is 2:
		now page of diary is 0;
		now month of diary is 3;
		now mname is "February";
	if page of diary is 28 and month of diary is 3:
		now page of diary is 0;
		now month of diary is 4;
		now mname is "March";
	if page of diary is 31 and month of diary is 4:
		now page of diary is 0;
		now month of diary is 5;
		now mname is "April";
	if page of diary is 30 and month of diary is 5:
		now page of diary is 0;
		now month of diary is 6;
		now mname is "May";
	if page of diary is 31 and month of diary is 6:
		now page of diary is 0;
		now month of diary is 7;
		now mname is "June";
	if page of diary is 30 and month of diary is 7:
		now page of diary is 0;
		now month of diary is 8;
		now mname is "July";
	if page of diary is 31 and month of diary is 8:
		now page of diary is 0;
		now month of diary is 9;
		now mname is "August";
	if page of diary is 31 and month of diary is 9:
		now page of diary is 0;
		now month of diary is 10;
		now mname is "September";
	if page of diary is 30 and month of diary is 10:
		now page of diary is 0;
		now month of diary is 11;
		now mname is "October";
	if page of diary is 31 and month of diary is 10:
		now page of diary is 0;
		now month of diary is 11;
		now mname is "November";


table of intro-fragments
prose
"I've got a headache, but I ignored it"
"Wanted to stay in bed. Didn't"
"I was excited for some reason"
"Time for another diary entry"
"Fog's coming in across the valley"
"Fog lifting"
"It rained again"

table of fragment one
prose
"I walked amongst"
"I tended"
"I cut some of"
"I smelled"
"I admired"
"I gathered some of"

table of plants
prose
"the ginger plants"
"the clivias"
"the orchids"
"the daisies"
"the daffodils"
"the roses"
"the agaves"
"the angel's trumpets"
"the sunflowers"
"the lilies"
"the dahlias"
"the ferns"
"the pansies"

table of fragment two
prose
"They're amazing"
"I hope they'll keep growing"
"It's not the right season for them"
"My work[if a random number between 1 and 2 is 1] on them[end if] [one of]is paying off[or]has paid off[at random]"
"I need to water them [one of]now[or]soon[or]tomorrow[or]in a couple of days[at random]"
"The soil here isn't right for them"
"There's too much clay in the soil, though"
"They're beautiful"

table of fragment three
prose
"I feel tired"
"The weather's getting warmer"
"I need to bring some more supplies over, though.."
"My sister should be here in a few days"
"I found a beehive nearby, too"
"I keep dreaming of that greenhouse"

Test me with "read diary/g/g/g/g/g/g".
1 Like

It’s trickier than it sounds. There are different ways to do it, but this is the laziest I could come up with that seemed to work as desired (after some pretty cursory testing, so beware bugs):

the Garden is a room.

a table is a fixed in place supporter in the garden.

A month is a kind of value. Some months are defined by the Table of Calendar Months.

Table of Calendar Months
month	number-of-days	month of year
January	31	1
February	28	2
March	31	3
April	30	4
May	31	5
June	30	6
July	31	7
August	31	8
September	30	9
October	31	10
November	30	11
December	31	12

a diary is on the table.
The diary has a number called page. The page of the diary is 20.
The diary has a month.


The nebulous page is a thing. Understand "[month]" or "[number]" as the nebulous page.

To decide whether the diary is open to the right page:
	if the month understood is month of diary and the number understood is page of diary, decide yes;
	decide no.

To decide whether (X - thing) is near enough to (Y - thing):
	if the location of X is not the location of Y, no;
	if X is enclosed by a closed opaque container (called Z) that does not enclose Y, no;
	yes.

After deciding the scope of the player:
	if player is near enough to diary: [can't use visibility or touchability]
		place nebulous page in scope.

Instead of examining the nebulous page:
	let M be month of diary;
	let D be page of diary;
	if the player's command includes "[month]":
		now month of diary is the month understood;
	if the player's command includes "[number]":
		now page of diary is the number understood;
	unless M is month of diary and D is page of diary:
		say "You turn to [month of diary] [page of diary]...[paragraph break]";
	print current diary entry.

Rule for writing a paragraph about table:
	say "An open [diary] sits here on the table.";

Instead of examining diary:
	[if the table of fragment one is empty:
		say "Riveting! You've read the whole thing!!!";
	otherwise:]
	unless we have examined the diary:
		say "There are almost a year of entries in this diary. You feel sort of bad reading it, but, judging by the carnage outside the door, this person likely needs your help:[paragraph break]";
	otherwise:
		advance the diary;
	print current diary entry;
	rule succeeds. [force action success]

To advance the diary:
	let N be the number-of-days corresponding to a month of (month of diary) in the Table of Calendar Months;
	if page of diary is at least N:
		now page of diary is 1;
		now month of diary is the month after month of diary;
	otherwise:
		increment page of diary.


To print current diary entry:
	repeat through the Table of Known Diary Entries:
		if month entry is month of diary and day-of-month entry is page of diary:
			say "[journal entry][paragraph break]";
			stop;
	if the number of blank rows in Table of Known Diary Entries is zero:
		say "It seems that the rest of the pages are blank." instead;
	let current entry be text;
	now current entry is "'[month of diary] [page of diary]: ";
	if a random chance of 1 in 2 succeeds:
		choose a random row in the table of intro-fragments;
		now current entry is "[current entry] [prose entry]. ";
 	now current entry is "[current entry] [one of]Today[or]This morning[or]This evening[or]This afternoon[or]Tonight[or]In the morning[or]In the evening[or]In the afternoon[at random] ";
	[print a sentence beginning]
	choose a random row in the table of fragment one;
	now current entry is "[current entry] [prose entry] ";
	[print a plant name]
	choose a random row in the table of plants;
	now current entry is "[current entry] [prose entry]. ";
	[print a final comment]
	choose a random row in the table of fragment two;
	now current entry is "[current entry] [prose entry]. ";
	[extra comment made 1 in 3 times:]
	if a random number between 1 and 3 is 1:
		choose a random row in the table of fragment three;
		now current entry is "[current entry] [prose entry].";
	now current entry is  "[current entry]'";
	say "[current entry][paragraph break]";
	add current entry to diary.

To add (T - text) to diary:
	choose a blank row in the Table of Known Diary Entries;
	now month entry is month of diary;
	now day-of-month entry is page of diary;
	now journal entry is T.



table of intro-fragments
prose
"I've got a headache, but I ignored it"
"Wanted to stay in bed. Didn't"
"I was excited for some reason"
"Time for another diary entry"
"Fog's coming in across the valley"
"Fog lifting"
"It rained again"

table of fragment one
prose
"I walked amongst"
"I tended"
"I cut some of"
"I smelled"
"I admired"
"I gathered some of"

table of plants
prose
"the ginger plants"
"the clivias"
"the orchids"
"the daisies"
"the daffodils"
"the roses"
"the agaves"
"the angel's trumpets"
"the sunflowers"
"the lilies"
"the dahlias"
"the ferns"
"the pansies"

table of fragment two
prose
"They're amazing"
"I hope they'll keep growing"
"It's not the right season for them"
"My work[if a random number between 1 and 2 is 1] on them[end if] [one of]is paying off[or]has paid off[at random]"
"I need to water them [one of]now[or]soon[or]tomorrow[or]in a couple of days[at random]"
"The soil here isn't right for them"
"There's too much clay in the soil, though"
"They're beautiful"

table of fragment three
prose
"I feel tired"
"The weather's getting warmer"
"I need to bring some more supplies over, though.."
"My sister should be here in a few days"
"I found a beehive nearby, too"
"I keep dreaming of that greenhouse"


Table of Known Diary Entries
month	day-of-month (number)	journal (text)
with 50 blank rows.

You can pre-populate the Table of Known Diary Entries with non-random entries. Looking up entries by a shorthand topic would be possible, but maybe you can give an example of the kind of interaction you’re looking for here.

3 Likes

Lazy? Crikey!

Thank you for that.

I’ll look it over and see if I can make sense of it.

This is really amazing. It works like a charm and I appreciate your work.

I have a couple of questions about the code (I’m not going to pretend I understand everything).The “With 50 blank rows”, will this restrict a person from looking up more that 50 pages or 50 special pages? This will not be an issue but it’s a point of interest.

Can the code be modified to accept ordinal numbers as well as cardinal or would that require a new column?

Can maximum and minimum numbers be stipulated? Currently negative and positive numbers (in excess of actual days) still generate responses.

EDIT: I tried this…to no avail.

if M is December and D is less than 1:
		say "That's not a real date!";

The blank rows are for randomly-generated responses, over and above anything that you put into the table.

Cardinal numbers are already handled by Inform’s built-in token for understanding numbers. You can add ordinal numbers with a small cheat via lines like:

Understand "first" as 1.
Understand "second" as 2.
...

but note that a command like >PUSH BUTTON FOURTH would be interpreted the same as >PUSH BUTTON 4 or >PUSH BUTTON FOUR.

It should be possible to write some logic to ensure that the date is legal by checking the Table of Calendar Months. WWI 16.3 Corresponding entries covers some useful built-in phrases to help with this. If you can’t figure it out on your own, let me know.

1 Like

Thank you for the speedy reply and for the tip regarding the recipe.

I should have been more specific regarding the ordinal numbers, I found that if I entered “read November 4th” the “th” confused the program which the “cheat” would take care of.

You can just modify the Understand... lines to include alphanumeric abbreviations:

Understand "first" or "1st" as 1.

and so forth.

For the date check, building a phrase along the lines of:

To decide whether day (N - number) of month (M - month) is legal:
	...

will let you modify the Instead of examining the nebulous page: rule with the lines

unless day (page of diary) of month (month of diary) is legal:
	say "There's no such date!" instead;

inserted where appropriate. You would also want to add lines to revert the month and page values of the diary to M and D, respectively, or change the order of operations to prevent the illegal values from being written to those properties in the first place.

1 Like

The date check is interesting.

I was going at it totally wrong I was trying to get at the variable after it was entered but before it was written and check it with a less than or greater than query.

I even tried to enter some general values into the table at the bottom.

Not smart.

As you say, it’s more complicated than it seems.

I tried this, it works, sort of, but I’m suspicious.

The first addition doesn’t need to be month specific so that works as is. The second part needs to have some month specific change which I’m struggling with and is, perhaps, not possible when attacking it from this angle.

Instead of examining the nebulous page:
	let M be month of diary;
	let D be page of diary;
	if the player's command includes "[month]":
		now month of diary is the month understood;
	if the player's command includes "[number]":
		now page of diary is the number understood;
	if the number understood is less than 1:
		say "that's not a real date.";
		stop the action;		
	if the number understood is greater than 31:
		say "That's not a real date.";
		stop the action;
	unless M is month of diary and D is page of diary:
		say "You turn to [month of diary] [page of diary]...[paragraph break]";
	print current diary entry.

This is where the phrases from the chapter in the documentation that I pointed to come in handy. Since the maximum day of the month varies by month, you want to be able to cross-reference the information in the Table of Calendar Months to find out whether the entered date is legitimate for the month in question.

To decide whether day (N - number) of month (M - month) is legal:
	if N is less than one, no;
	if N is greater than the number-of-days corresponding to a month of M in the Table of Calendar Months, no;
	yes.
3 Likes

Thank you again. This was really great and definitely an over-reach on my behalf. I’m not sure if I’d have got there without your extensive help.

It feels like I have a Rolls Royce piece of code in my golf cart and I’m so greatful.

I know this is solved, but I always liked modeling books physically. If they contain a ton of data, a table is probably the best way to go, but I’m table-averse.

1 Like