[I6] DM4 Ex 101 scope question - Dwarves can already see in the dark?

Using Inform 6.31, I worked out a solution for DM4 Ex 101 (p. 235), but it seems, from the discussion in the example solution, that my solution shouldn’t have worked. The discussion (p. 495-496) states: “Note that the routine puts the light switch in scope for the dwarf – if it didn’t, the dwarf would not be able to understand ‘dwarf, turn light on’, and that was the whole point.”

My solution didn’t take any special pains to add the light switch to scope for the dwarf, and yet the dwarf had no trouble executing the order.

The example solution includes:

[ InScope person i;
    if (person in Dark_Room)
        if (person == dwarf || light_switch.player_knows)
            PlaceInScope(light_switch);
    if (person == player && location == thedark)
        objectloop (i in parent(player))
            if (i has moved || i==dwarf)
                PlaceInScope(i);
    rfalse;
];

To test that the dwarf seems to have the light_switch in scope regardless of InScope() tampering, I loaded up the example solution, but changed InScope() to:

[ InScope person i;
    PlaceInScope(dwarf); ! still need the dwarf in scope
    rfalse;
];

…and the dwarf still has no trouble responding to >DWARF, TURN ON LIGHT

Also, compiling with Infix, I see the following responses before any “real” commands:

>; TestScope(light_switch, dwarf)
; == 1

>; TestScope(light_switch, selfobj)
; == 0

and with >TRACE 4 active, I see the following after giving the command:

[line 3 * 'on' noun -> SwitchOn]
 [line 3 token 1 word 4 : 'on']
  [token resulted in success]
 [line 3 token 2 word 5 : noun]
  [Object list from word 5]
  [Calling NounDomain on location and actor]
   [NounDomain called at word 5
   seeking definite object
   [ND made 1 matches]
  [ND returned the light switch]
  [token resulted in success]
 [line 3 token 3 word 6 : END]
[Line successfully parsed]
"Right you are, squire."

So, what’s the deal here? How is the dwarf getting the light switch in its scope? For that matter, how is the command even being successfully parsed with the light_switch not having been added to the player’s scope?

For reference, attached is the complete code I’m looking at (including modified InScope() per the above).exercise-101b.inf (1.9 KB)

1 Like

For even easier reference, following is the entire source code:

Constant Story "DM4 Exercise 101";
Constant Headline "^from p. 235^";

! EXERCISE 101
! Code the following puzzle. In an initially dark room there is a light switch. Provided
! you’ve seen the switch at some time in the past, you can turn it on and off – but before
! you’ve ever seen it, you can’t. Inside the room is nothing you can see, but you can hear
! the distinctive sound of a dwarf breathing. If you tell this dwarf to turn the light on, he
! will. [Note: Other than InScope(), this is the exact text of the example solution, which
! can be found on DM4 p. 495.]

Include "Parser";
Include "VerbLib";

[ InScope person i;
    PlaceInScope(dwarf);
    rfalse;
];

Include "Grammar";

Object Dark_Room "Dark Room"
    with    description "A disused broom cupboard.";

Object -> light_switch "light switch"
    with    name 'light' 'switch',
            player_knows,
            initial "On one wall is the light switch.",
            after [;
                SwitchOn: give Dark_Room light;
                SwitchOff: give Dark_Room ~light;
            ],
    has     switchable static;

Object -> diamond "shiny diamond"
    with    name 'shiny' 'diamond'
    has     scored;

Object -> dwarf "dwarf"
    with    name 'voice' 'dwarf' 'breathing',
            life [;
                Order:
                    if (action == ##SwitchOn && noun == light_switch) {
                        give Dark_Room light;
                        light_switch.player_knows = true;
                        StopDaemon(self);
                        if (light_switch has on) "~Typical human.~";
                        give light_switch on; "~Right you are, squire.~";
                    }
                ],
            daemon [;
                if (location == thedark && real_location == Dark_Room)
                    "^You hear the breathing of a dwarf.";
            ],
    has     animate;

[ Initialise ;

    location = Dark_Room;
    StartDaemon(dwarf);

];

For anyone looking at this, Ex 101 is found online at https://inform-fiction.org/manual/html/s32.html and the solution discussion at https://inform-fiction.org/manual/html/sa6.html#ans101.