While I was working on the project and testing some of the things I implemented recently, I stumbled upon a… let’s call it wrinkle. It’s nothing that is really important, but something that I felt was just missing. The pronoun “It.”
When you play a text adventure, the last thing you want to see is the parser spitting a response back at you that it didn’t understand what you’re saying, especially when it seems to be the most natural thing to say and the game should be able to get you.
I think the use of a pronoun, particularly it, is such a case. When I enter a command like
Look at the lantern
I want to be able to go on and refer back to it in my next command, like
But the problem with a pronoun like It is, of course, that it changes meaning constantly. I decided to fix that.
In my project, I am already keeping track of the context of a sentence with my theVerb, theNoun variables and so on. To allow the player to refer back to the last command, all I really need is to remember and recall the last command’s context. Easy. I’ll simply store it.
To handle the word It, all I need to remember, actually, is the last noun, so the first thing in my game loop, I’ll make a backup of it before erasing it.
globals.theLastNoun = globals.theNoun
globals.theLastNounString = globals.theNounString
globals.theNoun = None
globals.theNounString = None
I’m preserving the actual command string of the word as well because it is used in certain instances of the game to create particular error responses.
To make it work, I needed to change my parser a little, so I created a function that I called
InstaCheck(). Whenever the parser decoded a word from the vocabulary and tokenized it, I am calling
InstaCheck() which can then take a look at the sentence context so far and adjust it if necessary. So, whenever I find Tokens.It as the first noun, I am instantly replacing it with the noun from the previous command.
def InstaCheck ( self ):
""" Check for word combinations that can be instantly replaced, while still parsing the input """
if Tokens.It == globals.theNoun: # Handle IT
globals.theNoun = globals.theLastNoun
globals.theNounString = globals.theLastNounString
The reason I decided to do this right after decoding a word and not once the entire sentence has been tokenized is so that for the parser and whatever (game) logic comes after it, it looks EXACTLY is if the payer had entered the actual noun. This should prevent any weird behavior down the line… or at least that’s what I’m hoping.
> examine the lantern
A rusty lantern. The glass is blackened with soot.
> light it
You have nothing to light the lantern with.
> fill it
You have nothing to fill the lantern with.
It works! And it makes me happy… and it was much easier than I had feared at first.