GOAL: Create a simple 2D simulation of ants crawling around. The ants live in a
ID: 638530 • Letter: G
Question
GOAL: Create a simple 2D simulation of ants crawling around.
The ants live in a world composed of a 20 x 20 grid of cells. Only one ant may occupy a cell at a time. The grid is enclosed, so an ant is not allowed to move off the edges of the grid. Time is simulated in time steps. Each ant performs some action every time step.
The ants behave according to the following rules:
Move. Every time step, randomly try to move up, down, left, or right. If the 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 (which all our ants will do in this first assignment since there are no doodlebugs to eat them), then at the end of the third 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. If there is no empty cell available, no breeding occurs. Once an offspring is produced, the ant cannot produce another offspring until three more time steps have elapsed.
Write a program to implement this simulation and draw the world using ASCII characters (say "A" for an ant and "." for an empty cell). So, it might look something like this (I've only drawn 12 rows instead of 20 here):
Initialize the world with 20 ants in random starting positions. After each time step, draw the world and prompt the user to press Enter to move to the next time step.
This is an outline we have to go by/advised:
class World
- World()
- static const LENGTH
- static const WIDTH
- static const DOODLEBUGS //number to place in world
- static const ANTS
- int doodlebugs //number currently in world
- int ants
- Organism *grid[LENGTH][WIDTH]
- print() //cycles through grid and calls organism.print()
class Organism
- test_spaces() //find allowable spaces to move into
- choose_move() //randomly pick one of the allowable spaces to move to
- move_or_breed() //uses 'delete' and 'new' to manipulate grid
- print() //prints letter
- char letter
Explanation / Answer
File: Ant
public class Ant extends Organism
{
private int row;
private int col;
private int stepsSurvived;
/**
* Constructors call the super constructors (i.e. the constructor from the Organism class)
* and initialize the stepsSurvived variable to zero
*/
public Ant()
{
super();
stepsSurvived = 0;
}
public Ant(World grid, int r, int c)
{
super(grid, r, c);
stepsSurvived = 0;
}
/**
* Spawns another Ant in an adjacent location if the stepsSurvived
* is three and if the new placed location is null.
* Then the stepsSurvived counter is reset to 0.
*/
public void breed()
{
if(stepsSurvived == 3)
{
if((col > 0) && (world.getOrgAt(row, col-1) == null))
{
Ant a = new Ant(world, row, col-1);
stepsSurvived = 0;
}
else if ((col < world.SIZE-1) && (world.getOrgAt(row, col+1) == null))
{
Ant a = new Ant(world, row, col+1);
stepsSurvived = 0;
}
else if((row > 0) && (world.getOrgAt(row-1, col) == null))
{
Ant a = new Ant(world, row - 1, col);
stepsSurvived = 0;
}
else if((row < world.SIZE-1) && world.getOrgAt(row+1, col) == null)
{
Ant a = new Ant(world, row + 1, col);
stepsSurvived = 0;
}
}
stepsSurvived = 0;
}
/**
* returns a printable symbol to represent an Ant
*/
public String toString()
{
return "A";
}
/**
* Uses Math.random to randomly decide which direction an Ant will move.
* If the cell in the selected direction is occupied or would move the ant off the grid, then the ant stays in the current cell.
*/
public void move()
{
if(row < world.SIZE)
{
if(col < world.SIZE)
{
//generates a random double number to decide which direction to move
double x = Math.random();
//move up
if(x < 0.25)
{
if((row > 0) && (world.getOrgAt(row -1, col)== null))
{
world.setOrgAt(row-1, col, world.getOrgAt(row, col));
world.setOrgAt(row, col, null);
row--;
}
}
//move right
else if(x < 0.5)
{
if ((col < world.SIZE -1) && (world.getOrgAt(row, col + 1) == null))
{
world.setOrgAt(row, col + 1, world.getOrgAt(row, col));
world.setOrgAt(row, col, null);
col++;
}
}
//move down
else if ((x < 0.75) && (row < world.SIZE -1)&& (world.getOrgAt(row + 1, col)== null) )
{
world.setOrgAt(row+1, col, world.getOrgAt(row, col));
world.setOrgAt(row, col, null);
row++;
}
//move left
else
{
if((col > 0)&& (row < world.SIZE - 1) && (world.getOrgAt(row, col -1) == null))
{
world.setOrgAt(row, col-1, world.getOrgAt(row, col));
world.setOrgAt(row, col, null);
col--;
}
}
}
stepsSurvived++;
}
}
}
File: World
import java.util.Scanner;
import java.util.Random;
public class World
{
/**
* creates a grid and sets all of the spaces to null.
*/
protected final static int SIZE = 20;
protected static Organism [][] land = new Organism[SIZE][SIZE];
public World()
{
for (int r = 0; r < land.length; r++)
{
for(int c = 0; c < land[r].length; c++)
{
land[r][c] = null;
}
}
}
/**
* returns the Organism in the sent (parameter) location.
* Returns null if the location is empty.
*/
public Organism getOrgAt(int r, int c)
{
if((r >= 0) && (r < World.SIZE) && (c >= 0) && (c < World.SIZE))
{
if(land[r][c] == null)
{
return null;
}
else
{
return land[r][c];
}
}
return null;
}
/**
* places the the organism in the given location
*/
public void setOrgAt(int r, int c, Organism organism)
{
if((r >= 0) && (r < World.SIZE) && (c >= 0) && (c < World.SIZE))
{
land[r][c] = organism;
}
}
/**
* Uses a for loop to display the grid. If there is nothing in the location a . is shown,
* otherwise the correct toString() method is called.
*/
public void display()
{
System.out.println(" ");
for (int r = 0; r < land.length; r++)
{
for(int c = 0; c < land[r].length; c++)
{
if(land[r][c] == null)
{
System.out.print(".");
}
else
{
System.out.print(land[r][c].toString());
}
}
System.out.println("");
}
}
/**
* runs through one step simulation by checking to move the ants and breed them
*/
public void moveOneStep()
{
for (int r = 0; r < land.length; r++)
{
for(int c = 0; c < land[r].length; c++)
{
if(land[r][c] != null)
{
land[r][c].setHasMoved(false);
}
}
}
//check for ants and make them move if the boolean variable is false
for(int r = 0; r < land.length; r++)
{
for(int c = 0; c < land[r].length; c++)
{
if((land[r][c] != null) && (land[r][c].getHasMoved() == false))
{
land[r][c].move();
land[r][c].setHasMoved(true);
}
}
}
//check the breed method, and breed after the ants have moved.
for(int r =0; r < land.length; r++)
{
for(int c = 0; c < land[r].length; c++)
{
if((land[r][c] != null) && (land[r][c].getHasMoved() == true))
{
land[r][c].breed();
}
}
}
}
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
//creates a new World and Random object
World grid = new World();
Random random = new Random();
System.out.println("Ant Simulation. Press Enter to simulate one time step. ");
grid.display();
/**
* Uses a for loop to initialize all ants and place them in the grid and in the Ant array
*/
int tempRow;
int tempCol;
Ant[] ants = new Ant[20];
for(int numAntsAdded = 0; numAntsAdded <= 19; numAntsAdded++)
{
tempRow = random.nextInt(20);
tempCol = random.nextInt(20);
if(land[tempRow][tempCol] == null)
{
ants[numAntsAdded] = new Ant(grid, tempRow, tempCol);
}
else
{
//does not add an Ant or increment the counter if the location is already filled
numAntsAdded--;
}
}
/**
* Run through a couple simulations
*/
String temp = keyboard.nextLine();
grid.display();
temp = keyboard.nextLine();
grid.moveOneStep();
grid.display();
temp = keyboard.nextLine();
grid.moveOneStep();
grid.display();
temp = keyboard.nextLine();
grid.moveOneStep();
grid.display();
temp = keyboard.nextLine();
grid.moveOneStep();
grid.display();
temp = keyboard.nextLine();
grid.moveOneStep();
grid.display();
temp = keyboard.nextLine();
grid.moveOneStep();
grid.display();
}
}
File: Organism
public abstract class Organism
{
private int row;
private int col;
protected int stepsSurvived;
protected boolean hasMoved;
protected World world;
/**
* Organsim constructors initialize the variables.
* The second constructor
* accepts a World object, a row, and a column for varaibles.
*/
public Organism()
{
hasMoved = false;
stepsSurvived = 0;
row = 0;
col = 0;
}
public Organism(World world, int row, int col)
{
this.world = world;
hasMoved = false;
stepsSurvived = 0;
this.row = row;
this.col = col;
world.setOrgAt(row, col, this);
}
/**
* accessor and mutator methods get and set the value of the hasMoved variable
*/
public boolean getHasMoved()
{
return hasMoved;
}
public void setHasMoved(boolean hasMoved)
{
this.hasMoved = hasMoved;
}
/**
* returns a printable symbol to represent an Organism
*/
public String toString()
{
return "O";
}
/**
* abstract methods to be overrided in extended classes
*/
public abstract void move();
public abstract void breed();
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.