help on dealing with simplifying

I need help with simplifying this code I wrote for a project. I want to be able to pull from it the save throw values and use them when I do rolls, however I don't know how to connect the classes with representatives for them. Could anyone help me?
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include <iostream>
#include <string>
using namespace std;

class Ranger
{
        private:
                int Str;
                int Dex;
                int Con;
                int Int;
                int Wis;
                int Cha;
                int roll;
                
        public:
                void displayStats()  //in order to cout in must be declared
                {
                    cout << "enter the number you rolled for ranger\n";
                    cin >> roll;
                    cout << "Saving throws for ranger are \n";
                    cout << "Str = " << roll+Str << "\n";
                    cout << "Dex = " << roll+Dex << "\n";
                    cout << "Con = " << roll+Con << "\n";
                    cout << "Int = " << roll+Int << "\n";
                    cout << "Wis = " << roll+Wis << "\n";
                    cout << "Cha = " << roll+Cha << "\n";
                    
                }
                
                void setStr(int value) //void set can be called out in int main
                { Str = value;    }
                
                void setDex(int value) //title void set___ is how it is found by anil
                { Dex = value;    }
                
                void setCon(int value)  
                { Con = value;    }
                
                void setInt(int value) 
                { Int = value;    }
                
                void setWis(int value) 
                { Wis = value;    }
                
                void setCha(int value) 
                { Cha = value;    }
                

};

class Sorcerer
{
        private:
                int Str;
                int Dex;
                int Con;
                int Int;
                int Wis;
                int Cha;
                int roll;
                
        public:
                void displayStats()  //in order to cout in must be declared
                {
                    cout << "enter the number you rolled for sorcerer\n";
                    cin >> roll;
                    cout << "Saving throws for sorcerer are \n";
                    cout << "Str = " << roll+Str << "\n";
                    cout << "Dex = " << roll+Dex << "\n";
                    cout << "Con = " << roll+Con << "\n";
                    cout << "Int = " << roll+Int << "\n";
                    cout << "Wis = " << roll+Wis << "\n";
                    cout << "Cha = " << roll+Cha << "\n";
                    
                }
                
                void setStr(int value) 
                { Str = value;   }
                
                void setDex(int value) 
                { Dex = value;    }
                
                void setCon(int value)  
                { Con = value;    }
                
                void setInt(int value) 
                { Int = value;    }
                
                void setWis(int value) 
                { Wis = value;    }
                
                void setCha(int value) 
                { Cha = value;    }
};               

class Bard
{
        private:
                int Str;
                int Dex;
                int Con;
                int Int;
                int Wis;
                int Cha;
                int roll;
                
        public:
                void displayStats()  //in order to cout in must be declared
                {
                    cout << "enter the number you rolled for bard\n";
                    cin >> roll;
                    cout << "Saving throws for bard are \n";
                    cout << "Str = " << roll+Str << "\n";
                    cout << "Dex = " << roll+Dex << "\n";
                    cout << "Con = " << roll+Con << "\n";
                    cout << "Int = " << roll+Int << "\n";
                    cout << "Wis = " << roll+Wis << "\n";
                    cout << "Cha = " << roll+Cha << "\n";
                    
                }
                
                void setStr(int value) 
                { Str = value;   }
                
                void setDex(int value) 
                { Dex = value;    }
                
                void setCon(int value)  
                { Con = value;    }
                
                void setInt(int value) 
                { Int = value;    }
                
                void setWis(int value) 
                { Wis = value;    }
                
                void setCha(int value) 
                { Cha = value;    }
};

class Warlock
{
        private:
                int Str;
                int Dex;
                int Con;
                int Int;
                int Wis;
                int Cha;
                int roll;
                
        public:
                void displayStats()  //in order to cout in must be declared
                {
                    cout << "enter the number you rolled for warlock\n";
                    cin >> roll;
                    cout << "Saving throws for warlock are \n";
                    cout << "Str = " << roll+Str << "\n";
                    cout << "Dex = " << roll+Dex << "\n";
                    cout << "Con = " << roll+Con << "\n";
                    cout << "Int = " << roll+Int << "\n";
                    cout << "Wis = " << roll+Wis << "\n";
                    cout << "Cha = " << roll+Cha << "\n";
                    
                }
                
                void setStr(int value) 
                { Str = value;   }
                
                void setDex(int value) 
                { Dex = value;    }
                
                void setCon(int value)  
                { Con = value;    }
                
                void setInt(int value) 
                { Int = value;    }
                
                void setWis(int value) 
                { Wis = value;    }
                
                void setCha(int value) 
                { Cha = value;    }
};





        int main ()
        {
                Ranger player1;
                player1.setStr(3);  //searches through void set___
                player1.setDex(3);
                player1.setCon(-1);
                player1.setInt(0);
                player1.setWis(2);
                player1.setCha(1);
                player1.displayStats();
                
                Sorcerer player2;
                player2.setStr(1);  //searches through void set___
                player2.setDex(3);
                player2.setCon(2);
                player2.setInt(2);
                player2.setWis(0);
                player2.setCha(-1);
                player2.displayStats();
                
                Bard player3;
                player3.setStr(0);  //searches through void set___
                player3.setDex(2);
                player3.setCon(1);
                player3.setInt(1);
                player3.setWis(0);
                player3.setCha(3);
                player3.displayStats();
                
                Warlock player4;
                player4.setStr(-1);  //searches through void set___
                player4.setDex(2);
                player4.setCon(1);
                player4.setInt(2);
                player4.setWis(0);
                player4.setCha(3);
                player4.displayStats();
                
                return 0;
        }
First of all, all your classes have the exact same methods, so you should probably create a base class that implements all of these methods and just have each of your classes derive from it. You don't need to override the methods, just have them defined in the base class.
@icecody12

Here is the condensed version of your program, as @TheToaster suggested, but I had to change your class from private to public, so I can print out the values. I then added in the ability to view any of the 4 classes, to see that each has their own values.
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
#include <iostream>
#include <string>

using namespace std;

class 
{

public:
	string char_type;
	int Str;
	int Dex;
	int Con;
	int Int;
	int Wis;
	int Cha;
	int roll;

	void Roll_Die(string character)
	{
		char_type = character;
		cout << "\nEnter the number you rolled for the " << char_type << "\n";
		cin >> roll;
	}
	void setStr(int value) //void set can be called out in int main
	{ Str = value + roll;    }

	void setDex(int value) //title void set___ is how it is found by anil
	{ Dex = value + roll;    }

	void setCon(int value)  
	{ Con = value + roll;    }

	void setInt(int value) 
	{ Int = value + roll;    }

	void setWis(int value) 
	{ Wis = value + roll;    }

	void setCha(int value) 
	{ Cha = value + roll;    }

	void displayStats(string character)  //in order to cout in must be declared
	{
		cout << "Saving throws for " << char_type << " are \n";
		cout << "Str = " << Str << "\n";
		cout << "Dex = " << Dex << "\n";
		cout << "Con = " << Con << "\n";
		cout << "Int = " << Int << "\n";
		cout << "Wis = " << Wis << "\n";
		cout << "Cha = " << Cha << "\n";

	}
} play_char[4];


int main ()
{
	int x;

	string players[4] = {"Ranger", "Sorcerer", "Bard", "Warlock"};
	int strength[4] = {3, 1, 0, -1}, dexterity[4] = {3, 3, 2, 2}, constiution[4] = {-1, 2, 1, 1}, intelligence[4] = {0, 2, 1, 2}, wisdom[4] = {2, 0, 0, 0},charisma[4] = {1, -1, 3, 3 };
	for(x=0;x<4;x++)
	{
		play_char[x].Roll_Die(players[x]);
		play_char[x].setStr(strength[x]);
		play_char[x].setDex(dexterity[x]);
		play_char[x].setCon(constiution[x]);
		play_char[x].setInt(intelligence[x]);
		play_char[x].setWis(wisdom[x]);
		play_char[x].setCha(charisma[x]);
		play_char[x].displayStats(players[x]);
	}
	do
	{
		cout << "Review which character? (1 thru 4 - Enter 0 to quit)" << endl;
		cin >> x;
		if (x==0)
		{
			cout << "End program.." << endl;
			return 0;
		}
		x--;
		cout << "Reviewing the " << play_char[x].char_type << "\n";

		cout << "Strength = " << play_char[x].Str << "\n";
		cout << "Dexterity = " << play_char[x].Dex << "\n";
		cout << "Constitution = " << play_char[x].Con << "\n";
		cout << "Intellegence = " << play_char[x].Int << "\n";
		cout << "Wisdom = " << play_char[x].Wis << "\n";
		cout << "Charisma = " << play_char[x].Cha << "\n";
	}while(x!=-1 || x>3);
	return 0;
}
@whitenite
While your code works, I strongly suggest this kind of hierarchy be implemented using simple inheritance. The method you have suggested is inefficient since all of the attributes are compile-time constants and not to mention it would be horrible to maintain long term. There is no need for client code to set the initial stats of the Characters since they should be hardcoded in by the type of character they are.

OP, since it is the programmer and not the client code that sets the attributes for each class, it would be much better to implement this as a heirarchy. Furthermore, the client code should NOT have direct access to change the attributes of particular entities (for example, client code should not be able to set the dexterity or strength of a ranger. This should be done by the ranger class itself). Here's something to get started with:

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
#include <iostream>

template<int... Args>
class Character
{
protected:
    struct
    {
        int DEX{},
            STR{},
            COM{};
    } stats;
public:
    Character() : stats{Args...} {}
    virtual void do_character_specific_action() =0;
    virtual void display_character() final
    {
        std::cout << stats.DEX << ' '
                  << stats.STR << ' '
                  << stats.COM << '\n';
    }
};

class Ranger : public Character<2,3,-1>
{
    std::string m_name;
public:
    Ranger(std::string const& name) : Character(), m_name{name} {}
    virtual void do_character_specific_action() override 
    {
        std::cout << "I am " << m_name << '\n';
        display_character();
    }
};

int main()
{
    Ranger ranger("John");
    ranger.do_character_specific_action();
}
Last edited on
I avoid complexity until I actually NEED it.
so I would actually just use a generic character class that has a type (enum seems useful here?) that says what it is (ranger, fighter, whatever). You may need more than 1, are you going to allow multi-classing (just think ahead on stuff like this so you are not trapped later when you need it but can't easily slice it in).

Inheritance and all that works well too, but it may be overkill. As above, *think ahead* so you can decide if inheritance and polymorphism and so on are actually providing you anything useful or not.

Stop and write down exactly what you want to support and actually write some pseudoC++ that gives you the syntax of how you want to USE your classes (this really, really helps!). Write some code to create a character and access the data for it that you need to perform the actions you want in your program. Then back track that and figure out what you need to make it work like that. It is just for thinking, it does not matter if you make the methods you list or the data items you access, the point is to just to have them on paper -- pretend your class does not even exist yet, and you are going back in time to design it from scratch...
Last edited on
If those values for Ranger, Sorcerer, Bard and Warlock will apply to all characters of those types then you could have a generic character class and just set the values in the constructor for each derived class:
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
113
#include <iostream>
#include <string>
using namespace std;

class Character
{
  private:
    int Str;
    int Dex;
    int Con;
    int Int;
    int Wis;
    int Cha;
    int roll;
    string charType;
    
  public:
    Character(int str, int dex, int con, int intel, int wis, int cha,
	      const string &chType) :
	Str(str), Dex(dex), Con(con), Int(intel), Wis(wis), Cha(cha),
	roll(0), charType(chType)
    {}
    
    void Roll()
    {
	cout << "enter the number you rolled for " << charType<< '\n';
	cin >> roll;
    }	

    void displayStats()		//in order to cout in must be declared
    {
	cout << "Saving throws for " << charType << " are \n";
	cout << "Str = " << roll + Str << "\n";
	cout << "Dex = " << roll + Dex << "\n";
	cout << "Con = " << roll + Con << "\n";
	cout << "Int = " << roll + Int << "\n";
	cout << "Wis = " << roll + Wis << "\n";
	cout << "Cha = " << roll + Cha << "\n";
    }

    void setStr(int value)	//void set can be called out in int main
    {
	Str = value;
    }

    void setDex(int value)	//title void set___ is how it is found by anil
    {
	Dex = value;
    }

    void setCon(int value)
    {
	Con = value;
    }

    void setInt(int value)
    {
	Int = value;
    }

    void setWis(int value)
    {
	Wis = value;
    }

    void setCha(int value)
    {
	Cha = value;
    }

};

class Ranger : public Character
{
public:
    Ranger() : Character(3,3,-1,0,2,1,"ranger") {}
};
class Sorcerer : public Character
{
public:
    Sorcerer(): Character(1,2,3,3,0,-1, "sorcerer") {}
};

class Bard : public Character
{
public:
    Bard() : Character(0,2,1,1,0,3, "bard") {}
};

class Warlock : public Character
{
public:
    Warlock(): Character(-1,2,1,2,0,3, "warlock") {}
};

int
main()
{
    Ranger player1;
    player1.Roll();
    player1.displayStats();
    Sorcerer player2;
    player2.Roll();
    player2.displayStats();
    Bard player3;
    player2.Roll();
    player3.displayStats();
    Warlock player4;
    player2.Roll();
    player4.displayStats();

    return 0;
}


But it's likely that Jonnin's approach will turn out to be the right one. You have one character class and the different traits of just encoded in the members.
Thank you guys I have been trying to get it to work for our overall project and been having problems trying to condense and implement it into the project thank you.
Topic archived. No new replies allowed.