Here's a slightly simplified version of a scenario I'm trying to implement:
[code] The Train Platform is a room. "The platform is deserted. No trains, either."
The luggage is in the Train Platform. "The group's luggage is all piled near the tracks." The description is "Grace's suitcase, Paul's suitcase, Marty's suitcase, Jorma's suitcase, Jack's suitcase, and Spencer's suitcase."
A suitcase is a kind of container. Understand "suitcase" and "bag" as a suitcase. Understand "suitcases" and "bags" as the plural of suitcase. Grace's suitcase is a suitcase. Paul's suitcase is a suitcase. Marty's suitcase is a suitcase. Jorma's suitcase is a suitcase. Jack's suitcase is a suitcase. Spencer's suitcase is a suitcase.
Grace's suitcase is part of the luggage. Paul's suitcase is part of the luggage. Marty's suitcase is part of the luggage. Jorma's suitcase is part of the luggage. Jack's suitcase is part of the luggage. Spencer's suitcase is part of the luggage.
Instead of taking the luggage: say "But you just finished piling the luggage up there so neatly! What kind of roadie are you, anyway?"
Instead of taking a suitcase: try taking the luggage.
Test me with "take suitcases". [end code]
The problem is that the output in response to 'take suitcases' spits out the text from the Instead of taking the luggage rule six times, once for each suitcase. The question is, how can I get a rule like this to run once and then stop? The player might try 'take grace's and jorma's and jack's' ... and again, we only want to see one message of refusal, not three.
I could make 'suitcases' a synonym for the luggage object instead of a plural for the kind -- but with my real scenario, that probably wouldn't work well, because the real pile of luggage is somewhat more complex, and the player may want to try various commands with it. And indeed, it wouldn't work with 'take grace's and jorma's and jack's'.
This is perhaps an instance of a more general problem, which is how to handle a group of objects as a collective when they're NOT indistinguishable. I've had problems of this sort before, and may even have posted about them before. But every collective is a little different. What one wants, I suppose, is a general way to tell Inform, "Look, objects A, B, and C, when two or more of them are in scope, should be handled by routing the player's action to a collective object (call it X) instead, but only with respect to actions M, N, and P."
Is there a general solution to this problem? How might I construct one? Thanks in advance!
>This is perhaps an instance of a more general problem, which is how to >handle a group of objects as a collective when they're NOT >indistinguishable.
In past efforts, what I tried to do along these lines was to introduce a new object to represent the collective, and then make sure that actions on the collective do the appropriate thing to its members, and that removing all the members causes the collective to be removed. It's a lot of programming, but it eventually worked.
So for example, "suitcases" and "luggage" would be names for the collective, rather than the plural of "suitcase".
>> This is perhaps an instance of a more general problem, which is how to >> handle a group of objects as a collective when they're NOT >> indistinguishable.
> In past efforts, what I tried to do along these lines was to > introduce a new object to represent the collective, and then > make sure that actions on the collective do the appropriate > thing to its members, and that removing all the members causes > the collective to be removed. It's a lot of programming, but > it eventually worked.
I've ended up doing it that way in the past as well. In "Lydia's Heart," for example, there is a pluralFigurines object, which is always in scope whenever at least one of the statues is in scope, but pretends not to be unless there are at least two in scope. And I vaguely recall doing it in "Ballerina" as well, because I6 makes it pretty darn easy (using parse_name) for each object to decide whether it wants to respond to any particular vocabulary word at any particular time.
This could probably be accomplished in I7 without dropping into I6 using an Understand phrase -- something like this:
Understand "suitcases" as multSuitcases when scCount is greater than 1.
...and then another line to calculate the current value of scCount.
Even so, I'm hoping I7 has some sort of built-in "throw out everything in the action queue and stop RIGHT NOW" command, because that would ameliorate the difficulty, at least to a first approximation.
And ultimately, it seems this design might be something that would work well in an extension. There are numerous IFish situations (the plates and silverware on a table, the tools in a tool chest, the jewels in a jewelry box, the punks in a motorcycle gang) where it would be useful to be able to give the player commands that would treat the members of a diverse collective collectively, AND to decide, when the player tries to use one of them individually, whether the collective should handle it instead.
On Nov 10, 12:02 pm, Jim Aikin <midigur...@gmail.com> wrote:
> And ultimately, it seems this design might be something that would work > well in an extension. There are numerous IFish situations (the plates > and silverware on a table, the tools in a tool chest, the jewels in a > jewelry box, the punks in a motorcycle gang) where it would be useful to > be able to give the player commands that would treat the members of a > diverse collective collectively, AND to decide, when the player tries to > use one of them individually, whether the collective should handle it > instead.
This is something I've been thinking about on and off for a while, mainly with regard to my Consolidated Multiple Actions extension (which I do hope to update and expand one of these years). Inform already has some support for collectives in output, via the "grouping together" activity used in the list-writer; unfortunately this doesn't really help with setting up actions on collectives, but it might be a starting point. I've done a bit of work on handling them nicely in input and output (one of the examples in CMA does this, or maybe it's in my in-progress version), but I haven't tried to do anything that would allow, say, Instead rules to apply to a collective.
Realistically, I'm not going to have a chance to do much with this for the next couple of months, but I'd be curious to hear any insights people have.
> Here's a slightly simplified version of a scenario I'm trying to > implement:
> [code] > The Train Platform is a room. "The platform is deserted. No trains, > either."
> The luggage is in the Train Platform. "The group's luggage is all > piled near the tracks." The description is "Grace's suitcase, Paul's > suitcase, Marty's suitcase, Jorma's suitcase, Jack's suitcase, and > Spencer's suitcase."
> A suitcase is a kind of container. Understand "suitcase" and "bag" as > a suitcase. Understand "suitcases" and "bags" as the plural of > suitcase. Grace's suitcase is a suitcase. Paul's suitcase is a > suitcase. Marty's suitcase is a suitcase. Jorma's suitcase is a > suitcase. Jack's suitcase is a suitcase. Spencer's suitcase is a > suitcase.
> Grace's suitcase is part of the luggage. Paul's suitcase is part of > the luggage. Marty's suitcase is part of the luggage. Jorma's suitcase > is part of the luggage. Jack's suitcase is part of the luggage. > Spencer's suitcase is part of the luggage.
> Instead of taking the luggage: > say "But you just finished piling the luggage up there so neatly! > What kind of roadie are you, anyway?"
> Instead of taking a suitcase: > try taking the luggage.
> Test me with "take suitcases". > [end code]
> The problem is that the output in response to 'take suitcases' spits > out the text from the Instead of taking the luggage rule six times, > once for each suitcase. The question is, how can I get a rule like > this to run once and then stop? The player might try 'take grace's and > jorma's and jack's' ... and again, we only want to see one message of > refusal, not three.
> I could make 'suitcases' a synonym for the luggage object instead of a > plural for the kind -- but with my real scenario, that probably > wouldn't work well, because the real pile of luggage is somewhat more > complex, and the player may want to try various commands with it. And > indeed, it wouldn't work with 'take grace's and jorma's and jack's'.
> This is perhaps an instance of a more general problem, which is how to > handle a group of objects as a collective when they're NOT > indistinguishable. I've had problems of this sort before, and may even > have posted about them before. But every collective is a little > different. What one wants, I suppose, is a general way to tell Inform, > "Look, objects A, B, and C, when two or more of them are in scope, > should be handled by routing the player's action to a collective > object (call it X) instead, but only with respect to actions M, N, and > P."
> Is there a general solution to this problem? How might I construct > one? Thanks in advance!
> --JA
Hacky, kind-of-working solution:
[code] The Train Platform is a room. "The platform is deserted. No trains, either."
The luggage is in the Train Platform. "The group's luggage is all piled near the tracks." The description is "Grace's suitcase, Paul's suitcase, Marty's suitcase, Jorma's suitcase, Jack's suitcase, and Spencer's suitcase."
A suitcase is a kind of container. Understand "suitcase" and "bag" as a suitcase. Understand "suitcases" and "bags" as the plural of suitcase.
There is a suitcase called Grace's suitcase. There is a suitcase called Paul's suitcase. There is a suitcase called Marty's suitcase. There is a suitcase called Jorma's suitcase. There is a suitcase called Jack's suitcase. There is a suitcase called Spencer's suitcase.
Grace's suitcase is part of the luggage. Paul's suitcase is part of the luggage. Marty's suitcase is part of the luggage. Jorma's suitcase is part of the luggage. Jack's suitcase is part of the luggage. Spencer's suitcase is part of the luggage.
Test me with "take suitcases".
Instead of taking the luggage: say "But you just finished piling the luggage up there so neatly! What kind of roadie are you, anyway?"
Rule for printing the name of a suitcase while taking suitcases: say "Luggage:".
Before taking suitcases: let L be the multiple object list; truncate L to 1 entries; alter the multiple object list to L; change the noun to luggage. [/code]
This only half works. What it does is remove most of the items from the multiple object list (after Inform 7 adds all the suitcases to it) and then just performs the action once. Unfortunately, it is not perfect as it invokes the "multiple object" listing, and I'm not sure how to supersede that. Without the "Rule for printing the name of a suitcase while taking suitcases" rule, it prints "Grace's suitcase: " before proceeding with your denial. With that rule, it'll say "Luggage: " first, which is inconsistent with your other denials (when taking either one suitcase or the collective "luggage"). If you change the printing to "" it still prints a colon, so that's no good either. I'm not sure how that printing functions...when it happens in rule processing, for instance. But it's a start. I'll keep looking into it for you.
> On Nov 10, 1:24 am, Jim Aikin <midigur...@gmail.com> wrote:
> > Here's a slightly simplified version of a scenario I'm trying to > > implement:
> > [code] > > The Train Platform is a room. "The platform is deserted. No trains, > > either."
> > The luggage is in the Train Platform. "The group's luggage is all > > piled near the tracks." The description is "Grace's suitcase, Paul's > > suitcase, Marty's suitcase, Jorma's suitcase, Jack's suitcase, and > > Spencer's suitcase."
> > A suitcase is a kind of container. Understand "suitcase" and "bag" as > > a suitcase. Understand "suitcases" and "bags" as the plural of > > suitcase. Grace's suitcase is a suitcase. Paul's suitcase is a > > suitcase. Marty's suitcase is a suitcase. Jorma's suitcase is a > > suitcase. Jack's suitcase is a suitcase. Spencer's suitcase is a > > suitcase.
> > Grace's suitcase is part of the luggage. Paul's suitcase is part of > > the luggage. Marty's suitcase is part of the luggage. Jorma's suitcase > > is part of the luggage. Jack's suitcase is part of the luggage. > > Spencer's suitcase is part of the luggage.
> > Instead of taking the luggage: > > say "But you just finished piling the luggage up there so neatly! > > What kind of roadie are you, anyway?"
> > Instead of taking a suitcase: > > try taking the luggage.
> > Test me with "take suitcases". > > [end code]
> > The problem is that the output in response to 'take suitcases' spits > > out the text from the Instead of taking the luggage rule six times, > > once for each suitcase. The question is, how can I get a rule like > > this to run once and then stop? The player might try 'take grace's and > > jorma's and jack's' ... and again, we only want to see one message of > > refusal, not three.
> > I could make 'suitcases' a synonym for the luggage object instead of a > > plural for the kind -- but with my real scenario, that probably > > wouldn't work well, because the real pile of luggage is somewhat more > > complex, and the player may want to try various commands with it. And > > indeed, it wouldn't work with 'take grace's and jorma's and jack's'.
> > This is perhaps an instance of a more general problem, which is how to > > handle a group of objects as a collective when they're NOT > > indistinguishable. I've had problems of this sort before, and may even > > have posted about them before. But every collective is a little > > different. What one wants, I suppose, is a general way to tell Inform, > > "Look, objects A, B, and C, when two or more of them are in scope, > > should be handled by routing the player's action to a collective > > object (call it X) instead, but only with respect to actions M, N, and > > P."
> > Is there a general solution to this problem? How might I construct > > one? Thanks in advance!
> > --JA
> Hacky, kind-of-working solution:
> [code] > The Train Platform is a room. "The platform is deserted. No trains, > either."
> The luggage is in the Train Platform. "The group's luggage is all > piled near the tracks." The description is "Grace's suitcase, Paul's > suitcase, Marty's suitcase, Jorma's suitcase, Jack's suitcase, and > Spencer's suitcase."
> A suitcase is a kind of container. Understand "suitcase" and "bag" as > a suitcase. Understand "suitcases" and "bags" as the plural of > suitcase.
> There is a suitcase called Grace's suitcase. > There is a suitcase called Paul's suitcase. > There is a suitcase called Marty's suitcase. > There is a suitcase called Jorma's suitcase. > There is a suitcase called Jack's suitcase. > There is a suitcase called Spencer's suitcase.
> Grace's suitcase is part of the luggage. Paul's suitcase is part of > the luggage. Marty's suitcase is part of the luggage. Jorma's suitcase > is part of the luggage. Jack's suitcase is part of the luggage. > Spencer's suitcase is part of the luggage.
> Test me with "take suitcases".
> Instead of taking the luggage: > say "But you just finished piling the luggage up there so neatly! > What kind of roadie are you, anyway?"
> Rule for printing the name of a suitcase while taking suitcases: > say "Luggage:".
> Before taking suitcases: > let L be the multiple object list; > truncate L to 1 entries; > alter the multiple object list to L; > change the noun to luggage. > [/code]
> This only half works. What it does is remove most of the items from > the multiple object list (after Inform 7 adds all the suitcases to it) > and then just performs the action once. Unfortunately, it is not > perfect as it invokes the "multiple object" listing, and I'm not sure > how to supersede that. Without the "Rule for printing the name of a > suitcase while taking suitcases" rule, it prints "Grace's suitcase: " > before proceeding with your denial. With that rule, it'll say > "Luggage: " first, which is inconsistent with your other denials (when > taking either one suitcase or the collective "luggage"). If you change > the printing to "" it still prints a colon, so that's no good either. > I'm not sure how that printing functions...when it happens in rule > processing, for instance. But it's a start. I'll keep looking into it > for you.
Okay, I got it fully working now:
[code] The Train Platform is a room. "The platform is deserted. No trains, either."
The luggage is in the Train Platform. "The group's luggage is all piled near the tracks." The description is "Grace's suitcase, Paul's suitcase, Marty's suitcase, Jorma's suitcase, Jack's suitcase, and Spencer's suitcase."
A suitcase is a kind of container. Understand "suitcase" and "bag" as a suitcase. Understand "suitcases" and "bags" as the plural of suitcase.
There is a suitcase called Grace's suitcase. There is a suitcase called Paul's suitcase. There is a suitcase called Marty's suitcase. There is a suitcase called Jorma's suitcase. There is a suitcase called Jack's suitcase. There is a suitcase called Spencer's suitcase.
Grace's suitcase is part of the luggage. Paul's suitcase is part of the luggage. Marty's suitcase is part of the luggage. Jorma's suitcase is part of the luggage. Jack's suitcase is part of the luggage. Spencer's suitcase is part of the luggage.
A procedural rule: if taking suitcases then ignore the announce items from multiple object lists rule.
Instead of taking the luggage: say "But you just finished piling the luggage up there so neatly! What kind of roadie are you, anyway?"
Before taking suitcases: let L be the multiple object list; truncate L to 1 entries; alter the multiple object list to L; try taking luggage instead.
Test me with "take luggage / take suitcases / take Grace's suitcase / take Jack's suitcase / take suitcase". [code]
> On Nov 10, 12:02 pm, Jim Aikin <midigur...@gmail.com> wrote:
> > And ultimately, it seems this design might be something that would work > > well in an extension. There are numerous IFish situations (the plates > > and silverware on a table, the tools in a tool chest, the jewels in a > > jewelry box, the punks in a motorcycle gang) where it would be useful to > > be able to give the player commands that would treat the members of a > > diverse collective collectively, AND to decide, when the player tries to > > use one of them individually, whether the collective should handle it > > instead.
> This is something I've been thinking about on and off for a while, > mainly with regard to my Consolidated Multiple Actions extension > (which I do hope to update and expand one of these years). Inform > already has some support for collectives in output, via the "grouping > together" activity used in the list-writer; unfortunately this doesn't > really help with setting up actions on collectives, but it might be a > starting point. I've done a bit of work on handling them nicely in > input and output (one of the examples in CMA does this, or maybe it's > in my in-progress version), but I haven't tried to do anything that > would allow, say, Instead rules to apply to a collective.
> Realistically, I'm not going to have a chance to do much with this for > the next couple of months, but I'd be curious to hear any insights > people have.
> -JDC
An option here, which I've been toying with, is to set up a new relation like "ownership" or "collectiveness." Then you can ask Inform 7 to systematically collect all things that "belong to" a particular collective-idea and redirect actions to that collective-idea.
On Nov 11, 9:09 pm, Roger <roger.helge...@gmail.com> wrote:
> Works as you requested.
Thanks, Roger. Your procedural rule was a BIG boost in the right direction. I substituted a slightly less grotesque scenario and constructed the code below, which seems to work pretty well. I'd love to have a couple of people try to poke holes in it before I add it to the next release of the Handbook. It's still too scenario-specific to make it useful as an extension, but it produces an output that reads nicely when I test it.
--JA
[code] The Sultan's Treasure Room is a room. "Awesome treasures surround you! To the north, an arch opens on a balcony."
[To make sure the scoping works properly, we'll add a second room so the tester can carry a jewel or two elsewhere, drop them, and come back:] The Balcony is north of the Treasure Room. "From here you can see the entire city. The treasure room is back to the south."
The jewel box is an open container in the Treasure Room. "A jewel box sits here, invitingly open. On the front of the box is an intricate ivory carving. In the box you can see [a list of things in the jewel box]." The jewel box can be safe or dangerous. The jewel box has some text called the zap-message. The zap-message of the jewel box is "Zap! As your fingers near the jewel box, you recoil from a powerful electric shock". The intricate ivory carving is part of the jewel box.
[We can make the jewel box safe or dangerous with 'turn carving':] Instead of turning the carving: say "Click -- the carving rotates a quarter-turn to the [run paragraph on]"; if the jewel box is dangerous: now the jewel box is safe; say "left."; otherwise: now the jewel box is dangerous; say "right."
A gem is a kind of thing. Understand "jewel" as a gem. Understand "jewels" and "gems" as the plural of gem.
The diamond is a gem in the jewel box. The ruby is a gem in the jewel box. The sapphire is a gem in the jewel box.
[The box only protects jewels. The token can be taken from it at any time:] The player carries a subway token.
A procedural rule: if taking gems when the jewel box is dangerous then ignore the announce items from multiple object lists rule.
[We need to cover the action of removing it from as a separate procedural rule:] A procedural rule: if removing gems from the jewel box when the jewel box is dangerous then ignore the announce items from multiple object lists rule.
Before taking gems: let L be the multiple object list; let N be the number of entries in L; [If the player is only trying to take one jewel, the length of the multiple object list will be 0:] if N is 0: if the noun is in the jewel box and the jewel box is dangerous: say "[zap-message of the jewel box]." instead; otherwise: continue the action; [Still here? Then either the player is trying to take several jewels or the jewel box is safe:] if the jewel box is safe: continue the action; [Okay, now we know the jewel box is dangerous, but we don't yet know whether any of the jewels the player aims to take are actually IN the jewel box ... so we'll set up a flag and a list:] let danger-present be a truth state; let danger-present be false; let safe-list be a list of things; let safe-list be {}; [Now let's find out what the player is trying to take:] repeat with G running through gems: if G is listed in L: if G is in the jewel box: now danger-present is true; otherwise: add G to the safe-list; [If none of the jewels the player is trying to take is in the dangerous box:] if danger-present is false: continue the action; [Now we know that at least one of the jewels in the multiple object list is in the dangerous box -- but maybe some of them aren't in the box. In that case, we're going to assume there is no other obstacle, such as inventory management, a possessive hyena, or the player wearing mittens, that would prevent their being picked up. We'll only check to make sure they're in the location:] if the number of entries in safe-list is not 0: repeat with item running through safe-list: if item is enclosed by the location and item is not carried by the player: now the player carries item; say "[item]: Taken."; truncate L to 1 entries; alter the multiple object list to L; say "[zap-message of the jewel box]." instead.
Test me with "put token in box / take token and ruby / take jewels / take diamond / turn carving / take diamond and ruby / turn carving / drop all / take jewels". [end code]