#!/usr/bin/perl
use GD;
main();
sub main {
get_dimensions();
initialise();
generate_genes();
while(1){
draw_images();
score_images();
if($best < $prevbest){
$prevbest = $best;
output_best();
}
$numreps = int(rand(50));
for($m = 0; $m <= $numreps; $m++){
if(int(rand(100)) < 100){ soft_mutate_x(); }
if(int(rand(100)) < 100){ soft_mutate_y(); }
if(int(rand(100)) < 100){ soft_mutate_r(); }
if(int(rand(100)) < 100){ soft_mutate_g(); }
if(int(rand(100)) < 100){ soft_mutate_b(); }
if(int(rand(100)) < 100){ soft_mutate_a(); }
}
$generation++;
}
}
sub generate_genes {
for($i = 1; $i <= 10; $i++){
for($d = 1; $d <= 50; $d++){
for($c = 1; $c <= 4; $c++){
push(@{"xchrom".$i}, int(rand($width + 1)));
push(@{"ychrom".$i}, int(rand($height + 1)));
}
for($c = 1; $c <= 3; $c++){
push(@{"rchrom".$i}, int(rand(256)));
push(@{"gchrom".$i}, int(rand(256)));
push(@{"bchrom".$i}, int(rand(256)));
}
push(@{"achrom".$i}, int(rand(128)));
}
}
}
sub get_dimensions {
$timage = GD::Image->newFromPng("ml.png");
($width, $height) = $timage->getBounds;
}
sub initialise {
$generation = 1;
$best = 195010 * $width * $height;
$prevbest = 195010 * $width * $height;
}
sub draw_images {
for($i = 1; $i <= 10; $i++){
$im[$i] = new GD::Image($width,$height,1);
for($z = 0; $z <= 196; $z+=4){
$poly = new GD::Polygon;
$poly->addPt(${"xchrom".$i}[$z], ${"ychrom".$i}[$z]);
$poly->addPt(${"xchrom".$i}[$z+1], ${"ychrom".$i}[$z+1]);
$poly->addPt(${"xchrom".$i}[$z+2], ${"ychrom".$i}[$z+2]);
$poly->addPt(${"xchrom".$i}[$z+3], ${"ychrom".$i}[$z+3]);
$col = $im[$i]->colorAllocateAlpha(${"rchrom".$i}[$z/4], ${"gchrom".$i}[$z/4], ${"bchrom".$i}[$z/4], ${"achrom".$i}[$z/4]);
$im[$i]->filledPolygon($poly,$col);
}
}
}
sub score_images {
for($i = 1; $i <= 10; $i++){
$score[$i] = 0;
foreach $x ( 0 .. $width ) {
foreach $y ( 0 .. $height ) {
($index1) = $timage->getPixel($x,$y);
($index2) = $im[$i]->getPixel($x,$y);
($r1,$g1,$b1) = $timage->rgb($index1);
($r2,$g2,$b2) = $im[$i]->rgb($index2);
$score[$i] += ($r1 - $r2)**2;
$score[$i] += ($g1 - $g2)**2;
$score[$i] += ($b1 - $b2)**2;
}
}
if($score[$i] < $best){
$best = $score[$i];
$savedIndex = $i;
}
}
}
sub output_best {
print $generation.",".$score[$savedIndex]."\n";
open FILE, ">".$generation."\.png" or die $!;
binmode FILE;
print FILE $im[$savedIndex]->png;
close FILE;
}
sub soft_mutate_x {
$randomchrom = int(rand(10)) + 1;
while($randomchrom == $savedIndex){
$randomchrom = int(rand(10)) + 1;
}
$randlocus = int(rand(200));
${"xchrom".$randomchrom}[$randlocus] += int(rand(35));
${"xchrom".$randomchrom}[$randlocus] = ${"xchrom".$randomchrom}[$randlocus] % ($width + 1);
}
sub soft_mutate_y {
$randomchrom = int(rand(10)) + 1;
while($randomchrom == $savedIndex){
$randomchrom = int(rand(10)) + 1;
}
$randlocus = int(rand(200));
${"ychrom".$randomchrom}[$randlocus] += int(rand(35));
${"ychrom".$randomchrom}[$randlocus] = ${"ychrom".$randomchrom}[$randlocus] % ($height + 1);
}
sub soft_mutate_r {
$randomchrom = int(rand(10)) + 1;
while($randomchrom == $savedIndex){
$randomchrom = int(rand(10)) + 1;
}
$randlocus = int(rand(50));
${"rchrom".$randomchrom}[$randlocus] += int(rand(35));
${"rchrom".$randomchrom}[$randlocus] = ${"rchrom".$randomchrom}[$randlocus] % 256;
}
sub soft_mutate_g {
$randomchrom = int(rand(10)) + 1;
while($randomchrom == $savedIndex){
$randomchrom = int(rand(10)) + 1;
}
$randlocus = int(rand(50));
${"gchrom".$randomchrom}[$randlocus] += int(rand(35));
${"gchrom".$randomchrom}[$randlocus] = ${"gchrom".$randomchrom}[$randlocus] % 256;
}
sub soft_mutate_b {
$randomchrom = int(rand(10)) + 1;
while($randomchrom == $savedIndex){
$randomchrom = int(rand(10)) + 1;
}
$randlocus = int(rand(50));
${"bchrom".$randomchrom}[$randlocus] += int(rand(35));
${"bchrom".$randomchrom}[$randlocus] = ${"bchrom".$randomchrom}[$randlocus] % 256;
}
sub soft_mutate_a {
$randomchrom = int(rand(10)) + 1;
while($randomchrom == $savedIndex){
$randomchrom = int(rand(10)) + 1;
}
$randlocus = int(rand(50));
${"achrom".$randomchrom}[$randlocus] += int(rand(35));
${"achrom".$randomchrom}[$randlocus] = ${"achrom".$randomchrom}[$randlocus] % 128;
}