Genetic algorithm-with Bugs
//genetic algorithm. practice with bug-based search.
//each bugs has energy, and it will die so soon if it didn't eat bacteria.
//bugs have genes, and that genes have 6 vectors - straight go, 60 degree left, 60 degree right, straight back, 120 degree left, 120 degree right.
//As time goes on, good genes survive - maybe pure Red or Blue bugs.
//reference - evolutionary learning strategy using bug-based search, Hitoshi Iba, et al.
/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/bFdf
*/
//genetic algorithm. practice with bug-based search.
//each bugs has energy, and it will die so soon if it didn't eat bacteria.
//bugs have genes, and that genes have 6 vectors - straight go, 60 degree left, 60 degree right, straight back, 120 degree left, 120 degree right.
//As time goes on, good genes survive - maybe pure Red or Blue bugs.
//reference - evolutionary learning strategy using bug-based search, Hitoshi Iba, et al.
package {
import flash.text.*;
import flash.display.Sprite;
import flash.events.*;
import flash.filters.*;
import flash.geom.Matrix;
import net.hires.debug.Stats;
public class FlashTest extends Sprite {
public var generation:int=0;
public var time:uint=0;
public var back_sp:Sprite=new Sprite();
public var graph_Sp:Sprite=new Sprite();
public var border_sp:Sprite=new Sprite();
public var penetrate:Boolean=true;
public var eden:Boolean=false;
public var bugs:Array=[];
public var bug:Bug;
public var init_bug_num:int=10;
public var bacs:Array=[];
public var bac:Bacteria;
public var init_bac_num:int=1000;
public var reproduce_threshold:int=1000;
public var mature_threshold:int=720;
public var reproduction_radius:int=150;
public var white:GlowFilter=new GlowFilter(0xffffff);
public var age_txt:TextField=new TextField();
public var eaten_txt:TextField=new TextField();
public var generation_txt:TextField=new TextField();
public var gene_txt:TextField=new TextField();
public var forward_but:Sprite;
public var play_but:Sprite;
public var pause_but:Sprite;
public var eden_but:Sprite;
public var border_but:Sprite;
public function FlashTest() {
stage.frameRate=24;
var m:Matrix;
back_sp.graphics.beginGradientFill("radial",[0x00cc00,0xcccc00],[50,100],[50,200],m=new Matrix(400,400,Math.PI/4,0,0),"reflect","linearRGB");
back_sp.graphics.drawRect(0,0,400,400);
back_sp.graphics.endFill();
addChild(back_sp);
var stats:Stats=new Stats();
stats.x=400;
stats.y=0;
addChild(stats);
addChild(graph_Sp);
var f:TextFormat=new TextFormat;
f.size=11;
f.font="Courier New";
f.bold=true;
var t1:TextField=new TextField();
t1.defaultTextFormat=f;
t1.x=410;
t1.y=100;
t1.text="Age";
addChild(t1);
var t2:TextField=new TextField();
t2.defaultTextFormat=f;
t2.x=410;
t2.y=250;
t2.text="Eaten";
addChild(t2);
f.size=9;
age_txt.defaultTextFormat=f;
age_txt.x=450;
age_txt.y=118;
age_txt.autoSize=TextFieldAutoSize.LEFT;
addChild(age_txt);
eaten_txt.defaultTextFormat=f;
eaten_txt.x=450;
eaten_txt.y=268;
eaten_txt.autoSize=TextFieldAutoSize.LEFT;
addChild(eaten_txt);
f.size=12;
generation_txt.defaultTextFormat=f;
generation_txt.x=10;
generation_txt.y=410;
generation_txt.text="Generation : ";
generation_txt.autoSize=TextFieldAutoSize.LEFT;
addChild(generation_txt);
gene_txt.defaultTextFormat=f;
gene_txt.x=140;
gene_txt.y=410;
gene_txt.width=200;
gene_txt.text="";
addChild(gene_txt);
forward_but=new Sprite();
forward_but.graphics.lineStyle(1, 0xBBBBBB);
forward_but.graphics.beginFill(0xEEEEEE);
forward_but.graphics.drawRoundRect(0, 0, 20, 20, 5, 5);
forward_but.graphics.endFill();
forward_but.x=340;
forward_but.y=410;
forward_but.mouseChildren = false;
forward_but.buttonMode = true;
addChild(forward_but);
var field:TextField = new TextField();
field.width = 20;
field.height = 20;
field.htmlText = "<p align='center'><font size='8'>▶▶</span></p>";
forward_but.addChild(field);
play_but=new Sprite();
play_but.graphics.lineStyle(1, 0xBBBBBB);
play_but.graphics.beginFill(0xEEEEEE);
play_but.graphics.drawRoundRect(0, 0, 20, 20, 5, 5);
play_but.graphics.endFill();
play_but.x=365;
play_but.y=410;
play_but.mouseChildren = false;
play_but.buttonMode = true;
addChild(play_but);
field = new TextField();
field.width = 20;
field.height = 20;
field.htmlText = "<p align='center'><font size='10'>▶</span></p>";
play_but.addChild(field);
pause_but=new Sprite();
pause_but.graphics.lineStyle(1, 0xBBBBBB);
pause_but.graphics.beginFill(0xEEEEEE);
pause_but.graphics.drawRoundRect(0, 0, 20, 20, 5, 5);
pause_but.graphics.endFill();
pause_but.x=390;
pause_but.y=410;
pause_but.mouseChildren = false;
pause_but.buttonMode = true;
addChild(pause_but);
field = new TextField();
field.width = 20;
field.height = 20;
field.htmlText = "<p align='center'><font size='10'>■</span></p>";
pause_but.addChild(field);
eden_but=new Sprite();
eden_but.graphics.lineStyle(1, 0xBBBBBB);
eden_but.graphics.beginFill(0xEEEEEE);
eden_but.graphics.drawRoundRect(0, 0, 20, 20, 5, 5);
eden_but.graphics.endFill();
eden_but.x=415;
eden_but.y=410;
eden_but.mouseChildren = false;
eden_but.buttonMode = true;
addChild(eden_but);
field = new TextField();
field.width = 20;
field.height = 20;
field.htmlText = "<p align='center'><font size='10'>E</span></p>";
eden_but.addChild(field);
border_but=new Sprite();
border_but.graphics.lineStyle(1, 0xBBBBBB);
border_but.graphics.beginFill(0xEEEEEE);
border_but.graphics.drawRoundRect(0, 0, 20, 20, 5, 5);
border_but.graphics.endFill();
border_but.x=440;
border_but.y=410;
border_but.mouseChildren = false;
border_but.buttonMode = true;
addChild(border_but);
field = new TextField();
field.width = 20;
field.height = 20;
field.htmlText = "<p align='center'><font size='10'>B</span></p>";
border_but.addChild(field);
showgeneration();
//var colors:Array=[0xff0000,0xffff00,0x00ff00,0x00ffff,0x0000ff,0xff00ff];
//var colors:Array=[0xff0000,0x2a2a2a,0x2a2a2a,0x0000ff,0x2a2a2a,0x2a2a2a];
//var colors:Array=[16711680,2763306,2763306,255,2763306,2763306];
forward_but.addEventListener(MouseEvent.CLICK,forwardon);
play_but.addEventListener(MouseEvent.CLICK,playon);
pause_but.addEventListener(MouseEvent.CLICK,pauseon);
border_but.addEventListener(MouseEvent.CLICK,borderon);
eden_but.addEventListener(MouseEvent.CLICK,edenon);
stage.addEventListener(Event.ENTER_FRAME,regenbac);
addChild(border_sp);
init_pop();
}
public function edenon(e:MouseEvent):void
{
if(eden==true)
{
eden=false;
}
else
{
eden=true;
}
}
public function borderon(e:MouseEvent):void
{
if(penetrate==true)
{
border_sp.graphics.lineStyle(4,0xdd0000,1);
border_sp.graphics.drawRect(0,0,400,400);
penetrate=false;
}
else
{
border_sp.graphics.clear();
penetrate=true;
}
}
public function newgen():void
{
generation++;
showgeneration();
showage();
if(bugs.length==0)
{
stage.frameRate=0;
}
}
public function regenbac(e:Event):void
{
time++;
if(time%240==0)
{
newgen();
}
if(Math.random()<0.5)
{
bac=new Bacteria();
bac.x=Math.random()*(400-bac.width)+bac.width/2;
bac.y=Math.random()*(400-bac.width)+bac.width/2;
addChild(bac);
bacs.push(bac);
}
if(eden==true)
{
var dense:int=1;
for(var k:int=0;k<dense;k++)
{
bac=new Bacteria();
bac.x=Math.random()*55+55;
bac.y=Math.random()*55+270;
addChild(bac);
bacs.push(bac);
}
}
if(bugs.length!=0)
{
for(var i:int=bugs.length-1;i>-1;i--)
{
bug=bugs[i];
if(bug.energy<=0)
{
removeChild(bug);
bug.removeEventListener(Event.ENTER_FRAME,bug_move);
bugs.splice(i,1);
}
}
}
}
public function forwardon(e:MouseEvent):void
{
stage.frameRate=48;
}
public function playon(e:MouseEvent):void
{
stage.frameRate=24;
}
public function pauseon(e:MouseEvent):void
{
stage.frameRate=0;
}
public function init_pop():void
{
for(var i:int=0;i<init_bac_num;i++)
{
bac=new Bacteria();
bac.x=Math.random()*(400-bac.width)+bac.width/2;
bac.y=Math.random()*(400-bac.width)+bac.width/2;
addChild(bac);
bacs.push(bac);
}
for(i=0;i<init_bug_num;i++)
{
bug=new Bug();
bug.x=Math.random()*400;
bug.y=Math.random()*400;
var r:Number=0;
var g:Number=0;
var b:Number=0;
var total:uint=0;
var gentotal:uint=0;
for(var j:int=0;j<6;j++)
{
var gen:int=int(Math.random()*11);
switch(j)
{
case 0:
r+=255*gen;
break;
case 1:
r+=128*gen;
g+=128*gen;
break;
case 2:
g+=255*gen;
break;
case 3:
b+=255*gen;
break;
case 4:
g+=128*gen;
b+=128*gen;
break;
case 5:
r+=128*gen;
b+=128*gen;
break;
}
gentotal+=gen;
bug.gene.push(gen);
}
r=int(r/gentotal);
g=int(g/gentotal);
b=int(b/gentotal);
total=(r<<16) | (g<<8) | b;
bug.color=total;
bug.init();
addChild(bug);
bugs.push(bug);
bug.addEventListener(Event.ENTER_FRAME,bug_move);
bug.addEventListener(MouseEvent.CLICK,showbuginfo);
}
showage();
}
public function showbuginfo(e:MouseEvent):void
{
gene_txt.text="";
gene_txt.appendText("Gene : [ ");
for(var i:int=0;i<e.target.gene.length;i++)
{
gene_txt.appendText(String(e.target.gene[i])+" ");
}
e.target.filters=[white];
gene_txt.appendText("]");
}
public function bug_move(e:Event):void
{
var bug:Bug=Bug(e.target);
bug.age++;
var rand:Number=Math.random();
var tot:Number=0;
var probs:Array=[];
for(var i:int=0;i<bug.gene.length;i++)
{
tot+=bug.gene[i];
}
var accum:Number=0;
for(i=0;i<bug.gene.length-1;i++)
{
accum+=bug.gene[i];
probs.push(accum/tot);
}
if(rand<probs[0])
{
bug.x+=Math.cos(bug.rotation)*bug.vel;
bug.y+=Math.sin(bug.rotation)*bug.vel;
}
else if(rand<probs[1])
{
bug.rotation+=60;
}
else if(rand<probs[2])
{
bug.rotation+=120;
}
else if(rand<probs[3])
{
bug.x-=Math.cos(bug.rotation)*bug.vel;
bug.y-=Math.sin(bug.rotation)*bug.vel;
}
else if(rand<probs[4])
{
bug.rotation-=60;
}
else
{
bug.rotation-=120;
}
if(penetrate==true)
{
if(bug.x-bug.width/2<0)
{
bug.x=400-bug.width/2;
}
else if(bug.x+bug.width/2>400)
{
bug.x=bug.width/2;
}
if(bug.y-bug.width/2<0)
{
bug.y=400-bug.width/2;
}
else if(bug.y+bug.width/2>400)
{
bug.y=bug.width/2;
}
}
else
{
if(bug.x-bug.width/2<0)
{
bug.x=bug.width/2;
}
else if(bug.x+bug.width/2>400)
{
bug.x=400-bug.width/2;
}
if(bug.y-bug.width/2<0)
{
bug.y=bug.width/2;
}
else if(bug.y+bug.width/2>400)
{
bug.y=400-bug.width/2;
}
}
if(bacs.length!=0)
{
for(i=bacs.length-1;i>-1;i--)
{
bac=bacs[i];
var dx:Number=bac.x-bug.x;
var dy:Number=bac.y-bug.y;
if(Math.abs(dx)<10)
{
if(Math.abs(dy)<10)
{
if(bug.hitTestObject(bac))
{
removeChild(bac);
bug.energy+=bac.energy;
bug.eaten++;
bacs.splice(i,1);
}
}
}
}
}
if(bug.energy>=1500)
{
bug.energy=1500;
}
bug.energy--;
if(bug.energy<400)
{
bug.alpha=1-((400-bug.energy)/400)+0.2;
}
if(bug.energy>=reproduce_threshold && bug.age>=mature_threshold)
{
var bug2:Bug;
bug2=new Bug();
bug2.x=bug.x;
bug2.y=bug.y;
var r:Number=0;
var g:Number=0;
var b:Number=0;
var total:uint=0;
var gentotal:uint=0;
var rnd:int=int(Math.random()*6);
for(var j:int=0;j<6;j++)
{
var gen:int;
if(rnd==j)
{
gen=bug.gene[j]+int(Math.random()*5)-2;
if(gen<0)
{
gen=0;
}
else if(gen>10)
{
gen=10;
}
}
else
{
gen=bug.gene[j];
}
switch(j)
{
case 0:
r+=255*gen;
break;
case 1:
r+=128*gen;
g+=128*gen;
break;
case 2:
g+=255*gen;
break;
case 3:
b+=255*gen;
break;
case 4:
g+=128*gen;
b+=128*gen;
break;
case 5:
r+=128*gen;
b+=128*gen;
break;
}
gentotal+=gen;
bug2.gene.push(gen);
}
r=int(r/gentotal);
g=int(g/gentotal);
b=int(b/gentotal);
total=(r<<16) | (g<<8) | b;
bug2.color=total;
bug2.init();
bug2.energy=Math.floor(bug.energy/2);
addChild(bug2);
bugs.push(bug2);
bug2.addEventListener(Event.ENTER_FRAME,bug_move);
bug2.addEventListener(MouseEvent.CLICK,showbuginfo);
bug.energy/=2;
}
}
public function showgeneration():void
{
generation_txt.text="";
generation_txt.appendText("Generation : "+String(generation));
}
public function showage():void
{
graph_Sp.graphics.clear();
var ages:Array=[0,0,0,0,0,
0,0,0,0,0,
0];
var eatens:Array=[0,0,0,0,0,
0,0,0,0,0,
0];
for(var i:int=0;i<bugs.length;i++)
{
bug=bugs[i];
var agenum:int=int(bug.age/720);
if(agenum>=10)
{
agenum=10;
}
ages[agenum]++;
var eatennum:int=int(bug.eaten/50);
if(eatennum>=10)
{
eatennum=10;
}
eatens[eatennum]++;
}
var totalage:int=0;
var highage:int=0;
age_txt.text="";
for(i=0;i<ages.length;i++)
{
age_txt.appendText(String(ages[i])+"\n");
totalage+=ages[i];
if(highage<ages[i])
{
highage=ages[i];
}
}
graph_Sp.graphics.lineStyle(0,0x127198);
graph_Sp.graphics.beginFill(0x2BAEE6);
var hifactor:Number=1;
if(highage<10)
{
hifactor=highage/10;
}
for(i=0;i<ages.length;i++)
{
graph_Sp.graphics.drawRect(400,i*12+120,55*ages[i]/highage*hifactor,8);
}
var totaleaten:int=0;
var higheaten:int=0;
eaten_txt.text="";
for(i=0;i<eatens.length;i++)
{
eaten_txt.appendText(String(eatens[i])+"\n");
totaleaten+=eatens[i];
if(higheaten<eatens[i])
{
higheaten=eatens[i];
}
}
graph_Sp.graphics.lineStyle(0,0xCDA818);
graph_Sp.graphics.beginFill(0xEACB51);
hifactor=1;
if(higheaten<10)
{
hifactor=higheaten/10;
}
for(i=0;i<eatens.length;i++)
{
graph_Sp.graphics.drawRect(400,i*12+270,55*eatens[i]/higheaten*hifactor,8);
}
}
}
}
import flash.display.Sprite;
class Bug extends Sprite{
public var radius:Number;
public var color:uint;
public var vel:Number=5;
public var gene:Array=[];
public var age:uint=0;
public var eaten:int=0;
public var energy:int=800;
public function Bug(radius:Number=5){
this.radius=radius;
//init();
}
public function init():void{
graphics.lineStyle(0,0x000000);
graphics.beginFill(color);
graphics.drawCircle(0,0,radius);
graphics.endFill();
graphics.moveTo(0,0);
graphics.lineTo(radius,0);
}
}
import flash.display.Sprite;
class Bacteria extends Sprite{
public var radius:Number;
public var color:uint;
public var linecolor:uint;
public var energy:int=40;
public function Bacteria(radius:Number=2, color:uint=0xffff5e, linecolor:uint=0xdddd00){
this.radius=radius;
this.color=color;
this.linecolor=linecolor;
init();
}
private function init():void{
graphics.lineStyle(0,linecolor);
graphics.beginFill(color);
graphics.drawCircle(0,0,radius);
graphics.endFill();
}
}