Hello,
I'm trying to make an agents-based simulation (Preys vs Hunters) and so far got it running with random "movement".
For the simulation, I have a grid of pointers to a class `Agent` and have classes `Prey` and `Hunter` that are also `Agent`.
Now I'm trying to implement some directed movement through some flags (boolean variables in Hunter class) but my issue is that when I add the following code, my simulation 'breaks'. (It compiles, but runs only for three rounds)
And it doesn't work as intended because it either doesn't change the boolean in a probabilistic way or is counting them erroneously, but I do not know which one is the mistaken.
I'm missing something obvious about the use of dynamic_cast?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
void Environment::setNumberOfAltruistHunters(long _prop) {
for (int j = 0; j < WORLDSIZEY; j++) {
for (int i = 0; i < WORLDSIZEX; i++) {
if (grid[i][j] && grid[i][j]->getType() == HUNTER) {
long roll = (long)rand() / (long)RAND_MAX;
if (roll < _prop) {
Hunter *hptr = dynamic_cast<Hunter*>(grid[i][j]);
if (hptr) {
hptr->altruistic = true;
}
}
}
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
int Environment::numberAltruisticHunters() {
int numAltruisticHunters = 0;
for (int j = 0; j < WORLDSIZEY; j++) {
for (int i = 0; i < WORLDSIZEX; i++) {
if (grid[i][j] && grid[i][j]->getType() == HUNTER) {
Hunter *hptr = dynamic_cast<Hunter*>(grid[i][j]);
if (hptr) {
numAltruisticHunters++;
}
}
}
}
return numAltruisticHunters;
}
|
This is a reduced version of the structure of classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
class Environment {
public:
Environment();
~Environment();
private:
Agent* grid[WORLDSIZEX][WORLDSIZEY];
};
enum AgentType { PREY, HUNTER };
class Agent {
public:
Agent(Environment* aWorld, int xcoord, int ycoord);
virtual ~Agent() { }
virtual void move() = 0;
virtual void breed() = 0;
virtual AgentType getType() const = 0;
protected:
void movesTo(int xNew, int yNew);
int x;
int y;
Environment* world;
private:
};
class Prey : public Agent {
public:
Prey(Environment* aWorld, int xcoord, int ycoord);
void move();
void breed();
AgentType getType() const;
private:
int huntingDifficulty;
};
class Hunter : public Agent {
public:
Hunter(Environment* aWorld, int xcoord, int ycoord);
void move();
void breed();
AgentType getType() const;
vector<Agent *> preyList;
bool altruistic;
private:
int huntingSkill;
};
|
And this is my `main` program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#include <iostream>
#include <ctime> // for time
#include <vector>
#include "Environment.h"
using namespace std;
void simpleSimulation();
void multipleSimulation();
int main() {
int choice;
do {
cout << "Simulation of Cooperative Behaviour: Hunters vs Preys" << endl;
cout << "SIMULATION OPTIONS" << endl;
cout << "==================" << endl;
cout << "0 - Exit the program" << endl;
cout << "1 - Simulate once" << endl;
cout << "2 - Simulate automatically for different ammounts of cooperative hunters and create results file" << endl;
cout << endl << "Enter choice: ";
cin >> choice;
switch (choice) {
case 0:
cout << "Auf wiedersehen." << endl;
break;
case 1:
simpleSimulation();
break;
case 2:
multipleSimulation();
break;
}
} while (choice != 0);
return 0;
}
void simpleSimulation() {
//For world size check "Parameters.h"
// Number of initial preys
int initialPreys = 60;
cout << "The number of initial Preys is:" << initialPreys << endl;
// Number of initial hunters
int initialHunters = 15;
cout << "The number of initial Hunters is:" << initialHunters << endl;
long probAltruisticChoice = 0;
cout << "Indicate probability of presence of altruistic hunters: (0-100)";
cin >> probAltruisticChoice;
probAltruisticChoice = (float)probAltruisticChoice / 100;
// Time steps between breeding of preys
int breedPreys = BREED_PREYS;
// Time steps between breeding of hunters
int breedHunters = BREED_HUNTER;
// Time steps until hunters die if they have not eaten
int starveHunters = STARVE_HUNTERS;
int id = 0;
//Creating the pattern world
int seed = time(NULL);
Environment myWorld(seed, id, initialPreys, initialHunters, breedPreys, breedHunters, starveHunters);
myWorld.setNumberOfAltruistHunters(probAltruisticChoice);
cout << "Press q to quit world simulation." << endl;
cout << "This is the timestep 0" << endl;
myWorld.display();
char ch;
while (cin.get(ch) && ch != 'q') { // q for quit
myWorld.simulateOneStep();
myWorld.display();
}
}
void multipleSimulation() {
//For world size check "Parameters.h"
// Number of initial preys
int initialPreys = 60;
cout << "The number of initial Preys is:" << initialPreys << endl;
// Number of initial hunters
int initialHunters = 15;
cout << "The number of initial Hunters is:" << initialHunters << endl;
long probAltruisticChoice = 0;
// Time steps between breeding of preys
int breedPreys = BREED_PREYS;
// Time steps between breeding of hunters
int breedHunters = BREED_HUNTER;
// Time steps until hunters die if they have not eaten
int starveHunters = STARVE_HUNTERS;
int id = 0;
//Creating the pattern world
int seed = time(NULL);
Environment myWorld(seed, id, initialPreys, initialHunters, breedPreys, breedHunters, starveHunters);
cout << "This is the timestep " << myWorld.getTimestep() << " of the environment for all the simulations" << endl;
myWorld.display();
vector<Environment> simulationResults;
simulationResults.reserve(310);
simulationResults.push_back(myWorld);
int timestepsPerSimulation = 600;
int ammountSimulations = 300;
do {
id++;
myWorld = simulationResults[0];
myWorld.setId(id);
long probAltruisticChoice = (long)(id % 10) / (long)10;
myWorld.setNumberOfAltruistHunters(probAltruisticChoice);
cout << "\n\n\n" << "This is the timestep " << myWorld.getTimestep() << " of the environment for the simulation number " << id << endl;
myWorld.display();
for (int j = 0; j < timestepsPerSimulation; j++) {
myWorld.simulateOneStep();
}
simulationResults.push_back(myWorld);
cout << "\n\n\n" << "This is the timestep " << myWorld.getTimestep() << " of the environment for the simulation number " << id << endl;
myWorld.display();
myWorld.setNumberOfAltruistHunters(probAltruisticChoice);
} while (id < ammountSimulations);
char ch;
while (cin.get(ch) && ch != 'q') { // q for quit
cout << "Press q to quit world simulation." << endl;
}
}
|
Should I post my whole code?
Thanks for any comment. Best!