tom dunigan
/
antsnbugs
stochastic simulation, predator/prey
World.cpp
- Committer:
- manitou
- Date:
- 2019-12-23
- Revision:
- 0:fc1335b7b54f
File content as of revision 0:fc1335b7b54f:
#include "mbed.h" #include "World.h" #include "Ant.h" #include "Bug.h" extern Timer tmr; #define micros tmr.read_us #define CELL 9 int nabors[NABORS]; /////////////////// // Public functions /////////////////// // Default constructor: creates and initializes the world // the seed is used for seeding the random behaviour. World::World(unsigned int seed) { srand(seed); // seed the random generator steps = 0; step_us = 0; for(int i=0; i < NABORS; i++) nabors[i] =i; // Create an empty world for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { grid[i][j] = NULL; } } // creates the ants = 3 createOrganisms(ANT, INITIAL_ANTS); // creates the bugs = 8 createOrganisms(BUG, INITIAL_BUGS); } // Deallocate memory allocated to organisms in this world. World::~World() { for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { if (grid[i][j] != NULL) { delete grid[i][j]; } } } } // Return the organism at the given coordinates // If the coordinates are not valid, returns NULL Organism* World::getAt(int x, int y) const { if ((x >= 0) && (x < ROWS) && (y >= 0) && (y < COLS)) { return grid[x][y]; } else { return NULL; } } // Sets the entry at x,y to the value passed in. void World::setAt(int x, int y, Organism* org) { if ((x >= 0) && (x < ROWS) && (y >= 0) && (y < COLS)) { grid[x][y] = org; } } // Displays the world in ASCII. void World::print() const { printf("\n"); for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { if (grid[i][j] == NULL) { printf( "."); } else { printf("%c", grid[i][j]->representation()); } } printf("\n"); } // cout << "Ants: " << numAnts << " Bugs: " << numBugs << endl; printf("Ants: %d Bugs: %d steps %d %d us\n",counter<Ant>::objects_alive,counter<Bug>::objects_alive,steps,step_us); #if 0 Serial.print("Ants: "); Serial.print(counter<Ant>::objects_alive); Serial.print(" Bugs: "); Serial.print(counter<Bug>::objects_alive); Serial.print(" steps: "); Serial.print(steps); Serial.print(" "); Serial.print(step_us); Serial.println(" us"); #endif } // for serialplotter void World::plot() const { //Serial.print("Ants: "); Serial.print(counter<Ant>::objects_alive); //Serial.print(" Bugs: "); Serial.println(counter<Bug>::objects_alive); //Serial.println(step_us); } void World::simulateOneStep() { // The main routine that simulates one turn in the world: // 1. move bugs // 2. move ants // 3. make bugs starve (which happends under a certain condition) // 4. make the organisms breed (again which happens under a certain // condition). steps++; step_us = micros(); // shuffle nabors for (int i=0; i< NABORS; i++) { int n = rand() % NABORS; int tmp = nabors[n]; nabors[n] = nabors[i]; nabors[i] = tmp; } // Reset all organisms to not moved resetOrganisms(); // Move the bugs moveOrganism(BUG); // Move the ants moveOrganism(ANT); // Make the bugs starve cleanup(); //Make them breed breedOrganisms(); step_us = micros() - step_us; } Position World::randomPosition() const { // returns a random number in the range 0 to MAX-1 Position p; p.x = rand() % ROWS; p.y = rand() % COLS; return p; } Move World::randomMove() const { return static_cast<Move>(rand() % 4); } //////////////////// // Private functions //////////////////// void World::createOrganisms(OrganismType orgType, int count) { int orgCount = 0; while (orgCount < count) { Position p = randomPosition(); // Only put ant in empty spot if (grid[p.x][p.y] == NULL) { orgCount++; if (orgType == ANT) { new Ant(this, p.x, p.y); // Create an Ant and put it into the world } else if (orgType == BUG) { new Bug(this, p.x, p.y); // Create a Bug and put it into the world } } } } // Reset all organisms to not moved void World::resetOrganisms() { for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { if (grid[i][j] != NULL) { grid[i][j]->setMoved(false); } } } } // Move all organisms of type aType void World::moveOrganism(OrganismType aType) { for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { if (grid[i][j] != NULL) { if (grid[i][j]->getType() == aType && !(grid[i][j]->hasMoved())) { grid[i][j]->move(); } } } } } // Remove all dead organisms from this world. void World::cleanup() { for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { // Kill off any organisms that haven't eaten recently if ((grid[i][j] != NULL) && grid[i][j]->isDead()) { delete grid[i][j]; grid[i][j] = NULL; } } } } // Make the organisms breed void World::breedOrganisms() { for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { if (grid[i][j] != NULL) { grid[i][j]->breed(); } } } }