Conditionals

So, I have this bit in my game where the player needs to look under something for a clue, but they have to pry the item up with a specific tool.

I am having a great deal of difficulty mastering conditionals. Every time I try to do a conditional with more than one condition it wont work with referencing the first noun and the second noun.

In fact it seems like conditional statements are the hardest thing to get right in Inform 7, I always seem to screw them up.

Heres what I have so far:

[spoiler][code]
understand the command “pry” as something new.

Understand “pry [something] with [something]” as prying it with. Prying it with is an action applying to two things.

instead of prying something with something:
if the noun is the floor begin;
if the floor is secured begin;
if the player is holding the foo begin;
say “You pry the floorboard with the foo, revealing something hidden underneath!”;
now the floor is unsecured;
move the foundthing to the old cabin;
otherwise if the floor is unsecured:
say “It’s already loose.”;
end if;
otherwise if the noun is not the floor:
say “Nothing happens.”;
otherwise if the player is not holding the foo:
say “You don’t have a suitable tool for that.”;
otherwise if the second noun is not the foo:
say “You can’t pry with that.”;
otherwise if the first noun is not the floor:
say “Nothing happens.”;
end if.
[/code][/spoiler]

I’ve always had trouble with conditionals in I7. I don’t know why. Sometimes I write things that I feel look exactly like the documentation and they don’t compile. Why are they so hard?

When using the begin / end notation, you need one end for every begin. (Think of them as open and close parentheses.) It looks as though you’re missing some.

The trick is that there are two different notation formats for conditionals; the tabbed system and the begin/end system. They cannot be mixed in a single code block, although you can have both in different bits of code in the same game. See 11.7: Beginning and end. If you use begin/end, tabs make no difference to conditionals, and are used solely to make things more legible.

The example code typically uses the tabbed system, though I think there are some exceptions. (It would be a nifty feature if you could choose which syntax to display examples in.)

Also, I think you may want to revisit your logic. For one thing, your first condition of if the noun is the floor and your first otherwise condition of if the noun is not the floor covers the entire universe, so there is no “otherwise” that could possibly fire after that.

To simplify things, you might want to consider taking advantage of the fact that Inform process the most specific rule possible. So, you have a default rule of “instead of prying something with something”, which would fire if nothing more specific applies. It would just contain your “nothing happens” message. Then you could have the most specific rule of “instead of prying the floor with the foo”, which would contain your actual prying code (success message, moving things around, etc.). And you could have an intermediate rule of “instead of prying the floor with something”, which would only fire if you were trying to pry the floor with something other than the foo (since there is a more specific rule to cover that case). There you could put your “you don’t have a suitable tool” message.

Doing it this way instead of one giant if statement makes it a lot easier for me to think about and, I think, significantly easier to debug.

-Kevin

One thing that may make it easier to follow one’s own logic is to break up an action into several rules:

Before prying something with something:
	if the player is not carrying the second noun:
		silently try taking the second noun;
		say "(first taking [the second noun])[paragraph break]".
		
Instead of prying the floor with the foo:
	if the floor is secured:
		say "You pry the floorboard with the foo, revealing something hidden underneath!";
		now the floor is unsecured;
		move the foundthing to the old cabin;
	otherwise if the floor is unsecured:
		say "It's already loose."

Instead of prying something with the foo: say "Nothing happens."

Instead of prying something with something: 
	if the player is not holding the foo, say "You don't have a suitable tool for that.";
	otherwise say "You can't pry with that."

EDIT – Oops! Well, what Kevin already said then.

But you gave actual useful examples, so that’s good :slight_smile:

-Kevin

Thanks, guys. After some tweaking (apparently pasted spaces don’t translate to tabs) Felix’s code worked.

Weird tip: if you want to copy code from someone’s post, hit “quote” to the post and copy the code from the text box in which you’d type your reply. This will preserve the tab stops of their code. (This only works if they copy-pasted the code from the IDE with tab stops intact – if they typed the code directly in the window then the tabs will be spaces anyway. But I think most folks copy-paste from the IDE.)

Huh. Good tip. Thanks. I still don’t fully understand conditionals in Inform.

Generally, in constructing a set of rules governing actions, I find it helps to break them into as many free-standing rules as possible. Not only is a rulebook easier to skim to see the order of execution than a large, complex nest of conditionals, but Inform’s automatic sorting of those rules usually does most of the conceptual heavy lifting for you. Felix has taken big steps in this direction, but it’s possible to split these rules further. In addition, putting as much of the conditions as possible into the preamble of every rule helps with the sorting (and with the legibility when debugging or perusing the rulebooks).

I also think, even in a small project, that it’s a good idea to get into the habit of dividing the rules governing every action into the appropriate groups: check/carry out/report for default behavior, and before/instead/after for unique special cases. The two sets of rulebooks have subtly different behavior, and in a large project with many new and altered actions, the clarity of execution in actions can be invaluable.

That aside, in refactoring the initial code code, mattw has left out one behavior from the original: the foo is no longer assumed to be the second noun if it is held.

[spoiler][code]Understand “pry [something] with [something]” as prying it with. Prying it with is an action applying to two things. Understand “pry [something]” as prying it with.

Rule for supplying a missing second noun when prying something with:
if the foo is held, now the second noun is the foo;
otherwise say “You don’t have a suitable tool for that.” instead.

Before prying something with something not carried:
say “(first taking [the second noun])[command clarification break]”;
silently try taking the second noun.

Check prying something with something:
say “Nothing happens.” instead.

Instead of prying the secured floor with the foo:
say “You pry the floorboard with the foo, revealing something hidden underneath!”;
now the floor is unsecured;
move the foundthing to the old cabin;
rule succeeds.

Instead of prying the unsecured floor with something,
say “It’s already loose.”

Instead of prying something with something that is not the foo:
say “You can’t pry with that.”[/code][/spoiler]