Inform 7 - Test for related things (Photographs - Camera)

Hi,

I have a quick question and I bet the solution is very simple in Inform 7:
How can i check the (if there is a) relation between photographs and one kind of animal/thing?
I have 3 different dogs, but when I try to check, if I have taken a picture of every dog, it is enough to have 3 pictures of the same dog, to trigger the scene “Fun”.

Right now i try this with :
Fun begins when every dog is shown by a photographs.

What am I missing? (Skill obviously :smiley: )

Thank you :slight_smile:

1 Like

I’m certainly not the person to give you technical advice.

However, it would be mighty helpful for the people who do have the technical knowledge if you could specify the program you are using to create your game/story.

Is it Twine, Inform, Adrift, Tads,…?

There are specific categories for many IF-creation programs right here on the forum. If you ask your question in the appropriate category, you have a much better chance of getting a helpful reply soon.

(And I mean soon. People around here are fast when it comes to helping others out with technical solutions.)

Oh right :smiley: I am using Inform 7, I will edit my Question

this’ll do it (tested in v10)

Lab is a room.
A dog is a kind of animal.
Spot is a dog in the lab.
Fido is a dog in the lab.
Admiral Fluffikins is a dog in the lab.
A photograph is a kind of thing.
A photograph can be exposed or unexposed.
There are three photographs.
Soul-theft relates one photograph to one thing.
The verb to depict means the soul-theft relation.
Photographing is an action applying to one thing.
understand "photograph [something]" as photographing..

carry out photographing:
  let p be a random unexposed photograph;
  now p is exposed;
  now p depicts the noun;

report photographing: say "[We] [take] a picture of [the noun]."

Fun is a scene.
Fun begins when all dogs are depicted by a photograph.
When fun begins: say "Fun!"

Test me with "photograph spot / photograph fido / photograph admiral".

But if you just need to track “is this thing photographed: yes/no” it’s just as easy to use an attribute.

A thing can be photographed or unphotographed.
Fun begins when all dogs are photographed.

[within Carry out photographing:]
  now the noun is photographed;

But the relationship is a perfectly fine way to do it too. :grinning:

3 Likes

Thank you very much!
This is exactly how I have done it in the past and it worked fine :smiley:

Later I implemented a Camera which I found somewhere as is. The Camera relates a thing to a Photograph. I wanted to check these relations for further implementations of events and such.

The player carries a camera.

Understand "photograph [something] with [camera]" as photographing. Understand "photograph [something] with [something preferably held]" as photographing. Photographing is an action applying to one visible thing and one carried thing, requiring light.

The photographing action has an object called the selected film.
Before photographing, play the sound of Photo.

Setting action variables for photographing:
	let N be a random photograph in the film roll;
	now the selected film is N.

Check photographing:
	if the second noun is not the camera, say "[one of]You have to use the camera to take a photo of something." instead.

Check photographing:
	if the noun is the camera, say "Impossible." instead.

Check photographing:
	if the selected film is nothing, say "No film.." instead.


Carry out photographing:
	now the noun is shown by the selected film;
	move the selected film to the player.

Report photographing:
	say "You now have the picture of [a selected film] in your inventory."
	
After printing the name of a photograph (called target):
	say " of [a random thing which is shown by the target]".

After printing the plural name of a photograph (called target):
	let N be the holder of the target;
	say " of [a list of things which are shown by photographs which are held by N]";
	if the number of things which are shown by photographs which are held by N is greater than one, say " (variously)".

What somehow works fine is:

Every turn when the remainder after dividing the turn count by 4 is 0 during the fun:
	if no dog is shown by a photograph:
		say "I need to photograph the dogs.";
	otherwise:
		Say "  - already photographed: [a list of dogs which are shown by photographs]".

But if i ask wether all dogs are photographed it is enough to have the same Number of photographs as there are dogs… So i can’t get the game to check if there is a Relation of each Dog to a Photograph…

I need to ask something like “[…]when every/each Dog is shown by a photograph (atleast one Photo of each Dog), action”

Hmm, I think there’s a bug in your code: you establish that souls exist, that photographing steals them, and since you can photograph dogs, implicitly that means dogs have souls. All well and good, but that means that successfully photographing these three dogs steals their souls, which means all dogs don’t go to heaven, which is a clear violation of the Inform world model.

5 Likes

EDIT: I just saw that this was not related to my solution

It’s a cruel world we live in…
No actually, the camera works fine and i can take pictures of everything. Was the way i implemented it a mistake or are you toying with me? :smiley:

Inform is so delightfully naïve that way…

Hap…Crunch…Njam

More doggy souls please.

Definition: a thing is successfully photographed rather than yet to be photographed if it is depicted by a photo.

Every turn when a dog (called the dog in question) is yet to be photographed:
    say "You should go take a picture of [the dog in question]."

Every turn when all dogs are successfully photographed:
    end the story finally saying "You have photographed all the dogs."

But with just one sentence it is not quiet feasible with my camera implementation:

Fun begins when every dog is shown/depicted by a photograph.

As of now, this works as well, when the number of photographs of dogs is equal to the number of dogs, but this doesent mean, that every dog is photographed… Because i can (and want to for imersion) take multiple photos of the same dog/thing.

Nice Extension btw!

yeah, my use of a one-to-one relation was a bad choice. I took a couple stabs at using a straightforward conditional statement regarding the one-to-various relation in Example 322 and I couldn’t get it to work either. It’s feeling like there’s a bug here.

I don’t really know how Inform compiles these under the hood, but if you use the system from the example “Claims adjustment” (as it seems you do), here’s how you can check in one line (seems to work in my tests at least):

Fun begins when no dog is not shown by a photograph.

which is, perhaps surprisingly, not equivalent to:

Fun begins when each dog is shown by a photograph.

(The latter is triggered, as you say, by any three photographs of any dog (if we have three dogs in the example), for example two of dog A and one of dog B.)

What also seems to work in one line, though it’s not very reader-friendly either:

Fun begins when a random dog not shown by a photograph is nothing.
1 Like

Wow I will test this, this might realy do the trick!
Thank you all!

The following also works correctly:

when the number of dogs shown by photographs is the number of dogs

As to your original problem, the condition

every dog is shown by a photograph

compiles to something like:

! True or false?
! [ ForAll x IN[ dog(x) IN] : Exists y : photograph(y) & is(x, (RGuard_f0_2(y))) ]
[ Prop_1 
    x ! internal use only
    x_ix ! internal use only
    y ! internal use only
    y_ix ! internal use only
    qcy_0 ! internal use only
    qcn_0 ! internal use only
    ;
    ;
    qcy_0 = 0;
    qcn_0 = 0;
    for (x=IK17_First: x: x=x.IK17_Link){ ! iterate through dogs
        qcn_0++; ! number of dogs
        for (y=IK16_First: y: y=y.IK16_Link){ ! iterate through photographs
            if ((x == (RGuard_f0_2(y)))){ ! iterated dog is shown by iterated photograph
                qcy_0++; ! # of times photograph matched dog... but this may happen for multiple photographs
            }
        }
    }
    if (qcy_0 == qcn_0){ ! does # of dogs equal # of matches?
        rtrue;
    }
    rfalse;
];

[ RGuard_f0_2 
    X ! which is related to at most one object
    ;
    if (X ofclass K16_photograph) return (X.p59_depiction_relation_stora);
    return nothing;
];

It seems to work as expected if the body of the innermost loop of the compiled proposition looks like:

            if ((x == (RGuard_f0_2(y)))){ ! iterated dog is shown by iterated photograph
                qcy_0++; ! # of times photograph matched dog
                break;   ! stop matching photographs for the current dog
            }

I agree with @Zed that this looks like a bug in 6M62. The comment indicating the intended prepositional logic looks like the routine should mean what the English that it represents means. (Though I don’t quite understand what the second “IN” is about.)

EDIT: The generated code for the prepositional logic looks a little different in 10.1 but is logically the same.

4 Likes

Good catch! I agree, this sounds like a straight-up bug.

1 Like

It’s the same behavior in v10; I’ll file a bug. It seems particular to one-to-various relations.

2 Likes

I7-2185: “all” determiner tests failing with relations

It’s not particular to one-to-various.