How do I let variables change based upon a string entry?

Hi! I'm setting up a fight system for my text adventure/rpg, and I got random rolls to meet different enemies working. But I'm stuck trying to find out how to change their HP and damage without dozens of if-statements for each one. I want to have a HP/damage-base construct, and it should change it's values just by reading the enemy's name.

I tried to get it working with arrays, I'm currently trying it with namespaces, but I don't know the commands or methods to finish it.

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
#include <iostream>
#include <iostream>
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <ctime>
#include <string>
#include <sstream>

using namespace std;

bool fightmode = 0;
string ACTION = "0";
string mname = "0";
int mroll = 0;
int phealth = 0;
int mhealth = 0;
int mdamage = 0;
int pdamage = 0;
int game = 1;


namespace DEATHDRAKE{
    int mhealth = 380;
    int mdamage = 35;
}
namespace MANAVIPER{
    int mhealth = 185;
    int mdamage = 8;
    }
namespace THIRSTER{
    int mhealth = 220;
    int mdamage = 24;
    }

int main (){
srand(time(0));

while(game == 1){

reroll:

getline (cin, ACTION);

if (ACTION == "f")
{
    fightmode = 1;
    mroll = rand() % 100;


if  (mroll > 50)
    {mname = "DEATHDRAKE";}

if  (mroll == 50)
    {mname = "THIRSTER";}

if  (mroll < 50)
    {mname = "MANAVIPER";}


    goto Battle;
}
}


while (fightmode == 1){
Battle:
    cout << mname << "\n";
    cout << "Monster health: " << mhealth << "\n";
    cout << "Monster damage: " << mdamage << "\n";
    cout << "Encounter roll: " << mroll << "\n";
    cout << "fightmode: " << fightmode << "\n";
    cout <<  "\n";
    cout <<  "\n";


fightmode = 0;
goto reroll;
    }


}


That's the code and where I'm at, and it's stopping my entire project! Please help!
Im just started to learn about class hierarchies but if "DEATHDRAKE", "MANAVIPER", "THIRSTER" are monsters I would create abstract base class as interface for all monsters
for example
1
2
3
4
5
6
class Monster{
public:
     virtual void attack(/*some1 thats being attacked*/) = 0;
     virtual void eat_healing_potion() = 0;
     //...
};


and than derive specific monster classes from this interface
1
2
3
4
5
6
7
8
9
10
11
class Deathdrake : public Monster{
public:
     void attack(/*some1 thats being attacked*/) override;
     void eat_healing_potion() override;
     //...
private:
     //implementation details like
     int health;
     int damage;
     //...
};

Than it would be easy to create monsters where needed and they would keep track of their own stats.
Last edited on
hey, thanks for answering me! It didn't help me all too much though, I don't know how to use classes, and I never used the void type before. You have to give me a better explanation how to implement it into the code, I see that it can save me a lot of typing, but until I figure out how to use it, i must work to my capabilities.

Speaking of, your tip-off to classes made me look deeper into pointers and datastructures, and I am actually getting a grip on that! I can make use of pointers, which could be quintessential to solving my problem, and get a data structure going.
Infact, I already created a monster structure, and put my 3 beasts in them, but once again, a problem cockblocks me from progressing: I can't assign values to specific members of a structure! The error just says "expected intializer before '.' token", i'll show you the code:

1
2
3
4
5
6
struct MONSTER{
    int mdamage;
    int mhealth;} DEATHDRAKE;

int DEATHDRAKE.mdamage = 35;
int DEATHDRAKE.mhealth = 380;


If you can solve me this, I could finish up the rest with the use of pointers, and then it's finally done!
(And I would owe you an exclusive ULTIMATE edition of my future game, hehe!)
1
2
int DEATHDRAKE.mdamage = 35;
int DEATHDRAKE.mhealth = 380;


Your use of int is superfluous / incorrect. To the compiler it looks like you're trying to instantiate a new variable with incorrect syntax.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Monster {
	int health;
	int damage;
};

int main() {

	Monster drake;

	drake.health = 100;
	drake.damage = 15;

	return 0;
}


That should be enough to get you going. Classes are an extremely important concept, so much so that you won't be able to avoid using them.
Last edited on
xismn already showed how to use struct but maybe I could show a little more how to use them

First you can create your monsters with very specific stats for each of them
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
#include <iostream>

struct Deathdrake{
    //if you initialize variable here the stats will be there when you create an instance
    //of this object, otherwise you would have to give these stats yourself after each
    //object is created!

    int HP = 1000;               
    int damage = 150;
};

struct Manaviper{
    int HP = 500;
    int damage = 70;
};

//now you can use him like this
int main(){
                                  //deathdrake is just a type like int or double so you
                                  //have to create object of that type before you can use it
                                  //objects created here is 'drake' and 'viper'
    Deathdrake drake;    
    Manaviper viper;
    /*Tnx to 'default construtor' of drake and viper they already have damage given 
    and HP given : drake has 1000HP and 150 dmg and viper has 500 HP and 70 dmg*/
    
    //now you can access individual parts of this drake like this;
    
    if(drake.damage > viper.damage) std::cout << "Deathdrake is so much cooler than Manaviper!\n" ;

    //or

    int drakes_dmg = drake.damage;    //drakes_dmg variable will have value of 150

    //or reduce manavipers HP

    viper.HP -= 70;  // same as viper.HP = viper.HP - 70;  
    //now viper's HP will become 430

    //or 

    std::cout << "drake's damage is " << drake.damage << std::endl;
}


You can create as much objects of Deathdrake or whatever else as you want and each time they will be given default stats. Of course you have to name them differently like int x; int x2; int x3;
Hope this helps a little bit.
But yea like xismn told - classes are very important and not that hard to learn. You should read a bit more into them and in no time you can get this program done better than you expected!

You can also add member function like is_alive() to check if dude has any health left
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

struct Manaviper{
    int HP = 500;
    int damage = 70;

    bool is_alive() const { 
        if(HP > 0) return true;
        return false; }
};

int main(){
    Manaviper viper;
    //viper gets attacked here and looses 600 HP by 1 hit
    viper.HP -= 600;

    if(viper.is_alive()) std::cout << "viper is alive and ready to fight!\n";
    else std::cout << "viper is long gone! RIP\n";
}


EDIT :

you can also add member function that removes HP for you so you dont have to write viper.HP -= 70;
Ill upgrade the last struct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

struct Manaviper{
    int HP = 500;
    int damage = 70;

    bool is_alive() const { 
        if(HP > 0) return true;
        return false; }
    void reduce_HP(int num_of_hp){ HP -= num_of_hp;} //void means that function is not returning any value
};

//now you can rewrite prevous code like this

int main(){
    Manaviper viper;
    //viper gets attacked here and looses 600 HP by 1 hit
    viper.reduce_HP(600);
    
    if(viper.is_alive()) std::cout << "viper is alive and ready to fight!\n";
    else std::cout << "viper is long gone! RIP\n";
}
Last edited on
YESSSSSSS! I DID IT!

http://abload.de/img/yessssssssssdiumh.png

thanks to etrusks and xismn, especially to you etrusks! I can't believe how happy I can get just by seeing 4 lines of text, ahahaha! And I can do even more stuff now that I can use data structures, and when I actually learn about classes, oh this is going to be GOOOOD! Oh man, the door has just opened!

here is the code that I used!:


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
#include <iostream>
#include <iostream>
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <ctime>
#include <string>
#include <sstream>

using namespace std;

bool fightmode = 0;
string ACTION = "0";
string mname = "0";
int mroll = 0;
int phealth = 0;
int pdamage = 0;
int game = 1;
int *mh;
int *md;



struct  DEATHDRAKE{
    int mdamage = 35;
    int mhealth = 380;
        bool is_alive() const {
        if(mhealth > 0) return true;
        return false; }};

struct MANAVIPER{
    int mdamage = 8;
    int mhealth = 185;
       bool is_alive() const {
        if(mhealth > 0) return true;
        return false; } };






int main (){
srand(time(0));

DEATHDRAKE drake;
MANAVIPER viper;

while(game == 1){

reroll:

getline (cin, ACTION);

if (ACTION == "f")
{
    fightmode = 1;
    mroll = rand() % 100;


if  (mroll > 50)
    {mname = "DEATHDRAKE";
    mh = &drake.mhealth;
    md = &drake.mdamage;
    }

if (mroll < 50)
{
    mname = "MANAVIPER";
    mh = &viper.mhealth;
    md = &viper.mdamage;
}

    goto Battle;
}
}


while (fightmode == 1){
Battle:
    cout << mname << "\n";
    cout << "Monster-damage: " << *md << "\n";
    cout << "Monster-health: " << *mh << "\n";


fightmode = 0;
goto reroll;
    }


}



Sometime in the future, you will recieve an ominous private message, promising danger, glory and adventure with a link to a mysterious game...!!! hahaha, thanks so much!!
Ok, Good Work !!

Now see if you can improve that quite a bit by not using goto or have using namespace std; Google that one !!

The goto is especially awkward because you jump in and out of loops.

Also try not to #include files you don't need :+) , and the ones you do need - only include them once.

Use true and false with bool variables, it's easier to read.

Good Luck !!
Last edited on
Would be cool to see next projects like this from you! And keep learning! :D
Topic archived. No new replies allowed.