3 fixed sizes, and comparing them (Small, Medium, Large)

I see Inform 7 can get quite fancy with specifying volumes etc. inform7.com/learn/man/RB_10_5.html I was fooling around with the concepts there, but I couldn’t quite get what I wanted though. Perhaps it could be numerically based in the back end with terms applied on top (like the weight example, where anything above 10kg is “heavy”) or it could be completely rule based (eg. medium is larger than small, large is larger than medium, etc.) - whatever is easiest, I’m open to suggestions.

Here is what I’m trying to achieve;

Everything has a size. A size can be Small, Medium or Large. But size isn’t a measurement - it means an appropriate size, eg. a normal “medium” human can hold and drink from a normal “medium” cup.

I need to be able to act on relative sizes, but on a per object (or object type) basis. Here’s some examples of some rules:

  • You may not “take” something any size larger than you.
  • You may not “enter” a door any size smaller than you.
  • If you eat a food size larger than you, it always remains (you bite a piece out of it, and you get a description along those lines).
  • If you eat a food size the same size or smaller than you, the item is gone (consumed).

Also (and this would be really cool, but I realise I might be asking a lot here) if the descriptions of things automatically told you their size relative to them eg;

  • If the cup is the same size as you, there is no alteration to the description, Eg. both you and the cup are at the “small” size, it’s simply described as “a cup”.
  • If the cup is 1 size up or down from you, you get the appropriate relative descriptor. Eg. if you are “medium” and the cup is “small”, you see “a small cup”. But if you are “small”, and the cup is “medium” you see “a large cup.”
  • And then when you are 2 sizes apart, the terms “tiny” and “huge” are applied in those cases, eg. if you are “small” and the cup is “large”, you see “a huge cup”. If you are “large” and the cup is “small”, you see “a tiny cup”.

It sounds like what you want to do would be a lot easier to do by defining small, medium, and large as a kind of value, and writing a bunch of rules for that. So something like:

[code]Size is a kind of value. The sizes are small, medium, and large.
A thing has a size. The size of a thing is usually medium.

To decide whether (X - a thing) is larger than (Y - a thing):
if X is large and Y is not large, yes;
if X is medium and Y is small, yes;
no.

To decide whether (X - a thing) is smaller than (Y - a thing):
if X is small and Y is not small, yes;
if X is medium and Y is large, yes;
no.

Definition: A thing is oversized if it is larger than the player.
Definition: A thing is undersized if it is smaller than the player.

Check taking an oversized thing: say “That’s too large for you to handle.” instead.
Check entering an undersized door: say “You can’t fit through that.” instead.

To say size-text of (item - a thing):
if the player is small:
if the item is medium, say "large ";
if the item is large, say "huge ";
if the player is medium:
if the item is small, say "small ";
if the item is large, say "large ";
if the player is large:
if the item is small, say "tiny ";
if the item is medium, say "small ".

Before printing the name of a thing (called item): say “[size-text of item]”.

Hall is a room. A rock is in the Hall. It is large. A cup is in the Hall. It is small.
Cave is a room.
The stone door is a large door. It is north of the Hall and south of the cave.
Mouse Warren is a room.
The mouse hole is a small open unopenable door. It is south of the Hall and north of the mouse warren.

Test me with “take rock/take cup/open stone door/enter stone door/enter stone door/enter mouse hole”.[/code]

It might be possible to automate this a little more by exploiting “the size after” and “the size before,” as discussed in §11.18 of Writing with Inform, but if you’ve only got three sizes it’s probably just as easy to specify the combinations by hand.

Also you might want to think about some of the implications here–the way you’ve described it, I could eat up a cake that was exactly my size. So you might want to give some foodstuffs a portion size that was separate from their physical size (which determines takability).

There are a couple of tricks that can make Matt’s example even more concise:

Once you’ve defined your range of sizes, you can make comparisons by testing if “the size of X is greater/less than the size of Y”.

You can also print the name of a size value directly, without having to define a separate say-phrase for it.

[code]Size is a kind of value. The sizes are tiny, small, medium, large, and huge. Everything has a size. The size of a thing is usually medium.

To decide if (X - a thing) is smaller than (Y - a thing):
if the size of X is less than the size of Y, yes;
otherwise no.

To decide if (X - a thing) is larger than (Y - a thing):
if the size of X is greater than the size of Y, yes;
otherwise no.

Before printing the name of a thing (called the item):
say "[size of the item] ".[/code]

Oh, well that trick is even simpler than what I thought it would be! Yes, this is definitely a good idea even with three sizes.

Yes, but I thought the desired behavior was that it should print something based on the size of the object relative to the player–so if the player is small and the table is medium, it will be described as a “large table.”

Another thing that occurred to me is that if you are printing “large table,” the player will want to be able to refer to the table as “large table.” Here again I couldn’t think of anything better to do than to brute-force a bunch of conditional Understand statements:

Understand "large" as a thing when (the item described is large and the player is medium) or (the item described is medium and the player is small). Understand "small" as a thing when (the item described is small and the player is medium) or (the item described is medium and the player is large). Understand "huge" as a thing when the item described is large and the player is small. Understand "tiny" as a thing when the item described is small and the player is large.

I had thought of using “Understand “large” as a thing when the size of the item described is the size after the size of the player,” but the problem is that “size after” wraps around, so this would apply when the player is large and the item is small. (You could actually take care of this by having a couple of never-used sizes before “small” and after “large,” I guess.) It’s straightforward enough to have something understood by a property like “size”, but it’s trickier to have it understood by something that you calculate the way you calculate the size-text.

Anyway, here’s a sample implementation of something with size-changing. The line about Dennett and Chalmers is a joke about The Swapper, for which I apologize. Also note that there are some edge cases; the code for shrinking doesn’t check to see whether any of the things you’re holding get to be oversized.

[spoiler][code]Use the serial comma.

Size is a kind of value. The sizes are small, medium, and large.
A thing has a size. The size of a thing is usually medium.

To decide if (X - a thing) is smaller than (Y - a thing):
if the size of X is less than the size of Y, yes;
otherwise no.

To decide if (X - a thing) is larger than (Y - a thing):
if the size of X is greater than the size of Y, yes;
otherwise no.

Definition: A thing is oversized if it is larger than the player.
Definition: A thing is undersized if it is smaller than the player.

Check taking an oversized thing: say “That’s too large for you to handle.” instead.
Check entering an undersized door: say “You can’t fit through that.” instead.

To say size-text of (item - a thing):
if the player is small:
if the item is medium, say "large ";
if the item is large, say "huge ";
if the player is medium:
if the item is small, say "small ";
if the item is large, say "large ";
if the player is large:
if the item is small, say "tiny ";
if the item is medium, say "small ".

Understand “large” as a thing when (the item described is large and the player is medium) or (the item described is medium and the player is small).
Understand “small” as a thing when (the item described is small and the player is medium) or (the item described is medium and the player is large).
Understand “huge” as a thing when the item described is large and the player is small.
Understand “tiny” as a thing when the item described is small and the player is large.

Before printing the name of a thing (called item): say “[size-text of item]”.

Hall is a room. A rock is in the Hall. It is large. A cup is in the Hall. It is small.
Cave is a room. “This looks like a place where [a rock] would be happy.”
The stone door is a large door. It is north of the Hall and south of the cave.
Mouse Warren is a room.
The mouse hole is a small open unopenable door. It is south of the Hall and north of the mouse warren.

The drink-me is a small thing in the Hall.
A cake is a kind of thing. A cake is always small and edible. Two cakes are in the mouse warren.

Check drinking the drink-me when the player is small:
say “You’re already small enough as it is. You don’t want to vanish away.” instead.

Instead of drinking the drink-me:
say “You suddenly shrink!”;
now the size of the player is the size before the size of the player;
now the drink-me is nowhere.

Check eating a cake when the player is large:
say “You’re already large enough as it is. You don’t want to burst the roof off.” instead.

Instead of eating a cake (called gateau):
say “You suddenly grow!”;
now the size of the player is the size after the size of the player;
now the gateau is nowhere.

After dropping the rock when the location is the Cave:
say “The [rock] sighs with contentment. Dennett and Chalmers bicker over whether this was a good idea.”;
end the story finally saying “You have won”.

Test me with “take large rock/take small cup/open stone door/enter stone door/enter stone door/enter mouse hole/drink drink-me/look/enter mouse hole/take small cakes/take cakes/enter mouse hole/eat cake/look/eat cake/look/take rock/enter stone door/drop rock”.[/code][/spoiler]

Ah, I see. Your example makes sense, then.

If you’re willing to use a very small I6 hack:

To decide what number is (X - a size) minus (Y - a size): (- (({X}) - ({Y})) -). To describe (Y - a size) from the viewpoint of (X - a size): if X minus Y is: -- -2: say "tiny"; -- -1: say "small"; -- 0: say "regular-size"; -- 1: say "large"; -- 2: say "huge".

Wow, thanks guys. I thought for sure I was asking more than someone would have time to illustrate fully, but you guys have come up with 100% complete solutions, complete with working example, thanks @matt w… I keep seeing your name a lot here. You seem to really know this thing inside out. I’m going to use your final example. And thanks @mikegentry for the more succinct version of size comparison, that matt incorporated.

I just want to say, I love reading well formed Inform code. I’m a programmer by trade, and there’s something cathartic about reading good Inform code, it’s like reading about someone telling me about how the program should work, than reading actual code. I really love it. That’s why I’m making Inform games at night to help me wind down. In fact I fell asleep before I got to implement your solution fully, heheh. I’m going to try it tonight.

Actually do you know what - I DID have that described when I was originally writing the post. But then I thought for sure, after asking for the “relative size description” thing, I was asking for WAY too much and I could probably work that part out myself :slight_smile: Really what I needed is how to act on size. Once I know it’s the same “size” as you, I can have each food item last 3 bites or something (changes per food). But thinking on it again, I could just not have anything in the game world that couldn’t realistically be eaten as one serving, which might just work out given the context of the game.