stochastic simulation, predator/prey
Revision 0:fc1335b7b54f, committed 2019-12-23
- Comitter:
- manitou
- Date:
- Mon Dec 23 18:56:56 2019 +0000
- Commit message:
- stochastic simulation
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Ant.cpp Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,89 @@
+//
+// Ant.cpp
+// INHERITANCE_AND_POLYMORPHISM
+//
+// Created by Kristjan Thorsteinsson on 01/04/14.
+// Copyright (c) 2014 Kristjan Thorsteinsson. All rights reserved.
+//
+#include <cstdlib>
+
+//#include <iostream>
+#include "Ant.h"
+#include "Organism.h"
+#include "World.h"
+using namespace std;
+
+Ant::Ant(World* aWorld, int xcoord, int ycoord) : Organism(aWorld, xcoord, ycoord)
+{
+
+}
+
+void Ant::move()
+{
+ breedTicks++;
+ Move mover = world->randomMove();
+ switch (mover) {
+ case UP:
+ if (world->getAt(x, y + 1) == NULL && in_range(x, y + 1))
+ {
+ movesTo(x, y + 1);
+ }
+ break;
+ case DOWN:
+ if (world->getAt(x, y - 1) == NULL && in_range(x, y - 1))
+ {
+ movesTo(x, y - 1);
+ }
+ break;
+ case LEFT:
+ if (world->getAt(x - 1, y) == NULL && in_range(x - 1, y))
+ {
+ movesTo(x - 1, y);
+ }
+ break;
+ case RIGHT:
+ if (world->getAt(x + 1, y) == NULL && in_range(x + 1, y))
+ {
+ movesTo(x + 1, y);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Ant::breed()
+{
+ if (breedTicks >= BREED_ANTS)
+ {
+ breedAtAdjacentCell();
+ }
+}
+
+
+void Ant::generateOffspring(int whereX, int whereY)
+{
+ new Ant(this->world, whereX, whereY);
+ breedTicks = 0;
+}
+
+
+OrganismType Ant::getType() const
+{
+ return ANT;
+}
+
+char Ant::representation() const
+{
+ return 'o';
+}
+
+int Ant::size() const
+{
+ return 10;
+}
+
+bool Ant::in_range(int xx, int yy)
+{
+ return (xx >= 0) && (xx < ROWS) && (yy >= 0) && (yy < COLS);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Ant.h Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,44 @@
+//
+// Ant.h
+// INHERITANCE_AND_POLYMORPHISM
+//
+// Created by Kristjan Thorsteinsson on 01/04/14.
+// Copyright (c) 2014 Kristjan Thorsteinsson. All rights reserved.
+//
+
+#ifndef INHERITANCE_AND_POLYMORPHISM_Ant
+#define INHERITANCE_AND_POLYMORPHISM_Ant
+
+//#include <iostream>
+#include "Organism.h"
+#include "World.h"
+#include "Counter.h"
+
+class Ant : public Organism, public counter<Ant>
+{
+public:
+
+ Ant(World* aWorld, int xcoord, int ycoord);
+ // In the given world moves this organism.
+ void move();
+
+ // Makes this organism breed.
+ void breed();
+
+ // Returns the type of this organism.
+ OrganismType getType() const;
+
+ // The character representation of this organism.
+ char representation() const;
+
+ // The size of this organism.
+ int size() const;
+
+ bool in_range(int xx, int yy);
+
+private:
+
+ void generateOffspring(int whereX, int whereY);
+};
+
+#endif /* defined(__INHERITANCE_AND_POLYMORPHISM__Ant__) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Bug.cpp Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,207 @@
+//
+// Bug.cpp
+// INHERITANCE_AND_POLYMORPHISM
+//
+// Created by Kristjan Thorsteinsson on 01/04/14.
+// Copyright (c) 2014 Kristjan Thorsteinsson. All rights reserved.
+//
+
+#include "Bug.h"
+#include "Organism.h"
+using namespace std;
+
+Bug::Bug(World* aWorld, int xcoord, int ycoord) : Organism(aWorld, xcoord, ycoord)
+{
+ starveTicks = 0;
+}
+
+
+void Bug::move()
+{
+ breedTicks++;
+ starveTicks++;
+
+#if 1
+ // find an edible nabor
+ for (int i = 0; i < NABORS; i++) {
+ switch (nabors[i]) {
+ case 0:
+ if (world->getAt(x, y + 1) != NULL)
+ {
+ if (world->getAt(x, y + 1)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x, y + 1);
+ movesTo(x, y + 1);
+ return;
+ }
+ }
+ break;
+
+ case 1:
+ if (world->getAt(x, y - 1) != NULL)
+ {
+ if (world->getAt(x, y - 1)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x, y - 1);
+ movesTo(x, y - 1);
+ return;
+ }
+ }
+ break;
+
+ case 2:
+ if (world->getAt(x - 1, y) != NULL)
+ {
+ if (world->getAt(x - 1, y)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x - 1, y);
+ movesTo(x - 1, y);
+ return;
+ }
+ }
+ break;
+
+ case 3:
+ if (world->getAt(x + 1, y) != NULL)
+ {
+ if (world->getAt(x + 1, y)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x + 1, y);
+ movesTo(x + 1, y);
+ return;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ } // for nabors
+#else
+
+ if (world->getAt(x, y + 1) != NULL)
+ {
+ if (world->getAt(x, y + 1)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x, y + 1);
+ movesTo(x, y + 1);
+ return;
+ }
+ }
+
+ if (world->getAt(x, y - 1) != NULL)
+ {
+ if (world->getAt(x, y - 1)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x, y - 1);
+ movesTo(x, y - 1);
+ return;
+ }
+ }
+
+ if (world->getAt(x - 1, y) != NULL)
+ {
+ if (world->getAt(x - 1, y)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x - 1, y);
+ movesTo(x - 1, y);
+ return;
+ }
+ }
+ if (world->getAt(x + 1, y) != NULL)
+ {
+ if (world->getAt(x + 1, y)->getType() == ANT)
+ {
+ starveTicks = 0;
+ delete world->getAt(x + 1, y);
+ movesTo(x + 1, y);
+ return;
+ }
+ }
+#endif
+
+ Move mover = world->randomMove();
+ switch (mover) {
+ case UP:
+ if (world->getAt(x, y + 1) == NULL && in_range(x, y + 1))
+ {
+ movesTo(x, y + 1);
+ }
+ break;
+ case DOWN:
+ if (world->getAt(x, y - 1) == NULL && in_range(x, y - 1))
+ {
+ movesTo(x, y - 1);
+ }
+ break;
+ case LEFT:
+ if (world->getAt(x - 1, y) == NULL && in_range(x - 1, y))
+ {
+ movesTo(x - 1, y);
+ }
+ break;
+ case RIGHT:
+ if (world->getAt(x + 1, y) == NULL && in_range(x + 1, y))
+ {
+ movesTo(x + 1, y);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Bug::generateOffspring(int whereX, int whereY)
+{
+ new Bug(this->world, whereX, whereY);
+ breedTicks = 0;
+}
+
+void Bug::breed()
+{
+ if (breedTicks >= BREED_BUGS)
+ {
+ breedAtAdjacentCell();
+ }
+
+}
+
+bool Bug::isDead() const
+{
+ if (starveTicks >= STARVE_BUGS)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+OrganismType Bug::getType() const
+{
+ return BUG;
+}
+
+
+char Bug::representation()const
+{
+ return 'X';
+}
+
+int Bug::size() const
+{
+ return 30;
+}
+
+bool Bug::in_range(int xx, int yy)
+{
+ return (xx >= 0) && (xx < ROWS) && (yy >= 0) && (yy < COLS);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Bug.h Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,48 @@
+//
+// Bug.h
+// INHERITANCE_AND_POLYMORPHISM
+//
+// Created by Kristjan Thorsteinsson on 01/04/14.
+// Copyright (c) 2014 Kristjan Thorsteinsson. All rights reserved.
+//
+
+#ifndef INHERITANCE_AND_POLYMORPHISM_Bug
+#define INHERITANCE_AND_POLYMORPHISM_Bug
+
+//#include <iostream>
+
+#include "World.h"
+#include "Organism.h"
+#include "Counter.h"
+
+class Bug : public Organism, public counter<Bug>
+{
+public:
+
+ Bug(World* aWorld, int xcoord, int ycoord);
+ // In the given world moves this organism.
+ void move();
+
+ // Makes this organism breed.
+ void breed();
+
+ // Returns the type of this organism.
+ OrganismType getType() const;
+
+ // The character representation of this organism.
+ char representation() const;
+
+ // The size of this organism.
+ int size() const;
+ // Returns true if organism is dead, false otherwise.
+ bool isDead() const;
+
+ bool in_range(int xx, int yy);
+
+private:
+
+ void generateOffspring(int whereX, int whereY);
+ int starveTicks;
+};
+
+#endif /* defined(__INHERITANCE_AND_POLYMORPHISM__Bug__) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Counter.h Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,21 @@
+#ifndef MYCOUNTER
+#define MYCOUNTER
+template <typename T>
+struct counter
+{
+ counter()
+ {
+ objects_created++;
+ objects_alive++;
+ }
+
+ virtual ~counter()
+ {
+ --objects_alive;
+ }
+ static int objects_created;
+ static int objects_alive;
+};
+template <typename T> int counter<T>::objects_created( 0 );
+template <typename T> int counter<T>::objects_alive( 0 );
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Organism.cpp Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,104 @@
+//#include <iostream>
+#include "Organism.h"
+#include "World.h"
+
+// Create an organism at the given coordinates in the given world.
+Organism::Organism(World* aWorld, int xcoord, int ycoord) {
+ world = aWorld;
+ x = xcoord;
+ y = ycoord;
+ breedTicks = 0;
+ moved = false;
+ world->setAt(x, y, this);
+}
+
+// flags the organism as moved or not
+void Organism::setMoved(bool hasMoved) {
+ moved = hasMoved;
+}
+
+// has the organism moved or not?
+bool Organism::hasMoved() const {
+ return moved;
+}
+
+// moves the organism from coordinates (x,y) to (xNew,yNew)
+void Organism::movesTo(int xNew, int yNew) {
+
+ world->setAt(xNew, yNew, world->getAt(x, y));
+
+ world->setAt(x, y, NULL);
+
+ x = xNew;
+ y = yNew;
+
+ world->getAt(x, y)->setMoved(true);
+}
+
+// Breeds an organism at an adjacent cell. This method calls the
+// generateOffspring() method.
+void Organism::breedAtAdjacentCell() {
+#if 1
+ // find empty nabor for breeding
+ for (int i = 0; i < NABORS; i++) {
+ switch (nabors[i]) {
+ case 0:
+ if ((world->getAt(x, y + 1) == NULL) && in_range(x, y + 1))
+ {
+ generateOffspring(x, y + 1);
+ return;
+ }
+ break;
+ case 1:
+ if ((world->getAt(x, y - 1) == NULL) && in_range(x, y - 1))
+ {
+ generateOffspring(x, y - 1);
+ return;
+ }
+ break;
+ case 2:
+ if ((world->getAt(x - 1, y) == NULL) && in_range(x - 1, y))
+ {
+ generateOffspring(x - 1, y);
+ return;
+ }
+ case 3:
+ if ((world->getAt(x + 1, y) == NULL) && in_range(x + 1, y))
+ {
+ generateOffspring(x + 1, y);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ } // nabor for
+#else
+ if ((world->getAt(x, y + 1) == NULL) && in_range(x, y + 1))
+ {
+ generateOffspring(x, y + 1);
+ }
+ else if ((world->getAt(x, y - 1) == NULL) && in_range(x, y - 1))
+ {
+ generateOffspring(x, y - 1);
+ }
+ else if ((world->getAt(x - 1, y) == NULL) && in_range(x - 1, y))
+ {
+ generateOffspring(x - 1, y);
+ }
+ else if ((world->getAt(x + 1, y) == NULL) && in_range(x + 1, y))
+ {
+ generateOffspring(x + 1, y);
+ }
+#endif
+}
+
+
+bool Organism::in_range(int xx, int yy)
+{
+ return (xx >= 0) && (xx < ROWS) && (yy >= 0) && (yy < COLS);
+}
+// Returns true if organism is dead, false otherwise.
+bool Organism::isDead() const {
+ return false;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Organism.h Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,70 @@
+#ifndef ORGANISM_H
+#define ORGANISM_H
+
+enum OrganismType {ANT, BUG};
+
+// forward declaration
+class World;
+
+class Organism {
+ public:
+ // Create an organism at the given coordinates.
+ Organism(World* aWorld, int xcoord, int ycoord);
+ virtual ~Organism() { }
+
+ // In the given world moves this organism.
+ virtual void move() = 0;
+
+ // Makes this organism breed.
+ virtual void breed() = 0;
+
+ // Returns the type of this organism.
+ virtual OrganismType getType() const = 0;
+
+ // Flags this organism as moved or not.
+ void setMoved(bool hasMoved);
+
+ // The character representation of this organism.
+ virtual char representation() const = 0;
+
+ // The size of this organism.
+ virtual int size() const = 0;
+
+ // Has this organism moved in this time slot or not?
+ bool hasMoved() const;
+
+ // Returns true if organism is dead, false otherwise.
+ virtual bool isDead() const;
+
+ bool in_range(int xx, int yy);
+
+ protected:
+ // Generates an offspring at the given position.
+ virtual void generateOffspring(int whereX, int whereY) = 0;
+
+ // Moves this organism from coordinates (x,y) to (xNew,yNew).
+ void movesTo(int xNew, int yNew);
+
+ // Breeds a new organism at an adjacent cell. Tries to produce one new
+ // organism in UP, DOWN, LEFT, or RIGHT cell (in that order). Makes
+ // sure not to breed off the grid.
+ void breedAtAdjacentCell();
+
+ // This organism's x position in the world.
+ int x;
+
+ // This organism's y position in the world.
+ int y;
+
+ // Has moved this turn?
+ bool moved;
+
+ // Number of ticks since breeding.
+ int breedTicks;
+
+ // A pointer to the world in which this organism lives.
+ World* world;
+ private:
+};
+
+#endif // ORGANISM_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/World.cpp Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,223 @@
+#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();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/World.h Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,114 @@
+#ifndef WORLD_H
+#define WORLD_H
+#include <stddef.h>
+
+#include "Organism.h"
+
+// The possible moves
+enum Move {UP = 0, DOWN, LEFT, RIGHT};
+
+// The size of this world
+const int ROWS = 24, COLS = 32;
+
+// Number of initial ants
+const int INITIAL_ANTS = 50;
+
+// Number of initial bugs
+const int INITIAL_BUGS = 10;
+
+// Time steps between breeding of ants
+const int BREED_ANTS = 3;
+
+// Time steps between breeding of bugs
+const int BREED_BUGS = 8;
+
+// Time steps until bugs die if they have not eaten
+const int STARVE_BUGS = 3;
+
+const int NABORS = 4;
+extern int nabors[];
+
+struct Position
+{
+ int x;
+ int y;
+};
+
+class World
+{
+ public:
+ // Constructor: creates and initializes this world. the seed is used for
+ // seeding the random behaviour.
+ World(unsigned int seed);
+
+ // Destructor.
+ ~World();
+
+ // Returns the organism at the given coordinates.
+ Organism* getAt(int x, int y) const;
+
+ // Sets the organism org at position (x,y).
+ void setAt(int x, int y, Organism* org);
+
+ // Displays this world.
+ void display() const;
+ void print() const;
+ void plot() const;
+
+ // Simulates one time step in this world.
+ void simulateOneStep();
+
+ // Returns a random position in the grid.
+ Position randomPosition() const;
+
+ // Returns a random move (UP, DOWN, LEFT or RIGHT).
+ Move randomMove() const;
+
+ private:
+ // The grid in which the organisms live. According the to image below,
+ // the correct iteration order through grid starts at the top left
+ // corner (i.e. grid[0][0]), loops through one column at a time and ends
+ // at the bottom right corner (i.e. grid[WORLDSIZE-1][WORLDSIZE-1]).
+ //
+ // grid[0, 0] , grid[1, 0], ..., grid[WORLDSIZE-1, 0]
+ // grid[0, 1] , grid[1, 1], ..., grid[WORLDSIZE-1, 1]
+ // . .
+ // . .
+ // . .
+ // grid[0, WORLDSIZE-2], grid[1, WORLDSIZE-2], ..., grid[WORLDSIZE-1, WORLDSIZE-2]
+ // grid[0, WORLDSIZE-1], grid[1, WORLDSIZE-1], ..., grid[WORLDSIZE-1, WORLDSIZE-1]
+ //
+ // (See e.g. the destructor for correct iteration through the grid)
+ Organism* grid[ROWS][COLS];
+ unsigned long steps, step_us;
+
+ // Randomly create `count` many organisms of type `orgType`. This
+ // method uses the parameterized constructor in Ant and Bug.
+ void createOrganisms(OrganismType orgType, int count);
+
+ // Reset all organisms to not moved. This is necessary because later we
+ // iterate through the grid starting from the top left moving to the
+ // bottom right looking for an organism to move. Say if an organism
+ // moves down, we don't want to move the organism again when we reach
+ // it.
+ void resetOrganisms();
+
+ // Make every organisms in this world of type aType move. Make sure to
+ // to iterate through grid in order as specified above and only move an
+ // organism if it hasn't moved already.
+ void moveOrganism(OrganismType aType);
+
+ // Remove all dead organism from this world. Iterates through the grid
+ // and uses the method Organism::isDead() to test if an organism is
+ // dead. For this assignment in this method, only starved bugs will be
+ // removed.
+ void cleanup();
+
+ // Make every organism in this world breed. Make sure to iterate
+ // through grid in order as specified above and to only breed organisms
+ // that have moved, since breeding places new organisms on the map we
+ // don't want to try and breed those.
+ void breedOrganisms();
+};
+
+#endif // WORLD_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Dec 23 18:56:56 2019 +0000
@@ -0,0 +1,37 @@
+// predator play stochastic simulation
+// https://github.com/Kristjan93/Ants-and-bugs
+
+#include "mbed.h"
+
+#include "World.h"
+Serial pc(USBTX, USBRX);
+Timer tmr;
+#define micros tmr.read_us
+
+main()
+{
+ tmr.start();
+
+
+ printf("hit a key to step\n");
+
+ World myWorld(0); // seed analogRead(0)
+
+ myWorld.print();
+ // myWorld.display(); // TFT display
+ while (1) {
+#if 1
+ if (pc.readable() ) {
+ pc.getc();
+ myWorld.simulateOneStep();
+ myWorld.print();
+ // myWorld.display(); // TFT display
+ }
+#else
+ myWorld.simulateOneStep();
+ myWorld.plot(); // for serialplotter
+ // myWorld.display(); // TFT display
+ wait(.3);
+#endif
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Dec 23 18:56:56 2019 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/f9eeca106725 \ No newline at end of file