Help with a text based game I am trying to make

Hello, Im pretty new to programming but i think i knew enough information to make a small text based game right now i am having an issue where i want it to return the race and class from functions back into my main function so it will say something like "Welcome Drexsel you are a human mage." heres my code im using so far.

#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

enum races {human, orc, dwarf, elf, undead};
enum classes {mage, rogue, warrior};

void raceFun (char race);
void classFun (char spec);

int main()
{
char race, spec;
string name;

cout << "Welcome to the game... This game takes place in the forth age of on a small planet called valmor. One hero must fight their way to the end and bring peace back to the forth age. Press enter to continue." << endl;

//Used to pause the system
cin.get();

//Prompt the user to enter their race
cout << "Choose a race from the list of human, orc, dwarf, elf, or undead... Each race as its own racial advantages and disadvantages. Just enter the first letter of the race you want to be" << endl;

//Enter your race
cin >> race;

//Takes entered race to the race function
raceFun (race);

//Promt the user to enter their class
cout << "Please select a class from the list of mage, rogue, warrior." << endl;

//Enter your class
cin >> spec;

//Takes you to class function
classFun(spec);

//Promt the user to enter characters name
cout << "Enter the name of your character" << endl;

//Enter name
cin >> name;

//Recap of all the options the user choose
cout << "Welcome " << name << " the " << race << " " << spec << "." << endl;
}

void raceFun (char race)
{
//Changes race to an uppercase letter
race = toupper(race);

//Tells the user what their races backstory and racial benefits are
switch (race)
{
case 'D':
cout << "When the third age of Valmor came dwarves were more accepted by the society of the surface, leaving their homes under the mountains to experience a much different life. But when the skys darkened and the fear creatures of legend fell from the sky the dwarves fled back under the mountain to wait. The hard life of the stone and craft gives you an additional 7 percent health as well as an additional 5 percent damage when using a two handed axe or mac. Dwarves however, cannot use magic of any kind. " << endl;
break;
case 'E':
cout << "You choose to be an elf" << endl;
break;
case 'H':
cout << "You choose to be a human" << endl;
break;
case 'O':
cout << "You choose to be an orc" << endl;
break;
case 'U':
cout << "You choose to be an undead" << endl;
break;
default:
cout << "Bad input program terminated." << endl;
}
}

void classFun (char spec)
{
//Changes spec to an uppercase letter
spec = toupper(spec);

//Tells the user what class they choose
switch (spec)
{
case 'M':
cout << "You choose to be a mage." << endl;
break;
case 'R':
cout << "You choose to be a rouge." << endl;
break;
case 'W':
cout << "You choose to be a warrior." << endl;
break;
default:
cout << "Bad input program terminated." << endl;
}

}

I believe I need to change the chars to strings in the switch but I am not sure. Any help would be greatly appreciated.
Use std::map to look up the strings, perhaps. http://en.cppreference.com/w/cpp/container/map

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 <cstdlib>
#include <string>
#include <cctype> // *** added
#include <map> // *** added

// using namespace std; // *** removed

enum races {human, orc, dwarf, elf, undead};
enum classes {mage, rogue, warrior};

const std::map< char, std::string > race_map =
    { { 'H', "human" }, { 'O', "orc" }, { 'D', "dwarf" }, { 'E', "elf" }, { 'U', "undead" } } ;

const std::map< char, std::string > class_map = { { 'M', "mage" }, { 'R', "rogue" }, { 'W', "warrior" } } ;

void raceFun (char race);
void classFun (char spec);

int main()
{
    std::cout << "Welcome to the game...\n"
                 "This game takes place in the forth age of on a small planet called valmor.\n"
                 "One hero must fight their way to the end and bring peace back to the forth age.\n"
                 "Press enter to continue\n" ;
    std::cin.get();

    //Prompt the user to enter their race
    std::cout << "Choose a race from the list of human, orc, dwarf, elf, or undead...\n"
                 "Each race as its own racial advantages and disadvantages.\n"
                 "Just enter the first letter of the race you want to be: " ;
    char race ;
    std::cin >> race;
    raceFun (race);

    std::cout << "\nPlease select a class from the list of mage, rogue, warrior: " ;
    char spec ;
    std::cin >> spec;
    classFun(spec);

    std::cout << "\nEnter the first name of your character: " ;
    std::string name;
    std::cin >> name ;

    const auto riter = race_map.find( std::toupper(race) ) ;
    const std::string race_str = riter == race_map.end() ? "????" : riter->second ;

    const auto citer = class_map.find( std::toupper(spec) ) ;
    const std::string class_str = citer == class_map.end() ? "????" : citer->second ;
    std::cout << "\n\nWelcome " << name << ", the " << race_str << ' ' << class_str << ".\n" ;
}

void raceFun (char race)
{
    race = std::toupper(race); // #include <cctype>

    //Tells the user what their races backstory and racial benefits are
    switch (race)
    {
    case 'D':
        std::cout << "When the third age of Valmor came dwarves were more accepted by the society of the surface,\n"
                     "leaving their homes under the mountains to experience a much different life\n."
                     "But when the skys darkened and the fear creatures of legend fell from the sky\n"
                     "the dwarves fled back under the mountain to wait.\n"
                     "The hard life of the stone and craft gives you an additional 7 percent health\n"
                     "as well as an additional 5 percent damage when using a two handed axe or mac.\n"
                     "Dwarves however, cannot use magic of any kind.\n" ;
        break;
    case 'E':
        std::cout << "You choose to be an elf\n" ;
        break;
    case 'H':
        std::cout << "You choose to be a human\n" ;
        break;
    case 'O':
        std::cout << "You choose to be an orc\n" ;
        break;
    case 'U':
        std::cout << "You choose to be an undead\n" ;
        break;
    default:
        std::cout << "Bad input program terminated.\n" ;
        std::exit(1) ;
    }
}

void classFun (char spec)
{
//Changes spec to an uppercase letter
    spec = toupper(spec);

//Tells the user what class they choose
    switch (spec)
    {
    case 'M':
        std::cout << "You choose to be a mage.\n" ;
        break;
    case 'R':
        std::cout << "You choose to be a rouge.\n" ;
        break;
    case 'W':
        std::cout << "You choose to be a warrior.\n" ;
        break;
    default:
        std::cout << "Bad input program terminated.\n" ;
        std::exit(1) ;
    }
}

http://coliru.stacked-crooked.com/a/e51baf7b04723c72
Ok awesome that worked i had to do some research on maps first though lol. I am just wondering why wouldn't something like this work? I was trying to make both race and spec strings and then when the strings go to the raceFun it would use race.at(0) to grab the letter at that position (I.e 'D' for 'Dwarf') and then convert that letter into a char variable known as ch. So i can keep my strings in the main function and then just convert them to char in the other function when i need to preform a switch operation.

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
int main()
{
    string race, spec;
    string name;
    
    cout << "Welcome to the game... This game takes place in the forth age of on a small planet called valmor. One hero must fight their way to the end and bring peace back to the forth age. Press enter to continue." << endl;
    
    //Used to pause the system
    cin.get();
    
    //Prompt the user to enter their race and takes them to the race function
    cout << "Choose a race from the list of human, orc, dwarf, elf, or undead... Each race as its own racial advantages and disadvantages. Just enter the first letter of the race you want to be" << endl;
    cin >> race;
    raceFun (race);
    
    //Promt the user to enter their class and takes them to the spec function
    cout << "Please select a class from the list of mage, rogue, warrior." << endl;
    cin >> spec;
    classFun(spec, race);
    
    //Promt the user to enter characters name
    cout << "Enter the name of your character" << endl;
    cin >> name;
    
    //Recap of all the options the user choose
    cout << "Welcome " << name << " the " << race << " " << spec << "." << endl;
}

void raceFun (string race)
{
    char ch;
    
//Takes the first letter of the string and makes it a char variable
    race.at(0) = ch;
    
    //Changes the letter grab from race to an uppercase letter
    ch = toupper(ch);
    
    //Tells the user what their races backstory and racial benefits are
    switch (ch)
     {
         case 'D':
             cout << "When the third age of Valmor came dwarves were more accepted by the   society of the surface, leaving their homes under the mountains to experience a much different life. But when the skys darkened and the fear creatures of legend fell from the sky the dwarves fled back under the mountain to wait. The hard life of the stone and craft gives you an additional 7 percent health as well as an additional 5 percent damage when using a two handed axe or mace. Dwarves however, cannot use magic of any kind. Press enter to continue." << endl;
             break;
         case 'E':
             cout << "You choose to be an elf" << endl;
             break;
         case 'H':
            cout << "You choose to be a human" << endl;
            break;
         case 'O':
            cout << "You choose to be an orc" << endl;
            break;
         case 'U':
             cout << "You choose to be an undead" << endl;
             break;
         default:
             cout << "Bad input program terminated." << endl;
             exit(1);
     }
}

Also I tried using an enumeration function where I entered the race as a string and then set the enumeration identifier to race (myRace = race) but when it converts it the output of the enumeration value is always zero even before i toss it into the raceFun. any ideas?

heres an example

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
int main()
{
races myRace;
string race, spec;
string name;

cout << "Welcome to the game... This game takes place in the forth age of on a small planet called valmor. One hero must fight their way to the end and bring peace back to the forth age. Press enter to continue." << endl;

//Used to pause the system
cin.get();

//Prompt the user to enter their race and takes them to the race function
cout << "Choose a race from the list of human, orc, dwarf, elf, or undead... Each race as its own racial advantages and disadvantages. Just enter the first letter of the race you want to be" << endl;
cin >> race;
myRace = race;

//when i cout it here i get zero as the value
cout << myRace << endl;


raceFun (races myRace);

//Promt the user to enter their class and takes them to the spec function
cout << "Please select a class from the list of mage, rogue, warrior." << endl;
cin >> spec;
classFun(spec, race);

//Promt the user to enter characters name
cout << "Enter the name of your character" << endl;
cin >> name;

//Recap of all the options the user choose
cout << "Welcome " << name << " the " << race << " " << spec << "." << endl;
}

This is my first time writing a code that I wasnt assigned so i really dont have any guidelines to go by. I wanted to type something myself to better understand c++. To anyone who helps me thank you.
Last edited on
1
2
//Takes the first letter of the string and makes it a char variable
race.at(0) = ch;

You have your assignment statement backwards. The value you're assigning to must be on the left.

1
2
//when i cout it here i get zero as the value
cout << myRace << endl;

myRace is of type races. You haven't shown your declaration for type races. If you're using JLBorges definition in line 9 of his post, his races is an enum enums are integer values implicitly numbered from 0. Using his example, the value for human is 0. SO if myRace is human, then yes, displaying a 0 is correct.

PLEASE USE CODE TAGS (the <> formatting button) when posting code.
It makes it easier to read your code and also easier to respond to your post.
http://www.cplusplus.com/articles/jEywvCM9/
Hint: You can edit your post, highlight your code and press the <> formatting button.

> I was trying to make both race and spec strings and then when the strings go to the raceFun
> it would use race.at(0) to grab the letter at that position (I.e 'D' for 'Dwarf')
> and then convert that letter into a char variable known as ch.
> So i can keep my strings in the main function and then just convert them to char
> in the other function when i need to preform a switch operation.

Yes, that would work.

However, you may find that this kind of special-casing (for name) is not very flexible in the long run.
In a lookup table, we can store all the information that is required.



> I tried using an enumeration function where I entered the race as a string and then
> set the enumeration identifier to race (myRace = race)
> but when it converts it the output of the enumeration value is always zero


Something along these lines, perhaps:
(For brevity, this illustrative program manages information and operations only for the race.)

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
109
110
111
112
#include <iostream>
#include <cstdlib>
#include <string>
#include <cctype>
#include <map>

namespace game // http://en.cppreference.com/w/cpp/language/namespace
{
    // http://www.stroustrup.com/C++11FAQ.html#enum
    enum class race_type : unsigned int { human, orc, dwarf, elf, undead, invalid };

    struct race_info
    {
        std::string name ;
        std::string greeting ;
        int initial_strength ;
        int initial_health = 100 ; // http://www.stroustrup.com/C++11FAQ.html#member-init
        // ...
    };

    const std::map< race_type, race_info > race_map = // http://www.stroustrup.com/C++11FAQ.html#uniform-init
    {
        { race_type::human, { "human", "put some introdctory information about humans here", 50 } },
        { race_type::orc, { "orc", "intro stuff for orc", 70 } },
        { race_type::dwarf, { "dwarf", "When the third age of Valmor ... magic of any kind.", 30 } },
        { race_type::elf, { "elf", "something about elves", 15 } },
        { race_type::undead, { "undead", "info about undead", 60 } },
        { race_type::invalid, { "???", "???", -1 } }
    } ;

    std::string to_string( race_type r )
    {
        const auto iter = race_map.find(r) ; // unqualified looks up at namespace scope, finds game::race_map
        return iter != race_map.end() ? iter->second.name : "unknown race" ;
    }

    race_type to_race_type( std::string str )
    {
        for( char& c : str ) c = std::tolower(c) ;
        for( const auto& pair : race_map ) if( pair.second.name == str ) return pair.first ;
        return race_type::invalid ;
    }

    std::ostream& operator<< ( std::ostream& stm, race_type r ) { return stm << to_string(r) ; }

    std::istream& operator>> ( std::istream& stm, race_type& r )
    {
        std::string name ;
        if( stm >> name )
        {
            // http://en.cppreference.com/w/cpp/language/unqualified_lookup
            r = to_race_type(name) ; // unqualified looks up at namespace scope, finds game::to_race_type
            
            // http://en.cppreference.com/w/cpp/io/basic_ios/clear
            if( r == race_type::invalid ) stm.clear( std::ios::failbit ) ;
        }
        else r = race_type::invalid ;

        return stm ;
    }

    race_type get_race_type()
    {
       race_type r ;
       std::cout << "race ( " ;
       for( const auto& p : race_map ) if( p.first != race_type::invalid ) std::cout << p.second.name << ' ' ;
       std::cout << ")? " ;

       if( std::cin >> r && r != race_type::invalid ) return r ;

       std::cin.clear() ; // http://en.cppreference.com/w/cpp/io/basic_ios/clear
       std::cin.ignore( 1000, '\n' ) ; // http://en.cppreference.com/w/cpp/io/basic_istream/ignore
       std::cout << "invalid race. try again\n" ;

       return get_race_type() ;
    }

    void race_fun( race_type r ) ;
}

int main()
{
    std::cout << "Welcome to the game...\n"
                 "This game takes place in the forth age of on a small planet called valmor.\n"
                 "One hero must fight their way to the end and bring peace back to the forth age.\n"
                 "Press enter to continue\n\n" ;
    std::cin.get();

    //Prompt the user to enter their race
    std::cout << "Choose a race. Each race as its own racial advantages and disadvantages.\n" ;
    const game::race_type race = game::get_race_type() ;
    
    //  http://en.cppreference.com/w/cpp/language/adl
    race_fun(race) ; // Koenig lookup, finds game::race_fun

    std::cout << "\nEnter the first name of your character: " ;
    std::string name;
    std::cin >> name ; // Koenig lookup, finds std::operator>> ( std::istream&, std::string& )

    std::cout << "\n\nWelcome " << name << ", the " << to_string(race) << ".\n" ;
}

void game::race_fun( race_type r )
{
    if( r != race_type::invalid )
    {
        const race_info& info = race_map.find(r)->second ;
        std::cout << "\n\n" << info.greeting << '\n'
                  << "your current strength is: " << info.initial_strength << '\n'
                  << "and your current health is: " << info.initial_health << '\n' ;
    }
}

http://coliru.stacked-crooked.com/a/e19e6c273dbf39ed
Last edited on
Haha awesome such an easy fix! I was driving myself crazy with it today. Im going to try fixing the enumeration one now just so i can understand it better. JLBorges i wanted to stay away from maps just because i have not learned them. But thanks for all the help so far guys. Im going to try to finish this whole code by Monday. So it is very likely that youll be hearing more from me lol.

Also, I will defiantly start using code tags. You guys here have already helped me out more then most people. Much appreciation!!
Topic archived. No new replies allowed.