Struggling with Inform 7 (Newbie here)

I love interactive fiction. I’ve been playing it since the early days of Scott Adams games on the VIC-20. I’ve written a few games back in the day in BASIC, mostly for my own amusement.

I’ve tried my hand at a few different versions of Inform, and never quite “gotten it”. However I really like Inform 7. I really like the ease of the language for describing rooms and basic rules, however what I am wanting to do is beyond my programming knowledge and I’m looking for help.

Imagine a grid of “rooms” say 10 X 10 or even bigger set in a forest with very similar descriptions . One of which randomly has a “treasure” placed in it when game play begins. (None of this is the problem)

What I need to figure out is a compass like device, (actually a GPS with a compass setting) that points to the direction of the “treasure room” each time game play starts regardless of any road blocks in the way. I have no idea how to do this in Inform.

In other words, if the "treasure’ is located to the north of the starting location, I want the GPS to point to the north, even if the player has to go west, west, north, east, east, north to get there.

Like I said, I can create the rooms and place the “treasure” randomly without any issue. I just can’t figure out how to program the GPS itself.

Any help or links to similar code snippets would be greatly appreciated!

Well, this is how I would do something like that (conceptually) …

Give each room an “x coordinate” and a “y coordinate” (eg. the south-westernmost room could have x = 0 and y = 0; the room to its north would have x = 0 and y = 1).

To work out which direction room 2 is from room 1, find the differences in the x and y values (room 2’s values minus room 1’s values). For example, if room 1 has x = 5 an y = 3, and room 2 has x = 5 and y = 1, the x difference is 0 and the y difference is -2.

The GPS direction depends on the x and y difference. For example, if the x difference is 0 and the y difference is > 0, the direction is north; if the y difference is < 0, the direction is south. If the y difference between the rooms is 0, the direction is east or west if the x difference is positive or negative, respectively.

It is trickier if neither the x or y difference equals 0, since the rooms are then not in a straight line with each other (north/south or east/west). It depends whether you want to include NE, NW, SE and SW in your GPS directions. If you don’t, and just want to stick to N/S/E/W for the GPS, then work out which one has the smallest absolute (non-negative) value and treat it as “0”.

[Edit: I have posted some Inform 7 code to do this (including NE, etc.) later in this thread].

Give every room two properties, an “x coordinate” and a “y coordinate”.

Method 1: Define the x coordinate and y coordinate directly for each room.

Method 2: Make the x coordinates all -100 by default. (Just a value to indicate that a room isn’t set yet.) Manually set the x and y coordinates of 1 room. Write a loop that keeps looping over all the rooms. If a room has x coordinate of -100 and some adjacent room has an x coordinate not -100, set the x & y coordinates appropriately. (Optionally, whenever you set coordinates, check that all adjacent rooms, if set, have appropriate locations and print a warning if not.)

Method 3: Similar to #2, but write a recursive function that sets all adjacent rooms instead of a loop, and call that function instead of manually setting one room.

Let me know if you need any more explanation on any of these.

I had a go at doing this in Inform 7 … here is the code, with some debugging left in (the x and y coordinates of the player and the treasure are printed along with the location). Using ralphmerridew’s suggestion for setting up the x and y values initially would save time, too.


Forestpart is a kind of room.
A forestpart has a number called xpos.
A forestpart has a number called ypos.
The printed name of a forestpart is "Forest (at [xpos of location] [ypos of location]) (treasure [xpos of location of treasure] [ypos of location of treasure])".
The description of a forestpart is "You are in a forest of twisty trees, all alike.
Your GPS is [GPS direction to treasure]."

The player carries a GPS.
The inventory listing of the GPS is "A GPS ([GPS direction to treasure])".
The description of the GPS is "The GPS is [GPS direction to treasure]."

The player is in forest0_0.
forest3_3 contains a treasure.

To say GPS direction to (t - a thing):
	let tr_loc be the location of t;
	let dx be xpos of tr_loc minus xpos of location;
	let dy be ypos of tr_loc minus ypos of location;
	if dx is 0 and dy is 0
	begin;
		say "spinning in circles";
	otherwise;
		say "pointing ";
		let abs_dx be dx;
		if abs_dx is less than 0, change abs_dx to 0 minus abs_dx;
		let abs_dy be dy;
		if abs_dy is less than 0, change abs_dy to 0 minus abs_dy;
		if abs_dx is less than abs_dy
		begin;
			if abs_dx <= abs_dy divided by 2, change dx to 0;
		otherwise;
			if abs_dy <= abs_dx divided by 2, change dy to 0;
		end if;
		if dx is 0
		begin;
			if dy is greater than 0, say "north";
			otherwise say "south";
		otherwise;
			if dy is 0
			begin;
				if dx is greater than 0, say "east";
				otherwise say "west";
			otherwise;
				if dx is greater than 0
				begin;
					if dy is greater than 0, say "northeast";
					otherwise say "southeast";
				otherwise;
					if dy is greater than 0, say "northwest";
					otherwise say "southwest";
				end if;
			end if;
		end if;
	end if.

forest0_0 is a forestpart. The xpos of forest0_0 is 0. The ypos of forest0_0 is 0.
forest0_1 is a forestpart. The xpos of forest0_1 is 0. The ypos of forest0_1 is 1.
[...]

forest0_1 is north of forest0_0.
forest0_2 is north of forest0_1.
[...]

forest1_0 is east of forest0_0.
forest2_0 is east of forest1_0.
[...]

Thanks for the quick replies! I won’t have any time to work on the game tonight, but I am anxious to try out all the suggestions.

Seeing the actual code helped out a lot! I’m certain that with very little tweaking it will do exactly what I was looking for.

Thanks again! :mrgreen:

Please keep in mind, that I said I was new to Inform 7, but I’m having issues getting the code posted above to work for me. :frowning:

Looking at it, I thought it was complete enough to compile and play around with, but no such luck.

While I am well versed in Inform complaining about every line of code I try to write, normally it just won’t compile when I have something incorrect. In this case the code compiles without issue, but ends up giving me something I have not encountered before, a runtime error :exclamation:

I hate to be a pest, but can someone shed some light on what’s going on here?

The parts of code that say “[ … ]” were left out to save space.

I’ll send you a private message with the complete code, to save cluttering the thread …

David Fisher

Here’s an implementation of David’s GPS compass, without resorting to x and y coordinates in the kind. Instead, this uses the built-in best route mechanism to find the direction the treasure is in from where the player is.

[code]To say GPS direction to (t - a thing):
let tr_loc be the location of t;
let the total distance be the number of moves from the location to tr_loc, using even locked doors;
let count of ns moves be 0;
let count of ew moves be 0;
let next place be the location;
repeat with counter running from 1 to the total distance
begin;
let the way be the best route from the next place to tr_loc, using even locked doors;
if the way is north, let count of ns moves be the count of ns moves plus 1;
if the way is east, let count of ew moves be the count of ew moves plus 1;
if the way is south, let count of ns moves be the count of ns moves minus 1;
if the way is west, let count of ew moves be the count of ew moves minus 1;
if the way is northeast
begin;
let count of ns moves be the count of ns moves plus 1;
let count of ew moves be the count of ew moves plus 1;
end if;
if the way is southeast
begin;
let count of ns moves be the count of ns moves minus 1;
let count of ew moves be the count of ew moves plus 1;
end if;
if the way is southwest
begin;
let count of ns moves be the count of ns moves minus 1;
let count of ew moves be the count of ew moves minus 1;
end if;
if the way is northwest
begin;
let count of ns moves be the count of ns moves plus 1;
let count of ew moves be the count of ew moves minus 1;
end if;
let next place be the room the way from next place;
end repeat;
if count of ns moves is 0 and count of ew moves is 0
begin;
say “spinning in circles”;
otherwise;
say "pointing ";
let absolute count of ns moves be the count of ns moves;
let absolute count of ew moves be the count of ew moves;
if absolute count of ns moves is less than 0, let absolute count of ns moves be 0 minus absolute count of ns moves;
if absolute count of ew moves is less than 0, let absolute count of ew moves be 0 minus absolute count of ew moves;
if absolute count of ns moves is less than absolute count of ew moves
begin;
if absolute count of ns moves is at most the absolute count of ew moves divided by 2, let count of ns moves be 0;
otherwise;
if absolute count of ew moves is at most the absolute count of ns moves divided by 2, let count of ew moves be 0;
end if;
if count of ew moves is 0
begin;
if count of ns moves is greater than 0, say “north”;
otherwise say “south”;
otherwise;
if count of ns moves is 0
begin;
if count of ew moves is greater than 0, say “east”;
otherwise say “west”;
otherwise;
if count of ew moves is greater than 0
begin;
if count of ns moves is greater than 0, say “northeast”;
otherwise say “southeast”;
otherwise;
if count of ns moves is greater than 0, say “northwest”;
otherwise say “southwest”;
end if;
end if;
end if;
end if.

Forestpart is a kind of room. The printed name of a forestpart is “Somewhere in a Forest”. The description of a forestpart is “You are in a forest of twisty trees, all alike. Your GPS is [GPS direction to treasure].”

The player carries a GPS. The inventory listing of the GPS is “A GPS ([GPS direction to treasure])”. The description of the GPS is “The GPS is [GPS direction to treasure].”

Forest_01 is a forestpart. Forest_02 is a forestpart. Forest_03 is a forestpart. Forest_04 is a forestpart. Forest_05 is a forestpart. Forest_06 is a forestpart. Forest_07 is a forestpart. Forest_08 is a forestpart. Forest_09 is a forestpart. Forest_10 is a forestpart. Forest_11 is a forestpart. Forest_12 is a forestpart. Forest_13 is a forestpart. Forest_14 is a forestpart. Forest_15 is a forestpart. Forest_16 is a forestpart. Forest_17 is a forestpart. Forest_18 is a forestpart. Forest_19 is a forestpart. Forest_20 is a forestpart. Forest_21 is a forestpart. Forest_22 is a forestpart. Forest_23 is a forestpart. Forest_24 is a forestpart. Forest_25 is a forestpart.

The player is in Forest_11. A treasure is in Forest_04.

Forest_06 is north of Forest_11. Forest_01 is north of Forest_06. Forest_02 is east of Forest_01. Forest_07 is south of Forest_02. Forest_08 is east of Forest_07. Forest_13 is south of Forest_08. Forest_12 is west of Forest_13. Forest_17 is south of Forest_12. Forest_16 is west of Forest_17. Forest_21 is south of Forest_16. Forest_22 is east of Forest_21. Forest_23 is east of Forest_22. Forest_24 is east of Forest_23. Forest_19 is north of Forest_24. Forest_20 is east of Forest_19. Forest_15 is north of Forest_20. Forest_10 is north of Forest_15. Forest_05 is north of Forest_10. Forest_04 is west of Forest_05.

Forest_03 is north of Forest_08. Forest_09 is east of Forest_08. Forest_14 is south of Forest_09. Forest_18 is south of Forest_13. Forest_25 is east of Forest_24.

Index map with Forest_02 mapped east of Forest_01. Index map with Forest_03 mapped east of Forest_02. Index map with Forest_04 mapped east of Forest_03. Index map with Forest_05 mapped east of Forest_04.

Index map with Forest_06 mapped south of Forest_01. Index map with Forest_07 mapped south of Forest_02. Index map with Forest_08 mapped south of Forest_03. Index map with Forest_09 mapped south of Forest_04. Index map with Forest_10 mapped south of Forest_05.

Index map with Forest_11 mapped south of Forest_06. Index map with Forest_12 mapped south of Forest_07. Index map with Forest_13 mapped south of Forest_08. Index map with Forest_14 mapped south of Forest_09. Index map with Forest_15 mapped south of Forest_10.

Index map with Forest_16 mapped south of Forest_11. Index map with Forest_17 mapped south of Forest_12. Index map with Forest_18 mapped south of Forest_13. Index map with Forest_19 mapped south of Forest_14. Index map with Forest_20 mapped south of Forest_15.

Index map with Forest_21 mapped south of Forest_16. Index map with Forest_22 mapped south of Forest_17. Index map with Forest_23 mapped south of Forest_18. Index map with Forest_24 mapped south of Forest_19. Index map with Forest_25 mapped south of Forest_20.

The Start Room is a region. Forest_11 is in the Start Room.
The Treasure Room is a region. Forest_04 is in the Treasure Room.[/code]

Thanks guys! I completely missed “best route” in the documentation.