sim.app.antsforage.Ant Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.
The newest version!
/*
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.antsforage;
import sim.field.grid.*;
import sim.portrayal.*;
import sim.portrayal.simple.*;
import sim.util.*;
import sim.engine.*;
import java.awt.*;
public class Ant extends OvalPortrayal2D implements Steppable
{
private static final long serialVersionUID = 1;
public boolean getHasFoodItem() { return hasFoodItem; }
public void setHasFoodItem(boolean val) { hasFoodItem = val; }
public boolean hasFoodItem = false;
double reward = 0;
int x;
int y;
Int2D last;
public Ant(double initialReward) { reward = initialReward; }
// at present we have only one algorithm: value iteration. I might
// revise this and add our alternate (TD) algorithm. See the papers.
public void depositPheromone( final SimState state)
{
final AntsForage af = (AntsForage)state;
Int2D location = af.buggrid.getObjectLocation(this);
int x = location.x;
int y = location.y;
if (AntsForage.ALGORITHM == AntsForage.ALGORITHM_VALUE_ITERATION)
{
// test all around
if (hasFoodItem) // deposit food pheromone
{
double max = af.toFoodGrid.field[x][y];
for(int dx = -1; dx < 2; dx++)
for(int dy = -1; dy < 2; dy++)
{
int _x = dx+x;
int _y = dy+y;
if (_x < 0 || _y < 0 || _x >= AntsForage.GRID_WIDTH || _y >= AntsForage.GRID_HEIGHT) continue; // nothing to see here
double m = af.toFoodGrid.field[_x][_y] *
(dx * dy != 0 ? // diagonal corners
af.diagonalCutDown : af.updateCutDown) +
reward;
if (m > max) max = m;
}
af.toFoodGrid.field[x][y] = max;
}
else
{
double max = af.toHomeGrid.field[x][y];
for(int dx = -1; dx < 2; dx++)
for(int dy = -1; dy < 2; dy++)
{
int _x = dx+x;
int _y = dy+y;
if (_x < 0 || _y < 0 || _x >= AntsForage.GRID_WIDTH || _y >= AntsForage.GRID_HEIGHT) continue; // nothing to see here
double m = af.toHomeGrid.field[_x][_y] *
(dx * dy != 0 ? // diagonal corners
af.diagonalCutDown : af.updateCutDown) +
reward;
if (m > max) max = m;
}
af.toHomeGrid.field[x][y] = max;
}
}
reward = 0.0;
}
public void act( final SimState state )
{
final AntsForage af = (AntsForage)state;
Int2D location = af.buggrid.getObjectLocation(this);
int x = location.x;
int y = location.y;
if (hasFoodItem) // follow home pheromone
{
double max = AntsForage.IMPOSSIBLY_BAD_PHEROMONE;
int max_x = x;
int max_y = y;
int count = 2;
for(int dx = -1; dx < 2; dx++)
for(int dy = -1; dy < 2; dy++)
{
int _x = dx+x;
int _y = dy+y;
if ((dx == 0 && dy == 0) ||
_x < 0 || _y < 0 ||
_x >= AntsForage.GRID_WIDTH || _y >= AntsForage.GRID_HEIGHT ||
af.obstacles.field[_x][_y] == 1) continue; // nothing to see here
double m = af.toHomeGrid.field[_x][_y];
if (m > max)
{
count = 2;
}
// no else, yes m > max is repeated
if (m > max || (m == max && state.random.nextBoolean(1.0 / count++))) // this little magic makes all "==" situations equally likely
{
max = m;
max_x = _x;
max_y = _y;
}
}
if (max == 0 && last != null) // nowhere to go! Maybe go straight
{
if (state.random.nextBoolean(af.momentumProbability))
{
int xm = x + (x - last.x);
int ym = y + (y - last.y);
if (xm >= 0 && xm < AntsForage.GRID_WIDTH && ym >= 0 && ym < AntsForage.GRID_HEIGHT && af.obstacles.field[xm][ym] == 0)
{ max_x = xm; max_y = ym; }
}
}
else if (state.random.nextBoolean(af.randomActionProbability)) // Maybe go randomly
{
int xd = (state.random.nextInt(3) - 1);
int yd = (state.random.nextInt(3) - 1);
int xm = x + xd;
int ym = y + yd;
if (!(xd == 0 && yd == 0) && xm >= 0 && xm < AntsForage.GRID_WIDTH && ym >= 0 && ym < AntsForage.GRID_HEIGHT && af.obstacles.field[xm][ym] == 0)
{ max_x = xm; max_y = ym; }
}
af.buggrid.setObjectLocation(this, new Int2D(max_x, max_y));
if (af.sites.field[max_x][max_y] == AntsForage.HOME) // reward me next time! And change my status
{ reward = af.reward ; hasFoodItem = ! hasFoodItem; }
}
else
{
double max = AntsForage.IMPOSSIBLY_BAD_PHEROMONE;
int max_x = x;
int max_y = y;
int count = 2;
for(int dx = -1; dx < 2; dx++)
for(int dy = -1; dy < 2; dy++)
{
int _x = dx+x;
int _y = dy+y;
if ((dx == 0 && dy == 0) ||
_x < 0 || _y < 0 ||
_x >= AntsForage.GRID_WIDTH || _y >= AntsForage.GRID_HEIGHT ||
af.obstacles.field[_x][_y] == 1) continue; // nothing to see here
double m = af.toFoodGrid.field[_x][_y];
if (m > max)
{
count = 2;
}
// no else, yes m > max is repeated
if (m > max || (m == max && state.random.nextBoolean(1.0 / count++))) // this little magic makes all "==" situations equally likely
{
max = m;
max_x = _x;
max_y = _y;
}
}
if (max == 0 && last != null) // nowhere to go! Maybe go straight
{
if (state.random.nextBoolean(af.momentumProbability))
{
int xm = x + (x - last.x);
int ym = y + (y - last.y);
if (xm >= 0 && xm < AntsForage.GRID_WIDTH && ym >= 0 && ym < AntsForage.GRID_HEIGHT && af.obstacles.field[xm][ym] == 0)
{ max_x = xm; max_y = ym; }
}
}
else if (state.random.nextBoolean(af.randomActionProbability)) // Maybe go randomly
{
int xd = (state.random.nextInt(3) - 1);
int yd = (state.random.nextInt(3) - 1);
int xm = x + xd;
int ym = y + yd;
if (!(xd == 0 && yd == 0) && xm >= 0 && xm < AntsForage.GRID_WIDTH && ym >= 0 && ym < AntsForage.GRID_HEIGHT && af.obstacles.field[xm][ym] == 0)
{ max_x = xm; max_y = ym; }
}
af.buggrid.setObjectLocation(this, new Int2D(max_x, max_y));
if (af.sites.field[max_x][max_y] == AntsForage.FOOD) // reward me next time! And change my status
{ reward = af.reward; hasFoodItem = ! hasFoodItem; }
}
last = location;
}
public void step( final SimState state )
{
depositPheromone(state);
act(state);
}
// a few tweaks by Sean
private Color noFoodColor = Color.black;
private Color foodColor = Color.red;
public final void draw(Object object, Graphics2D graphics, DrawInfo2D info)
{
if( hasFoodItem )
graphics.setColor( foodColor );
else
graphics.setColor( noFoodColor );
// this code was stolen from OvalPortrayal2D
int x = (int)(info.draw.x - info.draw.width / 2.0);
int y = (int)(info.draw.y - info.draw.height / 2.0);
int width = (int)(info.draw.width);
int height = (int)(info.draw.height);
graphics.fillOval(x,y,width, height);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy