How to make efficient interactions between classes?

Hey guys, so I'm trying to make a simple console (by console i mean cmd) game where you have a character with some attributes and he will fight enemies until he dies.I feel like it would be fun and also a good way for me to learn more about classes and objects.

The question is: How could I find an efficient way to make two classes interact, without having to write all interactions in my main() function? I was reading up on something about Mediator Pattern in c++ but I didn't really understand much of it: Here is what I have read on it.

http://en.wikipedia.org/wiki/Mediator_pattern
http://sourcemaking.com/design_patterns/mediator/cpp/2

Here is some insight of what I would like to achieve:
Say I have two classes, Character and Weapon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef WEAPON_H_INCLUDED
#define WEAPON_H_INCLUDED

class Weapon
{
public: 
    Weapon(float dmgT, int dur);
    virtual float getDmg();
private:
    float dmg;
    int durability;
};

#endif // WEAPON_H_INCLUDED 


1
2
3
4
5
6
7
8
9
10
11
#include "Weapon.h"

Weapon::Weapon(float dmgT, int dur)
{
    dmg = dmgT;
    durability = dur;
}
float Weapon::getDmg()
{
    return dmg;
}


---------------------------------- End of Weapon

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
#ifndef CHARACTER_H_INCLUDED
#define CHARACTER_H_INCLUDED

class Character
{
public:
    Character(float maxHp,float str,float def);
    //return functions
    float getHp();
    float getMaxHp();
    float getStr();
    float getDef();
    float getLf();
    float getCrit();
    float getBlock();
    float getAgility();
    int getMint();
    float getDmg();
    //editing functions
    void healHp(float quan); //used to heal current hit points
    void upMaxHp(float quan); //used to increase max hp
    void modDmg(float damage); //used to modify dmg

private:
    int mints; //currency to buy weapons
    float xp; //experience
    float dmg; //dmg output
    float hp; //current hit points
    float maxHp; //max hit points
    float str; //strength
    float def; //defense
    float lf; //lifesteal %
    float crit; //crit %
    float block; //block %
    float agility; //agility %
};

#endif // CHARACTER_H_INCLUDED 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Character::Character(float maxHpT, float strT, float defT)//constructor
{
    mints = 50;//currency
    hp = maxHpT;
    maxHp = maxHpT;
    str = strT;
    dmg = 1 + (1.2 * str);
    def = defT;
    lf = 0.0; crit = 0.0; block = 0.0; agility = 0.0;
}
float Character::getHp(){return hp;}
int Character::getMint(){return mints;}
float Character::getDmg(){return dmg;}
void Character::modDmg(float damage)
{
    dmg += damage;
}

--------------------------------- End of Character

Now, they are simple classes, however, I would like to find a way for the object of weapon to "stick" itself to my character object is that possible? Weapons are supposed to modify the dmg of my character object, so what could I do to modify the dmg of Character object without having to really worry about it too much. ie. High maintainability.

Here is what I have for main(){}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include "Character.h"
#include "Weapon.h"
#include "BWeapon.h"
#include "create.h"

int main()
{
    Character Hero = create(); //create() returns a character object
    int mints = Hero.getMint();//all character objects start with 50 currency
    Weapon weapon = BWeapon(mints);
    //BWeapon is a function which returns a weapon object
    Hero.modDmg(weapon.getDmg());
    // am I going to have to do this to modify dmg of my hero?
    std::cout.precision(2);
    bool gameLoop = true;
    while(gameLoop == true)
    {
      //game stuff
    }
    return 0;
}


Thanks for reading :D
I'm no expert, but why not something like this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class Character
{
//your stuff
Weapon * Equipped_Weapon; //Pointer to current equipped Weapon
vector <Item*> Inventory;    //Inventory contains pointer to Item class, Weapon can be derived class of Item
//your stuff
void EquipWeapon(Weapon weap);
};

void Character::EquipWeapon(Weapon weap)
{
Equipped_Weapon = &weap;
}
Object interaction is a broad subject, probably one of the most challenging obstacles when programming anything.

The way I deal with it, which probably by standard is far from the best, is by using intermediate functions.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Weapon Sword;
Player HumanControlled;

void DoBattle(Player* p, Monster* m);

int main()
{
    HumanControlled.EquipWeapon(&Sword); // See hyperfine's post - To make things a little easier on yourself, give your player a pointer to object, rather than having to deal with polymorphism and virtual functions for different types of items
    return 0;
}

void DoBattle(Player* p, Monster* m)
{
    while(p.GetHealth > 0 && m.GetHealth > 0)
    {
    // Battle loop
    }
}


Man I wish I could tab..
I would say Hyperfine is on the right track. You'll want your player to have a Weapon pointer ( even better, a std::weak_ptr, or std::reference_wrapper ).

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
struct Weapon
{
  int physical_damage;
  // int magical_damage;
};

// pre-declare Attack struct here, but these should be different files
struct Attack;

struct Character
{
  Weapon* weapon; // or std::weak_ptr or std::reference_wrapper
  
  int attack_modifier;

  Attack getAttack( void );
};

struct Attack
{
  int damage;

  Attack( const Character& ch )
  {
    damage = ch.weapon->damage * ch.attack_modifier;
  }
};

Attack Character::getAttack( void ) const
{
  return Attack( *this );
}


This allows you to separate the functionality of the attack from the character. For example, what if there are dice rolls to determine if the attack is a hit? This is not something a Character should contain the logic for.

You will probably want to create Defense objects as well. Maybe even a Damage object. I'm seeing something like:
1
2
3
4
5
6
7
8
9
10
struct Character
{
    void defend( const Attack& attack )
    {
      Damage damage = this->defense().counter( attack );
      damage.effect( *this );
    }

    // code about a Character ommited
};



Making an rpg is a big undertaking, some might say that it is beyond a "beginner". It takes a large amount of object oriented design skills to create an rpg that has the features that we would expect in a game made today.

I don't think beginners should avoid making an rpg, but I do emphasize the phrase "game made today". You have to understand that role playing games have been in development for near 40 years, and that the beginning were humble. My point is, make something super simple and polish it. Then you actually have a game. Learn how to use git, and slowly add features in a way that protects your original code.
Is there any special reason that you are using struct instead of class?
It's a matter of personal preference. In C++ there is no difference between struct and class other than the default privacy settings (take a guess).
Hm, I thought I remembered reading that there were other differences between the two. Thanks.
Yep, it just saves me those few seconds in my post to declare structs rather than have to write public as well.
I appreciate the help guys, I had learned about pointers but I guess I completely skipped the part where you can use them to connect to other classes from one class. So, before continuing I will probably learn more about pointers in respects to classes and objects.

Also thanks hyperfine for that valuable insight with using vectors to hold items, probably would have taken me much longer to use them for that.
Topic archived. No new replies allowed.