0
\$\begingroup\$

Apologies if this has been asked before, or if it is a bit too simple for this forum.
I'm new to C++ and as one of my first projects I have decided to try a textual adventure. Step 1: the text parser.
Note that I am aware that there are libraries out there that will make this for you, but I want to code it from scratch to learn what is going on :)

So! I've gotten to the point where I add the user's input to a vector, so that I can handle each word individually. However, I cannot for the life of me figure out a "handler" that does not hard-code everything. I want to create a map through which to associate the string, for example "Go", to the relative action handler. Something like this:

map<string, ActionHandler> actionMap;

actionMap["Go", GoActionHandler];

GoActionHandler would be a struct of ActionHandler type, and I would put in ActionHandler or the general messages/actions/reactions, and then in GoActionHandler I'd elaborate on the possible "Go" actions. But, one thing at a time... The code above does not compile, as ActionHandler is not a "type". Considering that for now I am just focusing on having a (scalable!) program that reacts differently based on the word entered, could someone help me by showing me real code? I've found online people making examples in pseudocode, but I'm to big of a noob to then know how to execute what they are talking about, even though I understand the logic.
So could anyone dumb this down and point me in the right direction? How do I include in my main() a way to call a struct/function based on the a string contained in a vector? (eg. string "Go" in vector[0]?)

\$\endgroup\$
2
  • \$\begingroup\$ I don't think asking for people to write code for you is a good use of this site. Further, text parsers are not unique to game development, questions like this should be asked on stackoverflow.com \$\endgroup\$
    – House
    Oct 1 '13 at 14:31
  • \$\begingroup\$ It seems I was misunderstood. As I mentioned, I am doing this to learn, so if I wanted to just use someone else's code I could easily find it somewhere else. What I meant was that I got replies that used pseudocode and because my knowledge of C++ is limited, I would first spend a lot of time looking for types/commands that do not really exist, and then still be unable to figure out how to translate pseudocode into C++. So while I am grateful for any answer I get, I would much prefer it if examples used proper syntax/code that I can research, rather than pseudocode that mostly confuses me. \$\endgroup\$
    – Nicholas
    Oct 1 '13 at 15:13
2
\$\begingroup\$

Hope I've written it clear enough, so it could answer all your questions. (I put several keywords in the comments that you can look up if you don't understand something I did)

#include <iostream>
#include <map>
#include <vector>

using namespace std;

// Interface for all handlers
class AbstractHandler {
public:
    // this as an abstract method (pure virtual) which every handler must override
    // with its own implementation
    virtual void doAction() = 0;
};

// This class will handle the word "Go", it implements the abstract handler
class GoActionHandler : public AbstractHandler {
public:
    // here we override the pure virtual method of the abstract handler,
    // and replace it with our own implementation (in this case, we print "Go!")
    virtual void doAction() {
        cout << "Go!" << endl;
    }
};

int main() {
    // this is the vector we'll put words in
    vector<string> words;

    // we map a string to an action handler. The value (second template argument)
    // is a pointer to an abstract handler (we need to do this to take advantage
    // of polymorphism)
    map<string, AbstractHandler*> actionMap;

    // here we map the string "Go" to the GoActionHandler
    actionMap["Go"] = new GoActionHandler;
    // ... populate with additional handlers ...

    // ... populate your vector with words ...
    words.push_back("Go");

    // iterate over words in vector, activate handler for each word
    for (vector<string>::iterator iter = words.begin(); iter != words.end(); ++iter) {
        // retrieve handler for current word from action map. We supply the map with
        // a key (word) and get in return an action handler. We don't know which one
        // is it, but we know it inherit the basic handler
        AbstractHandler* handler = actionMap[*iter];

        // this is where we leverage polymorphism
        handler->doAction();
    }

    // cleanup dynamically allocated handlers
    for (map<string, AbstractHandler*>::iterator iter = actionMap.begin(); iter != actionMap.end(); ++iter) {
        delete iter->second;
    }

    return 0;
}
\$\endgroup\$
1
  • \$\begingroup\$ This is amazing! Thank you so much for taking the time to add all those comments as well - incredibly helpful! \$\endgroup\$
    – Nicholas
    Oct 1 '13 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.