There’s plenty of routines to modify the command vocabulary of a Thing. You can remove nouns, remove adjectives, add more words to the ones that are already there. But what I can’t seem to find is a good way to efficiently REPLACE the vocabulary of a thing without it getting really really messy.
What I’d like to do is something along these lines (pseudocode) :
[code]PokerCard: Thing
… stuff ommitted for brevity …
rank = ‘king’ // Multiple instances of this class will exist with other strings here. This is an example value to override.
suit = ‘hearts’ // Multiple instances of this class will exist with other strings here. This is an example value to override.
faceUpVocab { return ‘<> (of) <>’; }
faceDownVocab = ‘poker card’;
isFaceUp = nil
changeFaceUpness( newVal )
{
isFaceUp = newVal;
if( isFaceUp ) {
removeOldVocabForMe(); // This is the routine I need help implementing.
initializeVocabWith( faceUpVocab );
// I also put a lot of stuff here to change the display name and desc() but I’m ommitting
// it to keep the example short. What matters here is the vocabulary change.
} else {
removeOldVocabForMe(); // This is the routine I need help implementing.
initializeVocabWith( faceDownVocab );
// I also put a lot of stuff here to change the display name and desc() but I’m ommitting
// it to keep the example short. What matters here is the vocabulary change.
}
}
… etc …
;
[/code]
So the idea is that every time the card flips from face up to face down or visa versa, I want to completely remove the old vocabulary and give it brand new vocabulary. The goal is to make it so that if the card is face-down on top of a deck of cards, you can only refer to it in a generic way as “take card from deck” or “take poker card from deck” but you absolutely must not be allowed to say “take king of hearts” or “look at king of hearts” while the card is still face down.
I’m trying to implement this because of the potential exploit where a player who isn’t supposed to know what the card is yet decides to type things and watch the kinds of errors he gets. If you type “look at king” and the face down card has the noun “king” attached to it but the action is stopped with a custom verification routine because it’s face down, you’ll still get a very different response than if the face down card isn’t a king and the parser says it can’t find any such thing as a king. Thus the player can cheat by typing several such guesses until one “hits”. Since the parser’s complaint doesn’t cause any time to pass in game turns, there’s no cost at all to doing this and it’s very hard to trap that it’s happening.
So, in more precise terms, why I am having a problem doing this is:
1 - initializeVocabWith() only adds MORE words, it doesn’t take words away.
2 - The only method I found to remove words requires explicitly knowing what they were and removing them one at a time, using cmdDict.removeWord( obj, str, vocabType ). So this isn’t very practical for a generic solution to use on any and all instances of subclasses of playing card that users of this library will make.
3 - Although there are means to iterate over words in the dictionary like cmdDict.findWords() and cmdDict.foreachWord() and pull all the words fitting certain criteria out of the dictionary so I can then use cmdDict.removeWord on them, and that would work, I fear it would be very inefficient because those methods only work across the entire dictionary, not just on one object. There doesn’t seem to be a way to give it “stuff referring to this object” as the search criterion. You have to search based on knowing the word already in order to find the objects it refers to, and I’m trying to search in the opposite direction. I know the object and want to find the words for it.