you will use cellular automata to create a 2D predator–prey simulation in your program. The
preys are ants and the predators are doodlebugs. These critters live in a 20 * 20 grid of cells.
Only one critter may occupy a cell at a time. The grid is enclosed and no critter may move off
the grid. Time is simulated in steps. Each critter performs some action every time step. The ants
behave according to the following model: Move: For every time step, the ants randomly try to
move up, down, left, or right. If the neighboring cell in the selected direction is occupied or
would move the ant off the grid, then the ant stays in the current cell. Breed: If an ant survives
for three time steps (not been eaten by doodlebugs), at the end of the time step (i.e., after
moving) the ant will breed. This is simulated by creating a new ant in an adjacent (up, down, left,
or right) cell that is empty randomly. If there is no empty cell available, no breeding occurs.
Once an offspring is produced, an ant cannot produce an offspring again until it has survived
three more time steps.
The doodlebugs behave according to the following model:
Move: For every time step, the doodlebug will firstly try to move to an adjacent cell containing
an ant and eat the ant (you can decide if there are several ants in the adjacent cells, how the
doodlebug will choose to move). If there are no ants in adjacent cells, the doodlebug moves
according to the same rules as the ant. Note that a doodlebug cannot eat other doodlebugs.
Breed: If a doodlebug survives for eight time steps, at the end of the time step, it will spawn off a
new doodlebug in the same manner as the ant.
Starve: If a doodlebug has not eaten an ant within three time steps, at the end of the third time
step it will starve and die. The doodlebug should then be removed from the grid of cells.
Initialize the world with 5 doodlebugs and 100 ants. You will randomly place them. You should
see a cyclical pattern between the population of predators and prey, although random
perturbations may lead to the elimination of one or both species. You will prompt the user to
enter the number of time steps to run.
Create a class named Critter that contains data and functions common to ants and doodlebugs.
This class should have a virtual function named move that is defined in the derived classes of
Ant and Doodlebug. Each class will be in its own source file.
For each time step, do the following in your program: after moves, when breeding, eating, and
starving are resolved, display the resulting grid. Draw the world using ASCII characters of “O”
for an ant, “X” for a doodlebug and “E” for an empty space (the characters should be arranged to
look like a grid). The doodlebugs will move before the ants in each time step. When you reach
the time steps entered by the user, ask them to enter another number and start to run the
simulation again or to exit the program. You must maintain the state of the current grid while
creating the next displa.
Basic Civil Engineering notes on Transportation Engineering & Modes of Transport
you will use cellular automata to create a 2D predator–prey simulati.pdf
1. you will use cellular automata to create a 2D predator–prey simulation in your program. The
preys are ants and the predators are doodlebugs. These critters live in a 20 * 20 grid of cells.
Only one critter may occupy a cell at a time. The grid is enclosed and no critter may move off
the grid. Time is simulated in steps. Each critter performs some action every time step. The ants
behave according to the following model: Move: For every time step, the ants randomly try to
move up, down, left, or right. If the neighboring cell in the selected direction is occupied or
would move the ant off the grid, then the ant stays in the current cell. Breed: If an ant survives
for three time steps (not been eaten by doodlebugs), at the end of the time step (i.e., after
moving) the ant will breed. This is simulated by creating a new ant in an adjacent (up, down, left,
or right) cell that is empty randomly. If there is no empty cell available, no breeding occurs.
Once an offspring is produced, an ant cannot produce an offspring again until it has survived
three more time steps.
The doodlebugs behave according to the following model:
Move: For every time step, the doodlebug will firstly try to move to an adjacent cell containing
an ant and eat the ant (you can decide if there are several ants in the adjacent cells, how the
doodlebug will choose to move). If there are no ants in adjacent cells, the doodlebug moves
according to the same rules as the ant. Note that a doodlebug cannot eat other doodlebugs.
Breed: If a doodlebug survives for eight time steps, at the end of the time step, it will spawn off a
new doodlebug in the same manner as the ant.
Starve: If a doodlebug has not eaten an ant within three time steps, at the end of the third time
step it will starve and die. The doodlebug should then be removed from the grid of cells.
Initialize the world with 5 doodlebugs and 100 ants. You will randomly place them. You should
see a cyclical pattern between the population of predators and prey, although random
perturbations may lead to the elimination of one or both species. You will prompt the user to
enter the number of time steps to run.
Create a class named Critter that contains data and functions common to ants and doodlebugs.
This class should have a virtual function named move that is defined in the derived classes of
Ant and Doodlebug. Each class will be in its own source file.
For each time step, do the following in your program: after moves, when breeding, eating, and
starving are resolved, display the resulting grid. Draw the world using ASCII characters of “O”
for an ant, “X” for a doodlebug and “E” for an empty space (the characters should be arranged to
look like a grid). The doodlebugs will move before the ants in each time step. When you reach
the time steps entered by the user, ask them to enter another number and start to run the
simulation again or to exit the program. You must maintain the state of the current grid while
creating the next display. You will use a dynamic array to represent the grid. Each array element
2. will be a pointer to a Critter. Get your program running and tested. For debugging your program,
you should save the random placement until you have everything else working properly. In
general, “random” is bad for testing and debugging.
Solution
World.java
import java.util.*;
import java.awt.*;
public class World{ private static Random r= new Random(); private int doodlebugs; private int
ants; private static final int SIZE = 20; private Critter[][] oGrid; World(int d,int a){ oGrid = new
Critter[SIZE][SIZE]; doodlebugs = d; ants = a; for(int i = 0; i < d; i++){ boolean isOccupied =
true; while(isOccupied){ int potX = r.nextInt(SIZE); int potY = r.nextInt(SIZE);
if(oGrid[potX][potY] == null) { isOccupied = false; oGrid[potX][potY] = new
Doodlebug(this,potX,potY); } } } for(int i = 0; i < a; i++){ boolean isOccupied = true;
while(isOccupied){ int potX = r.nextInt(SIZE); int potY = r.nextInt(SIZE); if(oGrid[potX][potY]
== null) { isOccupied = false; oGrid[potX][potY] = new Ant(this,potX,potY); } } } } public int
getdoodlebugs(){ return doodlebugs; } public int getants(){ return ants; } public char[][]
getCGrid(){ char[][] grid = new char[SIZE][SIZE]; for(int i = 0; i < SIZE; i++){ for(int j = 0;j <
SIZE; j++){ if(oGrid[j][i]!=null) if(oGrid[j][i].getClass().getName().equals("Ant")) Grid[j][i] =
'o'; else if(oGrid[j][i].getClass().getName().equals("Doodlebug")) grid[j][i] = 'x'; else
if(oGrid[j][i].getClass().getName().equals("Empty"))
grid[j][i] = 'e';
else
grid[j][i] = ' ';
}
}
return grid;
}
public void increasedoodlebugs(){
doodlebugs++;
}
public void decreasedoodlebugs(){
doodlebugs--;
}
public void increaseants(){
3. ants++;
}
public void decreaseants(){
ants--;
}
public void moveAll(){
for(int i = 0; i < SIZE; i++){
for(int j = 0;j < SIZE; j++){
if(oGrid[j][i] !=null)
oGrid[j][i].move();
}
}
for(int i = 0; i < SIZE; i++){
for(int j = 0;j < SIZE; j++){
if(oGrid[j][i] !=null)
oGrid[j][i].moved=false;
}
}
}
public void breedAll(){
for(int i = 0; i < SIZE; i++){
for(int j = 0;j < SIZE; j++){
if(oGrid[j][i]!=null)
oGrid[j][i].breed();
}
}
}
public void starveAll(){
for(int i = 0; i < SIZE; i++){
for(int j = 0;j < SIZE; j++){
if(oGrid[j][i]!=null)
oGrid[j][i].starve();
}
}
}
public boolean isEmpty(int x,int y){
4. boolean tbr = false;
if(oGrid[x][y]==null)
tbr = true;
return tbr;
}
public boolean isAnt(int x,int y){
boolean tbr = false;
if(oGrid[x][y] instanceof Ant)
tbr = true;
return tbr;
}
public void setCell(int x, int y, Critter O){
oGrid[x][y] = O;
}
}
Ant.java
import java.awt.*;
import java.io.*;
import java.util.*;
public class Ant extends Critter{
private static Random r = new Random();
private int untilBreed;
public Ant(World world,int _x, int _y){
super(world,_x, _y );
untilBreed = 3;
moved = false;//defaults to TRUE so that 'child' ants dont move
}
public void move(){
if(!moved){
int[] potMoves = new int[4];
int i = 1;
potMoves[0] = r.nextInt(4);
do{
do{
potMoves[i] = r.nextInt(4);
}
5. while(potMoves[i]!=potMoves[i-1]);
i++;
}
while(i<4);
i = 0;
boolean empty = false;
int oldx = x;
int oldy = y;
while(i<4 && !empty){
switch(potMoves[i]){
case 0:
if(x!=0){
if(world.isEmpty(x-1,y)){
empty = true;
world.setCell(x-1,y,this);
world.setCell(oldx,y,null);
moved = true;
untilBreed--;
x=x-1;
}
}
else if(world.isEmpty(19,y)){
empty = true; untilBreed--; world.setCell(19,y,this); world.setCell(oldx,y,null); moved = =19;
}
break;
case 1:
if(x!=19){
if(world.isEmpty(x+1,y)){
untilBreed--;
world.setCell(x+1,y,this);
world.setCell(oldx,y,null);
moved = true;
empty = true;
x=x+1;
}
}
6. else if(world.isEmpty(0,y)){
world.setCell(0,y,this);
world.setCell(oldx,y,null);
moved = true;
empty = true;
x=0;
untilBreed--;
}
break;
case 2:
if(y!=0){
if(world.isEmpty(x,y-1)){
world.setCell(x,y-1,this);
world.setCell(x,oldy,null);
moved = true;
empty = true;
y=y-1;
untilBreed--;
}
}
else if(world.isEmpty(x,19)){
world.setCell(x,19,this);
world.setCell(x,oldy,null);
moved = true;
empty = true;
y=19;
untilBreed--;
}
break;
case 3:
if(y!=19){
if(world.isEmpty(x,y+1)){
world.setCell(x,y+1,this);
world.setCell(x,oldy,null);
moved = true;
empty = true;