// Pathfinding w/ Genetic Algorithms // Daniel Shiffman // Creature class -- this is just like our Boid / Particle class // the only difference is that it has DNA & fitness class Creature { //*ALL THE STUFF WE HAD BEFORE*// Vector3D loc; Vector3D vel; Vector3D acc; float r; float recordDist; Man aMan; //**FITNESS AND DNA**// float fitness; DNA genes; boolean stopped; //am I stuck? int finish; //what was my finish? (first, second, etc. . . ) //constructor Creature(Vector3D l, DNA dna, int f) { acc = new Vector3D(0.0,0.0,0.0); vel = new Vector3D(0.0,0.0,0.0); loc = l.copy(); r = 4.0f; genes = dna; stopped = false; finish = f; recordDist = width; aMan = new Man(); } //***FITNESS FUNCTION*****// // distance = distance from target // finish = what order did i finish (first, second, etc. . .) // f(distance,finish) = (1.0f / finish^1.5) * (1.0f / distance^6); // a lower finish is rewarded (exponentially) and/or shorter distance to target (exponetially) void calcFitness() { float d = recordDist; //Vector3D.distance(loc,target); if (d < diam/2) { d = 1.0f; } //reward finishing faster and getting closer fitness = (1.0f / pow(finish,1.5f)) * (1.0f / (pow(d,6))); } void setFinish(int f) { finish = f; //print(finish + " "); } //Run in relation to all the obstacles //If I'm stuck, don't bother updating or checking for intersection void run(ArrayList o) { if (!stopped) { update(); //if I hit an edge or an obstacle if ((borders()) || (obstacles(o))) { float rolldice =random(0,100); if (rolldice < 10){ //this number is percentage of if they stop or not stopped = true;//if this is false they roam all over--------------------------note from jody } } } else { float throwdice = random (0,100); if (throwdice < 5){//this number is pecentage of time they change color stopped =false; } } //draw me! render(); } //*DID I HIT AN EDGE??*// boolean borders() { if ((loc.x < 0) || (loc.y < 0) || (loc.x > width) || (loc.y > height)) { return true; } else { return false; } } //**DID I MAKE IT TO THE TARGET??*// boolean finished() { /* float d = dist(loc.x,loc.y,target.r.x,target.r.y); if (d < recordDist) recordDist = d; //if ( d < diam/2) { if (target.contains(loc)) {// THIS IS WHERE IT ASKS IF IT'S TOUCHING THE TARGET stopped = true; return true; }*/ return false; } //**DID I HIT AN OBSTACLE?**// boolean obstacles(ArrayList o) { for (int i = 0; i < o.size(); i++) { Obstacle obs = (Obstacle) o.get(i); if (obs.contains(loc)) { return true; } } return false; } void update() { if (!finished()) { //where are we? Our location will tell us what steering vector to look up in our DNA; int x = (int) loc.x/gridscale; int y = (int) loc.y/gridscale; x = constrain(x,0,width/gridscale-1); //make sure we are not off the edge y = constrain(y,0,height/gridscale-1); //make sure we are not off the edge //Get the steering vector out of our genes in the right spot acc.add(genes.getGene(x+y*width/gridscale)); //this is all the same stuff we've done before acc.mult(maxforce); vel.add(acc); vel.limit(maxspeed); loc.add(vel); acc.setXYZ(0,0,0); } } void render() { smooth(); int r = 255; int g = 0; int b = 0; if (stopped){ //c = color(255); //here is hwere they would disappear--could they the man change color here? g=255; b=255; } // else fill(255,75); noStroke(); pushMatrix(); translate( loc.x, loc.y); aMan.render( r,g,b ); //println("draw at: "+ loc.x + " / " +loc.y); popMatrix(); //rect(loc.x,loc.y,10,10); } float getFitness() { return fitness; } DNA getGenes() { return genes; } boolean stopped() { return stopped; } }