stochastic simulation, predator/prey

Dependencies:   mbed

Committer:
manitou
Date:
Mon Dec 23 18:56:56 2019 +0000
Revision:
0:fc1335b7b54f
stochastic simulation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
manitou 0:fc1335b7b54f 1 #include "mbed.h"
manitou 0:fc1335b7b54f 2
manitou 0:fc1335b7b54f 3 #include "World.h"
manitou 0:fc1335b7b54f 4 #include "Ant.h"
manitou 0:fc1335b7b54f 5 #include "Bug.h"
manitou 0:fc1335b7b54f 6
manitou 0:fc1335b7b54f 7 extern Timer tmr;
manitou 0:fc1335b7b54f 8 #define micros tmr.read_us
manitou 0:fc1335b7b54f 9
manitou 0:fc1335b7b54f 10 #define CELL 9
manitou 0:fc1335b7b54f 11
manitou 0:fc1335b7b54f 12 int nabors[NABORS];
manitou 0:fc1335b7b54f 13
manitou 0:fc1335b7b54f 14
manitou 0:fc1335b7b54f 15 ///////////////////
manitou 0:fc1335b7b54f 16 // Public functions
manitou 0:fc1335b7b54f 17 ///////////////////
manitou 0:fc1335b7b54f 18
manitou 0:fc1335b7b54f 19 // Default constructor: creates and initializes the world
manitou 0:fc1335b7b54f 20 // the seed is used for seeding the random behaviour.
manitou 0:fc1335b7b54f 21 World::World(unsigned int seed) {
manitou 0:fc1335b7b54f 22 srand(seed); // seed the random generator
manitou 0:fc1335b7b54f 23 steps = 0;
manitou 0:fc1335b7b54f 24 step_us = 0;
manitou 0:fc1335b7b54f 25 for(int i=0; i < NABORS; i++) nabors[i] =i;
manitou 0:fc1335b7b54f 26 // Create an empty world
manitou 0:fc1335b7b54f 27 for (int i = 0; i < ROWS; i++) {
manitou 0:fc1335b7b54f 28 for (int j = 0; j < COLS; j++) {
manitou 0:fc1335b7b54f 29 grid[i][j] = NULL;
manitou 0:fc1335b7b54f 30 }
manitou 0:fc1335b7b54f 31 }
manitou 0:fc1335b7b54f 32 // creates the ants = 3
manitou 0:fc1335b7b54f 33 createOrganisms(ANT, INITIAL_ANTS);
manitou 0:fc1335b7b54f 34 // creates the bugs = 8
manitou 0:fc1335b7b54f 35 createOrganisms(BUG, INITIAL_BUGS);
manitou 0:fc1335b7b54f 36 }
manitou 0:fc1335b7b54f 37
manitou 0:fc1335b7b54f 38 // Deallocate memory allocated to organisms in this world.
manitou 0:fc1335b7b54f 39 World::~World() {
manitou 0:fc1335b7b54f 40 for (int i = 0; i < ROWS; i++) {
manitou 0:fc1335b7b54f 41 for (int j = 0; j < COLS; j++) {
manitou 0:fc1335b7b54f 42 if (grid[i][j] != NULL) {
manitou 0:fc1335b7b54f 43 delete grid[i][j];
manitou 0:fc1335b7b54f 44 }
manitou 0:fc1335b7b54f 45 }
manitou 0:fc1335b7b54f 46 }
manitou 0:fc1335b7b54f 47 }
manitou 0:fc1335b7b54f 48
manitou 0:fc1335b7b54f 49 // Return the organism at the given coordinates
manitou 0:fc1335b7b54f 50 // If the coordinates are not valid, returns NULL
manitou 0:fc1335b7b54f 51 Organism* World::getAt(int x, int y) const {
manitou 0:fc1335b7b54f 52 if ((x >= 0) && (x < ROWS) && (y >= 0) && (y < COLS)) {
manitou 0:fc1335b7b54f 53 return grid[x][y];
manitou 0:fc1335b7b54f 54 } else {
manitou 0:fc1335b7b54f 55 return NULL;
manitou 0:fc1335b7b54f 56 }
manitou 0:fc1335b7b54f 57 }
manitou 0:fc1335b7b54f 58
manitou 0:fc1335b7b54f 59 // Sets the entry at x,y to the value passed in.
manitou 0:fc1335b7b54f 60 void World::setAt(int x, int y, Organism* org) {
manitou 0:fc1335b7b54f 61 if ((x >= 0) && (x < ROWS) && (y >= 0) && (y < COLS)) {
manitou 0:fc1335b7b54f 62 grid[x][y] = org;
manitou 0:fc1335b7b54f 63 }
manitou 0:fc1335b7b54f 64 }
manitou 0:fc1335b7b54f 65
manitou 0:fc1335b7b54f 66 // Displays the world in ASCII.
manitou 0:fc1335b7b54f 67 void World::print() const {
manitou 0:fc1335b7b54f 68
manitou 0:fc1335b7b54f 69 printf("\n");
manitou 0:fc1335b7b54f 70 for (int i = 0; i < ROWS; i++) {
manitou 0:fc1335b7b54f 71 for (int j = 0; j < COLS; j++) {
manitou 0:fc1335b7b54f 72 if (grid[i][j] == NULL) {
manitou 0:fc1335b7b54f 73 printf( ".");
manitou 0:fc1335b7b54f 74 } else {
manitou 0:fc1335b7b54f 75 printf("%c", grid[i][j]->representation());
manitou 0:fc1335b7b54f 76 }
manitou 0:fc1335b7b54f 77 }
manitou 0:fc1335b7b54f 78 printf("\n");
manitou 0:fc1335b7b54f 79 }
manitou 0:fc1335b7b54f 80 // cout << "Ants: " << numAnts << " Bugs: " << numBugs << endl;
manitou 0:fc1335b7b54f 81 printf("Ants: %d Bugs: %d steps %d %d us\n",counter<Ant>::objects_alive,counter<Bug>::objects_alive,steps,step_us);
manitou 0:fc1335b7b54f 82 #if 0
manitou 0:fc1335b7b54f 83 Serial.print("Ants: "); Serial.print(counter<Ant>::objects_alive);
manitou 0:fc1335b7b54f 84 Serial.print(" Bugs: "); Serial.print(counter<Bug>::objects_alive);
manitou 0:fc1335b7b54f 85 Serial.print(" steps: "); Serial.print(steps);
manitou 0:fc1335b7b54f 86 Serial.print(" "); Serial.print(step_us); Serial.println(" us");
manitou 0:fc1335b7b54f 87 #endif
manitou 0:fc1335b7b54f 88 }
manitou 0:fc1335b7b54f 89
manitou 0:fc1335b7b54f 90 // for serialplotter
manitou 0:fc1335b7b54f 91 void World::plot() const {
manitou 0:fc1335b7b54f 92 //Serial.print("Ants: "); Serial.print(counter<Ant>::objects_alive);
manitou 0:fc1335b7b54f 93 //Serial.print(" Bugs: "); Serial.println(counter<Bug>::objects_alive);
manitou 0:fc1335b7b54f 94 //Serial.println(step_us);
manitou 0:fc1335b7b54f 95 }
manitou 0:fc1335b7b54f 96
manitou 0:fc1335b7b54f 97
manitou 0:fc1335b7b54f 98
manitou 0:fc1335b7b54f 99 void World::simulateOneStep() {
manitou 0:fc1335b7b54f 100 // The main routine that simulates one turn in the world:
manitou 0:fc1335b7b54f 101 // 1. move bugs
manitou 0:fc1335b7b54f 102 // 2. move ants
manitou 0:fc1335b7b54f 103 // 3. make bugs starve (which happends under a certain condition)
manitou 0:fc1335b7b54f 104 // 4. make the organisms breed (again which happens under a certain
manitou 0:fc1335b7b54f 105 // condition).
manitou 0:fc1335b7b54f 106
manitou 0:fc1335b7b54f 107 steps++;
manitou 0:fc1335b7b54f 108 step_us = micros();
manitou 0:fc1335b7b54f 109 // shuffle nabors
manitou 0:fc1335b7b54f 110 for (int i=0; i< NABORS; i++) {
manitou 0:fc1335b7b54f 111 int n = rand() % NABORS;
manitou 0:fc1335b7b54f 112 int tmp = nabors[n];
manitou 0:fc1335b7b54f 113 nabors[n] = nabors[i];
manitou 0:fc1335b7b54f 114 nabors[i] = tmp;
manitou 0:fc1335b7b54f 115 }
manitou 0:fc1335b7b54f 116 // Reset all organisms to not moved
manitou 0:fc1335b7b54f 117 resetOrganisms();
manitou 0:fc1335b7b54f 118
manitou 0:fc1335b7b54f 119 // Move the bugs
manitou 0:fc1335b7b54f 120 moveOrganism(BUG);
manitou 0:fc1335b7b54f 121
manitou 0:fc1335b7b54f 122 // Move the ants
manitou 0:fc1335b7b54f 123 moveOrganism(ANT);
manitou 0:fc1335b7b54f 124
manitou 0:fc1335b7b54f 125 // Make the bugs starve
manitou 0:fc1335b7b54f 126 cleanup();
manitou 0:fc1335b7b54f 127
manitou 0:fc1335b7b54f 128 //Make them breed
manitou 0:fc1335b7b54f 129 breedOrganisms();
manitou 0:fc1335b7b54f 130 step_us = micros() - step_us;
manitou 0:fc1335b7b54f 131 }
manitou 0:fc1335b7b54f 132
manitou 0:fc1335b7b54f 133 Position World::randomPosition() const { // returns a random number in the range 0 to MAX-1
manitou 0:fc1335b7b54f 134 Position p;
manitou 0:fc1335b7b54f 135 p.x = rand() % ROWS;
manitou 0:fc1335b7b54f 136 p.y = rand() % COLS;
manitou 0:fc1335b7b54f 137 return p;
manitou 0:fc1335b7b54f 138 }
manitou 0:fc1335b7b54f 139
manitou 0:fc1335b7b54f 140
manitou 0:fc1335b7b54f 141 Move World::randomMove() const {
manitou 0:fc1335b7b54f 142 return static_cast<Move>(rand() % 4);
manitou 0:fc1335b7b54f 143 }
manitou 0:fc1335b7b54f 144
manitou 0:fc1335b7b54f 145 ////////////////////
manitou 0:fc1335b7b54f 146 // Private functions
manitou 0:fc1335b7b54f 147 ////////////////////
manitou 0:fc1335b7b54f 148
manitou 0:fc1335b7b54f 149 void World::createOrganisms(OrganismType orgType, int count) {
manitou 0:fc1335b7b54f 150 int orgCount = 0;
manitou 0:fc1335b7b54f 151 while (orgCount < count) {
manitou 0:fc1335b7b54f 152 Position p = randomPosition();
manitou 0:fc1335b7b54f 153
manitou 0:fc1335b7b54f 154 // Only put ant in empty spot
manitou 0:fc1335b7b54f 155 if (grid[p.x][p.y] == NULL) {
manitou 0:fc1335b7b54f 156 orgCount++;
manitou 0:fc1335b7b54f 157 if (orgType == ANT) {
manitou 0:fc1335b7b54f 158 new Ant(this, p.x, p.y); // Create an Ant and put it into the world
manitou 0:fc1335b7b54f 159 }
manitou 0:fc1335b7b54f 160 else if (orgType == BUG) {
manitou 0:fc1335b7b54f 161 new Bug(this, p.x, p.y); // Create a Bug and put it into the world
manitou 0:fc1335b7b54f 162 }
manitou 0:fc1335b7b54f 163 }
manitou 0:fc1335b7b54f 164 }
manitou 0:fc1335b7b54f 165 }
manitou 0:fc1335b7b54f 166
manitou 0:fc1335b7b54f 167 // Reset all organisms to not moved
manitou 0:fc1335b7b54f 168 void World::resetOrganisms() {
manitou 0:fc1335b7b54f 169 for (int i = 0; i < ROWS; i++)
manitou 0:fc1335b7b54f 170 {
manitou 0:fc1335b7b54f 171 for (int j = 0; j < COLS; j++)
manitou 0:fc1335b7b54f 172 {
manitou 0:fc1335b7b54f 173 if (grid[i][j] != NULL)
manitou 0:fc1335b7b54f 174 {
manitou 0:fc1335b7b54f 175 grid[i][j]->setMoved(false);
manitou 0:fc1335b7b54f 176 }
manitou 0:fc1335b7b54f 177 }
manitou 0:fc1335b7b54f 178 }
manitou 0:fc1335b7b54f 179 }
manitou 0:fc1335b7b54f 180
manitou 0:fc1335b7b54f 181 // Move all organisms of type aType
manitou 0:fc1335b7b54f 182 void World::moveOrganism(OrganismType aType) {
manitou 0:fc1335b7b54f 183 for (int i = 0; i < ROWS; i++)
manitou 0:fc1335b7b54f 184 {
manitou 0:fc1335b7b54f 185 for (int j = 0; j < COLS; j++)
manitou 0:fc1335b7b54f 186 {
manitou 0:fc1335b7b54f 187 if (grid[i][j] != NULL)
manitou 0:fc1335b7b54f 188 {
manitou 0:fc1335b7b54f 189 if (grid[i][j]->getType() == aType && !(grid[i][j]->hasMoved()))
manitou 0:fc1335b7b54f 190 {
manitou 0:fc1335b7b54f 191 grid[i][j]->move();
manitou 0:fc1335b7b54f 192 }
manitou 0:fc1335b7b54f 193 }
manitou 0:fc1335b7b54f 194 }
manitou 0:fc1335b7b54f 195 }
manitou 0:fc1335b7b54f 196 }
manitou 0:fc1335b7b54f 197
manitou 0:fc1335b7b54f 198 // Remove all dead organisms from this world.
manitou 0:fc1335b7b54f 199 void World::cleanup() {
manitou 0:fc1335b7b54f 200 for (int i = 0; i < ROWS; i++) {
manitou 0:fc1335b7b54f 201 for (int j = 0; j < COLS; j++) {
manitou 0:fc1335b7b54f 202 // Kill off any organisms that haven't eaten recently
manitou 0:fc1335b7b54f 203 if ((grid[i][j] != NULL) && grid[i][j]->isDead()) {
manitou 0:fc1335b7b54f 204 delete grid[i][j];
manitou 0:fc1335b7b54f 205 grid[i][j] = NULL;
manitou 0:fc1335b7b54f 206 }
manitou 0:fc1335b7b54f 207 }
manitou 0:fc1335b7b54f 208 }
manitou 0:fc1335b7b54f 209 }
manitou 0:fc1335b7b54f 210
manitou 0:fc1335b7b54f 211 // Make the organisms breed
manitou 0:fc1335b7b54f 212 void World::breedOrganisms() {
manitou 0:fc1335b7b54f 213 for (int i = 0; i < ROWS; i++)
manitou 0:fc1335b7b54f 214 {
manitou 0:fc1335b7b54f 215 for (int j = 0; j < COLS; j++)
manitou 0:fc1335b7b54f 216 {
manitou 0:fc1335b7b54f 217 if (grid[i][j] != NULL)
manitou 0:fc1335b7b54f 218 {
manitou 0:fc1335b7b54f 219 grid[i][j]->breed();
manitou 0:fc1335b7b54f 220 }
manitou 0:fc1335b7b54f 221 }
manitou 0:fc1335b7b54f 222 }
manitou 0:fc1335b7b54f 223 }