Skip to content

Instantly share code, notes, and snippets.

@spiterman
Created September 17, 2018 10:01
Show Gist options
  • Select an option

  • Save spiterman/3e9becd0c0216e1a841b12284e41c3b9 to your computer and use it in GitHub Desktop.

Select an option

Save spiterman/3e9becd0c0216e1a841b12284e41c3b9 to your computer and use it in GitHub Desktop.
class Environment {
constructor(r, g, b, startingOrganisms) {
this.r = r;
this.g = g;
this.b = b;
this.organisms = [];
this.weaknesses = [];
this.startingOrganisms = startingOrganisms;
this.addOrganisms(this.startingOrganisms);
this.generationTime = 1
}
// Begins Running the simulation
run() {
let e = this;
let generation = 1;
setInterval(() => {
e.replaceOrganism();
console.log(`Generation: ${generation}`);
console.log(`Average Weaknesses is now: ${e.computeAverageWeakness()}`);
if(generation % 100 === 0) {
console.log(`Population: ${e.weaknesses}`);
}
generation++;
}, e.generationTime);
}
// Adds a list of organisms with random fitnesses
addOrganisms(num) {
while(num > 0) {
let newOrganism = new Organism(randomValue(256), randomValue(256), randomValue(256));
this.organisms.push(newOrganism);
this.weaknesses.push(this.calculateWeakness(newOrganism));
num -= 1;
}
}
calculateWeakness(organism) {
return (Math.abs(this.r - organism.r) + Math.abs(this.g - organism.g) + Math.abs(this.b - organism.b));
}
replaceOrganism() {
let e = this;
// 1) Select a Random organism to reproduce
let randomIndex = randomValue(this.organisms.length)
let parentOrganism = this.organisms[randomIndex];
let newOrganism = parentOrganism.reproduce();
// 2) Use intervals to weight individuals by weakness
let intervals = createIntervals(this.weaknesses);
let intervalRange = intervals[intervals.length - 1][1]; //Sum of all weaknesses
let randomOrganismToReplace = randomValue(intervalRange);
// 3) Remove a random individual, weighted by weakness
intervals.forEach((interval, index) => {
if(isWithinInterval(interval, randomOrganismToReplace)) {
e.organisms[index] = newOrganism;
e.weaknesses[index] = e.calculateWeakness(newOrganism);
}
});
}
// Compute the average weakness of the population
computeAverageWeakness() {
return this.weaknesses.reduce((sum, current) => sum + current)/ (this.weaknesses.length);
}
}
// Helper function to detect if number falls within a range
function isWithinInterval(interval, num) {
return interval[0] <= num && num < interval[1];
}
function createIntervals(arr) {
let runningTotal = 0;
let result = arr.map(int => {
let newTotal = runningTotal + int;
let result = [runningTotal, newTotal]
runningTotal = newTotal;
return result;
});
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment