class Agent {
constructor(parent1, parent2) {
if (parent1 && parent2) {
this.initFromParents(parent1, parent2);
} else {
this.initWithoutParents();
}
}
initWithoutParents() {
this.x = randomUniform(0, scaleX / 2)();
this.gene = new Gene();
}
initFromParents(parent1, parent2) {
this.x = parent1.x + randomNormal(0, speed)()
if (this.x < 0) {
this.x = -this.x
} else if (this.x >= scaleX) {
this.x -= this.x - scaleX
}
this.gene = parent1.gene.recombinate(parent2.gene);
}
get fitness() {
const currentElevation = elevation(this.x)
let fractionOnes = this.gene.fractionOnes;
let fractionZeros = 1 - fractionOnes;
return currentElevation > 0 ? 1.0 + fractionOnes : 0.7 + fractionZeros;
}
inRadius(other) {
return Math.abs(this.x - other.x) < maxRadius;
}
compatible(other) {
return this.gene.compatible(other.gene)
}
createChildren(parent2) {
const children = [];
let prob = this.fitness;
while (prob > 0) {
if (random() < prob) {
children.push(new Agent(this, parent2));
}
prob -= 1;
}
return children;
}
render() {
let fill = d3.interpolateSpectral(this.gene.fractionOnes)
let stroke = d3.color(fill).darker()
return `<g><circle cx=${this.x} cy=${y(this.x)} r=20 fill="${fill}" stroke="${stroke}"/><text x=${this.x} y=${y(this.x)}>${this.gene.numOnes}</text></g>`
}
}