0

New to C++. Here is my code:

#include <string>
#include <cstdlib>
#include <time.h>
using namespace std;


const int Gardensize = 20;//Garden size, a 20X20 2d array
const int initialants = 100;//100 initial ants
const int initialdoodlebug = 5;//5 intial bug
const int antType = 1;// 
const int doodleType = 2;//
const char antchar = 'O';//ant will display'O'in the window
const char bugchar = 'X';//


class Garden;
class Organism;
class Ant;
class Doodlebug;


class Garden {
    friend class Organism;
    friend class Ant;
    friend class  Doodlebug;
public:
    Garden();
    ~Garden();
    int checkType(int x, int y);//check the element type (ant or bug)in the grid
    void Display();

private:
    Organism grid[Gardensize][Gardensize];  //C2079 'Garden::grid' uses undefined class 'Organism' I have already define the class Organism in advance,have no ideal how to fix this error.

};
Garden::Garden() { //initialize the garden, set all elements in grid to "NULL"
    for (int i = 0; i < Gardensize; i++) {
        for (int j = 0; j < Gardensize; j++) {
            grid[i][j] = NULL;   //error:subscript requires array or pointer 
        }
    }
}
Garden::~Garden() {
    for (int i = 0; i < Gardensize; i++) {
        for (int j = 0; j < Gardensize; j++) {
            if (grid[i][j] != NULL) {
               grid[i][j] = NULL;
            }
        }
    }
}
void Garden::Display() {
    for (int i = 0; i < Gardensize; i++) {
        for (int j = 0; j < Gardensize; j++) {
            if (grid[i][j].getType == antType) {
                cout << antchar;
            }
            else if (grid[i][j].getType == NULL) {
                cout << ".";
            }
            else if (grid[i][j].getType == doodleType) {
                cout << bugchar;
            }
        }
        cout << endl;
    }
}
int Garden::checkType(int x, int y) { 

    return grid[x][y].getType();
}

class Organism {
    friend class Garden;
public:
    virtual int getType() {}; //
    virtual void breed() {};
    virtual bool starve() {};
    virtual int move( int &breedtoken) {};

protected:
    int x = -1;              //initial xy place
    int y = -1;
    Garden garden;
    bool moved;             //used to define whether org has moved or not
    int breedtoken = 0;     //used to define whether org need to breed
};

class Ant : public Organism {
public:
    Ant() {}; //
    Ant(int x, int y, Garden* g)//initial a ant object by define the xy place in the gardene
    {
        this->x = x;
        this->y = y;
        garden = *g;
    }
    ~Ant() {};
   
    virtual int getType() {  
        return antType;
    }
    virtual int move(int &breedtoken);
    virtual void breed() {};
    virtual bool starve() { return false; };// ant wont starve


};
int Ant::move(int& breedtoken) {
    int dir = rand() % 4;// randomly select direction
    switch (dir) {
        case 0 :// 0move upwards
            if( this->x > 0 && garden.grid[x - 1][y] == NULL ){
               garden.grid[x-1][y] = garden.grid[x][y];
               garden.grid[x][y] = NULL;
               x--;
            }
            break;
        case 1:// 1 move downwards
            if (this->x < Gardensize - 1 && garden.grid[x + 1][y] == NULL) {
                garden.grid[x + 1][y] = garden.grid[x][y];
                garden.grid[x][y] = NULL;
                x++;
            }
            break;
        case 2: // 2 move leftwards
            if (this->y > 0 && garden.grid[x][y-1] == NULL) {
                garden.grid[x][y-1] = garden.grid[x][y];
                garden.grid[x][y] = NULL;
                y--;
            }
            break;
        case 3: // 3 move to right
            if (this->y < Gardensize- 1 && garden.grid[x][y + 1] == NULL) {
                garden.grid[x][y + 1] = garden.grid[x][y];
                garden.grid[x][y] = NULL;
                y++;
            }
            break;
            this->breedtoken += 1;
            return breedtoken;
    }
     
}
class Doodlebug :public Organism {
public:
    Doodlebug() {}; 
    Doodlebug(int x, int y, Garden* g)
    {
        this->x = x;
        this->y = y;
        garden = *g;
    }
    virtual int getType() {    
        return doodleType;
    }
};

int main()
{
    srand(time(NULL));//
    Garden garden;
    int antCount = 0;  //Ant counter, used to intilize 100 ants
    int DoodleCount = 0;
    Ant antarray[initialants]; 
    Doodlebug doodlebugarray[initialdoodlebug];

    while (antCount < initialants) {
        int x = rand() % Gardensize;
        int y = rand() % Gardensize;
        if (garden.checkType(x, y) == NULL) {

            antarray[antCount] =  Ant(x, y, &garden); //initilize 100 ants
            antCount++;
        }
    }
    while (DoodleCount < initialdoodlebug) {
        int x = rand() % Gardensize;
        int y = rand() % Gardensize;
        if (garden.checkType(x, y) == NULL) {

            doodlebugarray[DoodleCount] = Doodlebug(x, y, &garden); //用数组的模式创建100只蚂蚁
            DoodleCount++;
        }
    }


    garden.Display();//display
}

The project is not finished yet. Right now, the code can initialize 100ants and 5 bugs. It can run properly but keep showing"subscript requires array or pointer " wherever I write grid[i][j] in the for loop. and " 'Garden::grid' uses undefined class 'Organism'" when I define the "Organism grid[][]" in the Garden class. I wonder to know how can i fix these 2 errors, and what's wrong with my 2d array grid?

Zion962
  • 11
  • Welcome to Stack Overflow. Please read [the help pages](http://stackoverflow.com/help), take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly please learn how to create a [mre], with emphasis on the *minimal* part. – Some programmer dude May 14 '22 at 07:20
  • As a hint to the root cause of your problem: To create an object of a class, you need the full *definition* of the class, it's not enough with a declaration. Considering that you use polymorphism, the simple solution is to use *pointers* to objects, for which a declaration is enough. – Some programmer dude May 14 '22 at 07:21
  • On another note: The symbol `NULL` is a C-compatibility macro for null *pointers*. C++ doesn't have "null values", and if you return an `int` value then you should compare against an actual `int` value. Also, if you declare a function to return a value, then you should *always* return a value, otherwise you risk *undefined behavior*. If you have an abstract virtual function in a base class (a function you don't really want to define/implement) define it as abstract (e.g. `virtual int getType() = 0;`) – Some programmer dude May 14 '22 at 07:27
  • Your design also seems flawed, with way to many `friend` declarations. Also the `getType()` function is an anti-pattern. All in all I would recommend you spend some more time studying design and invest in [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282). – Some programmer dude May 14 '22 at 07:28

1 Answers1

0

The problem with the 2d array is caused, because you try to create an array of Organisms, which are up to that point only declared, not defined, and so the compiler doesn't know their size and can't create an array of them. This can b fixed by reordering your classes, or by putting the class declarations in headers. You can also just replace the array with a dynamic array (double pointer), and initialize it after they have been declared.

The other error is just a consequence of the first, fix it and they will both disapear.

You should try reading some book about c or c++ first, and learn a bit about pointers, and design and structure of c++ programs

Promitheas Nikou
  • 511
  • 4
  • 14