无法在另一个公共功能内调用公共功能

时间:2018-06-20 20:51:02

标签: c++ class agent-based-modeling

(编辑:在“注释”部分中建议的更改现在允许所需的行为)

我正在用C ++开发基于代理的仿真,到目前为止,我已经可以运行1个仿真,并且可以手动转录结果。它由一个环境类和一个带有代理(猎人和猎物)的二维数组组成

为使数据收集自动化,我正在尝试实现一些功能,以便以后可以将每次模拟的相关结果转录为CSV文件。

Visual Studio中的以下代码生成环境,对其进行填充,对代理进行计数并显示带有图例的猎人和猎物的ASCI映射。

#include <iostream>
#include <cstdlib>  // for rand
#include <ctime>    // for time
#include <vector>
#include <Windows.h> //for color in output

using namespace std;

const int WORLDSIZEX = 100;
const int WORLDSIZEY = 30;

enum AgentType { PREY, HUNTER };

class Environment;

class Agent {
public:
    Agent(Environment* aWorld, int xcoord, int ycoord);
    virtual ~Agent() { }
    virtual AgentType getType() const = 0;
    virtual char representation() const = 0;

protected:
    int x;
    int y;
    Environment* world;
private:
};

struct Position {
    int x;
    int y;
};

class Environment {
public:
    Environment(unsigned int seed, int _id, int _initialPopulationPreys, int _initialPopulationHunmters);
    ~Environment();
    Agent* getAt(int x, int y) const; 
    void setAt(int x, int y, Agent* org);
    void display();
    Position randomPosition() const;
    Position randomPositionHunter() const;
    int numberPreys();
    int numberHunters();

private:
    Agent* grid[WORLDSIZEX][WORLDSIZEY];

    void createOrganisms(AgentType orgType, int count);
    int id;

    int timeStep;
    int initialPopulationPreys;
    int initialPopulationHunters;

};

class Hunter : public Agent {
public:
    Hunter(Environment* aWorld, int xcoord, int ycoord);
    AgentType getType() const;
    char representation() const;

private:
    bool altruistic;
};

class Prey : public Agent {
public:
    Prey(Environment* aWorld, int xcoord, int ycoord);
    AgentType getType() const;
    char representation() const;

private:
    int huntingDifficulty;
};

Prey::Prey(Environment* aWorld, int xcoord, int ycoord) : Agent(aWorld, xcoord, ycoord) { huntingDifficulty = int(rand() % 3); }
AgentType Prey::getType() const { return PREY; }
char Prey::representation() const { return 'o'; }

Hunter::Hunter(Environment* aWorld, int xcoord, int ycoord) : Agent(aWorld, xcoord, ycoord) { }
AgentType Hunter::getType() const { return HUNTER; }
char Hunter::representation()const { return 'X'; }

Agent::Agent(Environment* aWorld, int xcoord, int ycoord) {
    world = aWorld;
    x = xcoord;
    y = ycoord;
    world->setAt(x, y, this);
}

Environment::Environment(unsigned int seed, int _id, int _initialPopulationPreys, int _initialPopulationHunters) {
    srand(seed);
    id = _id;

    initialPopulationPreys = _initialPopulationPreys;
    initialPopulationHunters = _initialPopulationHunters;

    for (int i = 0; i < WORLDSIZEX; i++) {
        for (int j = 0; j < WORLDSIZEY; j++) {
            grid[i][j] = NULL;
        }
    }
    timeStep = 0;
    createOrganisms(PREY, initialPopulationPreys);
    createOrganisms(HUNTER, initialPopulationHunters);
}

Environment::~Environment() {
    for (int i = 0; i < WORLDSIZEX; i++) {
        for (int j = 0; j < WORLDSIZEY; j++) {
            if (grid[i][j] != NULL) {
                delete grid[i][j];
            }
        }
    }
}

Agent* Environment::getAt(int x, int y) const {
    if ((x >= 0) && (x < WORLDSIZEX) && (y >= 0) && (y < WORLDSIZEY)) {
        return grid[x][y];
    }
    else {
        return NULL;
    }
}

void Environment::setAt(int x, int y, Agent* org) {
    if ((x >= 0) && (x < WORLDSIZEX) && (y >= 0) && (y < WORLDSIZEY)) {
        grid[x][y] = org;
    }
}

// Displays the world in ASCII.
void Environment::display() {
    int numPreys = 0;
    int numHunters = 0;

    HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
    // Remember how things were when we started
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hstdout, &csbi);

    cout << endl << endl;
    for (int j = 0; j < WORLDSIZEY; j++) {
        for (int i = 0; i < WORLDSIZEX; i++) {
            if (grid[i][j] == NULL) {
                cout << "_";
            }
            else {
                if (grid[i][j]->getType() == PREY) {
                    SetConsoleTextAttribute(hstdout, 10);
                    numPreys++;
                }
                else if (grid[i][j]->getType() == HUNTER) {
                    SetConsoleTextAttribute(hstdout, 12);
                    numHunters++;
                }
                cout << grid[i][j]->representation();
                SetConsoleTextAttribute(hstdout, csbi.wAttributes);
            }
        }
        cout << endl;
    }
    cout << "Preys 'o': " << numPreys << " Hunters 'X': " << numHunters << endl;
    cout << "Timestep:" << timeStep << " World ID:" << id << endl;
}

Position Environment::randomPosition() const {    // returns a random number in the range 0 to WORLDSIZEX - 1 (or WORLDSIZEY - 1)
    Position p;
    p.x = rand() % WORLDSIZEX;
    p.y = rand() % WORLDSIZEY;
    return p;
}

Position Environment::randomPositionHunter() const { // returns a random number in the central fifth of the grid
    Position p;
    int subGridSizeX = WORLDSIZEX / 5;
    int subGridSizeY = WORLDSIZEY / 5;

    p.x = subGridSizeX * 1 + (rand() % (3 * subGridSizeX));
    p.y = subGridSizeY * 2 + (rand() % subGridSizeY);
    return p;
}

int Environment::numberPreys() {
    int numPreys = 0;
    for (int j = 0; j < WORLDSIZEY; j++) {
        for (int i = 0; i < WORLDSIZEX; i++) {
            if (grid[i][j] && grid[i][j]->getType() == PREY) {
                numPreys++;
            }
        }
    }
    return numPreys;
}

int Environment::numberHunters() {
    int numHunters = 0;
    for (int j = 0; j < WORLDSIZEY; j++) {
        for (int i = 0; i < WORLDSIZEX; i++) {
            if (grid[i][j] && grid[i][j]->getType() == HUNTER) {
                numHunters++;
            }
        }
    }
    return numHunters;
}


void Environment::createOrganisms(AgentType orgType, int count) {
    int orgCount = 0;
    while (orgCount < count) {

        Position p = randomPosition();
        Position q = randomPositionHunter();

        if (orgType == PREY) {
            if (grid[p.x][p.y] == NULL) {           // Only put Organism in empty spot
                orgCount++;
                new Prey(this, p.x, p.y);       // Create a Prey and put it into the world
            }
        }
        else if (orgType == HUNTER) {
            if (grid[q.x][q.y] == NULL) {           // Only put Organism in empty spot
                orgCount++;
                new Hunter(this, q.x, q.y);     // Create a Hunter and put it into the world
            }
        }
    }
}


int main() {
    int initialPreys = 60;
    int initialHunters = 15;
    int id = 0;

    //Creating the environment
    int seed = time(0);
    Environment myWorld(seed, id, initialPreys, initialHunters);

    cout << "This is the setup of the environment for all the simulations" << endl;
    myWorld.display();

    char ch;

    return 0;
}

我想将Environment :: display()函数替换为:

void Environment::display() {
    int numPreys = numberPreys();
    int numHunters = numberHunters();

        HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
        // Remember how things were when we started
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        GetConsoleScreenBufferInfo(hstdout, &csbi);

        cout << endl << endl;
        for (int j = 0; j < WORLDSIZEY; j++) {
            for (int i = 0; i < WORLDSIZEX; i++) {
                if (grid[i][j] == NULL) {
                    cout << "_";
                }
                else {
                    if (grid[i][j]->getType() == PREY) {
                        SetConsoleTextAttribute(hstdout, 10);
                    }
                    else if (grid[i][j]->getType() == HUNTER) {
                        SetConsoleTextAttribute(hstdout, 12);
                    }
                    cout << grid[i][j]->representation();
                    SetConsoleTextAttribute(hstdout, csbi.wAttributes);
                }
            }
            cout << endl;
        }
        cout << "Preys 'o': " << numPreys << " Hunters 'X': " << numHunters << endl;
        cout << "Timestep:" << timeStep << " World ID:" << id << endl;
    }

但是,该功能什么也不会显示,并且控制台窗口会在一段时间后关闭。

我的问题:如何在显示功能内部调用计数功能?

0 个答案:

没有答案