#!/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; }