What not to wear

I didn’t catch on that you needed that. But do you? Is it even possible to have someone other than the player asking someone else to try doing something?

This is an area of Inform I have a lot of trouble with. I wonder if going back to Ron Newcomb’s book would help. In the meantime, have a gander at the error message for this code:

To decide what description of objects is the conflicting items: Decide on the list of garments that are worn by the person asked.

So we have three different types: A list of things of some kind, an instruction to work out a list of things of some kind, and a description of objects. Can anyone explain the difference?

I’d call it a bug in the compiler. It isn’t mysterious that you can “say” the list, because that is an immediate use of the temporary values involved (no attempt to store it). But you should certainly be able to define a temporary variable that makes use of a temporary variable with the same (or, as in this case, broader) scope.

–Erik

It comes from the original what not to wear example, and I’m not sure it’s strictly necessary any more. The way the example has it body-part and garment are both garment-elements, but garments are wearable where body-parts aren’t.

The implementation I’m playing with at the moment doesn’t actually need the body-parts at all (and I haven’t defined any) because I can just work with the body-area value instead. However, that won’t let you, for example, examine somebody’s head.

“Worn garments” and “garments worn by the player” are descriptions. Descriptions are a core I7 feature, but they are not values, and you can’t store them in variables. That’s because a description is a bit of code that can be used in various ways; it may describe different objects every time it is evaluated.

let D be the number of worn garments;
now all worn garments are smelly;
repeat with T running through worn garments: ...

A list is a value; it’s a data structure containing some things. Its contents are set when you build the thing, and then don’t change unless you explicitly change the list. (This is a mutable array in the usual programming language sense.) (The confusion here comes from the fact that lists were added to I7 only recently. Descriptions have been in since the beginning.)

You can build a list from a description:

let L be the list of worn garments;

That evaluates the description and sets L to its contents at that moment.

(You could also make a description based on a list, but it’s awkward and requires some ancilliary relation verbs.)

Further confusion: there’s a standard “say” phrase in the library defined this way:

To say a list of (OS - description of objects): ...

So when you say “I see [a list of worn garments],” you’re not creating a list at all. (Again, this dates from the days before I7 had a list type.) If you define L as above, and then say “I see [L],” you’re actually invoking different code.

…and this is why the code “let L be the list of things worn by the actor” should be allowed by the compiler. There is no need for the compiler to store the actor; all it needs to do is evaluate the description and save the list of things to L.

I succumbed to this confusion in my post above.

–Erik

Right, the “descriptions used as values are not allowed to contain references to temporary variables” problem. I have no good answer for that. In theory, I agree with you. In theory, I also see why it’s hard for the compiler to know which phrases use a description “in place” and which phrases store the description.

There may also be scoping issues. A description based on local variables may not be abstractable as a separate function. (Although “the actor” is not actually a local variable; it’s a rulebook variable, so I6 code can access it…)

Okay, thanks everybody for your help. capmikee’s comment on relationships was a huge help and let me greatly simplify everything. Here’s the code I currently have which seems to work fairly well (so far, I haven’t really tested it with multiple NPC’s yet):

[spoiler][code]
“What not to wear II” by Anonymous

Part 1 - Body areas

Body-area is a kind of value. The body-areas are feet, lower-body, legs, hips, upper-body, full-body, head, none.

[relates with areas include other areas]
Body-includes relates various body-area to various body-areas. The verb to body-include (it body-includes, they body-include, it body-included, it is body-including) implies the body-includes relation. The verb to be body-included by implies the reversed body-includes relation.

full-body body-includes hips, legs and upper-body. lower-body body-includes hips and legs.

[identity relationships]
feet body-includes feet. lower-body body-includes lower-body. legs body-includes legs. hips body-includes hips. upper-body body-includes upper-body. full-body body-includes full-body. head body-includes head.

Part 2 - Garments

Chapter 1 - Defining base kinds

A garment-element is a kind of thing. A garment-element has a number called the layer-level. A garment-element has a body-area called the area.

[not actually needed - but you might add body-parts and then test if they are covered in a similar way to testing if a garment covers another garment]
A body-part is a kind of garment-element. A body-part has layer-level 0.

A garment is a kind of garment-element. A garment is wearable. A garment can be transparent.

A pair of pants is a kind of garment. The plural of pair of pants is pairs of pants. The area of a pair of pants is lower-body. A pair of pants usually has layer-level 5.

A pair of underpants is a kind of garment. The plural of pair of underpants is pairs of underpants. The area of a pair of underpants is hips. A pair of underpants usually has layer-level 2.

A foundation garment is a kind of garment. The area of a foundation garment is upper-body. A foundation garment usually has layer-level 2.

A pair of socks is a kind of garment. The plural of pair of socks is pairs of socks. The area of a pair of socks is feet. A pair of socks usually has layer-level 2.

A pair of shoes is a kind of garment. The plural of pair of shoes is pairs of shoes. The area of a pair of shoes is feet. A pair of shoes usually has layer-level 5.

A jacket is a kind of garment. The area of a jacket is usually upper-body. A jacket usually has layer-level 10.

A hat is a kind of garment. The area of a hat is head. A hat usually has layer-level 5.

A dress is a kind of garment. The area of a dress is full-body. A dress usually has layer-level 5.

A skirt is a kind of garment. The area of a skirt is lower-body. A skirt usually has layer-level 5.

A tie is a kind of garment. The area of a tie is upper-body. A tie usually has layer-level 7. A tie is always transparent.

A shirt is a kind of garment. The area of a shirt is upper-body. A shirt usually has layer-level 5.

Chapter 2 - Relationships

Definition: a garment-element is uppermost if it is not unwearable because of something opaque.

Clothing conflict relates a garment (called the top layer) to a garment (called the conflicting layer) when the conflicting layer is worn by the person asked and the top layer conflicts with the conflicting layer.

The verb to be unwearable because of implies the clothing conflict relation.

The verb to prevent wearing (he prevents wearing, they prevent wearing, he prevented wearing, he is preventing wearing) implies the reversed clothing conflict relation.

To decide if (top layer - a garment) conflicts with (conflicting layer - a garment):
[simplest case - if the two garment are the same, they don’t conflict]
if the top layer is the conflicting layer:
decide no;
[simple case - if the top layer has a higher level, it doesn’t conflict]
if the layer-level of the top layer is greater than the layer-level of the conflicting layer:
decide no;
[some part of the top layer area = some part of the conflicting layer area]
otherwise if a body-area body-included by the area of the conflicting layer is body-included by the area of the top layer:
decide yes;
otherwise:
decide no;

Chapter 3 - Rules for handling garments

Section 1 - removing

Before an actor taking off something which is unwearable because of something which is worn by the actor:
while the noun is unwearable because of something (called the impediment) which is worn by the actor:
say “(first removing [the impediment])[command clarification break]”;
silently try actor taking off the impediment;
if the noun is unwearable because of the impediment, stop the action.

Check an actor taking off a garment:
if the noun is unwearable because of something (called the impediment) which is worn by the actor, say “[The impediment] is in the way.” instead.

Report taking off something:
say “You are now wearing [a list of uppermost things worn by the player].” instead.

Section 2 - wearing

Before an actor wearing something unwearable because of a garment worn by the actor:
while the actor wears a garment (called the impediment) which prevent wearing the noun:
say “(first removing [the impediment])[command clarification break]”;
silently try actor taking off the impediment;
if the actor is wearing the impediment, stop the action.

Instead of taking inventory:
say “You’re carrying [a list of things carried by the player][if the player wears something]. You are wearing [a list of uppermost garments worn by the player][end if].”

Part 3 - The Scenario

The Dressing Room is a room.

The player carries some capris, some jeans, a corset, a plunge bra, a thong, boy-shorts, black satin D’Orsay pumps, brown leather boots, a camisole, a cocktail dress, a bolero, a cashmere shrug, a sheer wrap, and a linen tunic.

The woolly socks are a pair of socks.
The D’Orsay pumps and the brown leather boots are pairs of shoes.
The thong and the boy-shorts are pairs of underpants.
The capris and the jeans are pairs of pants.
The tunic is a shirt.
The camisole, the corset, and the plunge bra are foundation garments.
The cocktail dress is a dress.
The bolero, the cashmere shrug, and the sheer wrap are jackets. The shrug and the wrap are transparent.

Test me with “wear capris / wear jeans / i / wear thong / i / wear dress / wear corset / wear dress / i / wear wrap / i / wear boots / wear pumps / i”.
[/code][/spoiler]

Any comments? Criticisms?

I learnt a lot about inform by doing this, the sad part is that I’m not sure I can really think of too many scenarios where this level of clothing detail might actually be useful, so I might well end up never using it. Still, finding the limitations of the original example compelled me to try and find a more efficient solution.

With a little tweaking, a similar system could be created for a situation where you have to keep track of items overlying (either completely or partially) over items.

So one last thing. I wanted to implement partial covering logic for deciding if a garment is uppermost. Right now we do this:

Definition: a garment-element is uppermost if it is not unwearable because of something opaque. 

What I want to do is replace that with a slightly more advanced logic. If (to use the what not to wear example) you wear the dress and the opaque jacket (the bolero - whatever that is) you should be able to still see the dress even though you can’t remove it because of the jacket (unless I’m completely misunderstand what a bolero is and it’s something more akin to a trench coat). So, what I want to do when deciding if something is uppermost is test whether any part of the body area it covers is not covered by something else.

I’ve been trying something along these lines, but can’t quite get it to work:

To decide if (item - a garment) is uppermost on (actor - a person):
	if the area of the item is not complex:
		if the item is not unwearable because of something opaque:
			decide yes;
		otherwise:
			decide no;
	otherwise:
		repeat with test-area running through body-area body-included by the area of the item:			
[the next condition I can't figure out - what I have here isn't any where close and won't compile anyway]
			if the layer-level of a garment worn by the actor is greater than the layer-level of the item:
				decide yes;
		decide no;

That last condition should say something equivalent to if there are no garments worn by the actor with a layer-level greater than the layer-level of the item which include the body-area I’m testing, then I can decide yes, this item is uppermost (i.e. it should be listed in the inventory).

Any ideas?

Okay, this seems to work for the time being:

Covering relates a garment (called item) to a body-area (called test-area) when the area of the item body-includes the test-area. The verb to cover (it covers, they cover, it is covering, it is covered) implies the covering relation.

Definition: a garment-element is uppermost if it is uppermost on the person asked.

To decide if (item - a garment) is uppermost on (actor - a person):
	if the area of the item is not complex:
		if the item is not unwearable because of something opaque:
			decide yes;
		otherwise:
			decide no;
	otherwise:
		repeat with test-area running through body-area body-included by the area of the item:			
			if the actor is wearing an opaque garment (called the coverer) which covers the test-area and the layer-level of the coverer is greater than the layer-level of the item:
				next;
			otherwise:
				decide yes;
		decide no;

I was almost there, but I had some problems once I tried to introduce another NPC. It seems “the person asked” in the clothing conflict relationship doesn’t really work right when I used it while trying to list the items an NPC was wearing. So I needed a subtly different relationship called “garment covers”. The code below (maybe) fixes all the problems:

"What not to wear II" by Anonymous

Part 1 - Body areas

Body-area is a kind of value. The body-areas are feet, lower-body, legs, hips, upper-body, full-body, head, none.

[relates with areas include other areas]
Body-includes relates various body-area to various body-areas. The verb to body-include (it body-includes, they body-include, it body-included, it is body-including) implies the body-includes relation. The verb to be body-included by implies the reversed body-includes relation.

full-body body-includes hips, legs and upper-body. lower-body body-includes hips and legs.

[identity relationships]
feet body-includes feet. lower-body body-includes lower-body. legs body-includes legs. hips body-includes hips. upper-body body-includes upper-body. full-body body-includes full-body. head body-includes head.

Definition: A body-area is complex rather than not complex if it body-includes more than one body-area.

Part 2 - Garments

Chapter 1 - Defining base kinds

A garment-element is a kind of thing. A garment-element has a number called the layer-level. A garment-element has a body-area called the area.

[not actually needed - but you might add body-parts and then test if they are covered in a similar way to testing if a garment covers another garment]
A body-part is a kind of garment-element. A body-part has layer-level 0.

A garment is a kind of garment-element. A garment is wearable. A garment can be transparent. 

A pair of pants is a kind of garment. The plural of pair of pants is pairs of pants. The area of a pair of pants is lower-body. A pair of pants usually has layer-level 5.

A pair of underpants is a kind of garment. The plural of pair of underpants is pairs of underpants. The area of a pair of underpants is hips. A pair of underpants usually has layer-level 2.

A foundation garment is a kind of garment. The area of a foundation garment is upper-body. A foundation garment usually has layer-level 2.

A pair of socks is a kind of garment. The plural of pair of socks is pairs of socks. The area of a pair of socks is feet. A pair of socks usually has layer-level 2.

A pair of shoes is a kind of garment. The plural of pair of shoes is pairs of shoes. The area of a pair of shoes is feet. A pair of shoes usually has layer-level 5.

A jacket is a kind of garment. The area of a jacket is usually upper-body. A jacket usually has layer-level 10.

A hat is a kind of garment. The area of a hat is head. A hat usually has layer-level 5.

A dress is a kind of garment. The area of a dress is full-body. A dress usually has layer-level 5.

A skirt is a kind of garment. The area of a skirt is lower-body. A skirt usually has layer-level 5.

A tie is a kind of garment. The area of a tie is upper-body. A tie usually has layer-level 7. A tie is always transparent.

A shirt is a kind of garment.  The area of a shirt is upper-body. A shirt usually has layer-level 5.

Chapter 2 - Relationships

Covering relates a garment (called item) to a body-area (called test-area) when the area of the item body-includes the test-area. The verb to cover (it covers, they cover, it is covering, it is covered) implies the covering relation.

Definition: a garment-element (called item) is uppermost if the item is uppermost on a random person wearing the item.

To decide if (item - a garment) is uppermost on (actor - a person):
	if (actor is nothing):
		decide yes;
	if the area of the item is not complex:
		[if the item is not unwearable because of something opaque:]
		if the item is not overlaid by something opaque:
			decide yes;
		otherwise:
			decide no;
	otherwise:
		repeat with test-area running through body-area body-included by the area of the item:			
			if the actor is wearing an opaque garment (called the coverer) which covers the test-area and the layer-level of the coverer is greater than the layer-level of the item:
				next;
			otherwise:
				decide yes;
		decide no;

Garment covers relates a garment (called the top layer) to a garment (called the bottom layer) when the bottom layer is worn by a random person wearing the top layer and the top layer conflicts with the bottom layer.

The verb to be overlaid by implies the garment covers relation.

Clothing conflict relates a garment (called the top layer) to a garment (called the conflicting layer) when the conflicting layer is worn by the person asked and the top layer conflicts with the conflicting layer.

The verb to be unwearable because of implies the clothing conflict relation.

The verb to prevent wearing (he prevents wearing, they prevent wearing, he prevented wearing, he is preventing wearing) implies the reversed clothing conflict relation.

To decide if (top layer - a garment) conflicts with (conflicting layer - a garment):
	[simplest case - if the two garment are the same, they don't conflict]
	if the top layer is the conflicting layer:
		decide no;
	[simple case - if the top layer has a higher level, it doesn't conflict]
	if the layer-level of the top layer is greater than the layer-level of the conflicting layer:
		decide no;
	[some part of the top layer area = some part of the conflicting layer area]
	otherwise if a body-area body-included by the area of the conflicting layer is body-included by the area of the top layer:
		decide yes;
	otherwise:
		decide no;

Chapter 3 - Rules for handling garments

Section 1 - removing
	
Before an actor taking off something which is unwearable because of something which is worn by the actor:
	while the noun is unwearable because of something (called the impediment) which is worn by the actor:
		say "(first removing [the impediment])[command clarification break]"; 
		silently try actor taking off the impediment; 
		if the noun is unwearable because of the impediment, stop the action.
		
Check an actor taking off a garment: 
    if the noun is unwearable because of something (called the impediment) which is worn by the actor, say "[The impediment] is in the way." instead. 

Report taking off something: 
    say "You are now wearing [a list of uppermost things worn by the player]." instead. 
        
Section 2 - wearing
	
Before an actor wearing something unwearable because of a garment worn by the actor:
	while the actor wears a garment (called the impediment) which prevent wearing  the noun:
		say "(first removing [the impediment])[command clarification break]"; 
		silently try actor taking off the impediment; 
		if the actor is wearing the impediment, stop the action.
		 
Instead of taking inventory: 
	say "You're carrying [a list of things carried by the player][if the player wears something]. You are wearing [a list of uppermost garments worn by the player][end if]." 

Section 3 - The Scenario 


The Dressing Room is a room. 


some capris, some jeans, a corset, a plunge bra, a thong, boy-shorts, black satin D'Orsay pumps, brown leather boots, a camisole, a cocktail dress, a bolero, a cashmere shrug, a sheer wrap, and a linen tunic are in the dressing room.


The woolly socks are a pair of socks. 
The D'Orsay pumps and the brown leather boots are pairs of shoes. 
The thong and the boy-shorts are pairs of underpants. 
The capris and the jeans are pairs of pants. 
The tunic is a shirt. 
The camisole, the corset, and the plunge bra are foundation garments. 
The cocktail dress is a dress. 
The bolero, the cashmere shrug, and the sheer wrap are jackets. The shrug and the wrap are transparent. 

Jane Doe is a person in the dressing room. The description of Jane is "Jane is carrying [a list of things carried by Jane][if Jane wears something]. Jane is wearing [a list of uppermost garments worn by Jane][end if]."   

Persuasion rule for asking somebody to try doing something: 
	persuasion succeeds.

Test me with "take all / wear capris / wear jeans / i / wear thong / i / wear dress / wear corset / wear dress / i / wear wrap / i / wear boots / wear pumps / i". 

Test jane with "jane, take all / jane, wear thong / jane, wear dress / x jane / jane, wear bra / x jane / jane, wear dress / jane, wear bolero / x jane / jane, remove dress".

I don’t think there’s anything wrong with that. As Eric S. Reynolds describes it, you were “scratching a developer’s itch.” I’ve taken frequent breaks from working on my WIP to write extensions. I’ve found it a satisfying way to work out a problem that’s on my mind without it interfering with the player experience of the actual game.

This is very cool. I was wrong earlier about “the person asked”; it seems to be whoever is either being asked to do something ortrying an action, whether or not they are doing so as a result of being asked to do something. Have I got that right? Anyway, I added this:

Instead of singing when Jane wears the bolero:
	say "Jane says, 'I can't resist a musical pun.'";
	repeat with item running through things worn by Jane:
		if item is not the bolero:
			try Jane taking off item.

and Jane takes off the bolero if she is wearing something under it, as she ought. (I think this tells us what sort of game needs this kind of modeling – roguelike-likes with various sorts of overlapping armor, of course.)

How speedy is this code? I may have to borrow it — what should I include as your byline?

Knock yourself out. It seems to be a lot speedier than the original by removing all the many-to-many relationships that caused the original to choke. I can’t guarantee it won’t break at some point, but so far, so good.

Thanks. I’ll probably call it “Efficient Layered Clothing” in my files, unless you can suggest a better descriptor. I may even expand it to include more narrowly defined body regions (Expanded ELC?) for a project that calls for it. (I have this idea of spotting a tattoo on someone’s scapula, but only while she is wearing a certain outfit. Or a scar … a watch … you get the idea.)

I believe I’ll also create “male/female supermodel” as a sub-category of “man/woman.” Man or woman would suitable for random NPCs who never change attire; there’s no need to even create garnent objects for them, or associate them with body parts. Their clothing can be included in the description. There are, after all, only a few characters we probably need in such detail as to interact with their underwear or examine their elbows. :slight_smile:

You must be using a modified form of “What Not To Wear” part 1. Part II doesn’t play nice with the one from the documentation.

It replaces the one from the documentation instead of adding on to it. (Think of it as version 2 instead of part 2.)

Got it working. It was the cut ‘n’ paste, it didn’t preserve the proper tabulations.

Best way to avoid that is to hit the quote button and copy it from the edit box, which preserves tabs.