# Evolutionary Symmetry

## In this example below you will see how to do a Evolutionary Symmetry with some HTML / CSS and Javascript

This awesome code was written by danthedev, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
• HTML
• CSS
• JavaScript
``````    <label>Width:</label>
<input type="number" id="width" value="5">
<br />

<label>Height:</label>
<input type="number" id="height" value="5">
<br />

<label>Pixel Size:</label>
<input type="number" id="px" value="10">
<br />

<canvas id="canvas"></canvas>

<hr />
<span id="iterations">0</span> /
<span id="tries">0</span>
``````
``````

``````
``````
var colors = [
hsl(Math.random() * 360, 10, 100),
hsl(Math.random() * 360, 10, 30),
hsl(Math.random() * 360, 50, 40),
hsl(Math.random() * 360, 50, 50),
hsl(Math.random() * 360, 50, 60)
];

function hsl(h, s, l) {
return 'hsl(' + h + ', ' + s + '%,' + l + '%)';
}

function fitness(pixels) {
var width = pixels.length;
var height = pixels[0].length;
var fitness = 0;

for(var x = 0; x < (width / 2); x++) {
for(var y = 0; y < height; y++) {
if(pixels[x][y] == pixels[width - 1 - x][y]) {
fitness += 1;
}
}
}

return fitness;
}

function generate(width, height) {
var pixels = [];
for(var x = 0; x < width; x++) {
pixels[x] = [];
for(var y = 0; y < height; y++) {
if(Math.random() > 0.4) {
pixels[x][y] = Math.floor(Math.random() * colors.length);
} else {
pixels[x][y] = 0;
}
}
}

return pixels;
}

function mutate(pixels) {
var width = pixels.length;
var height = pixels[0].length;

var rx = Math.floor(Math.random() * width);
var ry = Math.floor(Math.random() * height);

return pixels.map(function(row, x) {
return row.map(function(pixel, y) {
if(x == rx && y == ry) {
return Math.floor(Math.random() * colors.length);
} else {
return pixel
}
});
});
}

function render(pixels, context, px) {
var width = pixels.length;
var height = pixels[0].length;

for(var x = 0; x < width; x++) {
for(var y = 0; y < height; y++) {
context.fillStyle = colors[pixels[x][y] % colors.length];
context.fillRect(x * px, y * px, px, px);
}
}
}

function init() {
var iterations = 0;
var generations = 0;
var width = Number(document.getElementById('width').value || 10);
var height = Number(document.getElementById('height').value || 10);
var px = Number(document.getElementById('px').value || 10);
var count = document.getElementById('iterations');
var tries = document.getElementById('tries');

var canvas = document.getElementById('canvas');
canvas.width = width * px;
canvas.height = height * px;

var c = canvas.getContext('2d');

var pixels = generate(width, height);

function evolve() {
requestAnimationFrame(evolve);
var mutation = mutate(pixels);

var f1 = fitness(pixels);
var f2 = fitness(mutation);

var fScore = f2 / ((width * height) / 2);

if(f2 > f1) {
pixels = mutation;
generations += 1;
count.innerHTML = generations;
tries.innerHTML = fScore + '%';
}
iterations += 1;
render(pixels, c, px);
}

evolve();

}

init();

if(e.which == 13) {
init();
}
colors = [
hsl(Math.random() * 360, 10, 100),
hsl(Math.random() * 360, 10, 30),
hsl(Math.random() * 360, 50, 40),
hsl(Math.random() * 360, 50, 50),
hsl(Math.random() * 360, 50, 60),
hsl(Math.random() * 360, 50, 70)
];
})

``````