stochastic simulation, predator/prey

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
manitou
Date:
Mon Dec 23 18:56:56 2019 +0000
Commit message:
stochastic simulation

Changed in this revision

Ant.cpp Show annotated file Show diff for this revision Revisions of this file
Ant.h Show annotated file Show diff for this revision Revisions of this file
Bug.cpp Show annotated file Show diff for this revision Revisions of this file
Bug.h Show annotated file Show diff for this revision Revisions of this file
Counter.h Show annotated file Show diff for this revision Revisions of this file
Organism.cpp Show annotated file Show diff for this revision Revisions of this file
Organism.h Show annotated file Show diff for this revision Revisions of this file
World.cpp Show annotated file Show diff for this revision Revisions of this file
World.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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