/** * Bug.java */ package AntPheromones1; import java.util.Formatter; import java.awt.Point; import java.util.ArrayList; import uchicago.src.sim.util.*; import uchicago.src.sim.gui.*; import uchicago.src.sim.space.Object2DTorus; import uchicago.src.sim.space.Diffuse2D; import uchicago.src.sim.gui.ColorMap; import java.awt.Color; public class Bug implements Drawable { // class variables public static int nextID = 0; // to give each an ID public static Object2DTorus bugsWorld; // where the bugs live public static Diffuse2D pSpace; // where the pheromone is stored public static AntPheromones1 model; // the model "in charge" // instance variables int ID; private int x, y; // the Bug constructor public Bug ( ) { ID = nextID++; x = 0; y = 0; } //////////////////////////////////////////////////////////////////////////// // step // select a random 1-step (Moore) neighbor cell // if the cell is open, and if pheromone is higher there, move there. // If its not better, just pick a random open neighbor cell and move there. // If no open neighbor, don't move. public void step () { int moved = 0; // not moved this step if ( model.getRDebug() > 0 ) System.out.printf( " --Bug-step() for ID=%d at x,y=%d,%d.\n", ID, x, y ); // pick a random neighbor cell, and if it is open, // check the pheromone there, and if its more there, move there. Point pt = findRandomOpenNeighborCell (); if ( pt != null ) { // we got one! int newX = (int) pt.getX(); int newY = (int) pt.getY(); if ( pSpace.getValueAt( x, y ) < pSpace.getValueAt( newX, newY ) ) { moved = moveTo( newX, newY ); if ( model.getRDebug() > 1 ) System.out.printf(" -- moved to better cell at %d,%d.\n", x, y ); } } // if didn't move to better cell, then try to find any open neighbor. if ( moved == 0 ) { pt = findRandomOpenNeighborCell (); if ( pt != null ) { moved = moveTo( (int) pt.getX(), (int) pt.getY() ); if ( model.getRDebug() > 1 ) System.out.printf(" -- moved to random cell %d,%d.\n",x,y); } } if ( model.getRDebug() > 1 ) System.out.printf(" Bug.step() done. bug moved = %d.\n", moved ); } //////////////////////////////////////////////////////////////////////////// // findRandomOpenNeighborCell // pick random open Moore neighbor cell and return its // coordinates in a Point, // Return null if no open cell found. public Point findRandomOpenNeighborCell () { ArrayList openPts = new ArrayList(); // list of open points int minx = x - 1; // we could change the "neighborhood radius" here int maxx = x + 1; int miny = y - 1; int maxy = y + 1; for ( int tx = minx; tx <= maxx; ++tx ) { for ( int ty = miny; ty <= maxy; ++ty ) { if ( bugsWorld.getObjectAt( tx, ty ) == null ) { // its open openPts.add( new Point( tx, ty ) ); // add to list } } } // now pick a random open point, if any to pick from int numOpenPts = openPts.size(); Point openP = null; // the one we return if ( numOpenPts == 1 ) // only one to pick! openP = openPts.get( 0 ); else if ( numOpenPts > 1 ) // pick one at random openP = openPts.get( model.getUniformIntFromTo( 0, numOpenPts-1 ) ); return openP; } //////////////////////////////////////////////////////////////////////////// // moveTo newX, newY // check to see if the new location is open, and if so move to it: // - tell world it moved // - change bug's own x,y values // - return 1 to indicate move was succesful // if that location not open, return 0 // // NOTE: assumes we are on a torus (eg Object2DTorus object) public int moveTo( int newX, int newY ) { if ( bugsWorld.getObjectAt( newX, newY ) != null ) return 0; // oops, something is there! bugsWorld.putObjectAt( x, y, null ); // leaving that cell empty now bugsWorld.putObjectAt( newX, newY, this ); // move into new location x = SimUtilities.norm( newX, bugsWorld.getSizeX() ); // normalize for torus y = SimUtilities.norm( newY, bugsWorld.getSizeY() ); // normalize for torus return 1; } //////////////////////////////////////////////////////////////////////////// // setters and getters public void setID(int i) { ID = i; } public int getID() { return ID; } // note these are class methods, to set class variables public static void setBugsWorld( Object2DTorus world ) { bugsWorld = world; } public static void setPSpace( Diffuse2D space ) { pSpace = space; } public static void setModel( AntPheromones1 m ) { model = m; } public int getX() { return x; } public void setX( int i ) { x = i; } public int getY() { return y; } public void setY( int i ) { y = i; } // we implement Drawable interface, so we need this method // so that the Bug can draw itself when requested // (by the GUI display). public void draw( SimGraphics g ) { g.drawFastRoundRect( Color.blue ); } }