Riotson
Riotson

Reputation: 81

Derived Classes C++

I'm working on a text based game for fun and I'm struggling with inheritance from a base class. I have my base class Being which holds all the stats for whatever character I create. I then have a class Combat that I want to take all the stats from Being (Or from a Being and pass it into combat?) and do all the combat stuff. But I'm not quite understanding inheritance, or at least how to declare the functions in Main to get it to work. If I keep the attack function in Being, I can just write this line in main:

human.attack(monster);

But after splitting the combat into another class, I'm not sure how to write that in main so it works. Please & thank you for your help!

class Being // Base Class
{
public:

    string name, nameSpecialAttack; // Implement a special attack feature,
                                    // that has a specific mutliplier #
                                    // unique to each being
    int attackBonus, attackMod; // was a float attackMod method for casting
                                // spells that double or halve a Being’s
                                // attack power.
    int baseDamage; // base damage
    int health, healthMax; // current health and max health
    int mp, mpMax; // current mp and max mp
    int arrows; // change to [ranged?] ammo

    Being(); // Default Constructor
    Being(string name, string nameSpecialAttack, int attackBonus,
          int attackMod, int baseDamage, int health, int healthMax,
          int mp, int mpMax, int arrows); // Constructor 2
    // All my set and get functions
}

Then my derived class:

class Combat : public Being
{
private:

public:

    void attack(Being& target);

};

Combat.cpp:

void Combat::attack(Being& target)
{
    //unsigned seed = time(0);
    //srand(seed); 
    // Rand # 0-99, * damage+1, /100, * attackMod, parse to int.
    int damage = (int)(attackMod*( ( (rand()%100)*(baseDamage+1) /100) + attackBonus + (rand()%2))); 
    target.health -=damage;

    cout << name << " attacks " << target.name << " doing " << damage << " damage!" << endl;
    cout << target.name << "'s health: " << target.health << endl;

    // Use getHealth() instead and put this function there
    if(target.health <= 0)
    {
        cout << endl << name << " killed " << target.name << "! You have won the game! " << endl << endl;
        cout << "Terminating AMnew World, Good Bye.\n" << endl << endl;
        exit(0);
    }
}

Main:

Being human("", "FirstofFurry", 2, 1, 2, 50, 50, 20, 30, 7); // A thing of
                                                             // class Being
Being monster("Armored Goblin", "Rawr", 2, 1, 2, 65, 59, 20, 20, 6);

int main()
{
    human.attack(monster); // No longer works since attack is in
                           // combat class now
    Sleep(3000);
    cout << endl << endl;
    monster.attack(human);
}

Upvotes: 1

Views: 14992

Answers (3)

Syntactic Fructose
Syntactic Fructose

Reputation: 20144

This wouldn't be something you would want to have an inheritance, combat would not be a type of being. For example an apple is a kind of fruit, so a fruit base class and apple derived class would be logically correct. I would recommend creating an Enemy class and a Hero class, deriving monsters such as zombies and ninjas off of enemy.

#include <iostream>
#include <cmath>
#include <string>
using namespace std;

class Character
{
    public:
    Character(){}     //does nothing, just represents the heros class
};

class Enemy
{
    private:
        int Health;         //base class variables
        int WeaponID;
    public:
        Enemy(int hp, int wpID);
        virtual void Attack(Character& Target); //if all monsters have same attack, no need for virtual
        //etc...etc...
};

class Zombie:public Enemy               //DERIVED CLASS, uses base class attack method
{
    public:
        Zombie(int hp, int wpID):
            Enemy(hp,wpID)
        {}
};

class Ninja: public Enemy               //DERIVED CLASS, uses its own attack method
{
    private:
        int NumThrowingKnives;
    public:
        Ninja(int Hp , int ID) : Enemy(Hp,ID)
        {}
        void Attack(Character& Target); //different attack
        //etc..etc..

};

Enemy::Enemy(int hp, int wpID)
{
    Health = hp;
    WeaponID = wpID;
}

void Ninja::Attack(Character& Target)
{
    cout << "Ninja attack!" << endl;
}

void Enemy::Attack(Character& Target)
{
    cout << "Base class attack!" << endl;
}

int main()
{
    Character Bob;
    Ninja Bill(50,12);
    Zombie Rob(50,16);
    Bill.Attack(Bob);
    cout << endl;
    Rob.Attack(Bob);


}

Upvotes: 3

Mranz
Mranz

Reputation: 1278

It doesn't seem like you are leveraging inheritance correctly here, unless the following is true:

In your game, there is a distinction between beings that can attack, and beings that cant. That being said, changing what your inheritance hierarchy could be useful.

Consider making the 'type' of being what you inherit as.

Ex:

class Being
{
public:
    virtual void attack(...) = 0;
};

class Human : public Being
{
public:
    virtual void attack(...); // Overrides attack in a manner that humans generally would
};

class Goblin : public Being
{
public:
    virtual void attack(...); // Goblin attack style. This is actually a decent way to handle different types of attacks, as in the special attack in your above definition
};

Upvotes: 3

Jacob
Jacob

Reputation: 995

Why don't you declare human to be of type Combat instead?

Combat human("", "FirstofFurry", 2, 1, 2, 50, 50, 20, 30, 7);

It still has access to all of the public methods/data of Being, but can also use the Combat-only attack method.

Upvotes: 1

Related Questions