At my wits' end.

I am using Inform 7 to develop my game.

In my game, there is a puzzle where you are essentially trying to arrange some large objects next to an engine that moves water(where I do not intend for the water to be an object accessible by the player, only alluded to)–this was inspired by thoughts of the game ‘Mousetrap’ that I used to play when I was a kid. My problem is that I cannot seem to devise a routine that allows the player to move the objects freely with reference to the engine. I want the player to be able to move an object away from the engine, or from the other objects. I have tried using Table formats, I have tried value and string variables. Initially, I made the engine itself moveable, but then I decided that there were more permutations to that than I wanted to deal with, so I decided to make it stationary so that I would only have to account for six possible permutations(of three objects–if they are all connected). I really wanted to use a Table, where each row represents a placement next to the engine–placement 1 would be right next to the engine, 2 the next spot, 3 the next. Initially, the Table would be empty in each row, with each object placed in the room, but not at the engine–originally, since my Table entries are objects, I simply put the word ‘nothing’(as opposed to “nothing” as a textual value) in that column–then I tried using blanks(–), with the word ‘a thing’ in the top row. I even tried using string variables in a Table, where the entries were the textual names of the objects. I cannot seem to get this to work. Here is specifically what I want to do–

The engine, the thing that sets the whole thing going, moves water. It is stationary and collects the water from a trough filled by a spigot in the wall. There are three moveable objects in the room, though they are scenery and you can’t pick them up, you can push them(at least conceptually) to the engine. If arranged in the correct way, the intended result, of course, is a success(and the discovery or recovery of a certain item). I want the player to be able to arrange the objects in any way with respect to each other, and then be able to re-arrange them(before setting the thing in motion, of course) if the player so desires. For instance, if the item is not in place, it’s not on the table. But if it is pushed to the engine, it is in placement 1(which really is the only placement available to it, otherwise I would have the program say “You see no practical purpose to that.”). Then the next item, if the player tries to push it to the engine, I want the program to say “The [item(or whatever moniker I give to this column) entry in row 1 of Table 2] is already there.”(Inform returns a problem message with this line, and I don’t understand why I can’t say it). If the player pushes the next item to the item that is already there, then this second item is supposed to go into the second row, in position 2, etc. I want the player to be able to push any item out of configuration, and still have the other item(s) remain where they were pushed. I created a verb ‘heaving it to’(Understand “push [something] to [something]” as heaving it to), to refer to the action(of course the player does not have to type Heave, only ‘push’)–this was a solution to an earlier problem, because I did not want the objects moved between rooms, just this one room.
Simply put, is there something about Tables that I don’t understand or did not get? Or am I attempting something impossible? Can objects not be included in, or added to or removed from Tables?
I even tried making a Table where the objects were in the first column, their placements would be indicated in the other column, where a 0 would indicate that the object is not in the configuration(as it is initially or after being pushed out of it). For some reason I cannot get the program to refer to specific entries in the table.
I was having such a good time programming along until I hit this snag.
Some help would be appreciated.

From a player’s perspective, it will probably be cleaner to have multiple rooms and push the objects between them. I find it much easier to visualize positions between rooms than within them. Alternately, if you had an excuse to do this story-wise, you could make three supporters (perhaps there are three pedestals in the room?) each with a carrying capacity of 1.

There’s a subtle thing about the syntax here–when you’re referring directly to the row number you shouldn’t say “entry.” So here you want to say “[The item in row 1 of Table 2] is already there,” without the word “entry.” If you look carefully at Writing with Inform §16.2 it says “[element in row N of the Table of Selected Elements]” without the word “entry.”

When you need to use “entry” is in the perhaps more common case when you’ve chosen a row. So you could say

choose row N of the Table of Selected Elements; say "[The item entry] is already there."

(Also I’ve put “The” inside the brackets, because Inform can automatically handle the definite article when you do that.)

This also happens when you’ve used an “…is listed in” construction; then it chooses the row automatically, so you can use “the whatever entry”:

if K is an atomic weight listed in the Table of Selected Elements: say "The element with atomic weight of [K] is [element entry]."

Here’s a little implementation that shows off both “the item in row N…” and “choose row N” followed by “item entry”:

[code]Lab is a room. A rock, a stone, and a pebble are in Lab.

Table of Placements
item (a thing)
with 3 blank rows

Positioning it in is an action applying to one thing and one number. Understand “put [something] in --/slot/position/place [number]” as positioning it in.

Check positioning it in when the number understood is less than 1 or the number understood is greater than 3:
say “The only available positions are 1, 2, and 3.” instead.

Check positioning something (called the adjustee) in a number (called n):
if there is an item in row n of the Table of Placements:
say “[The item in row n of the Table of Placements] is already in position [n].” instead. [note that this produces an appropriate message whether or not the thing that’s there is the thing you’re trying to position!]

Carry out positioning something (called the adjustee) in a number (called n):
now the item in row n of the Table of Placements is the adjustee.

Report positioning:
say “You put [the noun] in position [the number understood].”

Carry out taking:
if the noun is an item listed in the Table of Placements:
blank out the whole row.

For writing a paragraph about a thing (called the placed item) when the placed item is an item listed in the Table of Placements: [this happens when looking]
repeat with n running from 1 to 3:
choose row n in the Table of Placements;
if there is an item entry:
say “[The item entry] is in position [n].” [The thing about this is that everything whose name is mentioned in a “writing a paragraph” rule gets omitted from the You can also see line, so this wraps up everything that’s in a position][/code]

I have to say I don’t really understand what you’re saying about pushing it to the engine, though. If I’ve already pushed one thing to the engine, so it’s in position 1, shouldn’t the next thing I push to the engine wind up in position 2? How do I get something into position 2 if heaving something fails whenever position 1 is occupied? You’ll have to be very carefully about describing this so the player can visualize it, and communicating how the player is to interact with it. Here Draconis’s idea of making three supporters (maybe three slots in the floor?) is very good; that will not only save you a lot of programming headache, it’ll make it clear to the player that their job is to put things in those slots.

(For the record I disagree with him about the rooms; for me it would be much easier to deal with this puzzle if the objects are all in the same room and I could survey them at once, as long as the description of where they are within the room is clear.)

Thank you so much Matt–I think you pretty much got the gist of what I was getting at. I really appreciate the example you posted–it’s pretty much exactly what I wanted.

Each of my objects in the situation is a supporter, but scenery. I want the player to try to climb or enter each one–unsuccessfully–with the exception of one, which will propel him/her to another location. Of course, none of these actually ‘moves’, just as nothing in IF actually ‘moves’. And yes I think it was the syntax that I was having trouble with, particularly the use of the word ‘entry’, using it seemed to cause a problem in some areas, not using it in others also did. I think you clarified that.

It is kind of a complicated puzzle, because there are about six different possible permutations of the gadgets, and when ‘run’ they will of course produce different results, with only one being ‘correct’. Of course, I am going to handle the positioning first, then the ‘results’ of ‘runs’(when the water is turned on, setting the thing in motion–I also intend to work in some method of ‘timing’), then finally the ‘successful’ result.

Thank you again.

Draconis did kind of give me an idea–I might create a room for each of the three gadgets, with the ‘engine’ room in the center. The place is supposed to be a ‘vacant’ building that is being remodeled to become a science museum. The central room is the auditorium, where only part of it is revealed by your lantern light at any time, so creating other ‘rooms’ as parts of the auditorium would make sense.

Thank you both!

Matt–about the positioning–only one of the items will respond ‘positively’ when ‘pushed to’ the engine. I want the next item to be ‘pushed to’ the first item, then the third ‘to’ the second. This would show that the player has a sense of how the objects should ‘fit’ together to obtain a result that would cause the player to be propelled by the resulting machine.

I am really enjoying my game-creating experience and appreciate the help.

now the solution is implemented;
now the man called IFaddicted is enlightened;
say “IFaddicted says, ‘Phew! I was getting rather frustrated there!’”

I think I get tables, now. But one question–how many conditions are allowed under an otherwise: statement??

Here is part of my code:

Table 2 - Watcha Placements[the ‘watchas’ are the three large objects that I am moving]
Witem(a thing)[the moniker for the watchas solely when they are in this table]
with 3 blank rows

Instead of heaving something to the screw-engine:[I created ‘heaving it to’ to differentiate it from ‘push’ because ‘push it to’ was already defined–but I have the program understand "push [something] to [something]’ as heaving it to]
if the noun is not a watcha, say “This is not the time to be auditioning for mobster movies.”;[pushing anything to the engine other than a watcha will generate that response]
otherwise:
if there is a witem in row 1 of table 2:
say “But the [witem in row 1 of table 2] is already there.”;
otherwise:
if the noun is:
–the see-saw:
say “You lug the see-saw over to the screw-engine, with the upper end under the top end of the machine. You admire the flawlessness of your logic.”;
–the tall scaffolding:
say “You heave the scaffolding, carefully so as not to disturb the items up top, over to the screw-engine, until the large bucket is just under the tops of the pipes. Now THIS is ART!”;
–the bathtub:[generates a problem message, even though the bathtub is a watcha like the other two]
say “You turn the crank and the tub swings over to the screw-engine. When the bathtub almost knocks against the pipes, you stop before it gets closer. You shake your head in doubt.”;
now the witem in row 1 of table 2 is the noun;
repeat with n running from 1 to 3:
choose row n in table 2;
if there is a witem entry:
say “The [witem entry] is pulled up next to the screw-engine.”
Instead of pushing a watcha:
if the noun is a witem listed in table 2:
say “You push [the noun] from its new perch. C[’]est la vie!”;
blank out the whole row;
otherwise:
say “You do so without purpose. (Why not try PUSHing it TO something…?)”

I included a little routine to report that the watcha has been placed in the table, but the program, for some reason, will generate a problem message for the bathtub. Originally, I typed that entry out completely–if the noun is the bathtub, say…(along with the other two entries typed out this way) and there was no problem message, but when I tested it, it did not print out the report for the bathtub, only saying that the bathtub was pushed up to the engine. When I amended the code to – form(as above), it gave me a problem message, saying that the statement wasn’t indented correctly…?? I only meant it to be a clause like the other two. Is there a rule limiting the number of statements under an ‘otherwise:’…??

try IFaddicted thanking anyone helpful

It would help a lot if you’d put code tags around your code so that the indentation is preserved, particularly for this question.

Use the “Code” button at the top of the text entry area when composing a post, or just type code and /code inside square brackets to start and end your code, like this:

[code]
My code goes here.
[/code]

I’ve had some trouble with clauses in I7 switch statements that start with conditionals, where I’ve had to do some funky indentation to satisfy the compiler.

Here’s a modified example from a WIP:

	if turns active of NPC is:
		-- 1: say "Something.";
		-- 2: say "Something else.";
		-- 3:
		if the player encloses the foo:
				now the foo is in Some Room;
				say "Yet another thing.";
			otherwise:
				say "Even more.";
		-- 4: say "The last thing.";

I think your code would benefit from some early exits via “instead say” to reduce the number of conditionals.

Instead of heaving something to the screw-engine:
	if the noun is not a watcha, instead say "This is not the time to be auditioning for mobster movies.";
	if there is a witem in row 1 of table 2, instead say "But the [witem in row 1 of table 2] is already there.";
	if the noun is:
		-- the see-saw: say "You lug the see-saw over to the screw-engine, with the upper end under the top end of the machine. You admire the flawlessness of your logic.";
		-- the tall scaffolding: say "You heave the scaffolding, carefully so as not to disturb the items up top, over to the screw-engine, until the large bucket is just under the tops of the pipes. Now THIS is ART!";
		-- the bathtub: say "You turn the crank and the tub swings over to the screw-engine. When the bathtub almost knocks against the pipes, you stop before it gets closer. You shake your head in doubt.";
	now the witem in row 1 of table 2 is the noun;
	repeat through table 2:
		if there is a witem entry, say "The [witem entry] is pulled up next to the screw-engine."
					
Instead of pushing a watcha:
	if the noun is a witem listed in table 2:
		say "You push [the noun] from its new perch. C[']est la vie!";
		blank out the whole row;
	otherwise:
		say "You do so without purpose. (Why not try PUSHing it TO something...?)".

Even better, you could split your rules into multiple smaller rules with context (i.e., “instead of doing X when Y”). If the first sentence of your rule body is a conditional, it’s a tipoff to consider this.

Instead of heaving something to the screw-engine, say "This is not the time to be auditioning for mobster movies."

Instead of heaving a watcha to the screw-engine when there is a witem in row 1 of table 2, say "But the [witem in row 1 of table 2] is already there."
	
Instead of heaving a watcha to the screw-engine:
	if the noun is:
		-- the see-saw: say "You lug the see-saw over to the screw-engine, with the upper end under the top end of the machine. You admire the flawlessness of your logic.";
		-- the tall scaffolding: say "You heave the scaffolding, carefully so as not to disturb the items up top, over to the screw-engine, until the large bucket is just under the tops of the pipes. Now THIS is ART!";
		-- the bathtub: say "You turn the crank and the tub swings over to the screw-engine. When the bathtub almost knocks against the pipes, you stop before it gets closer. You shake your head in doubt.";
		-- otherwise: say "*** BUG: unknown watcha: [noun] ***";
	now the witem in row 1 of table 2 is the noun;
	repeat through table 2:
		if there is a witem entry, say "The [witem entry] is pulled up next to the screw-engine."

Instead of pushing a watcha when the noun is a witem listed in table 2:
	say "You push [the noun] from its new perch. C[']est la vie!";
	blank out the whole row.
	
Instead of pushing a watcha, say "You do so without purpose. (Why not try PUSHing it TO something...?)".

Here’s a further refinement that implements the heaving of watchas using the check-carry out-report mechanism. The switch statement full of action reports is a bit of a code smell, and the instead rules make it difficult to work around it since diverting an action with an instead rule treats the action as a failure and the action doesn’t proceed to the after or report stages.

Check heaving something to something when the noun is not a watcha or the second noun is not the screw-engine:
	instead say "This is not the time to be auditioning for mobster movies."
	
Check heaving a watcha to the screw-engine when there is a witem in row 1 of table 2:
	instead say "But the [witem in row 1 of table 2] is already there."
	
Carry out heaving a watcha to the screw-engine:
	now the witem in row 1 of table 2 is the noun.
	
Report heaving the see-saw to the screw-engine:
	say "You lug the see-saw over to the screw-engine, with the upper end under the top end of the machine. You admire the flawlessness of your logic."
	
Report heaving the tall scaffolding to the screw-engine:
	say "You heave the scaffolding, carefully so as not to disturb the items up top, over to the screw-engine, until the large bucket is just under the tops of the pipes. Now THIS is ART!"
	
Report heaving the bathtub to the screw-engine:
	say "You turn the crank and the tub swings over to the screw-engine. When the bathtub almost knocks against the pipes, you stop before it gets closer. You shake your head in doubt."

Report heaving a watcha to the screw-engine (this is the witem status report rule):
	repeat through table 2:
		if there is a witem entry, say "The [witem entry] is pulled up next to the screw-engine."
			
The witem status report rule is listed last in the report heaving it to rules.

Vince,

Thanks a lot for your tips.

I tried the Check-Carry Out-Report format–as Matt suggested–but for some reason it would not report anything at all(and did not even carry out anything), perhaps because I had put an instead rule before it which I have since eliminated. I then tried the instead rules which I posted, of course with the caveat that the ‘heaving’ would result as a failure.

I think the real problem is that I am so ‘itching’ to create this game that I have not yet really absorbed the manual–I have read it through once, but there is so much material there, I feel a little overwhelmed. But I think I have come a long way, though I foresee going over the whole game (I am up to over 15000 words) and making the code more concise as you suggest with this part of it.

Thanks

No problem with not trying to absorb the manual before starting your game–lots of people learn best by doing, so your best way of learning may be to work on your project and pick up parts of the manual as you go. In fact I’d say it’s probably not possible to absorb the whole manual without doing a fair bit of programming along the way.

Just a tiny note–I don’t think you need the brackets in “C[’]est la vie.” Inform corrects apostrophes to quotation marks at the ends of words but not in the middle. So you need the brackets in “[’]Tis the season.” but not

Also (more substantively) as you’ve realized, “Instead” rules short-circuit the check-carry out-report rules unless you specifically state “continue the action” in the rule. More subtly, if you write an “After” rule it will short-circuit the “Report” rules unless you add “continue the action.” (The beginning of the chapter on Rulebooks in the documentation is actually pretty useful here, if you have the time to check it out.)

Thanks again, Matt

I would guess that probably a good practice is to use ‘instead’ rules in isolation or within a ‘check’ rule, and make sure that check-carry out-report rules are clear of any ‘instead’ rule.

I discovered the reason it did not report the bathtub, but reported the other two ‘watchas’. It was because there was another bathtub(the player’s own) in a much earlier part of the game, and I did not type the full name of the thing(the cast iron bathtub) in the report rule. As my own tub was not a watcha it was not pushed to the engine, and therefore it was not reported, but it did say that the cast iron tub was in the table(because the check rule and carry out rule covered it–as a ‘watcha’), therefore I could not push another thing there. I did not have a report rule for the cast iron bathtub as such, only for ‘bathtub’(my own). As with a child, you have to be careful what you say to a computer, eh?