public double eatValue(Protozoa zoa) { double meat = zoa.radius * zoa.digestibilityMeat; double herb = zoa.radius * zoa.digestibilityHerb; double water = zoa.radius * zoa.digestibilityWater; return(meat * digestibilityMeat + herb * digestibilityHerb + water * digestibilityWater); }
public void addZoa(Protozoa zoa) { zoa.id = increment++; lock (Protozoas) Protozoas.Add(zoa); if (OnNewZoa != null) { OnNewZoa(this, zoa); } }
public Protozoa gemmate(Random rnd) { double mutateRate = 0.1; if (radius < genome.constructor.radius * (1 + mutateRate) * 3) { return(null); } moveVector.setLength(0); Genome childGenome = new Genome(rnd, genome, mutateRate, mutateRate); double dx = rnd.Next(-(int)radius, (int)radius) + radius * Math.Sign(rnd.Next(-1, 0)); double dy = rnd.Next(-(int)radius, (int)radius) + radius * Math.Sign(rnd.Next(-1, 0)); Protozoa newZoa = new Protozoa(x + dx, y + dy, childGenome, 0); radius -= newZoa.radius; return(newZoa); }
public Protozoa love(Random rnd, Protozoa zz) { double mutateRate = 0.1; Genome childGenome = new Genome(rnd, genome, zz.genome, radius, zz.radius, mutateRate, mutateRate); if (radius < childGenome.constructor.radius / 2 || zz.radius < childGenome.constructor.radius / 2) { return(null); } moveVector.setLength(0); double dx = rnd.Next(-(int)radius, (int)radius) + radius * Math.Sign(rnd.Next(-1, 0)); double dy = rnd.Next(-(int)radius, (int)radius) + radius * Math.Sign(rnd.Next(-1, 0)); Protozoa newZoa = new Protozoa(x + dx, y + dy, childGenome, 0); radius -= newZoa.radius / 2; zz.radius -= newZoa.radius / 2; return(newZoa); }
public static Protozoa generateRandomZoa(Random rnd, int left, int top, int right, int bottom) { double x = rnd.Next(left, right); double y = rnd.Next(top, bottom); double radius = rnd.Next(7, 15); double accPower = rnd.Next(30000, 50000); double rotationPower = rnd.NextDouble() * 1.3; double color = rnd.NextDouble() * ZoaHSL.scale * 2 - ZoaHSL.scale; double viewDepth = rnd.Next(15, 50); double viewWidth = rnd.Next(20, 40); double moveAngle = (double)rnd.Next(-314, 314) / 100; double moveLength = rnd.Next(3, 8); double digestibilityMeat = rnd.NextDouble(); double digestibilityHerb = rnd.NextDouble(); double digestibilityWater = rnd.NextDouble(); Vector moveVector = new Vector(moveAngle, moveLength); Protozoa zoa = new Protozoa(rnd, x, y, new Constructor(radius, color, viewDepth, viewWidth, accPower, rotationPower, digestibilityMeat, digestibilityHerb, digestibilityWater)); zoa.moveVector = moveVector; return(zoa); }
public void ControlTick(double time) { notContolledTime = 0; lock (Protozoas) { List <Protozoa> newZoas = new List <Protozoa>(); //Parallel.ForEach(Protozoas, (zoa) => foreach (Protozoa zoa in Protozoas) { //check cooldown zoa.cooldown -= time; //eat under-body food if (zoa.cooldown <= 0) { lock (food) { foreach (Food f in food) { double dist = Vector.GetLength(zoa.centerP, f.point); if (dist < zoa.radius) { food.Remove(f); zoa.radius += foodWeight * zoa.eatValue(f); zoa.makeBusy(eatCooldown); break; } } } } //change acceleration due to food distribution double meatLeft = 0, meatRight = 0, herbLeft = 0, herbRight = 0, waterLeft = 0, waterRight = 0; lock (food) foreach (Food f in food) { double dist = Vector.GetLength(zoa.centerP, f.point); if (dist > zoa.viewDepth * zoa.radius) { continue; } if (pointInTriangle(f.point, zoa.leftP, zoa.farCenterP, zoa.centerP)) { meatLeft += f.meat / (dist * dist); herbLeft += f.herb / (dist * dist); waterLeft += f.water / (dist * dist); } else if (pointInTriangle(f.point, zoa.rightP, zoa.farCenterP, zoa.centerP)) { meatLeft += f.meat / (dist * dist); herbLeft += f.herb / (dist * dist); waterLeft += f.water / (dist * dist); } } double zoasLeft = 0, zoasRight = 0, colorLeft = 0, colorRight = 0; foreach (Protozoa z in Protozoas) { if (z.id != zoa.id) { if (pointInTriangle(z.centerP, zoa.leftP, zoa.farCenterP, zoa.centerP)) { double dist = Vector.GetLength(zoa.centerP, z.centerP); double coeff = 1 / (dist * dist); if (dist == 0) { coeff = 0; } zoasLeft += coeff * z.radius; colorLeft = (colorLeft + coeff * ((zoa.color - z.color) / ZoaHSL.scale) * z.radius) / 2; } else if (pointInTriangle(z.centerP, zoa.rightP, zoa.farCenterP, zoa.centerP)) { double dist = Vector.GetLength(zoa.centerP, z.centerP); double coeff = 1 / (dist * dist); if (dist == 0) { coeff = 0; } zoasRight += coeff * z.radius; colorRight = (colorRight + coeff * ((zoa.color - z.color) / ZoaHSL.scale) * z.radius) / 2; } } } double sum = meatLeft + meatRight + herbLeft + herbRight + waterLeft + waterRight; double sumLeft = meatLeft + herbLeft + waterLeft; double sumRight = meatRight + herbRight + waterRight; double sumMeat = meatLeft + meatRight; double sumHerb = herbLeft + herbRight; double sumWater = waterLeft + waterRight; double noFood = 0; if (sum == 0) { sum = noFood = 1; } if (sumMeat == 0) { sumMeat = 1; } if (sumHerb == 0) { sumHerb = 1; } if (sumWater == 0) { sumWater = 1; } zoa.moveControl(new double[] { sumLeft / sum, sumRight / sum, meatLeft / sumMeat, meatRight / sumMeat, herbLeft / sumHerb, herbRight / sumHerb, waterLeft / sumWater, waterRight / sumWater, noFood, colorLeft, colorRight }, time); //now collision between zoas if (zoa.cooldown <= 0) { foreach (Protozoa zz in Protozoas) { if (zz.radius != 0 && zoa.radius > zz.radius && zz.id != zoa.id) { double dist = Vector.GetLength(zoa.centerP, zz.centerP); if (dist < zz.radius + zoa.radius) { double[] input = new double[] { Math.Abs(zoa.color - zz.color) / ZoaHSL.scale, optimalRadius / zoa.radius - 1 }; double[] res = zoa.interactControl(input); double toEat = res[0]; double toLove = res[1]; if (toLove <= 0 && toEat <= 0) { continue; } if (toLove > toEat) { Protozoa child = zoa.love(rnd, zz); if (child != null) { newZoas.Add(child); child.makeBusy(interactCooldown); zoa.makeBusy(interactCooldown); } } else { zoa.radius += zoa.eatValue(zz); zz.radius = 0; zoa.makeBusy(eatCooldown); } } } } } //try to gemmate the Zoa if (gemmating && zoa.cooldown <= 0) { Protozoa newZoa = zoa.gemmate(rnd); if (newZoa != null) { newZoas.Add(newZoa); zoa.makeBusy(interactCooldown); } } }//; foreach (Protozoa zoa in newZoas) { addZoa(zoa); } } }
public void addRandomZoaInArea(Random rnd, int left, int top, int right, int bottom) { Protozoa zoa = World.generateRandomZoa(rnd, left, top, right, bottom); world.addZoa(zoa); }