// The Blues // // Controlling applet // // Author Matthew Caryl // Created 2.5.97 // // Although under copywrite to the author (Matthew Caryl) this code can be copied and modified for non-commercial // purposes as long as any derivatives contain this condition. package Blues; import java.awt.Color; import java.awt.Event; import java.awt.Image; import java.awt.Graphics; import java.applet.Applet; import java.lang.String; import ADT.Random; public final class World extends Applet implements Runnable { private int mutation_percentage = 25; private int crossover_percentage = 75; int black_value = 2; int purple_value = 3; int red_value = 5; int blue_value = 10; private int cycle_delay; private int block_width; private int block_height; private int block_size; private Thread animation; private Random random = new Random(); private Graphics graphics; private ControlFrame control; private Image image; private Graphics image_graphics; // read in parameter value or use default or minimum private int readInt(String param, int d, int m) { String cycleString = this.getParameter(param); try { int v = Integer.parseInt(cycleString); if (v < m) return m; else return v; } catch (NumberFormatException e) { return d; } } // parent choice private int roulette(int[] evaluation, int total) { int n = random.range(total); int sum = 0; int i; for (i = 0; n >= sum + evaluation[i]; i++) sum += evaluation[i]; return i; } // paint block (x, y) private void paintBlock(int x, int y, Color c) { synchronized (image) { image_graphics.setColor(c); image_graphics.fillRect(x * block_size, y * block_size, block_size, block_size); } } // mark controls as gone void cancel() { control = null; } // produce random number Random random() { return random; } // width in blocks int width() { return block_width; } // height in blocks int height() { return block_height; } int blockSize() { return block_size; } int generations() { return width(); } int population() { return height(); } int mutation() { return mutation_percentage; } int crossover() { return crossover_percentage; } int blackEvaluation() { return black_value; } int purpleEvaluation() { return purple_value; } int redEvaluation() { return red_value; } int blueEvaluation() { return blue_value; } // Read in applet parameters public void init() { setBackground(Color.black); // read in cycle time cycle_delay = readInt("endDelay", 1, 1); // Read in applet block width block_width = readInt("blockWidth", 64, 1); // Read in applet block height block_height = readInt("blockHeight", 64, 1); // Read in block size block_size = readInt("blockSize", 1, 1); graphics = this.getGraphics(); image = createImage(size().width, size().height); image_graphics = image.getGraphics(); } // Reset control values void initialiseWorld(int gen, int pop, int mut, int crs, int black, int purple, int red, int blue, int block) { block_width = gen; block_height = pop; block_size = block; mutation_percentage = mut; crossover_percentage = crs; if (mutation_percentage + crossover_percentage > 100) crossover_percentage = 100 - mutation_percentage; black_value = black; purple_value = purple; red_value = red; blue_value = blue; } // stop animation and dispose of a few things public void destory() { stop(); if (control != null) control.dispose(); if (graphics != null) graphics.dispose(); if (image_graphics != null) image_graphics.dispose(); } // start animation public void start() { if (animation == null) { animation = new Thread(this); animation.start(); } } // stop animation public void stop() { if (animation != null && animation.isAlive()) animation.stop(); animation = null; } // animation sequence public void run() { while (true) { int generation; Chromosome[] population = new Chromosome[height()]; int[] evaluation = new int[height()]; int total; Chromosome[] offspring = new Chromosome[height()]; image_graphics.setColor(Color.black); image_graphics.fillRect(0, 0, size().width, size().height); // initialise for (int i = population() - 1; i >= 0; i--) population[i] = new Chromosome(this); for (generation = 0; generation < generations(); generation++) { // evaluate total = 0; for (int i = population() - 1; i >= 0; i--) { evaluation[i] = population[i].evaluation(this); total += evaluation[i]; paintBlock(generation, i, population[i].color()); } // replacement for (int i = population() - 1; i >= 0; i--) { int r = random.range(100); if (r < mutation_percentage) offspring[i] = new Chromosome(this, population[i]); else if (r < mutation_percentage + crossover_percentage) offspring[i] = new Chromosome(this, population[i], population[roulette(evaluation, total)]); else offspring[i] = population[i]; } // remove for (int i = population() - 1; i >= 0; i--) population[i] = null; // replace for (int i = population() - 1; i >= 0; i--) population[i] = offspring[i]; paint(graphics); } try { animation.sleep(cycle_delay * 1000); } catch (InterruptedException e) { // do nothing } } } // display stored image public void paint(Graphics g) { synchronized (image) { g.drawImage(image, 0, 0, this); } } // create control panel public boolean mouseDown(Event e, int x, int y) { if (animation != null && control == null) { stop(); control = new ControlFrame(this); } return true; } public String[][] getParameterInfo() { String[][] info = { {"blockWidth ", "positive integer ", "width of world in blocks"}, {"blockHeight ", "positive integer ", "height of world in blocks"}, {"blockSize ", "positive integer ", "size of block in pixels"} , {"cycleDelay ", "positive integer ", "delay between runs"} }; return info; } public String getAppletInfo() { return "The Blues v1.0 Written by Matthew Caryl"; } }