Warning, lot of text ahead.
I thought it was better to open a new thread, to not drive the original one further off topic.
So, this post is about resolving ambiguities when parsing player input. More precisely, resolving without asking unnecessary questions to the player. Unnecessary as in the parser could have at least narrowed it down a bit further, based on the current game progress.
Suppose we have 2 boxes, red and green and 2 balls, also red and green. Now, “put ball into box” gives 4 possibilites. Most parses will detect there are multiple possible matches and will ask the player which ball and which box and will then continue and hand over 2 objects (the box and ball) and an action (put into) to the interpreter.
Now let’s consider the following scenario:
[code]
x red box
The red box is locked and you don’t have a key to unlock it.
put ball into box
Which box do you mean, the red box or the green box?
red
Which ball do you mean, the red ball or the green ball?
green
The red box is locked.[/code]
It would be nice if the parser would exclude the red box as a possible hit for ‘box’ in the player input because it knew that the player already examined the red box and found it to be locked.
Likewise, if the player carries one ball and the other one is on the floor, the parser might conclude that the player means the ball being carried. But if there’s only 1 ball and it’s on the floor, the parser will match it, because the story might have a rule to pick it up first and then put it into the box.
So, what I’m looking for is sort of a framework (thanks, matt w) to model additional knowledge/rules for the parser. And if we could assign a weight to each rule (thanks again, matt w), the parser could even pick the object that qualifies best to further limit the number of possible hits.
The rules could be written in the framework by the author and it could be part of the game source, so different games can have different parser rule sets but still use the same parser.
I’ve been thinking how something like this could be implemented (the framework that is, in the parser source code).
Let’s assume most player inputs consist of an action, some nouns with each some adjectives and some prepositions (e.g. “put ball with white dots in green box”). The high level description of a sentence being
It will then work as follows:
- the parser will match the player input to a first set of hits for object 1 and object 2, by comparing nouns, adjectives and prepositions from the player input to object descriptions from the game.
- if an object has 0 hits, parsing ends and the parser will print an error message (“You don’t see that here.”)
- if an object has 1 hit, that’s ok and parsing ends for that object as it has been uniquely identified.
- if an object has 2 or more hits, the parser will consult the framework with parsing rules and retrieve the rules for the action.
- each rule is assessed for each individual hit for the object and if the rule matches, the hit gets awarded the points for that rule.
- next, the hit with the most points “wins” and is considered to be the only match for the object.
- if multiple hits have the same score, the parser will ask the “which do you mean” question to the player for the final match.
- finally, for each object, 1 hit is handed over to the interpreter to work with.
I’m still thinking about what the parser rules must look like and what they will do and what they won’t do. Currently I have the following:
- Each action has a ruleset, which may consist of several rules.
- The action will likely have different rules for different prepositions. E.g. “put in” → skip if not a container; “put up” → skip if not a supporter, etc
- From the previous bullet it follows that rules may check the status of a possible hit. E.g. is it lockable, is it a supporter, is it takeable, has it been examined by the player, etc.
Finally, I think it is important to realize that these parse rules must only be used for the purpose of disambiguation.
To illustrate:
There are 2 rocks, 1 weighs 2 pounds and the other 1000 pounds. With “Lift rock”, the parser could find a rule for the lift action and limit the possible hits to the rock of 2 pounds.
If there’s one rock of 1000 pounds, “lift rock” will give one hit and the parser must pass this on to the interpreter without checking disambiguation rules. The interpreter will likely print an error message about the rock being too heavy. There was no ambiguation here, only an impossible command.
I appreciate any feedback on this.
Thanks for reading.