Need help with textRPG

Ok so I am trying to make an rpg that has set commands and depending on what they type they get a certain response. I can make it so it looks for a single word but i want it to look for multiple words and have a different response depending on what words are present. Basically I want a different response for if they type in "run" for example or "run from bear". I tried adding another for loop but it just isn't working right, any help would be appreciated.

heres the code I have so far

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 #include <iostream>
#include <string>
#include <vector>

using namespace std;

int userInput();

int main() {
    int HP;
    int maxHP;
    int MP;
    int maxMP;
    char name[12];
    int invenSpace;
    vector <string> keyWords;
    keyWords.reserve(5);
    keyWords.push_back("USE");
    keyWords.push_back("GO");
    keyWords.push_back("ATTACK");
    keyWords.push_back("RUN");
    keyWords.push_back("GRAB");
    
    bool bear = false;
    

    cout << "BASIC COMMANDS" << endl;
    cout << "USE, GO, ATTACK, RUN, GRAB, OPEN" << endl;
    cout << "" << endl;
    cout << "You are walking into a forest and see a bear " << endl;
    cout << "amongst the trees. It goes to attack you." << endl;
    cout << "What now?" << endl;
    
    userInput();
    
};

// Make the function under here 
int userInput() {
    //this adds all the command to the list of commands right?
    vector <string> keyWords;   // makes a vector named "keyWords"
    keyWords.reserve(6);        // makes the vector hold 5 values 
    keyWords.push_back("USE");  //done. all these are putting values ie the commands into the vector
    keyWords.push_back("GO");       // done.
    keyWords.push_back("ATTACK");  // 
    keyWords.push_back("RUN");    // done.
    keyWords.push_back("GRAB");   
    keyWords.push_back("OPEN");
    //enemy words
    vector <string> enemies;
    enemies.reserve(5);
    enemies.push_back("BEAR");
    // what is this?
    char input[100]; // this sets a variable with the type "char" named "input" capable of holding 100 
    
    
    cin >> input;    // this asks the user to input a value for the variable up here ^
    for (int i = 0; input[i] != '\0'; i++){    // this makes a loop that goes through all the letters of the
        input[i]=toupper(input[i]);            // input and capitalizes them
    }
    
    bool found = false;
    for (int i=0; i<keyWords.size(); i++){  
        if (input == keyWords.at(i)){ 
            
            if (keyWords.at(i) == "RUN") {
                cout << "Where are you planning on running?" << endl;
            }
            if (keyWords.at(i) == "USE") {
                cout << "Use what?" << endl;
            }
            if (keyWords.at(i) == "GRAB") {
                cout << "Grab what?" << endl;
            }
            if (keyWords.at(i) == "GO") {
                cout << "Go where?" << endl;
            }
            if (keyWords.at(i) == "ATTACK") {
                cout << "Attack what?" << endl;
            }
            if (keyWords.at(i) == "OPEN") {
                cout << "Open what?" << endl;
            }
            // if the input is equal to the keyword at that particular
            found = true;
            break;  // We can exit the loop
        }
    }
        
    if (! found) {
        cout << "'" << input << "'" << " not registered as a valid command." << endl;   
        
        }
}
Lets take one action, RUN. You need to decide what input to allow if the user enters RUN.
So instead of line 67, doing a cout. Call a function to handle run. The run function can then ask "Run where?" and parse the users response. Then take action based on the result by calling other functions. The same applies to each of your other actions.

You will find however, that this quickly gets very complicated with functions nested deeply.
Is your game going to have any type of map? If the user says RUN AWAY FROM BEAR, what does this mean in relation to the map?

A couple of general comments.
1) You're duplicating your keywords vector. This is a maintenance headache. Any changes have to be made to both arrays. Pass the vector from main to userInput as an argument so you have only one copy.

2) You're still not returning a value from user_input, as I suggested in your other thread.

3) When you call userInput() in main, you don't do anything based on the result. A minimal suggestion would be for userInput to return the status of the player. 1=play lives another day. 0=Player dies. main() then reports the status of the player at the end of the game.

4) You still don't have a loop to re-prompt the user if they enter invalid input as I suggested in your other thread. As it is now, if the user enters invalid input, the game is over.






Last edited on
Ok, sorry I didn't realize that you replied again on my other post and thank you. I went ahead and did your suggestions from the other post and the incorrect input works now with the loop. I don't really understand what return i does though. I get what you are saying with the run function but what if the user puts "run away from bear" or something of that nature. the function would ask run where.
Also how would I pass the vector into userInput (sorry if its a dumb question)

so the function for run would look like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int run(){
    vector <string> enemies;
    enemies.reserve(5);
    enemies.push_back("BEAR");
    char input[100];
    cout << "Run where?" << endl;
    cin >> input;
    for (int x = 0; input[x] != '\0'; x++){
        input[x]=toupper(input[x]);
    }
    for (int i = 0; i < enemies.size(); i++){
        if (input == enemies.at(i)){
            if (enemies.at(i) == "BEAR"){
                cout << "You can't escape." << endl;
            }
        }
        return i;
    }
    return 0;
}

I mean I think this is how you would set it up but something's not working so I guess not.
Well it works if i just type i bear after it says "Run where?" but why is that, shouldn't as long as they have bear in the sentence it would print out "You can't escape."?
and here is the whole code now
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int userInput();
int run();

int main() {
    int HP;
    int maxHP;
    int MP;
    int maxMP;
    char name[12];
    int invenSpace;
    vector <string> keyWords;
    keyWords.reserve(5);
    keyWords.push_back("USE");
    keyWords.push_back("GO");
    keyWords.push_back("ATTACK");
    keyWords.push_back("RUN");
    keyWords.push_back("GRAB");
    
    bool bear = false;
    

    cout << "BASIC COMMANDS" << endl;
    cout << "USE, GO, ATTACK, RUN, GRAB, OPEN" << endl;
    cout << "" << endl;
    cout << "You are walking into a forest and see a bear " << endl;
    cout << "amongst the trees. It goes to attack you." << endl;
    cout << "What now?" << endl;
    
    userInput();
    
};


int userInput() {
    vector <string> keyWords;  
    keyWords.reserve(6);       
    keyWords.push_back("USE");  
    keyWords.push_back("GO");       
    keyWords.push_back("ATTACK");  
    keyWords.push_back("RUN");    
    keyWords.push_back("GRAB");   
    keyWords.push_back("OPEN");
    //enemy words
    vector <string> enemies;
    enemies.reserve(5);
    enemies.push_back("BEAR");
    char input[100]; 
while (true){
    cin >> input;   
    for (int i = 0; input[i] != '\0'; i++){  
        input[i]=toupper(input[i]);            
    }
    for (int i=0; i<keyWords.size(); i++){  
        if (input == keyWords.at(i)){ 
            
            if (keyWords.at(i) == "RUN") {
                 run();
            }
            if (keyWords.at(i) == "USE") {
                cout << "Use what?" << endl;
            }
            if (keyWords.at(i) == "GRAB") {
                cout << "Grab what?" << endl;
            }
            if (keyWords.at(i) == "GO") {
                cout << "Go where?" << endl;
            }
            if (keyWords.at(i) == "ATTACK") {
                cout << "Attack what?" << endl;
            }
            if (keyWords.at(i) == "OPEN") {
                cout << "Open what?" << endl;
            }
            
            return i; 
        }
    }
             cout << "'" << input << "'" << " not registered as a valid command." << endl;  
}   
   return 0;
};

int run(){
    vector <string> enemies;
    enemies.reserve(5);
    enemies.push_back("BEAR");
    char input[100];
    cout << "Run where?" << endl;
    cin >> input;
    for (int x = 0; input[x] != '\0'; x++){
        input[x]=toupper(input[x]);
    }
    for (int i = 0; i < enemies.size(); i++){
        if (input == enemies.at(i)){
            if (enemies.at(i) == "BEAR"){
                cout << "You can't escape." << endl;
            }
        }
        return i;
    }
    return 0;
}
It's best to keep to one thread. It avoids confusion.

I don't really understand what return i does though

The purpose of the return i; is to communicate back to the caller which keyword was selected.

This brings up a style issue. Do want userInput() to act on what was typed (as in RUN), or do you want userInput() to simply get a keyword and return the index to that keyword back to the caller?

Also how would I pass the vector into userInput
1
2
3
4
5
6
7
8
9
10
// line 7
int userInput (const vector<string> & keywords);

// line 35
  userInput (keywords);

//  line 40
int userInput (const vector<string> & keywords)

// Delete lines 41-48 

Although with your current code it's not necessary to pass it. lines 17-23 are extraneous (not used).

lines 63, 89, 105, 107: The whole point of returning a value back to the caller, is to let the caller know the outcome of the function. You're passing back either i or 0. Since you currently have only one enemy, i can only be 0 since "BEAR" is the 0th entry.

lines 94-107: You need a loop here also (like in userInput) so that you repeat the question if the user did not type a valid answer.

edit:
Note that you're doing exactly the same thing in userInput and run, that is you're searching a vector of strings. Anytime you do something more than once, it suggests you need a function.

Consider calling the following from both userInput and run:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//  Search the passed vector for a keyword
//  Returns the index of the keyword that was found,
//  Loops until a valid keyword is entered.
int find_keyword (const vector<string> & keywords)
{   char input[100];
    while (true)
    {   cin >> input;   
        for (int i = 0; input[i] != '\0'; i++)
        {   input[i]=toupper(input[i]);            
        }
        for (int i=0; i<keywords.size(); i++)
        {   if (input == keywords.at(i))
                return i;   //  Return the index of the entry
        }
        //  Not found
        cout << "'" << input << "'" << " not a valid keyword." << endl;  
    }   
}


run() becomes simpler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int run()
{   int enemy;
    
    vector <string> enemies;
    enemies.reserve(5);
    enemies.push_back("BEAR");    
    cout << "Run where?" << endl;
    enemy = find_keyword (enemies);
    switch (enemy)
    {
    case 0:
        cout << "You can't escape from the bear." << endl;
    }
    return 0;
}

Last edited on
Topic archived. No new replies allowed.