-2

I'm doing a project where we need to create a basic Zoo Tycoon game, in which we create a base class called Animal, 3 derived classes of Animal: Tiger, Penguin, Turtle. We also need to create a Zoo class that holds 3 separate arrays for each animal. I've written up my code but keep getting segmentation faults when compiling. I believe this is due to the way I create my object arrays as well as the method I use for inserting objects into them. I've uploaded my entire code. I apologize for the length. I didn't know what segment I could have uploaded to give a clear idea of what I'm doing.

This is my code

Animal.h

#ifndef ANIMAL_H
#define ANIMAL_H

class Animal
{
   private:
     int age;
     double cost;
     int numberOfBabies;
     double baseFoodCost;
     double payoff;

   public:
     Animal();
     Animal(int, double, int, double, double);
     int getAge();
     void setAge(int);
     double getCost();
     void setCost(double);
     int getNumberOfBabies();
     void setNumberOfBabies(int);
     double getBaseFoodCost();
     void setBaseFoodCost(double);
     double getPayoff();
     void setPayoff(double);
};

#endif

Animal.cpp

#include "Animal.h"

Animal::Animal(int a, double c, int n, double b, double p)
{
    age = a;
    cost = c;
    numberOfBabies = n;
    baseFoodCost = b;
    payoff = p;
}

int Animal::getAge()
{
   return age;
}

void Animal::setAge(int a)
{
   age = a;
}

double Animal::getCost() 
{
   return cost;
}

void Animal::setCost(double c)
{
   cost = c;
}

int Animal::getNumberOfBabies()
{
   return numberOfBabies;
}

void Animal::setNumberOfBabies(int n)
{
   numberOfBabies = n;
}

double Animal::getBaseFoodCost()
{
   return baseFoodCost;
}

void Animal::setBaseFoodCost(double b)
{
   baseFoodCost = b;
}

double Animal::getPayoff()
{
   return payoff;
}

void Animal::setPayoff(double p)
{
   payoff = p;
}

Tiger.h

#ifndef TIGER_H
#define TIGER_H 

#include "Animal.h"

class Tiger: public Animal
{
  public:
    Tiger();
    Tiger(int, double, int, double, double);           
};

#endif // !TIGER_H

Tiger.cpp

#include "Tiger.h"

Tiger::Tiger(int age, double cost, int numberOfBabies, double baseFoodCost, double payoff) : Animal(age, cost, numberOfBabies, baseFoodCost, payoff)
{

}

Penguin.h

#ifndef PENGUIN_H
#define PENGUIN_H

#include "Animal.h"

class Penguin: public Animal
{
   public:
     Penguin();
     Penguin(int, double, int, double, double);
};

#endif

Penguin.cpp

#include "Penguin.h"

Penguin::Penguin(int age, double cost, int numberOfBabies, double baseFoodCost, double payoff) : Animal(age, cost, numberOfBabies, baseFoodCost, payoff)
{

}

Turtle.h

#ifndef TURTLE_H
#define TURTLE_H

#include "Animal.h"

class Turtle: public Animal
{
   public:
     Turtle();
     Turtle(int, double, int, double, double);
};

#endif

Turtle.cpp

#include "Turtle.h"

Turtle::Turtle(int age, double cost, int numberOfBabies, double baseFoodCost, double payoff) : Animal(age, cost, numberOfBabies, baseFoodCost, payoff)
{

}

Zoo.h

#ifndef ZOO_H
#define ZOO_H

#include "Animal.h"
#include "Tiger.h"
#include "Penguin.h"
#include "Turtle.h"
#include <cstdlib>
#include <iostream>

using namespace std;

class Zoo
{
   private:
     Tiger **arrayTiger;
     Penguin **arrayPenguin;
     Turtle **arrayTurtle;
     int sizeTiger, sizePenguin, sizeTurtle;
     int capacityTiger, capacityPenguin, capacityTurtle;
     double amount;
     double revenue;
   public:
     Zoo();
     Zoo(double);
     void insertTiger(Tiger);
     void insertPenguin(Penguin);
     void insertTurtle(Turtle);
     void Events();
     double getAmount();
     void setAmount(double);
     void subtractAmount(double);
     Tiger** getTigerArray();
     Penguin** getPenguinArray();
     Turtle** getTurtleArray();
     void calculateRevenue();
     double getRevenue();
     void incrementAge();
     void resetRevenue();
};

#endif

Zoo.cpp

#include "Zoo.h"

Zoo::Zoo(double a)
{
   amount = a;
   capacityTiger = 10;
   capacityPenguin = 10;
   capacityTurtle = 10;
   sizeTiger = 0; 
   sizePenguin = 0;
   sizeTurtle = 0;
   revenue = 0;

   arrayTiger = new Tiger*[capacityTiger]; 
   arrayPenguin = new Penguin*[capacityPenguin];
   arrayTurtle =  new Turtle*[capacityTurtle];

}

void Zoo::insertTiger(Tiger t)
{   
   if (sizeTiger < capacityTiger)
   {
      arrayTiger[sizeTiger++] = &t;
   } 
   else 
   {
      int oldTigerCapacity = capacityTiger;
      capacityTiger *= 2;
      Tiger** newArrayTiger = new Tiger* [capacityTiger];
      for (int i = 0; i < oldTigerCapacity; i++)
      {
         newArrayTiger[i] = arrayTiger[i];
      }
       delete[] arrayTiger;
       arrayTiger = newArrayTiger;
       arrayTiger[sizeTiger++] = &t;      
    }
} 

void Zoo::insertPenguin(Penguin p)
{
   if (sizePenguin < capacityPenguin)
   {
      arrayPenguin[sizePenguin++] = &p;
   }
   else
   {
      int oldPenguinCapacity = capacityPenguin;
      capacityPenguin *= 2;
      Penguin** newArrayPenguin = new Penguin* [capacityPenguin];
      for (int i = 0; i < oldPenguinCapacity; i++)
      {
         newArrayPenguin[i] = arrayPenguin[i];
      }
      delete[] arrayPenguin;
      arrayPenguin = newArrayPenguin;
      arrayPenguin[sizePenguin++] = &p;     
   }
}

void Zoo::insertTurtle(Turtle turt)
{
   if (sizeTurtle < capacityTurtle)
   {
      arrayTurtle[sizeTurtle++] = &turt;
   }
   else
   {
      int oldTurtleCapacity = capacityTurtle;
      capacityTurtle *= 2;
      Turtle** newArrayTurtle = new Turtle* [capacityTurtle];
      for (int i = 0; i < oldTurtleCapacity; i++)
      {
         newArrayTurtle[i] = arrayTurtle[i];
      }
      delete[] arrayTurtle;
      arrayTurtle = newArrayTurtle;
      arrayTurtle[sizeTurtle++] = &turt;  
    }
}

void Zoo::subtractAmount(double a)
{
   amount -= a;
}

double Zoo::getAmount()
{
   return amount;
}

void Zoo::setAmount(double a)
{
   amount += a;  
}

void Zoo::Events() 
{
   int option = 0;  
   option =  rand() % 4 + 1;

   switch(option)
   {

    case 1: cout << "\n\nA sickness has occurred at the zoo." << endl << endl;
            break;
    case 2: cout << "\n\nThere has been a boom in zoo attendance." << endl << endl;
            break;
    case 3: cout << "\n\nA baby animal is born." << endl << endl;
            break;
    case 4: cout << "\n\nNothing happens." << endl << endl;
            break;
   }

}

Tiger** Zoo::getTigerArray()
{
   return arrayTiger;
}

Penguin** Zoo::getPenguinArray()
{
   return arrayPenguin;
}

Turtle** Zoo::getTurtleArray()
{
   return arrayTurtle;
}

void Zoo::incrementAge()
{
   for(int i = 0; i < sizeTiger; i++)
   {
     if((arrayTiger[i]->getCost()) == 10000)
     {
       arrayTiger[i]->setAge((arrayTiger[i]->getAge()) + 1);
     }  
   }

   for(int i = 0; i < sizePenguin; i++)
   {
     if((arrayPenguin[i]->getCost()) == 1000)
     {
       arrayPenguin[i]->setAge((arrayPenguin[i]->getAge()) + 1);
     } 
   }

   for(int i = 0; i < sizeTurtle; i++)
   {
     if((arrayTurtle[i]->getCost()) == 100)
     {
       arrayTurtle[i]->setAge((arrayTurtle[i]->getAge()) + 1);
     } 
   }
}

void Zoo::calculateRevenue()
{
   for (int i = 0; i < sizeTiger; i++)
   {
        revenue += (arrayTiger[i]->getPayoff());
   }  
   for (int i = 0; i < sizePenguin; i++)
   {
        revenue += (arrayPenguin[i]->getPayoff());
   }
   for (int i = 0; i < sizeTurtle; i++)
   {
        revenue += (arrayPenguin[i]->getPayoff());
   }  
}

double Zoo::getRevenue()
{
   return revenue;   
}

void Zoo::resetRevenue()
{
   revenue = 0;
}

main.cpp

#include "Animal.h"
#include "Penguin.h"
#include "Tiger.h"
#include "Turtle.h"
#include "Zoo.h"

#include <iostream>

using namespace std;

int main()
{
   const int baseFeedingCost = 10;
   Zoo z1(100000);
   bool playGame = false;
   bool menuExit = false;
   char userStart, continueGame, loopPurchase, loopChoice = ' ';
   int day = 0;
   int initializer = 0;

   cout << "\nWelcome to Zoo Tycoon!\n\nIn this game you will manage a zoo business." << endl;

   while(!menuExit)
   {
      cout << "\nA: Play Game" << endl; 
      cout << "B: Exit" << endl;
      cout << "\n\nPlease Select an option: ";
      cin.get(userStart);
      cin.ignore(INT_MAX, '\n');

         if(userStart == 'A' || userStart == 'a')     //user selected to start game
         {
            playGame = true;
            menuExit = true;
            cout << "\n\nYou will start with $" << z1.getAmount() << " in the bank." << endl;
            cout << "\n\nTo begin your Zoo, you must purchase three types of animals (tigers, penguins, turtles)";
            cout <<"\nin quantities of either 1 or 2." << endl << endl;
            cout << "Please enter you desired number of tigers (1 or 2): ";
            cin >> initializer;

            if (initializer == 2)
            {
              Tiger t1(0, 10000, 1, 50, 2000);
              z1.insertTiger(t1);
              z1.subtractAmount(10000);

              Tiger t2(0, 10000, 1, 50, 2000);
              z1.insertTiger(t2);
              z1.subtractAmount(10000);
              cout << "\n\nYou will start with 2 tigers." << endl; 
            }
            else if (initializer == 1)
            {
              Tiger t1(0, 10000, 1, 50, 2000);
              z1.insertTiger(t1);
              z1.subtractAmount(10000);
              cout << "\nYou will start with 1 tiger." << endl;
            }
            cout << "\n\nPlease enter you desired number of penguins (1 or 2): ";
            cin >> initializer;

            if (initializer == 2)
            {
               Penguin p1(0, 1000, 5, 10, 100);
               z1.insertPenguin(p1);
               z1.subtractAmount(1000);

               Penguin p2(0, 1000, 5, 10, 100);
               z1.insertPenguin(p2);
               z1.subtractAmount(1000);
               cout << "\n\nYou will start with 2 penguins." << endl;
            }
            else if (initializer == 1)
            {
               Penguin p1(0, 1000, 5, 10, 100);
               z1.insertPenguin(p1);
               z1.subtractAmount(1000);
               cout << "\n\nYou will start with 1 penguin." << endl;
            }
            cout << "\n\nPlease enter you desired number of turtles (1 or 2): ";
            cin >> initializer;
            if (initializer == 2)
            { 
               Turtle tr1(0, 100, 10, 5, 5);
               z1.insertTurtle(tr1);
               z1.subtractAmount(100);

               Turtle tr2(0, 100, 10, 5, 5);
               z1.insertTurtle(tr2);
               z1.subtractAmount(100);
               cout << "\n\nYou will start with 2 turtles." << endl << endl;
            }
            else if (initializer == 1)
            {  
               Turtle tr1(0, 100, 10, 5, 5);
               z1.insertTurtle(tr1);
               z1.subtractAmount(100);
               cout << "\n\nYou will start with 1 turtle." << endl << endl;
            }
            cin.ignore(255, '\n');
            cin.clear();
         }
         else if(userStart == 'B' || userStart == 'b')
         {  
            cout << "\nThis game will now exit." << endl << endl;
            menuExit = true;
         }
         else     //user inputted invalid response
         {
            cout << "\n\nI'm sorry but your response is invalid. Please try again." << endl;
            cin.ignore(255, '\n');
            cin.clear();
         }      
   }

   while(playGame)    //daily turns that ends when user enters false for playGame
   { 
       loopChoice = loopPurchase = ' ';
       z1.incrementAge();
       cout << "\n\nDay: " << ++day << endl;
       cout << "\nYou have $" << z1.getAmount() << " in the bank";
       z1.Events(); 

       cout << "\n\nWould you like to purchase an adult animal? "; 
       cin.get(loopPurchase); 
       cin.ignore(INT_MAX, '\n');
       if(loopPurchase == 'Y' || loopPurchase == 'y')
       {
          cout << "\n\nA: Tiger" << endl;
          cout << "B: Penguin" << endl;
          cout << "C: Turtle" << endl;
          cout << "\nPlease choose from the animals listed above: ";
          cin.get(loopChoice);
          cin.ignore(INT_MAX, '\n');
          if(loopChoice == 'A' || loopChoice == 'a')
          {
             cout << "\n\nYou have chosen to purchase a Tiger" << endl;
             Tiger tLoop(3, 10000, 1, 50, 2000);
             z1.insertTiger(tLoop);
             z1.subtractAmount(10000);
          }         
          else if(loopChoice == 'B' || loopChoice == 'b')
          {
             cout << "\n\nYou have chosen to purchase a Penguin" << endl;
             Penguin pLoop(3, 1000, 5, 10, 100);
             z1.insertPenguin(pLoop);
             z1.subtractAmount(1000);
          }
          else if(loopChoice == 'C' || loopChoice == 'c')
          {
             cout << "\n\nYou have chosen to purchase a Turtle" << endl;
             Turtle trLoop(3, 100, 10, 5, 5);
             z1.insertTurtle(trLoop);
             z1.subtractAmount(100);
          }
       }

       z1.calculateRevenue();

       cout << "\n\nYour daily revenue is $" << z1.getRevenue();
       //z1.setAmount((z1.getAmount()) + (z1.getProfit()));
       z1.resetRevenue();
       cout << "\n\nEnd of Day: " << day << ". Would you like to continue? (Enter yes or no): ";
       cin.get(continueGame);
       cin.ignore(INT_MAX, '\n');         

       if (continueGame == 'y' || continueGame == 'Y')
       {
          cout << "\nGame will continue. Proceeding to next day." << endl << endl;
       }
       else
       {
          cout << "\n\nYou have chosen to quit the game. Game will now exit." << endl << endl;
          playGame = false;    
       }

   } 
   return 0;
}
Vishaal Shankar
  • 1,648
  • 14
  • 26
  • Way too many pointers! Whats wrong with a `std::vector`? Anyway, in `insertTiger` you store `&t` which is the address of the function parameter. The parameter goes away as soon as the function returns, and then the pointer is invalid. – Bo Persson Feb 06 '18 at 02:23
  • My teacher is requiring us to use dynamically allocated arrays to store our objects. We're not allowed to use vectors. – Arjun Kahlon Feb 06 '18 at 02:30
  • *My teacher is requiring us to use dynamically allocated arrays to store our objects* -- Yet Another Incompetent Teacher (YAIT). – PaulMcKenzie Feb 06 '18 at 03:47
  • 1
    Please post a [mcve]. Pay special attention to the word "minimal". – n. m. could be an AI Feb 06 '18 at 07:04

2 Answers2

0

The code is huge. I have not reviewed everything.

In Zoo, you define your Animal arrays as:

Tiger **arrayTiger;
Penguin **arrayPenguin;
Turtle **arrayTurtle;

I don't know why a double pointer. Just *arrayTiger, etc. would work. You must also change the Insert method. Instead of assigning &t, just use t.

There are other improvements to make.

In Zoo, the insertTiger (etc), should also subtract amount. You always subtract the amount after calling insert, and you already know the price.

Your wrote almost the same code 3 times for the three animals when initializing arrays of animals. You could check if the input is 1 or 2 (to validate) and then insert animals in a for loop.

Finally. You are not reusing almost anything. You have a lot of repeated code for tigers, turtles and penguins.

Pablo
  • 3,004
  • 1
  • 12
  • 19
0

Your code is too big as mentioned in the previous answer because of which I couldn't go through the entire code, but the segmentation fault you encounter could be because of the following piece of code :

    void Zoo::calculateRevenue()
   {
      for (int i = 0; i < sizeTiger; i++)
      {
         revenue += (arrayTiger[i]->getPayoff());
      }  
      for (int i = 0; i < sizePenguin; i++)
      {
        revenue += (arrayPenguin[i]->getPayoff());
      }
      for (int i = 0; i < sizeTurtle; i++)
      {
        revenue += (arrayPenguin[i]->getPayoff());
      }
   }

If you see here, in the third "for loop", you run the loop till sizeTurtle but are using the arrayPenguin for it. I think this is a mistake and what you wanted to do was something of this sort :

  for (int i = 0; i < sizeTurtle; i++)
  {
    revenue += (arrayTurtle[i]->getPayoff());
  }

That being said, they're could be other problems in the code that i am not aware of, but this certainly seems like a candidate to cause a crash in the program.

Vishaal Shankar
  • 1,648
  • 14
  • 26