import java.util.*;
import java.awt.*;
/**
The Environment class is used to represent the environment for the
simulation. It provides the core of the simulation, which cycles
through all of the Things in the simulation, asking each Thing to
act out its life cycle. In more detail, a simulation cycle consists of
the following phases.
- Checking for interactions: every thing that is situated in the
same cell is asked to possibly consume its neighbors.
- Spawning: every thing is asked to spawn children, if it wishes.
- Movement: every thing is asked to move, if it wishes to.
- Screen update: every thing is asked to display itself onto a
graphics window.
-
@author Ben Dugan, Hal Perkins
CSE 142 Summer 2001, Homework 6
*/
public class Environment {
// constant
private static int CELL_SIZE = 10; // the environment is subdivided into
// cells of this size for bookkeeping
// instance variables
private GWindow theWindow = new GWindow(); // drawing window
private WorldMap things = new WorldMap(CELL_SIZE); // collection of things
// in this simulation
// Internal interface used to implement operations like spawn and consumes.
// Not used directly by Thing code - used by class Environment to process
// each Thing every time the clock ticks.
private interface CallBack {
public void action(Thing t, ArrayList neighbors);
}
/** A WorldMap is a relatively efficient representation of the world.
The world is chopped up into a number of cells so that interactions
can be efficiently computed. */
private class WorldMap {
private HashMap cells = new HashMap();
int cellSize = CELL_SIZE;
/** Make a new worldmap with the given cellsize. */
WorldMap(int cellSize) {
this.cellSize = cellSize;
}
/** Answer the key (cell) for this thing. */
String getKey(Thing t) {
String pos = (t.getX() / cellSize) + ":" + (t.getY() / cellSize);
return pos;
}
/** Answer the key (cell) for this location. */
String getKey(int x, int y) {
String pos = (x / cellSize) + ":" + (y / cellSize);
return pos;
}
/** Answer the cell at this location. */
public ArrayList getCell(int x, int y) {
String key = getKey(x, y);
return (ArrayList)cells.get(key);
}
/** Add a thing to the world map. */
public void add(Thing t) {
String pos = getKey(t);
ArrayList cell = (ArrayList)cells.get(pos);
if (cell == null) {
ArrayList newCell = new ArrayList();
newCell.add(t);
cells.put(pos, newCell);
}
else {
cell.add(t);
}
}
/** Remove a thing from the world map. */
public void remove(Thing t) {
String pos = getKey(t);
ArrayList cell = (ArrayList)cells.get(pos);
if (cell != null) {
cell.remove(t);
}
}
/** Map this call back over the world. */
public void map(CallBack cb) {
Iterator cellIter = cells.values().iterator();
while (cellIter.hasNext()) {
ArrayList cell = (ArrayList)cellIter.next();
for (int i=0; i