On Uservoice there’s been the suggestion to change the phrasing “a random hat worn by the player” when the author knows there can be only one: instead, “the hat worn by the player” is more readable, and could make more efficient code (why loop through all hats if you don’t need to?).
I put together some code to try this out:
Include (-
[ FirstSatisfying filter x;
for(x=IK2_First: x: x=x.IK2_Link){
if(filter(x)) return x;
}
rfalse;
];
-).
To decide which K is the* (D - description of values of kind K):
(- FirstSatisfying({D}); -).
This allows you to refer “the* hat worn by the player”, with the asterisk. It also stops as soon as it finds one object fitting the criterion, even if there could potentially be more. (Unfortunately couldn’t make it work without the asterisk, since “the” has special meaning in Inform.)
Is there anything to be gained or lost by using this method? My code currently applies the test to all “things” it comes across, rather than only things of a certain kind—but the compiler won’t let me pass {K} to the function. Is there a way around this limitation? And, any recommendations for better syntax? The asterisk is ugly and confusing for readers, but this needs something short and readable.
Could “specific” just be a synonym for “random” (despite that being a real world paradox? - essentially it would do the same thing: pick a random hat or the only one.)
Before greeting someone:
if the player wears a hat:
now a specific hat worn by the player is carried by the player; [a specific hat chosen at random; a randomly chosen one of many specific hats worn by the player; it's not such a paradox, is it?]
say "First doffing your hat.[command clarification break]";
I like “the only”, but it breaks the Standard Rules (which have “only if victorious” as a column name in the table of ending options). This shouldn’t actually be a problem, since parsing is still unambiguous (“the only (if victorious entry)” doesn’t work), but the compiler doesn’t like it.
I like the idea of vanilla “a/the hat worn by the player” choosing a random one if the description has multiple matches, the single matching one if there’s only one match, and nothing if there are no matches.
That’s the same as “a random X”, though. You’re not defining new behavior.
The version I posted earlier (with {D}(-2)) is deterministic in the multiple case, and very slightly faster in the singleton case. This is not, to be honest, a improvement that’s really worth bothering with.
You might want this version, which validates that there’s exactly one D:
Include (-
[ SoleSatisfying desc obj obj2;
obj = desc(-2);
if (obj == nothing) {
print "BUG: description covers zero things.^";
return nothing;
}
obj2 = desc(-2, obj);
if (obj2 ~= nothing) {
print "BUG: description covers more than one thing.^";
return nothing;
}
return obj;
];
-).
To decide which K is *the* (D - description of values of kind K):
(- SoleSatisfying({D}) -).