(编辑:在“注释”部分中建议的更改现在允许所需的行为)
我正在用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;
}
但是,该功能什么也不会显示,并且控制台窗口会在一段时间后关闭。
我的问题:如何在显示功能内部调用计数功能?