0

I am doing an assignment for the university course and me and my partner have a problem. Program we are making is a game.

We have several classes, which all inherit from the base class, called Creature. These are all enemies player needs to deal with and they all run their own AIs. There are 4 different types of child classes, all within namespace Creature(Including parent, Creature), with one class having special functions that only it needs. This class is called Bunny.

Now, my job is to call AI functions as needed. Problem is, I do not always know what class I am calling out, as such, when I ask the game board to tell me what Creature I get.

All enemies are saved as pointers like so, in game board squares:

    struct Square
    {   
        // Pointers to Morso class, where the enemy is saved
        Creature::Creature* creature;
        //Undeeded stuff removed

    };

Now, this is all and fine until we need to access to special functions. Pupu will multiply if certain conditions are filled. As such, with in Pupu there are few functions I need to call to make sure it carries out it's act correctly.

However, here comes the problem.

I call our board class to give me the creature that is in the coordinates I give to it.

void GameEngine::GameEngine::runAI()
{
    Creature::Creature* creature= NULL;

    for(unsigned int y = 0; y < dimY; y++)
    {
        for(unsigned int x = 0; x < dimX; x++)
        {
            Coordinate target;

            target.setX(x);
            target.setY(y);

            creature= board_->returnCreature(target);

            //If there is a creature in the target, run its AI
            if(creature!= NULL)
            {

                //If it is, check special procedures
                if(creature->returnType() == "bunny")
                {
                    bunnyReproduce(creature);
                }

                creature->ai();
            }

        }//for x

    }//for y
}

Now, :

void GameEngine::GameEngine::bunnyReproduce(Ccreature::Creature* creature)
{

//Checks that it really is a bunny
if( creature->returnType() != "bunny"){ return; }

//Check is there another bunny near
creature->checkForMate();


}

The problem is, creature, at this point, can't call for checkForMate, which is public member of Bunny, but not Creature. Do we need to make virtual function into Creature?

I tried making checkForMate into Creature::Bunny, but since the original value I try to give to it is Creature class, I can't do so. Do we need to to create an empty virtual function in Creature class and then override it it Bunnyclass?

I am running Qt Creator 2.7.0, with QT 5.0.2.

Mandemon
  • 372
  • 3
  • 22
  • Both comments and identifiers in source should genrally be plain English, because sooner or later your source *will* go "international" (like here). – DevSolar Apr 25 '13 at 10:42
  • Well, I can change names quickly, so it should be easier to read. Just a check – Mandemon Apr 25 '13 at 10:45

2 Answers2

3

You should add virtual function reproduce to Creature class and implement it in Bunny or any other creature you may later add to the game. So that any creature will reproduce itself in it's own way. You don't even need to check creature type in this case. Since if you have some non reproducible creatures, you may just implement reproduce as empty method that will do nothing.

Community
  • 1
  • 1
alexrider
  • 4,449
  • 1
  • 17
  • 27
  • 1
    This is how we have it at the moment. It (at least seems to) work. I will accept this answer once we are sure. Right now our Bunnies don't really get a chance to reproduce, for some reason our Pandas have developed a taste for Bunny flesh... – Mandemon Apr 25 '13 at 11:33
  • 1
    I am accepting this answer, since it is the way we are going to go now. Although molbdnilo suggestion is good, it would require certain large rewrites in the code are not (yet) ready to do. Maybe after it works, we can start optimizing. – Mandemon Apr 25 '13 at 13:03
1

Ideally, your engine shouldn't need to care at all what kind of creature it's working with.

If you want the bunny to reproduce on each ai() step, why not do it in the bunny's ai()?
After all, shouldn't it be the bunny's responsibility to decide when to reproduce, rather than some almighty external Engine?

void Creature::Bunny::ai()
{
    if (niceMateNearby())
        reproduce();
    else
        eatCarrotsAndJumpAround();
}
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • Otherwise I agree, but the engine is needed to keep track of creatures and when a new bunny is born, engine needs to know about it. When the program is reseted or shut down, the engine frees the memory it had reserved with new commands. – Mandemon Apr 25 '13 at 11:31
  • @Mandemon There's no reason that a new bunny can't notify the engine that it exists without the engine initiating the creation of it. – molbdnilo Apr 25 '13 at 11:42
  • So... how do I do that? By sending a pointer of the engine to the new bunny, so it can tell engine that it has been born? – Mandemon Apr 25 '13 at 11:45
  • @Mandemon Yes, that would work. Even better, a pointer to an abstract interface that the engine can implement (that way, a creature can't manipulate the engine directly). – molbdnilo Apr 25 '13 at 12:02
  • Creating an abstract interface at this point is not possible, for two reasons. First, we got interface which we need to create from the course and we are not allowed to touch it. Second, our project is so far that creating such interface would require a quite redesing (AFAIK). Still, we might go for the pointer method. The engine has only one public function that can modify it's content and that one requires special input on which Bunny has no access to. – Mandemon Apr 25 '13 at 12:05