Advertisement
Guest User

Ants and Doodlebugs

a guest
Apr 16th, 2019
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.85 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. class Organism
  7. {
  8. private:
  9.   int x;
  10.   int y;
  11.   int id;
  12.   int roundsSurvived;
  13.   int roundsNotEaten;
  14.   bool hasMoved;
  15.   bool hasEaten;
  16.  
  17. public:
  18.   static constexpr int UP = 1;
  19.   static constexpr int DOWN = 2;
  20.   static constexpr int LEFT = 3;
  21.   static constexpr int RIGHT = 4;
  22.  
  23.   Organism(int x, int y, int id)
  24.   {
  25.     if (y < 0) {
  26.       std::cout << std::endl;
  27.     }
  28.     this->x = x;
  29.     this->y = y;
  30.     this->id = id;
  31.     this->roundsSurvived = 0;
  32.     this->roundsNotEaten = 0;
  33.     this->hasMoved = false;
  34.     this->hasEaten = false;
  35.   }
  36.  
  37.   virtual ~Organism() {}
  38.   virtual void move(Organism *grid[20][20]) = 0;
  39.   virtual char getType() const = 0;
  40.   virtual void breed(Organism *grid[20][20], int &) = 0;
  41.   virtual void starve(Organism *grid[20][20])
  42.   {}
  43.  
  44.   // Getters
  45.   int getX() const { return x; }
  46.   int getY() const { return y; }
  47.   int getID() const { return id; }
  48.   int getRoundsSurvived() const { return roundsSurvived; }
  49.   bool getIfMoved() const { return hasMoved; }
  50.   bool getIfAte() const { return hasEaten; }
  51.   int getRoundsNotEaten() const { return roundsNotEaten; }
  52.   // Setters
  53.   void setX(int x) { this->x = x; }
  54.   void setY(int y) { this->y = y; }
  55.   void setID(int id) { this->id = id; }
  56.   void setRoundsSurvived(int roundsSurvived) { this->roundsSurvived = roundsSurvived; }
  57.   void setRoundsNotEaten(int roundsNotEaten) { this->roundsNotEaten = roundsNotEaten; }
  58.  
  59.   void setIfMoved(bool condition) { this->hasMoved = condition; }
  60.   void setIfAte(bool condition) { this->hasEaten = condition; }
  61. };
  62.  
  63. constexpr int Organism::UP;
  64. constexpr int Organism::DOWN;
  65. constexpr int Organism::LEFT;
  66. constexpr int Organism::RIGHT;
  67. class Doodlebug : public Organism
  68. {
  69. private:
  70.   char type;
  71.   int getDirection(Organism* grid[20][20])
  72.   {
  73.     int x = this->getX(), y = this->getY();
  74.     // find directions which has ants and ones which are empty
  75.     std::vector<int> antDirections;
  76.     std::vector<int> emptyDirections;
  77.     if (x - 1 >= 0) {
  78.       if (grid[x - 1][y] == NULL) {
  79.         emptyDirections.push_back(UP);
  80.       } else if (grid[x - 1][y]->getType() == 'o') {
  81.         antDirections.push_back(UP);
  82.       }
  83.     }
  84.     if (x + 1 <= 19) {
  85.       if (grid[x + 1][y] == NULL) {
  86.         emptyDirections.push_back(DOWN);
  87.       } else if (grid[x + 1][y]->getType() == 'o') {
  88.         antDirections.push_back(DOWN);
  89.       }
  90.     }
  91.     if (y - 1 >= 0) {
  92.       if (grid[x][y - 1] == NULL) {
  93.         emptyDirections.push_back(LEFT);
  94.       } else if (grid[x][y - 1]->getType() == 'o') {
  95.         antDirections.push_back(LEFT);
  96.       }
  97.     }
  98.     if (y + 1 <= 19) {
  99.       if (grid[x][y + 1] == NULL) {
  100.         emptyDirections.push_back(RIGHT);
  101.       } else if (grid[x][y + 1]->getType() == 'o') {
  102.         antDirections.push_back(RIGHT);
  103.       }
  104.     }
  105.     // if any directions has ants, choose one of them
  106.     if (!antDirections.empty())
  107.     {
  108.       int randomIndex = rand() % antDirections.size();
  109.       return antDirections[randomIndex];
  110.     }
  111.     else if (!emptyDirections.empty())
  112.     {
  113.       // else choose a random movable direction
  114.       int randomIndex = rand() % emptyDirections.size();
  115.       return emptyDirections[randomIndex];
  116.     } else {
  117.       // else the Doodle is stuck
  118.       return 0;
  119.     }
  120.   }
  121.  
  122. public:
  123.   Doodlebug(int x, int y, int id) : Organism(x, y, id), type('X') {}
  124.   virtual ~Doodlebug() {}
  125.   char getType() const { return type; }
  126.   void move(Organism *grid[20][20]);
  127.   void breed(Organism *grid[20][20], int &doodlebugID);
  128.   void starve(Organism *grid[20][20]);
  129. };
  130.  
  131. void Doodlebug::move(Organism *grid[20][20])
  132. {
  133.   /*
  134.   1. Randomize a direction
  135.     (.) Let's define the directions by the following integers
  136.       (a) Up: 1
  137.       (b) Down: 2
  138.       (c) Left: 3
  139.       (d) Right: 4
  140.  
  141.   2. Depending on which direction you're going make sure it's a valid direction
  142.     (a) A direction is valid if the doodlebug doesn't fall off the grid
  143.  
  144.   3. Swap x, y with that point in the grid by creating a new object and marking
  145.      that object as one that moved
  146.   */
  147.   if (this->getIfMoved() == true) {
  148.     return;
  149.   }
  150.   this->setRoundsSurvived(this->getRoundsSurvived() + 1);
  151.  
  152.   int direction = this->getDirection(grid);
  153.   if (direction == 0) {
  154.     // the Doodle is stuck
  155.     return;
  156.   }
  157.   int x = this->getX(), newX = this->getX();
  158.   int y = this->getY(), newY = this->getY();
  159.   int newID = this->getID();
  160.  
  161.   switch (direction) {
  162.   case UP:
  163.     newX = x - 1;
  164.     break;
  165.   case DOWN:
  166.     newX = x + 1;
  167.     break;
  168.   case LEFT:
  169.     newY = y - 1;
  170.     break;
  171.   case RIGHT:
  172.     newY = y + 1;
  173.     break;
  174.   default:
  175.     break;
  176.   }
  177.   //------------------------------------------------
  178.   if (grid[newX][newY] && grid[newX][newY]->getType() == 'o') {
  179.     this->setIfAte(true);
  180.     this->setRoundsNotEaten(0);
  181.   } else {
  182.     this->setIfAte(false);
  183.     this->setRoundsNotEaten(this->getRoundsNotEaten() + 1);
  184.   }
  185.   if (newY < 0) {
  186.     std::cout << std::endl;
  187.   }
  188.   this->setX(newX);
  189.   this->setY(newY);
  190.  
  191.   grid[newX][newY] = this;
  192.   grid[x][y] = NULL;
  193.  
  194.   this->setIfMoved(true);
  195.   //------------------------------------------------
  196. }
  197.  
  198. void Doodlebug::breed(Organism *grid[20][20], int &doodlebugID)
  199. {
  200.   setRoundsSurvived(0);
  201.   if (getX() - 1 >= 0 && grid[getX() - 1][getY()] == NULL)
  202.   {
  203.     ++doodlebugID;
  204.     grid[getX() - 1][getY()] = new Doodlebug(getX() - 1, getY(), doodlebugID);
  205.   }
  206.  
  207.   else if (getX() + 1 <= 19 && grid[getX() + 1][getY()] == NULL)
  208.   {
  209.     ++doodlebugID;
  210.     grid[getX() + 1][getY()] = new Doodlebug(getX() + 1, getY(), doodlebugID);
  211.   }
  212.  
  213.   else if (getY() - 1 >= 0 && grid[getX()][getY() - 1] == NULL)
  214.   {
  215.     ++doodlebugID;
  216.     grid[getX()][getY() - 1] = new Doodlebug(getX(), getY() - 1, doodlebugID);
  217.   }
  218.  
  219.   else if (getY() + 1 <= 19 && grid[getX()][getY() + 1] == NULL)
  220.   {
  221.     ++doodlebugID;
  222.     grid[getX()][getY() + 1] = new Doodlebug(getX(), getY() + 1, doodlebugID);
  223.   }
  224. }
  225.  
  226. void Doodlebug::starve(Organism *grid[20][20])
  227. {
  228.   /*
  229.   Implement this after implementing the ant class
  230.   //*/
  231.   if (getRoundsNotEaten() == 3)
  232.   {
  233.     if (getIfAte() == false)
  234.     {
  235.       delete grid[getX()][getY()];
  236.       grid[getX()][getY()] = NULL;
  237.     }
  238.   }
  239. }
  240.  
  241. class Ant : public Organism
  242. {
  243.  
  244. private:
  245.   char type;
  246.  
  247. public:
  248.   Ant(int x, int y, int id) : Organism(x, y, id), type('o') {}
  249.  
  250.   virtual ~Ant() {}
  251.  
  252.   char getType() const { return type; }
  253.  
  254.   void move(Organism *grid[20][20]);
  255.  
  256.   void breed(Organism *grid[20][20], int &);
  257. };
  258.  
  259. void Ant::move(Organism *grid[20][20])
  260. {
  261.   int direction = rand() % 4 + 1;
  262.   if (direction == 1 && getX() - 1 >= 0 && getIfMoved() == false)
  263.   {
  264.     if (grid[getX() - 1][getY()] == NULL)
  265.     {
  266.       int newX = getX() - 1;
  267.       int newY = getY();
  268.       int newID = getID();
  269.       int newRoundsSurvived = getRoundsSurvived() + 1;
  270.       delete grid[getX()][getY()];
  271.       grid[getX()][getY()] = NULL;
  272.       grid[newX][newY] = new Ant(newX, newY, newID);
  273.       grid[newX][newY]->setRoundsSurvived(newRoundsSurvived);
  274.       grid[newX][newY]->setIfMoved(true);
  275.       return;
  276.     }
  277.   }
  278.  
  279.   if (direction == 2 && getX() + 1 <= 19 && getIfMoved() == false)
  280.   {
  281.     if (grid[getX() + 1][getY()] == NULL)
  282.     {
  283.       int newX = getX() + 1;
  284.       int newY = getY();
  285.       int newID = getID();
  286.       int newRoundsSurvived = getRoundsSurvived() + 1;
  287.       delete grid[getX()][getY()];
  288.       grid[getX()][getY()] = NULL;
  289.       grid[newX][newY] = new Ant(newX, newY, newID);
  290.       grid[newX][newY]->setRoundsSurvived(newRoundsSurvived);
  291.       grid[newX][newY]->setIfMoved(true);
  292.       return;
  293.     }
  294.   }
  295.  
  296.   if (direction == 3 && getY() - 1 >= 0 && getIfMoved() == false)
  297.   {
  298.     if (grid[getX()][getY() - 1] == NULL)
  299.     {
  300.       int newX = getX();
  301.       int newY = getY() - 1;
  302.       int newID = getID();
  303.       int newRoundsSurvived = getRoundsSurvived() + 1;
  304.       delete grid[getX()][getY()];
  305.       grid[getX()][getY()] = NULL;
  306.       grid[newX][newY] = new Ant(newX, newY, newID);
  307.       grid[newX][newY]->setRoundsSurvived(newRoundsSurvived);
  308.       grid[newX][newY]->setIfMoved(true);
  309.       return;
  310.     }
  311.   }
  312.  
  313.   if (direction == 4 && getY() + 1 <= 19 && getIfMoved() == false)
  314.   {
  315.     if (grid[getX()][getY() + 1] == NULL)
  316.     {
  317.       int newX = getX();
  318.       int newY = getY() + 1;
  319.       int newID = getID();
  320.       int newRoundsSurvived = getRoundsSurvived() + 1;
  321.       delete grid[getX()][getY()];
  322.       grid[getX()][getY()] = NULL;
  323.       grid[newX][newY] = new Ant(newX, newY, newID);
  324.       grid[newX][newY]->setRoundsSurvived(newRoundsSurvived);
  325.       grid[newX][newY]->setIfMoved(true);
  326.       return;
  327.     }
  328.   }
  329.   setRoundsSurvived(getRoundsSurvived() + 1);
  330. }
  331.  
  332. void Ant::breed(Organism *grid[20][20], int &antID)
  333. {
  334.   setRoundsSurvived(0);
  335.   if (getX() - 1 >= 0 && grid[getX() - 1][getY()] == NULL)
  336.   {
  337.     ++antID;
  338.     grid[getX() - 1][getY()] = new Ant(getX() - 1, getY(), antID);
  339.   }
  340.  
  341.   else if (getX() + 1 <= 19 && grid[getX() + 1][getY()] == NULL)
  342.   {
  343.     ++antID;
  344.     grid[getX() + 1][getY()] = new Ant(getX() + 1, getY(), antID);
  345.   }
  346.  
  347.   else if (getY() - 1 >= 0 && grid[getX()][getY() - 1] == NULL)
  348.   {
  349.     ++antID;
  350.     grid[getX()][getY() - 1] = new Ant(getX(), getY() - 1, antID);
  351.   }
  352.  
  353.   else if (getY() + 1 <= 19 && grid[getX()][getY() + 1] == NULL)
  354.   {
  355.     ++antID;
  356.     grid[getX()][getY() + 1] = new Ant(getX(), getY() + 1, antID);
  357.   }
  358.  
  359. }
  360.  
  361. void initialize(Organism *grid[20][20])
  362. {
  363.  
  364.   for (int i = 0; i < 20; i++)
  365.   {
  366.  
  367.     for (int j = 0; j < 20; j++)
  368.     {
  369.  
  370.       grid[i][j] = NULL;
  371.     }
  372.   }
  373. }
  374.  
  375. void render(Organism *grid[20][20])
  376. {
  377.  
  378.   for (int i = 0; i < 20; i++)
  379.   {
  380.     for (int j = 0; j < 20; j++)
  381.     {
  382.       if (grid[i][j] == NULL)
  383.       {
  384.         std::cout << "-"
  385.                   << " ";
  386.       }
  387.       else if (grid[i][j]->getType() == 'X')
  388.       {
  389.         std::cout << "X"
  390.                   << " ";
  391.       }
  392.       else if (grid[i][j]->getType() == 'o')
  393.       {
  394.         std::cout << "o"
  395.                   << " ";
  396.       }
  397.     }
  398.     std::cout << std::endl;
  399.   }
  400.   std::cout << std::endl;
  401. }
  402.  
  403. int countTheDoodles(Organism *grid[20][20])
  404. {
  405.  
  406.   int count = 0;
  407.  
  408.   for (int i = 0; i < 20; i++)
  409.   {
  410.  
  411.     for (int j = 0; j < 20; j++)
  412.     {
  413.  
  414.       if (grid[i][j] != NULL)
  415.       {
  416.  
  417.         if (grid[i][j]->getType() == 'X')
  418.         {
  419.  
  420.           count++;
  421.         }
  422.       }
  423.     }
  424.   }
  425.  
  426.   return count;
  427. }
  428.  
  429. int countTheAnts(Organism *grid[20][20])
  430. {
  431.   int count = 0;
  432.   for (int i = 0; i < 20; i++)
  433.   {
  434.     for (int j = 0; j < 20; j++)
  435.     {
  436.       if (grid[i][j] != NULL)
  437.       {
  438.         if (grid[i][j]->getType() == 'o')
  439.         {
  440.           count++;
  441.         }
  442.       }
  443.     }
  444.   }
  445.  
  446.   return count;
  447. }
  448.  
  449. int main()
  450. {
  451.   Organism *grid[20][20];
  452.   initialize(grid);
  453.   std::srand(time(NULL));
  454.   // Create 5 doodlebugs on the heap
  455.   int doodlebugCount = 0;
  456.   int doodlebugID = 0;
  457.   while (doodlebugCount < 5)
  458.   {
  459.     // Get a random x and y coordinate for the grid
  460.     int randomX = rand() % 20;
  461.     int randomY = rand() % 20;
  462.     if (grid[randomX][randomY] == NULL)
  463.     {
  464.       grid[randomX][randomY] = new Doodlebug(randomX, randomY, doodlebugID);
  465.       doodlebugCount++;
  466.       doodlebugID++;
  467.     }
  468.   }
  469.   // Create 100 ants on the heap
  470.   int antCount = 0;
  471.   int antID = 100;
  472.   while (antCount < 100)
  473.   {
  474.     int randomX = rand() % 20;
  475.     int randomY = rand() % 20;
  476.     if (grid[randomX][randomY] == NULL)
  477.     {
  478.       grid[randomX][randomY] = new Ant(randomX, randomY, antID);
  479.       antCount++;
  480.       antID++;
  481.     }
  482.   }
  483.   std::cout << "Intial Grid" << std::endl;
  484.   render(grid);
  485.   bool flag = true;
  486.   int step = 0;
  487.   while (flag)
  488.   {
  489.     std::cout << "Press Enter to continue..." << std::endl;
  490.     std::cin.ignore();
  491.     ++step;
  492.     std::cout << "****** Time Step: " << step << " ******" << std::endl;
  493.     for (int i = 0; i < 20; i++)
  494.     {
  495.       for (int j = 0; j < 20; j++)
  496.       {
  497.         if (grid[i][j] != NULL)
  498.         {
  499.           if (grid[i][j]->getType() == 'X' && !grid[i][j]->getIfMoved())
  500.           {
  501.             grid[i][j]->move(grid);
  502.           }
  503.         }
  504.       }
  505.     }
  506.  
  507.     for (int i = 0; i < 20; i++)
  508.     {
  509.       for (int j = 0; j < 20; j++)
  510.       {
  511.         if (grid[i][j] != NULL)
  512.         {
  513.           if (grid[i][j]->getType() == 'o' && !grid[i][j]->getIfMoved())
  514.           {
  515.             grid[i][j]->move(grid);
  516.           }
  517.         }
  518.       }
  519.     }
  520.  
  521.     for (int i = 0; i < 20; i++)
  522.     {
  523.       for (int j = 0; j < 20; j++)
  524.       {
  525.         if (grid[i][j] != NULL)
  526.         {
  527.           if (grid[i][j]->getType() == 'X' || grid[i][j]->getType() == 'o')
  528.           {
  529.             grid[i][j]->setIfMoved(false);
  530.           }
  531.         }
  532.       }
  533.     }
  534.  
  535.     for (int i = 0; i < 20; i++)
  536.     {
  537.       for (int j = 0; j < 20; j++)
  538.       {
  539.         if (grid[i][j] != NULL)
  540.         {
  541.           if (grid[i][j]->getType() == 'X')
  542.           {
  543.             grid[i][j]->starve(grid);
  544.           }
  545.         }
  546.       }
  547.     }
  548.  
  549.     for (int i = 0; i < 20; i++)
  550.     {
  551.       for (int j = 0; j < 20; j++)
  552.       {
  553.         if (grid[i][j] != NULL)
  554.         {
  555.           if (grid[i][j]->getType() == 'X' && grid[i][j]->getRoundsSurvived() == 8)
  556.           {
  557.  
  558.             grid[i][j]->breed(grid, doodlebugID);
  559.           }
  560.         }
  561.       }
  562.     }
  563.  
  564.     for (int i = 0; i < 20; i++)
  565.     {
  566.       for (int j = 0; j < 20; j++)
  567.       {
  568.         if (grid[i][j] != NULL)
  569.         {
  570.           if (grid[i][j]->getType() == 'o' && grid[i][j]->getRoundsSurvived() == 3)
  571.           {
  572.             grid[i][j]->breed(grid, antID);
  573.           }
  574.         }
  575.       }
  576.     }
  577.     render(grid);
  578.     if (countTheAnts(grid) == 400 || countTheDoodles(grid) == 400)
  579.     {
  580.       flag = false;
  581.     }
  582.   }
  583.  
  584.   for (int i = 0; i < 20; i++)
  585.   {
  586.     for (int j = 0; j < 20; j++)
  587.     {
  588.       delete grid[i][j];
  589.       grid[i][j] = NULL;
  590.     }
  591.   }
  592.   return 0;
  593. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement