The Predator‐Prey game is a simple board game where bugs (predators) and ants (preys) move freely across the board.
The following is a description of the game rules:
-Predators and preys move on a 2‐dimensional closed grid
-Predators and preys are not allowed to move outside the grid
-The game consists of successive turns. During one turn, each of the creatures moves one step into one of the adjacent cells randomly (up, down, left, or right). If there is no empty adjacent cell, the creature stays in its place during this turn.
-Ants breed if it survives for three time steps then it will breed into an adjacent cell. If there are no available cells then the ant cannot produce an offspring until three more time steps have elapsed.
-Bugs eat an ant if there is one in an adjacent spot. Otherwise it moves randomly. It will breed if it survives for eight time steps, then spawn in in adjacent spot(same rule as ants except for timeframe)
-Bugs starve if it has not eaten an ant within the last three time steps. If it starves then the space is empty.
I have everything figured out except my program is not breeding the ants correctly. On the first turn they are spawning when it shouldn't happen till the third turn. And I have no clue where I went wrong. PLEASE HELP!!
//Driver Program
#include <iostream>
#include <ctime>
#include <string>
#include "world.h"
using namespace std;
void wait (int seconds);
int main()
{
string s;
srand(time(NULL));
World w;
World *wPtr;
wPtr = &w;
int antcount = 0;
while (antcount < ANTS)
{
int x = rand() % SIZE;
int y = rand() % SIZE;
if (w.getAt(x,y)==NULL)
{
antcount++;
Ant *a1 = new Ant(&w,x,y);
}
}
int doodlecount = 0;
while (doodlecount < BUGS)
{
int x = rand() % SIZE;
int y = rand() % SIZE;
if (w.getAt(x,y)==NULL)
{
doodlecount++;
Doodlebug *d1 = new Doodlebug(&w,x,y);
}
}
while (s.length() == 0)
{
w.Display();
w.MoveStep();
//wait(1);
cout << endl;
cout << "Press enter for next step, any other key "
<< "(followed by enter) to end" << endl;
getline(cin,s);
system("cls");
}
w.Display();
cout << "\nHit any key to exit...";
getline(cin,s);
return 0;
}
void wait ( int seconds )
{
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait) {}
}
//implementation file
#include "world.h"
#include <iostream>
using namespace std;
World::World()
{
int i,j;
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
grid[i][j]=NULL;
}
}
}
World::~World()
{
int i,j;
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
if (grid[i][j]!=NULL) delete (grid[i][j]);
}
}
}
Organism* World::getAt(int x, int y)
{
if ((x>=0) && (x<SIZE) && (y>=0) && (y<SIZE))
return grid[x][y];
return NULL;
}
void World::setAt(int x, int y, Organism *org)
{
if ((x>=0) && (x<SIZE) && (y>=0) && (y<SIZE))
{
grid[x][y] = org;
}
}
void World::Display()
{
int i,j;
int countA=0, countB=0;
cout << endl << endl;
for (j=0; j<SIZE; j++)
{
for (i=0; i<SIZE; i++)
{
if (grid[i][j]==NULL)
cout << SPACE_CH;
else if (grid[i][j]->getType() == ANT)
{
countA++;
cout << ANT_CH;
}
else
{
countB++;
cout << BUG_CH;
}
}
cout << endl;
}
cout << endl << ANT_CH << " = " << countA << "\t " << BUG_CH << " = " << countB;
}
void World::MoveStep()
{
int i,j;
//reset organisms to not moved
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
if (grid[i][j]!=NULL)
{
grid[i][j]->moved = false;
}
}
}
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
if ((grid[i][j]!=NULL) && (grid[i][j]->getType()==BUG))
{
if (grid[i][j]->moved == false)
{
grid[i][j]->moved = true;
grid[i][j]->move();
}
}
}
}
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
if ((grid[i][j]!=NULL) && (grid[i][j]->getType()==ANT))
{
if (grid[i][j]->moved == false)
{
grid[i][j]->moved = true;
grid[i][j]->move();
}
}
}
}
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
if ((grid[i][j]!=NULL) &&
(grid[i][j]->getType()==BUG))
{
if (grid[i][j]->starve())
{
delete (grid[i][j]);
grid[i][j] = NULL;
}
}
}
}
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
if ((grid[i][j]!=NULL) && (grid[i][j]->moved==true))
{
grid[i][j]->breed();
}
}
}
}
Organism::Organism()
{
world = NULL;
moved = false;
breedTicks = 0;
x=0;
y=0;
}
Organism::Organism(World *wrld, int x, int y)
{
this->world = wrld;
moved = false;
breedTicks = 0;
this->x=x;
this->y=y;
wrld->setAt(x,y,this);
}
Organism::~Organism()
{
}
void Organism::move()
{
// randomize ant movement
// 0 = up
// 1 = down
// 2 = left
// 3 = right
int direction = rand() % 4;
switch(direction)
{
case 0:
{
if (validMove(this->x, (this->y)-1))
{
world->setAt(x, y, NULL);
world->setAt(x, y-1, this);
this->y -= 1;
}
break;
}
case 1:
{
if (validMove(this->x, (this->y)+1))
{
world->setAt(x, y, NULL);
world->setAt(x, y+1, this);
this->y += 1;
}
break;
}
case 2:
{
if (validMove((this->x)-1, this->y))
{
world->setAt(x, y, NULL);
world->setAt(x-1, y, this);
this->x -= 1;
}
break;
}
case 3:
{
if (validMove((this->x)+1, this->y))
{
world->setAt(x, y, NULL);
world->setAt(x+1, y, this);
this->x += 1;
}
break;
}
default:
break;
}
}
bool Organism::validMove(int xPos, int yPos)
{
if((xPos>=0 && xPos<SIZE && yPos>=0 && yPos<SIZE)&& (world->grid[xPos][yPos] == NULL))
{
return true;
}
else
{
return false;
}
}
Ant::Ant() : Organism()
{
}
Ant::Ant(World *world, int x, int y) : Organism(world, x, y)
{
}
int Ant::getType()
{
return ANT;
}
bool Ant::starve()
{
return false;
}
void Ant::breed()
{
if(((this->breedTicks) % ANTBREED == 0 ) &&
(validMove(x-1,y) || validMove(x+1,y) ||
validMove(x,y-1) || validMove(x,y+1)))
{
bool successful = false;
while (!successful)
{
int spot = rand() % 4;
switch(spot)
{
case 0:
{
if(validMove(x-1,y))
{
Ant *a1 = new Ant(world,x-1,y);
}
successful = true;
break;
}
case 1:
{
if(validMove(x+1,y))
{
Ant *a1 = new Ant(world,x+1,y);
}
successful = true;
break;
}
case 2:
{
if(validMove(x,y+1))
{
Ant *a1 = new Ant(world,x,y+1);
}
successful = true;
break;
}
case 3:
{
if(validMove(x,y-1))
{
Ant *a1 = new Ant(world,x,y-1);
}
successful = true;
break;
}
}
}
}
(this->breedTicks)++;
}
Doodlebug::Doodlebug() : Organism()
{
starvation = 0;
}
Doodlebug::Doodlebug(World *world, int x, int y) : Organism(world, x, y)
{
starvation = 0;
}
int Doodlebug::getType()
{
return BUG;
}
void Doodlebug::breed()
{
if(((this->breedTicks) % BUGBREED == 0 ) &&
(validMove(x-1,y) || validMove(x+1,y) ||
validMove(x,y-1) || validMove(x,y+1)))
{
bool successful = false;
while (!successful)
{
int spot = rand() % 4;
switch(spot)
{
case 0:
{
if(validMove(x-1,y))
{
Doodlebug *d1 = new Doodlebug(world,x-1,y);
}
successful = true;
break;
}
case 1:
{
if(validMove(x+1,y))
{
Doodlebug *d1 = new Doodlebug(world,x+1,y);
}
successful = true;
break;
}
case 2:
{
if(validMove(x,y+1))
{
Doodlebug *d1 = new Doodlebug(world,x,y+1);
}
successful = true;
break;
}
case 3:
{
if(validMove(x,y-1))
{
Doodlebug *d1 = new Doodlebug(world,x,y-1);
}
successful = true;
break;
}
}
}
}
}
bool Doodlebug::starve()
{
if(this->starvation == BUGSTARVE)
return true;
else
return false;
}
void Doodlebug::move()
{
if(world->getAt(x-1, y) != NULL && (world->getAt(x-1,y))->getType() == ANT)
{
world->setAt(x, y, NULL);
world->setAt(x-1, y, this);
this->x -= 1;
this->starvation = 0;
(this->breedTicks)++;
}
else if(world->getAt(x+1, y) != NULL && (world->getAt(x+1,y))->getType() == ANT)
{
world->setAt(x, y, NULL);
world->setAt(x+1, y, this);
this->x += 1;
this->starvation = 0;
(this->breedTicks)++;
}
else if(world->getAt(x, y-1) != NULL && (world->getAt(x,y-1))->getType() == ANT)
{
world->setAt(x, y, NULL);
world->setAt(x, y-1, this);
this->y -= 1;
this->starvation = 0;
(this->breedTicks)++;
}
else if(world->getAt(x, y+1) != NULL && (world->getAt(x,y+1))->getType() == ANT)
{
world->setAt(x, y, NULL);
world->setAt(x, y+1, this);
this->y += 1;
this->starvation = 0;
(this->breedTicks)++;
}
else
{
Organism::move();
this->starvation++;
(this->breedTicks)++;
}
}
//header file
#ifndef WORLD_KAS_H
#define WORLD_KAS_H
#include <iostream>
using namespace std;
const int SIZE = 20; // size of the square grid
const int ANTS = 100; // # of ants, initially
const int BUGS = 5; // # of ants, initially
const int ANT = 1; // value of the status flag for an ant
const int BUG = 2; // value of the status flag for a bug
const int ANTBREED = 3; // steps until an ant breeds
const int BUGBREED = 8; // steps until an bug breeds
const int BUGSTARVE = 3; // steps until an bug dies unless it ate const char BUG_CH = 178; // char to display for a bug
const char ANT_CH = 248; // char to display for an ant
const char SPACE_CH = 32; // char to display for a space
const char BUG_CH = 219; // char to display for a bug
class Organism;
class Doodlebug;
class Ant;
class World
{
friend class Organism;
friend class Doodlebug;
friend class Ant;
public:
World();
~World();
Organism* getAt(int x, int y);
void setAt(int x, int y, Organism *org);
void Display();
void MoveStep();
private:
Organism* grid[SIZE][SIZE];
};
class Organism
{
friend class World;
public:
Organism();
Organism(World *world, int x, int y);
~Organism();
virtual void breed() = 0;
virtual void move();
virtual bool validMove(int xPos, int yPos);
virtual int getType() = 0; // Return 1 if ant or 0 for doodlebug
virtual bool starve() = 0;
protected:
int x,y;
bool moved;
int breedTicks;
World *world;
};
class Ant : public Organism
{
public:
Ant();
Ant(World *world, int x, int y);
virtual void breed();
virtual int getType();
virtual bool starve();
};
class Doodlebug : public Organism
{
public:
Doodlebug();
Doodlebug(World *world, int x, int y);
virtual void breed();
virtual void move();
virtual int getType();
virtual bool starve();
private:
int starvation;
};
#endif