+int get_action_vocab_id(const char* word)
+// Return the first motion number that has 'word' as one of its words.
+{
+ for (int i = 0; i < NACTIONS; ++i)
+ {
+ for (int j = 0; j < actions[i].words.n; ++j)
+ {
+ if (strcasecmp(word, actions[i].words.strs[j]) == 0)
+ return(i);
+ }
+ }
+ // If execution reaches here, we didn't find the word.
+ return(WORD_NOT_FOUND);
+}
+
+int get_special_vocab_id(const char* word)
+// Return the first special number that has 'word' as one of its words.
+{
+ for (int i = 0; i < NSPECIALS; ++i)
+ {
+ for (int j = 0; j < specials[i].words.n; ++j)
+ {
+ if (strcasecmp(word, specials[i].words.strs[j]) == 0)
+ return(i);
+ }
+ }
+ // If execution reaches here, we didn't find the word.
+ return(WORD_NOT_FOUND);
+}
+
+long get_vocab_id(const char* word)
+// Search the vocab categories in order for the supplied word.
+{
+ long ref_num;
+
+ ref_num = get_motion_vocab_id(word);
+ if (ref_num != WORD_NOT_FOUND)
+ return(ref_num + 0); // FIXME: replace with a proper hash
+
+ ref_num = get_object_vocab_id(word);
+ if (ref_num != WORD_NOT_FOUND)
+ return(ref_num + 1000); // FIXME: replace with a proper hash
+
+ ref_num = get_action_vocab_id(word);
+ if (ref_num != WORD_NOT_FOUND)
+ return(ref_num + 2000); // FIXME: replace with a proper hash
+
+ ref_num = get_special_vocab_id(word);
+ if (ref_num != WORD_NOT_FOUND)
+ return(ref_num + 3000); // FIXME: replace with a proper hash
+
+ // Check for the reservoir magic word.
+ if (strcasecmp(word, game.zzword) == 0)
+ return(PART + 2000); // FIXME: replace with a proper hash
+
+ return(WORD_NOT_FOUND);
+}
+
+void juggle(long object)