/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.app.heatbugs;
import sim.field.grid.*;
import sim.util.*;
import sim.engine.*;
public /*strictfp*/ class HeatBug implements Steppable //, sim.portrayal.inspector.Tabbable //// See "provideTabNames()" below
{
private static final long serialVersionUID = 1;
public double idealTemp;
public double getIdealTemperature() { return idealTemp; }
public void setIdealTemperature( double t ) { idealTemp = t; }
public double heatOutput;
public double getHeatOutput() { return heatOutput; }
public void setHeatOutput( double t ) { heatOutput = t; }
public double randomMovementProbability;
public double getRandomMovementProbability() { return randomMovementProbability; }
public void setRandomMovementProbability( double t ) { if (t >= 0 && t <= 1) randomMovementProbability = t; }
public Object domRandomMovementProbability() { return new Interval(0.0,1.0); }
public HeatBug( double idealTemp, double heatOutput, double randomMovementProbability)
{
this.heatOutput = heatOutput;
this.idealTemp = idealTemp;
this.randomMovementProbability = randomMovementProbability;
}
public void addHeat(final DoubleGrid2D grid, final int x, final int y, final double heat)
{
grid.field[x][y] += heat;
if (grid.field[x][y] > HeatBugs.MAX_HEAT) grid.field[x][y] = HeatBugs.MAX_HEAT;
}
public void step( final SimState state )
{
HeatBugs hb = (HeatBugs)state;
Int2D location = hb.buggrid.getObjectLocation(this);
int myx = location.x;
int myy = location.y;
final int START=-1;
int bestx = START;
int besty = 0;
if (state.random.nextBoolean(randomMovementProbability)) // go to random place
{
bestx = hb.buggrid.stx(state.random.nextInt(3) - 1 + myx); // toroidal
besty = hb.buggrid.sty(state.random.nextInt(3) - 1 + myy); // toroidal
}
else if( hb.valgrid.field[myx][myy] > idealTemp ) // go to coldest place
{
for(int x=-1;x<2;x++)
for (int y=-1;y<2;y++)
if (!(x==0 && y==0))
{
int xx = hb.buggrid.stx(x + myx); // toroidal
int yy = hb.buggrid.sty(y + myy); // toroidal
if (bestx==START ||
(hb.valgrid.field[xx][yy] < hb.valgrid.field[bestx][besty]) ||
(hb.valgrid.field[xx][yy] == hb.valgrid.field[bestx][besty] && state.random.nextBoolean())) // not uniform, but enough to break up the go-up-and-to-the-left syndrome
{ bestx = xx; besty = yy; }
}
}
else if ( hb.valgrid.field[myx][myy] < idealTemp ) // go to warmest place
{
for(int x=-1;x<2;x++)
for (int y=-1;y<2;y++)
if (!(x==0 && y==0))
{
int xx = hb.buggrid.stx(x + myx); // toroidal
int yy = hb.buggrid.sty(y + myy); // toroidal
if (bestx==START ||
(hb.valgrid.field[xx][yy] > hb.valgrid.field[bestx][besty]) ||
(hb.valgrid.field[xx][yy] == hb.valgrid.field[bestx][besty] && state.random.nextBoolean())) // not uniform, but enough to break up the go-up-and-to-the-left syndrome
{ bestx = xx; besty = yy; }
}
}
else // stay put
{
bestx = myx;
besty = myy;
}
hb.buggrid.setObjectLocation(this,bestx,besty);
addHeat(hb.valgrid,bestx,besty,heatOutput);
}
// Would you like your model inspector to be broken into tabs? Here's an example.
// To get this to work, uncomment the "implements sim.portrayal.inspector.Tabbable" at the top of this class
public String[] provideTabNames()
{ return new String[] {"Heat", "Probability"}; }
public String[][] provideTabProperties()
{ return new String[][] {{"IdealTemperature", "HeatOutput"},
{"RandomMovementProbability", "Me"}}; }
public String provideExtraTab()
{ return null; }
}