Compare snippets with things? (RESOLVED)

Hello, I’m working on an “order” routine for a restaurant. So far I’ve got:

Restaurant is a room. Player is in Restaurant. In Restaurant is a menu. The description of the menu is “sandwich”.

Kitchen is a room. In Kitchen is a sandwich.

a thing can be orderable. the sandwich is orderable.
a thing can be ordered.

ordering is an action applying to topics. understand “order [text]” as ordering.

check ordering:
__repeat with item running through orderable things:
____now item is not ordered;
____if topic understood matches item:
______now item is ordered;
__if “[list of ordered things]” is “nothing”:
____say “That[apostrophe]s not on the menu.” instead;
__otherwise:
____say “So that[apostrophe]s [a list of ordered things].”

Compiling and running this, I get the error: “Problem. You wrote ‘if topic understood matches item begin’ , which I tried to match against several possible phrase definitions. None of them worked. […] topic understood = a non-temporary variable, holding a snippet / item = a temporary named value, holding a thing”

(Side question - how do I make my tabs show up on here? I’m substituting __ so you can see the indents.)

Thanks in advance for any advice you can provide.

You don’t want “order [text]”; that’s for matching against topics, not things.

Try something like this:

After deciding the scope of the player when ordering: Place the sandwich in scope. Ordering is an action applying to one thing. Understand "order [things]" as ordering. Check ordering: [this doesn't scale very well; try something like "If the noun is not in the kitchen" instead for a better option] If the noun is not the sandwich: Say "That's not on the menu." Report ordering: Say "So that's [the noun]."

Note that this will perform the ordering action multiple times if the player orders multiple things, one for each thing. You could capture them into a list and then print it with an Every Turn rule, perhaps.

And you can use code blocks to format your stuff on the forum. Tabs can be pasted in or simulated with spaces. Note that Inform only accepts tabs.

Thanks, Kevin! FYI, I had to add:

Rule for reaching inside Kitchen when ordering: allow access.

Do new commands, by default, require reaching ability? Can we define a new command so that reaching is not required?

I like the idea of making a list of things ordered:

[code]ordered items is a list of things that varies.

Report ordering: add noun to ordered items.

Every turn while ordered items is not nothing:
say “Coming right up.”;
now ordered items is nothing.[/code]

Except it doesn’t like my use of “nothing” here. Help?

The standard reaching rules cover normal containers and supporters, but when you add things to scope, you need additional reaching rules to tell the parser how they work.

Or you could define the ordering action as “an action applying to one visible thing.” The “visible” means that the player doesn’t have to be able to reach it.

You probably want to go over the lists chapter in the manual. You can say “if ordered items is non-empty…” To empty the list, you could say “truncate ordered items to 0 entries”, or “now ordered items is {}”.

One would expect this following to work:

A thing can be orderable.
Ordering is an action applying to one visible [i.e. not necessarily touchable] thing.
Understand "order [any orderable things]" as ordering.

but based on some testing, it doesn’t seem to; ordering single things works fine, but trying to order multiple things just gives the error “You can’t use multiple objects with that verb.”. However, using an explicit scoping rule does work:

A thing can be orderable.
Ordering is an action applying to one visible [i.e. not necessarily touchable] thing.
Understand "order [things]" as ordering.

Rule for deciding the scope of the player while ordering:
	repeat with the item running through orderable things:
		place the item in scope.

You may also want to tweak the error message you get if you try to order something non-orderable (or nonexistent) using the “printing a parser error” activity. A problem with that is that Inform seems to forget the current action by the time the parser error is printed, but that’s easy enough to work around:

The attempted action is a stored action that varies.
Before deciding the scope of the player: now the attempted action is the current action.
Rule for printing a parser error when the latest parser error is the can't see any such thing error and the attempted action is ordering:
	say "That's not on the menu."

You’ll probably also want to use something like the trick from Inform example 420, “The Facts Were These” to process multi-item orders at once, like this:

Order-completed is a truth state that varies.
Before reading a command: now order-completed is false.
Check ordering when order-completed is true: stop the action.
		
Check ordering:
	let L be the multiple object list;
	if L is empty, add the noun to L;
	let L be filter to things not in the kitchen of L;
	if L is not empty:
		say "I'm sorry, but we just sold our last [L].";
		now order-completed is true;
		stop the action.

Carry out ordering:
	let L be the multiple object list;
	if L is empty, add the noun to L;
	say "OK, so that would be [L with indefinite articles].";
	repeat with the item running through L:
		now the player carries the item;
	now order-completed is true.

Thanks guys, very helpful guidance.