// tjhCell.java import java.util.*; import java.awt.*; import tjh2dVector; import tjhGene; import tjhNeuron; /** Encapsulates a cell in our pseudo-biological simulation. The cell's properties include a position, a reference to its parent (if any) and a list of children (if any). This is a tree structure. */ public class tjhCell extends Object { //------------------------------------------------------------------------------- // static constants //------------------------------------------------------------------------------- /** the radius of the cells, fixed for now at least */ protected final static float RADIUS=6.0F; /** the maximum angular momentum of each cell in degrees */ protected final static float ANGULAR_MOMENTUM=5.0F; /** the distance within which cells can sense each other */ protected final static float SIGHT_DIST=RADIUS*6; /** do we want the cells to use their brains? */ protected final static boolean USE_BRAINS=true; //------------------------------------------------------------------------------- // protected data //------------------------------------------------------------------------------- /** the current location of the cell */ protected tjh2dVector location; /** a reference to the parent of the cell (if any) */ protected tjhCell parent; /** a reference to the owning host creature */ protected tjhCreature host_creature; /** stores whether this cell has a parent, or is the root cell for this creature */ protected boolean has_parent; /** a list of the cells that are children of this cell */ protected Vector subnodes; /** stores the type of the cell, determines its interactions and how it is drawn */ protected int type; /** the current angular momentum of the cell (in degrees) */ protected float angular_momentum; /** the cell's brains (they're a bit thick at the moment) */ protected tjhNeuron neuron; /** stores whether the cell has seen a red enemy cell nearby */ protected boolean seen_red; /** stores whether the cell has seen a green enemy cell nearby */ protected boolean seen_green; //------------------------------------------------------------------------------- // private data //------------------------------------------------------------------------------- /** internal flag, no point moving after death (makes bucketing easier) */ private boolean been_killed; //------------------------------------------------------------------------------ // public methods //------------------------------------------------------------------------------- /** default constructor */ public tjhCell() { location = new tjh2dVector(); subnodes = new Vector(); has_parent = false; angular_momentum = RandomAngularMomentum(); type=tjhGene.GREEN; neuron = new tjhNeuron(); } //-------------------------------------------------------------------------------- /** draws the cell (recurses to draw its daughter cells too) */ public void Draw(Graphics g) { g.setColor(type==tjhGene.RED?Color.red:(has_parent?Color.green:Color.magenta)); g.drawOval((int)(location.x-RADIUS),(int)(location.y-RADIUS), (int)RADIUS*2,(int)RADIUS*2); tjhCell cell; for(int i=0;i=30) return; type=genome.type; host_creature=host; buckets.PutCell(this); InstantiateChildren(genome,host,buckets,limit); // (recurses) } //-------------------------------------------------------------------------------- /** recurses down to instantiate all mid-level and leaf-level nodes in the tree of cells that is being created */ protected void InstantiateChildren(tjhGene genome,tjhCreature host,tjhBuckets buckets,tjh2dVector limit) { // add the subnodes of other as new subnodes of this cell tjhGene gene; for(int i=0;i=5) continue; tjhCell new_cell = new tjhCell(); new_cell.location = loc; new_cell.type = gene.type; new_cell.parent = this; new_cell.has_parent = true; new_cell.host_creature = host; subnodes.addElement(new_cell); buckets.PutCell(new_cell); // recurse to copy further children new_cell.InstantiateChildren(gene,host,buckets,limit); } } //-------------------------------------------------------------------------------- /** this cell has been killed, ask it to tidy itself away */ protected void Killed(tjhBuckets buckets) { // remove ourself from the parent's list of subnodes if(has_parent) { parent.subnodes.removeElement(this); } else { // we're a root cell, need to flag our death outside host_creature.has_died=true; } // remove ourself and our children from the global list of cells RemoveAllFromGlobalList(buckets); } //-------------------------------------------------------------------------------- /** recurses down to ask all children to remove themselves from the global buckets structure */ protected void RemoveAllFromGlobalList(tjhBuckets buckets) { // remove ourself been_killed=true; buckets.RemoveCell(this); // remove all our children (recurses) for(int i=0;iRADIUS && loc.y>RADIUS && loc.x0.5?-1.0F:1.0F); } //-------------------------------------------------------------------------------- /** return a random angle between 0 and 360 degrees */ protected float RandomAngle() { return (float)Math.random()*360.0F; } }