Files
sunny9898/task8/_ref/noc-examples-processing-master/chp09_ga/EvolveFlowField/EvolveFlowField.pde
louiscklaw 5637fbf94f update,
2025-02-01 02:07:58 +08:00

122 lines
3.1 KiB
Plaintext

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
// Pathfinding Flowfield w/ Genetic Algorithms
// This example produces an obstacle course with a start and finish
// Virtual "creatures" are rewarded for making it closer to the finish
// Each creature's DNA is a "flowfield" of PVectors that
// determine steering vectors for each cell on the screen
import java.awt.Rectangle;
int gridscale = 10; // Scale of grid is 1/24 of screen size
// DNA needs one vector for every spot on the grid
// (it's like a pixel array, but with vectors instead of colors)
int dnasize;
int lifetime; // How long should each generation live
Population population; // Population
int lifecycle; // Timer for cycle of generation
int recordtime; // Fastest time to target
Obstacle target; // Target position
Obstacle start; // Start position
int diam = 24; // Size of target
ArrayList<Obstacle> obstacles; //an array list to keep track of all the obstacles!
boolean debug = false;
Rectangle newObstacle = null;
void setup() {
size(640,360);
dnasize = (width / gridscale) * (height / gridscale);
lifetime = width/3;
// Initialize variables
lifecycle = 0;
recordtime = lifetime;
target = new Obstacle(width-diam-diam/2,height/2-diam/2,diam,diam);
start = new Obstacle(diam/2,height/2-diam/2,diam,diam);
// Create a population with a mutation rate, and population max
int popmax = 1000;
float mutationRate = 0.02;
population = new Population(mutationRate,popmax);
// Create the obstacle course
obstacles = new ArrayList<Obstacle>();
/*obstacles.add(new Obstacle(width/4,80,10,height-160));
obstacles.add(new Obstacle(width/2,0,10,height/2-20));
obstacles.add(new Obstacle(width/2,height-height/2+20,10,height/2-20));
obstacles.add(new Obstacle(2*width/3,height/2-height/8,10,height/4));*/
}
void draw() {
background(255);
// Draw the target positions
target.display();
// Draw the obstacles
for (Obstacle obs : obstacles) {
obs.display();
}
// If the generation hasn't ended yet
if (lifecycle < lifetime) {
population.live(obstacles);
if ((population.targetReached()) && (lifecycle < recordtime)) {
recordtime = lifecycle;
}
lifecycle++;
// Otherwise a new generation
} else {
lifecycle = 0;
population.calcFitness();
population.naturalSelection();
population.generate();
}
// Display some info
textAlign(RIGHT);
fill(0);
text("Generation #:" + population.getGenerations(),width-10,18);
text("Cycles left:" + ((lifetime-lifecycle)),width-10,36);
text("Record cycles: " + recordtime,width-10,54);
if (newObstacle != null) {
rect(newObstacle.x,newObstacle.y,newObstacle.width,newObstacle.height);
}
}
void keyPressed() {
if (key == 'd') {
debug = !debug;
}
}
void mousePressed() {
newObstacle = new Rectangle(mouseX,mouseY,0,0);
}
void mouseDragged() {
newObstacle.width = mouseX-newObstacle.x;
newObstacle.height = mouseY-newObstacle.y;
}
void mouseReleased() {
obstacles.add(new Obstacle(newObstacle));
newObstacle = null;
}