package sim.app.geo.haiti;
import sim.engine.SimState;
import sim.engine.Steppable;
import sim.field.grid.IntGrid2D;
import sim.field.grid.ObjectGrid2D;
import sim.field.grid.SparseGrid2D;
import sim.util.Bag;
/**
* Used to propagate information about food availability
* <p/>
*/
public class RumorMill implements Steppable
{
private static final long serialVersionUID = 1L;
int gridWidth;
int gridHeight;
int rumorDist = 1;
int neighborhoodType = 1; // 0 = von Neumann, 1 = Moore
IntGrid2D assembleInfo(SparseGrid2D population)
{
IntGrid2D info = new IntGrid2D(gridWidth, gridHeight);
// assemble info for each tile
for (int i = 0; i < gridWidth; i++)
{
for (int j = 0; j < gridHeight; j++)
{
int tileinfo = 0;
// comprehensive info for this tile
// check with all agents
Bag agents = population.getObjectsAtLocation(i, j);
if (agents != null)
{
for (Object o : agents)
{
Agent a = (Agent) o;
tileinfo = (a.centerInfo | tileinfo);
}
}
info.set(i, j, tileinfo);
}
}
return info;
}
IntGrid2D assembleInfoFromNeighbors(IntGrid2D info, ObjectGrid2D locations)
{
IntGrid2D infoFromNeighbors = new IntGrid2D(gridWidth, gridHeight);
for (int i = 0; i < gridWidth; i++)
{
for (int j = 0; j < gridHeight; j++)
{
// comprehensive info for this tile
int tileinfo = 0;
Bag neighbors = new Bag();
if (neighborhoodType == 0)
{
locations.getNeighborsHamiltonianDistance(i, j, rumorDist, false, neighbors, null, null);
} else if (neighborhoodType == 1)
{
locations.getNeighborsMaxDistance(i, j, rumorDist, false, neighbors, null, null);
}
for (Object o : neighbors)
{
Location l = (Location) o;
if (l.x == i && l.y == j)
{
continue; // don't exchange info with self
}
// get the information from the neighbor tile
int infoNeighboringTile = info.get(l.x, l.y);
tileinfo = (tileinfo | infoNeighboringTile);
}
infoFromNeighbors.set(i, j, tileinfo);
}
}
return infoFromNeighbors;
}
IntGrid2D distributeInfo(SparseGrid2D population, IntGrid2D oldInfo,
IntGrid2D neighborInfo)
{
// assemble info for each tile
for (int i = 0; i < gridWidth; i++)
{
for (int j = 0; j < gridHeight; j++)
{
// comprehensive info for this tile
int neighborInfoTile = neighborInfo.get(i, j);
neighborInfoTile = (neighborInfoTile | oldInfo.get(i, j));
Bag agents = population.getObjectsAtLocation(i, j);
if (agents != null)
{
for (Object o : agents)
{
((Agent) o).centerInfo = neighborInfoTile;
}
}
}
}
return neighborInfo;
}
@Override
public void step(SimState state)
{
SparseGrid2D population = ((HaitiFood) state).population;
System.out.println("RUMOR: " + state.schedule.getSteps());
// TODO: want a Moore vs von Neumann neighborhood? change it in these functions!
System.out.println("assemble info...");
IntGrid2D info = assembleInfo(population);
System.out.println("info assembled");
System.out.println("consult neighbors...");
IntGrid2D infoFromNeighbors = assembleInfoFromNeighbors(info, ((HaitiFood) state).locations);
System.out.println("neighbors consulted");
System.out.println("redistribute info...");
distributeInfo(population, info, infoFromNeighbors);
System.out.println("info redistributed");
}
}