multiple class instances

Started by
14 comments, last by cignox1 13 years, 9 months ago
If in a program I have a hero object/instance from the goodguy class who is fighting several monster objects from the badguy class.

The goodguy fights badguyOne, then badguythree, and then fights badguytwo and so on. Now the COMBAT FUNCTION that handles the combat passes on all relevant damage to the class and the computer stores the changing member varibales for each instance of that class.
My problem is this. The combat function handles all combat but needs many specific details and attributes from EACH of the different badguys. IE: Each badguy has varying degrees of damage and therefore less proficient in combat etc, and that information MUST be passed to the Combat Function. So if I request badguy damage how do I request the damage of the badguy he is actually fighting at that particular moment. ie; Code such as: badguyOne.damage would call the damage of badguyOne to the function, but to me that function is suddenly reduced to hero vs badguyOne only. What happens when badguyForty comes along? Do I need 40 such combat functions. Such an idea is obviously incorrect, but I am stumped as to how to make a combat function that caters for ALL the badguys and their individual attributes!
Thanks for any help. I am teaching myself C++ and I want to learn how functions can call on multiple instances without having multiple functions.
Advertisement
I admit I most probably misunderstood the question, but in case I got it: shouldn't the fighting function have access to the goodguy/badguy instances? In this case, simply call
if(hit)
{
goodGuy.health -= currentBadGuy.damage;
}

Of course there are many better ways to handle that, using design patterns and so on, but to keep it easy shouldn't this do the job?
Hi,

You need to have different implementations of your BadGuy classes, which can be done using 'interfaces'.
In your combat calculation methods you just deal with calls to the interface methods of the BadGuy class

The main benefit is that derived classes can easily read all paramters from an xml file or whatever which makes it easy to extend and/or tune.

Please note that i tried to make it simple as possible. There's enough lecture out there...

class BadGuy{public:  ...  virtual int getDamageValue() const = 0;  //Classes derived from 'BadGuys' MUST implement this method  ...};class BadGuyWeak : public BadGuy{public:  ...  virtual int getDamageValue() const  {    return 10;  //or whatever fits your damage calculation  }  ...};class BadGuyStrong : public BadGuy{public:  ...  virtual int getDamageValue() const  {    return 90;  //or whatever fits your damage calculation  }  ...};


You have an array of BadGuy instances for example:
std::vector<BadGuy*>  theBadGuys;theBadGuys.push_back(new BadGuyWeak);theBadGuys.push_back(new BadGuyStrong);

and in the damage calculation it might look like this:
for (int i = 0; i < theBadGuys.size(); ++i){  BadGuy* current_bad_guy = dynamic_cast<BadGuy*>(theBadGuys);  //now we update our Hero  theGoodGuy.IsGettingHit(current_bad_guy->getDamageValue());}


Hope this helps a little bit, and although for larger projects it's waaaayyy to slow and not my personal preference but you should get the idea ;-)

have fun & best regards

EDIT: no need for the dynamic_cast ;-)
I don't understand the question. If you were to implement several combat functions like you describe, what would be the difference between them? Maybe you can give a code example?
Hi
Wow, unbelievably fast response... thanks guys.

I will have to dissect Acid's response. I haven't really looked at vectors yet. But incredible code in so short a time. Again, wow and thanks.

To Cignox - Unfortunately not that simple. The combat function will require a vast number of variables, ie; a large amount of information regarding the CURRENT BADGUY. And that is my dilemma. I know how to call upon that information on an individual basis, ie; the particular attributes of a particular badguy within a function. In a combat situation the combat function will require the CURRENT BADGUY'S own status. But what I dont know what to do, is, when each and every badguy (lets say 20 or 40 badguys) all with different strengths, damage points, weapon types, etc, which the goodguy might fight at any one time throughout the game, must all be handled within the ONE Combat Function??? Is it possible? For instance, how do I call upon whatever attributes are required in the combat function from the CURRENT badguy, when there are so many different enemies the goodguy will fight. I mean, I could write the individual combat code for each and every badguy the goodguy encountered, if I had to, but I thought there might be a quick method encapsulated within a single function.

The problem I have is a little difficult to express, sorry.



To Gage
If I were to implement several combat functions, as I stated there would in fact be NO difference between them, and that is my point. The code for each combat function would be identical except for the fact that the goodguy would be fighting a DIFFERENT badguy and the function would require the specific individual attributes of that particular badguy at that particular time. And because there is no difference between the combat functions, except for the enemy type, that is precisely why I was wondering whether there was some way ONE combat function could handle all the different badguys and ALL of their individual factors and modifiers.
Unfortunately I don't have any code for this particular example. I have another game involving submarines with a similar problem, but the code for that is very long and thats only one sub vs one sub. I am merely exploring the possibilities of C++ and whether it is suitable for what I want to do.
If I could perhaps give another example.
5 Sopwith's vs 8 Albatross aircraft. Each could be put into a Sopwith class or Albatross class. But when it comes to shooting I would need to call upon the stats of each object involved. Easy enough to do, but lets say, at one particualr stage of the game, sopwithFive encounters albatrossTwo, each has a number of variable factors that affect the shooting function, altitude, heading, damage, gun capability, range, effectiveness etc.
How do I create the shooting function to call upon the different instances involved in the shooting without making the function specific to one or two objects alone.
Why can't the combat function take a bad guy as an argument?
Still having problems in understanding. Maybe you should post some pseudocode that shows how you handle that thing currently.

Howerver:

Quote:Original post by MikeWhiskyTango

The combat function will require a vast number of variables, ie; a large amount of information regarding the CURRENT BADGUY.

That should not be an issue: you already (implicitly) stated that the badguys are instances of a BadGuy class, then every relevant piece of information about a specific bad guy is kept as member variable of its instance:

class BadGuy
{
private:
unsigned int health;
unsigned int damage;
float strenght;
float speed;

//Ctor and methods
};

So when you call the fight function:

void fight(GoodGuy &hero, BadGuy &enemy)
{
//Combat logic
}

Every instance is bound to its own updated state. That's OO after all :-)
If you want to handle several badguys then:

void fight(GoodGuy &hero, BadGuy *enemies, unsigned int nEnemies)
{
//Combat logic
}

(BTW: I highly suggest to avoid c-style arrays and use C++ data structures instead)

On the other side, different enemies types are implemented as different classes either sharing a common interface, sharing a common parent or by delegation of some kind.

I suppose that you might find of use learning a bit more about OO programming, but the main idea behind is just that. Of course, you don't need to use an OO language to do that, just replace a class with a struct, an array of attributes, a hash table or whatever structured data container you can think of.


Yes, the power of C++ and its OOP is, I guess, what I am failing to understand. The logic of it makes perfect sense, hence my question, but after all my reading on classes I cannot find the 'magic something' that allows me to utilise OO. I fully understand that each instance is bound to its own updated state. It is in fact the updated state of any one of those badguy instances that I want to access and utilise in the one combat function (without having to create a hundred identical combat functions to allow the goodguy to fight those hundred different badguys).

The idea of carrying the badguy into the function as an argument sounds right. I guess Im not to sure how to achieve that exactly. Ill look more closely at cignox's example and the use of the reference and pointer to see if I can work it out.

Particularly, the;

void fight(GoodGuy &hero, BadGuy *enemies, unsigned int nEnemies)
{
//Combat logic
}

The &hero is getting the address of the Goodguy class and *enemies is pointing to the 'Badguy' class. Is the unsigned int nEnemies just an int argument being passed into the function? I am familiar with passing and returning values between functions and methods etc but I have never read about passing an instance. Thank you very much for your responses.
class Badguy
a=5
b=4
c= random value from 1-4 for each evil-instance
d= Each evil instance is assigned differing values,
ie; evilOne 6 evilTwo 4 evilThree 8

class Goodguy (could even be derived from badguy but it really doesnt matter)
x =6
y =8
z =10
a =8
b =5

Goodguy hero
Badguy evilOne, evilTwo, evilThree

//program

int combat ()
x - a
y + c
z + d - b

What I want to know, essentially is this, lets say hero encounters evilTwo and it goes to the combat function to sort out the result where it goes through the combat process using evilTwo's a, b, c and d stats as they are stored in his class. The combat results are then passed back to the respective methods and damage members in each class etc.
Then a bit later later in the same game the hero encounters evilOne and fights him. We go to the SAME combat function. But now we want evilOne's a, b, c, and d stats.
Before getting on this forum, in the combat function, I would have perhaps written the following; (basing it only on the pseudo code above).

int combat ()
int strength = hero.x;
int defence = evilOne.a;
int result = ((strength - defence) + evilOne.d);
if (result>=... etc etc...

As you can see I am calling only on evilOne's a,b, c, and d stats. As soon as I want to introduce a second instance, or a third, ie; evilTwo and evilThree I can no longer use that same combat function.

My problem is that I understand OO to cover this situation, but in all the tutorials I have read none seem to mention this particular brick wall I've encountered. Unfortunately I dont know anyone who knows C++ to ask questions regarding this. I know that I am missing something. I can see the logic of OO and its intentions. I mean there are hundreds of games in which a goodguy fights several different badguys using the power of C++.









This topic is closed to new replies.

Advertisement