From 90e3290c3eb5bd83e2f8b903e8ea2add78c855c2 Mon Sep 17 00:00:00 2001 From: "Paolo \"Nusco\" Perrotta" Date: Sun, 22 Feb 2015 14:20:31 +0100 Subject: [PATCH] Move creation of DNA to Gene Pool This is long overdue, and it fixes all the problems with the damn DNA serial ids and the horrible mechanics of their creation and updating. --- .../org/nusco/narjillos/creature/Egg.java | 3 +- .../nusco/narjillos/creature/Narjillo.java | 12 --- .../nusco/narjillos/ecosystem/Ecosystem.java | 36 +++++---- .../narjillos/experiment/Experiment.java | 15 +--- .../org/nusco/narjillos/genomics/DNA.java | 70 +++--------------- .../nusco/narjillos/genomics/DNAObserver.java | 21 ------ .../nusco/narjillos/genomics/GenePool.java | 73 ++++++++++++------- .../narjillos/serializer/DNAAdapter.java | 2 +- .../DeterministicExperimentTest.java | 9 +-- .../nusco/narjillos/NarjilloTickingTest.java | 7 +- .../org/nusco/narjillos/creature/EggTest.java | 2 +- .../creature/NarjilloEnergyLossTest.java | 6 +- .../narjillos/ecosystem/EcosystemTest.java | 2 +- .../narjillos/genomics/DNAAnalysisTest.java | 8 +- .../narjillos/genomics/DNADocumentTest.java | 2 +- .../narjillos/genomics/DNAIteratorTest.java | 8 +- .../narjillos/genomics/DNAObserverTest.java | 60 --------------- .../org/nusco/narjillos/genomics/DNATest.java | 30 +++----- .../narjillos/genomics/GenePoolTest.java | 53 ++++++-------- .../serializer/JSONDNASerializationTest.java | 2 +- .../JSONEcosystemSerializationTest.java | 4 +- .../JSONGenePoolSerializationTest.java | 25 ++----- .../JSONThingSerializationTest.java | 4 +- .../narjillos/utilities/LocatorTest.java | 2 +- 24 files changed, 151 insertions(+), 305 deletions(-) delete mode 100644 narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNAObserver.java delete mode 100644 narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAObserverTest.java diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/creature/Egg.java b/narjillos-core/src/main/java/org/nusco/narjillos/creature/Egg.java index d9c3c7fb..0b1cac6f 100644 --- a/narjillos-core/src/main/java/org/nusco/narjillos/creature/Egg.java +++ b/narjillos-core/src/main/java/org/nusco/narjillos/creature/Egg.java @@ -13,7 +13,8 @@ public class Egg implements Thing { public static final double RADIUS = 25; - + public static final int INCUBATION_TIME = 500; + private final DNA dna; private int age = 0; private Vector position; diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/creature/Narjillo.java b/narjillos-core/src/main/java/org/nusco/narjillos/creature/Narjillo.java index a3318927..dd64064f 100644 --- a/narjillos-core/src/main/java/org/nusco/narjillos/creature/Narjillo.java +++ b/narjillos-core/src/main/java/org/nusco/narjillos/creature/Narjillo.java @@ -11,7 +11,6 @@ import org.nusco.narjillos.shared.things.Energy; import org.nusco.narjillos.shared.things.FoodPiece; import org.nusco.narjillos.shared.things.Thing; -import org.nusco.narjillos.shared.utilities.RanGen; /** * A fully-formed, autonomous creature. @@ -19,7 +18,6 @@ public class Narjillo implements Thing { static final double MAX_LIFESPAN = 30_000; - private static final int INCUBATION_TIME = 500; private final Body body; private final DNA dna; @@ -73,16 +71,6 @@ public void feedOn(FoodPiece thing) { thing.setEater(this); } - public Egg layEgg(Vector position, RanGen ranGen) { - double percentEnergyToChildren = body.getPercentEnergyToChildren(); - double childEnergy = energy.chunkOff(percentEnergyToChildren); - if (childEnergy == 0) - return null; - - DNA childDNA = getDNA().copyWithMutations(ranGen); - return new Egg(childDNA, getPosition(), childEnergy, INCUBATION_TIME); - } - @Override public String getLabel() { return "narjillo"; diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/ecosystem/Ecosystem.java b/narjillos-core/src/main/java/org/nusco/narjillos/ecosystem/Ecosystem.java index fbcc0b8f..03eafe3f 100644 --- a/narjillos-core/src/main/java/org/nusco/narjillos/ecosystem/Ecosystem.java +++ b/narjillos-core/src/main/java/org/nusco/narjillos/ecosystem/Ecosystem.java @@ -17,6 +17,7 @@ import org.nusco.narjillos.creature.Egg; import org.nusco.narjillos.creature.Narjillo; import org.nusco.narjillos.genomics.DNA; +import org.nusco.narjillos.genomics.GenePool; import org.nusco.narjillos.shared.physics.Segment; import org.nusco.narjillos.shared.physics.Vector; import org.nusco.narjillos.shared.things.FoodPiece; @@ -75,15 +76,15 @@ public Vector findClosestFoodPiece(Thing thing) { return target.getPosition(); } - public void tick(RanGen ranGen) { + public void tick(GenePool genePool, RanGen ranGen) { for (Thing thing : new LinkedList<>(things.getAll("egg"))) tickEgg((Egg) thing); for (Narjillo narjillo : new LinkedList<>(narjillos)) if (narjillo.isDead()) - removeNarjillo(narjillo); + removeNarjillo(narjillo, genePool); - tickNarjillos(ranGen); + tickNarjillos(genePool, ranGen); if (shouldSpawnFood(ranGen)) { spawnFood(randomPosition(getSize(), ranGen)); @@ -153,7 +154,7 @@ private void tickEgg(Egg egg) { remove(egg); } - private synchronized void tickNarjillos(RanGen ranGen) { + private synchronized void tickNarjillos(GenePool genePool, RanGen ranGen) { if (executorService.isShutdown()) return; // we're leaving, apparently @@ -165,7 +166,7 @@ private synchronized void tickNarjillos(RanGen ranGen) { for (Entry> entry : narjillosToCollidedFood.entrySet()) { Narjillo narjillo = entry.getKey(); Set collidedFood = entry.getValue(); - consume(narjillo, collidedFood, ranGen); + consume(narjillo, collidedFood, genePool, ranGen); } } @@ -225,12 +226,12 @@ private void updateTargets(Thing food) { } } - private void consume(Narjillo narjillo, Set foodPieces, RanGen ranGen) { + private void consume(Narjillo narjillo, Set foodPieces, GenePool genePool, RanGen ranGen) { for (Thing foodPiece : foodPieces) - consumeFood(narjillo, (FoodPiece) foodPiece, ranGen); + consumeFood(narjillo, (FoodPiece) foodPiece, genePool, ranGen); } - private void consumeFood(Narjillo narjillo, FoodPiece foodPiece, RanGen ranGen) { + private void consumeFood(Narjillo narjillo, FoodPiece foodPiece, GenePool genePool, RanGen ranGen) { if (!things.contains(foodPiece)) return; // race condition: already consumed @@ -238,7 +239,7 @@ private void consumeFood(Narjillo narjillo, FoodPiece foodPiece, RanGen ranGen) narjillo.feedOn(foodPiece); - layEgg(narjillo, ranGen); + layEgg(narjillo, genePool, ranGen); updateTargets(foodPiece); } @@ -247,16 +248,21 @@ private void remove(Thing thing) { things.remove(thing); } - private void removeNarjillo(Narjillo narjillo) { + private void removeNarjillo(Narjillo narjillo, GenePool genePool) { notifyThingRemoved(narjillo); narjillos.remove(narjillo); - narjillo.getDNA().destroy(); + genePool.remove(narjillo.getDNA()); } - private void layEgg(Narjillo narjillo, RanGen ranGen) { - Egg egg = narjillo.layEgg(narjillo.getNeckLocation(), ranGen); - if (egg == null) // refused to lay egg - return; + private void layEgg(Narjillo narjillo, GenePool genePool, RanGen ranGen) { + double percentEnergyToChildren = narjillo.getBody().getPercentEnergyToChildren(); + double childEnergy = narjillo.getEnergy().chunkOff(percentEnergyToChildren); + if (childEnergy == 0) + return; // refused to lay egg + DNA childDNA = genePool.mutateDNA(narjillo.getDNA(), ranGen); + + Vector position = narjillo.getNeckLocation(); + Egg egg = new Egg(childDNA, position, childEnergy, Egg.INCUBATION_TIME); insert(egg); } diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/experiment/Experiment.java b/narjillos-core/src/main/java/org/nusco/narjillos/experiment/Experiment.java index 446baa8f..3da218fd 100644 --- a/narjillos-core/src/main/java/org/nusco/narjillos/experiment/Experiment.java +++ b/narjillos-core/src/main/java/org/nusco/narjillos/experiment/Experiment.java @@ -2,7 +2,6 @@ import org.nusco.narjillos.creature.body.physics.Viscosity; import org.nusco.narjillos.ecosystem.Ecosystem; -import org.nusco.narjillos.genomics.DNA; import org.nusco.narjillos.genomics.GenePool; import org.nusco.narjillos.shared.physics.Vector; import org.nusco.narjillos.shared.utilities.Chronometer; @@ -47,7 +46,6 @@ private void initializeGenePool(boolean trackGenePool) { return; genePool.enableTracking(); - DNA.setObserver(genePool); } public final void timeStamp() { @@ -64,10 +62,10 @@ private void populate(Ecosystem ecosystem, String dna) { if (dna == null) { for (int i = 0; i < INITIAL_NUMBER_OF_NARJILLOS; i++) - ecosystem.spawnEgg(DNA.random(ranGen), randomPosition(ecosystem.getSize()), ranGen); + ecosystem.spawnEgg(getGenePool().createRandomDNA(ranGen), randomPosition(ecosystem.getSize()), ranGen); } else { for (int i = 0; i < INITIAL_NUMBER_OF_NARJILLOS; i++) - ecosystem.spawnEgg(new DNA(dna), randomPosition(ecosystem.getSize()), ranGen); + ecosystem.spawnEgg(getGenePool().createDNA(dna), randomPosition(ecosystem.getSize()), ranGen); } } @@ -79,7 +77,7 @@ public boolean tick() { if (ticksChronometer.getTotalTicks() % 1000 == 0) executePeriodicOperations(); - getEcosystem().tick(ranGen); + getEcosystem().tick(genePool, ranGen); ticksChronometer.tick(); return areThereSurvivors(); } @@ -127,13 +125,6 @@ public GenePool getGenePool() { return genePool; } - // For serialization only. Don't call this in other situations, if you don't - // want to make the experiment non-deterministic. - public void setGenePool(GenePool genePool) { - this.genePool = genePool; - DNA.setObserver(genePool); - } - @Override public String toString() { return "Experiment " + getId(); diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNA.java b/narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNA.java index bcdda209..30271f59 100644 --- a/narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNA.java +++ b/narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNA.java @@ -12,44 +12,18 @@ public class DNA { public static final double MUTATION_RATE = 0.055; private static final int GENE_MUTATION_RANGE = 15; - private static DNAObserver observer = DNAObserver.NULL; - - // TODO: This static makes testing difficult. Find another way. - private static long serial = 0; - - // for testing - public static long getSerial() { - return serial; - } - - public static void setSerial(long value) { - serial = value; - } - - private long id; + private final long id; private final Integer[] genes; - public DNA(String dnaDocument) { - this(new DNADocument(dnaDocument).toGenes()); - } - - // Only use for deserialization. - public DNA(String dnaDocument, long id) { + public DNA(long id, String dnaDocument) { + this.id = id; this.genes = clipGenes(new DNADocument(dnaDocument).toGenes()); - setId(id); - } - - private DNA(Integer... genes) { - this.genes = clipGenes(genes); - setId(serial + 1); - DNA.observer.created(this, null); } - private DNA(DNA parent, Integer... genes) { + public DNA(long id, Integer[] genes) { + this.id = id; this.genes = clipGenes(genes); - setId(serial + 1); - DNA.observer.created(this, parent); } public long getId() { @@ -60,11 +34,7 @@ public Integer[] getGenes() { return genes; } - public void destroy() { - DNA.observer.removed(this); - } - - public DNA copyWithMutations(RanGen ranGen) { + public DNA copyWithMutations(long id, RanGen ranGen) { List resultChromosomes = new LinkedList<>(); DNAIterator iterator = new DNAIterator(this); @@ -79,12 +49,12 @@ public DNA copyWithMutations(RanGen ranGen) { } Integer[] resultGenes = flatten(resultChromosomes); - return new DNA(this, resultGenes); + return new DNA(id, resultGenes); } - public static DNA random(RanGen ranGen) { + public static DNA random(long id, RanGen ranGen) { int size = Chromosome.SIZE * (Math.abs(ranGen.nextInt()) % 10 + 2); - return random(size, ranGen); + return random(id, ranGen, size); } // From: http://en.wikipedia.org/wiki/Levenshtein_distance, @@ -129,10 +99,6 @@ public int getLevenshteinDistanceFrom(DNA other) { return v1[otherGenes.length]; } - public static void setObserver(DNAObserver dnaObserver) { - DNA.observer = dnaObserver; - } - @Override public int hashCode() { return (int) getId(); @@ -153,20 +119,6 @@ private Integer[] clipGenes(Integer[] genes) { return (genes.length > 0) ? clipToByteSize(genes) : new Integer[] { 0 }; } - private void setId(long id) { - this.id = id; - // This complicated mechanism guarantees that even - // after deserializing DNA, the serial will still - // contain the highest id in the system. (But - // if you generate DNA and *then* deserialize - // other DNA, then you might have duplicated - // DNA ids in the system. I assume that you - // will only deserialize DNA before ever creating - // it. - if (id > serial) - serial = id; - } - private Integer[] copyWithMutations(Chromosome chromosome, RanGen ranGen) { Integer[] result = new Integer[Chromosome.SIZE]; for (int i = 0; i < result.length; i++) @@ -210,9 +162,9 @@ private int clipToByteSize(int number) { return Math.max(0, Math.min(255, number)); } - private static DNA random(int size, RanGen ranGen) { + private static DNA random(long id, RanGen ranGen, int size) { Integer[] genes = randomGenes(size, ranGen); - return new DNA(genes); + return new DNA(id, genes); } private static Integer[] randomGenes(int size, RanGen ranGen) { diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNAObserver.java b/narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNAObserver.java deleted file mode 100644 index 1e7e2168..00000000 --- a/narjillos-core/src/main/java/org/nusco/narjillos/genomics/DNAObserver.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.nusco.narjillos.genomics; - -/** - * Observes DNA getting created and destroyed. - */ -public interface DNAObserver { - - public void created(DNA newDna, DNA parent); - public void removed(DNA dna); - - DNAObserver NULL = new DNAObserver() { - - @Override - public void created(DNA newDNA, DNA parent) { - } - - @Override - public void removed(DNA dna) { - } - }; -} diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/genomics/GenePool.java b/narjillos-core/src/main/java/org/nusco/narjillos/genomics/GenePool.java index b30a3b58..ccf2bf57 100644 --- a/narjillos-core/src/main/java/org/nusco/narjillos/genomics/GenePool.java +++ b/narjillos-core/src/main/java/org/nusco/narjillos/genomics/GenePool.java @@ -6,15 +6,18 @@ import java.util.List; import java.util.Map; +import org.nusco.narjillos.shared.utilities.RanGen; + /** * A pool of DNA strands. */ -public class GenePool implements DNAObserver { +public class GenePool { - private Map dnaById = new LinkedHashMap<>(); - private List currentPool = new LinkedList<>(); - private Map childrenToParents = new LinkedHashMap<>(); + private final Map dnaById = new LinkedHashMap<>(); + private final List currentPool = new LinkedList<>(); + private final Map childrenToParents = new LinkedHashMap<>(); + private long dnaSerial = 0; private boolean isTracking = false; public void enableTracking() { @@ -25,27 +28,6 @@ public boolean isTracking() { return isTracking; } - @Override - public void created(DNA newDNA, DNA parent) { - if (!isTracking()) - return; - - dnaById.put(newDNA.getId(), newDNA); - currentPool.add(newDNA.getId()); - if (parent == null) - childrenToParents.put(newDNA.getId(), 0l); - else - childrenToParents.put(newDNA.getId(), parent.getId()); - } - - @Override - public void removed(DNA dna) { - if (!isTracking()) - return; - - currentPool.remove(dna.getId()); - } - public List getAncestry(DNA dna) { List result = new LinkedList<>(); @@ -81,6 +63,47 @@ public int getHistoricalPoolSize() { return dnaById.size(); } + public DNA createDNA(String dna) { + DNA result = new DNA(nextId(), dna); + add(result, null); + return result; + } + + public DNA createRandomDNA(RanGen ranGen) { + DNA result = DNA.random(nextId(), ranGen); + add(result, null); + return result; + } + + public DNA mutateDNA(DNA parent, RanGen ranGen) { + DNA result = parent.copyWithMutations(nextId(), ranGen); + add(result, parent); + return result; + } + + public void remove(DNA dna) { + if (!isTracking()) + return; + + currentPool.remove(dna.getId()); + } + + private long nextId() { + return ++dnaSerial; + } + + private void add(DNA dna, DNA parent) { + if (!isTracking()) + return; + + dnaById.put(dna.getId(), dna); + currentPool.add(dna.getId()); + if (parent == null) + childrenToParents.put(dna.getId(), 0l); + else + childrenToParents.put(dna.getId(), parent.getId()); + } + private int totalLevenshteinDistanceFromTheRestOfThePool(DNA dna) { int result = 0; for (Long otherDNAId : currentPool) { diff --git a/narjillos-core/src/main/java/org/nusco/narjillos/serializer/DNAAdapter.java b/narjillos-core/src/main/java/org/nusco/narjillos/serializer/DNAAdapter.java index 002cf1ef..fad96796 100644 --- a/narjillos-core/src/main/java/org/nusco/narjillos/serializer/DNAAdapter.java +++ b/narjillos-core/src/main/java/org/nusco/narjillos/serializer/DNAAdapter.java @@ -27,6 +27,6 @@ public DNA deserialize(JsonElement json, Type type, JsonDeserializationContext c JsonObject jsonObject = json.getAsJsonObject(); String genes = jsonObject.get("genes").getAsString(); long id = jsonObject.get("id").getAsLong(); - return new DNA(genes, id); + return new DNA(id, genes); } } diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/DeterministicExperimentTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/DeterministicExperimentTest.java index a3d48d12..efe27529 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/DeterministicExperimentTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/DeterministicExperimentTest.java @@ -4,7 +4,6 @@ import org.junit.Test; import org.nusco.narjillos.experiment.Experiment; -import org.nusco.narjillos.genomics.DNA; import org.nusco.narjillos.serializer.JSON; /** @@ -42,14 +41,10 @@ public static void runTest(int cycles) { Experiment experiment2 = JSON.fromJson(json, Experiment.class); // Now we have two experiments. Keep ticking both for a few more cycles. - // Reset the DNA serial in between, so that we get the same DNA ids for - // both experiments. - long lastDNAId = DNA.getSerial(); - for (int i = 0; i < halfCycles; i++) + for (int i = 0; i < halfCycles; i++) { experiment1.tick(); - DNA.setSerial(lastDNAId); - for (int i = 0; i < halfCycles; i++) experiment2.tick(); + } // Reset the running time (which is generally different between // experiments, and that's OK). diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/NarjilloTickingTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/NarjilloTickingTest.java index ff9b891c..8ed87cd2 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/NarjilloTickingTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/NarjilloTickingTest.java @@ -10,6 +10,7 @@ import org.nusco.narjillos.creature.body.Organ; import org.nusco.narjillos.embryogenesis.Embryo; import org.nusco.narjillos.genomics.DNA; +import org.nusco.narjillos.genomics.GenePool; import org.nusco.narjillos.serializer.JSON; import org.nusco.narjillos.shared.physics.Vector; @@ -59,9 +60,8 @@ public class NarjilloTickingTest { @Test public void narjillosTickingIsDeterministic() { - // Create DNA with an id of 1. - DNA.setSerial(0); - DNA sampleDNA = new DNA(SAMPLE_DNA_DOCUMENT); + GenePool genePool = new GenePool(); + DNA sampleDNA = genePool.createDNA(SAMPLE_DNA_DOCUMENT); // Create the sample narjillo. Narjillo narjillo = new Narjillo(sampleDNA, new Embryo(sampleDNA).develop(), Vector.cartesian(100, 200), 10_000); @@ -77,7 +77,6 @@ public void narjillosTickingIsDeterministic() { // updated at the end of the tick, even when no readers are around. narjillo.tick(); - System.out.println(JSON.toJson(narjillo, Narjillo.class)); // Check that the narjillo's state is exactly what we expect. We use // JSON to make the comparison easier, and also to make sure that we're // not missing anything in the narjillo's state. diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/creature/EggTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/creature/EggTest.java index 1a6aa886..ac1b17b3 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/creature/EggTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/creature/EggTest.java @@ -12,7 +12,7 @@ public class EggTest { - DNA dna = new DNA("{1_2_3}"); + DNA dna = new DNA(1, "{1_2_3}"); Egg egg = new Egg(dna, Vector.cartesian(10, 20), 100, 20); @Test diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/creature/NarjilloEnergyLossTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/creature/NarjilloEnergyLossTest.java index 4485ab17..e95d9c9f 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/creature/NarjilloEnergyLossTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/creature/NarjilloEnergyLossTest.java @@ -18,9 +18,9 @@ public class NarjilloEnergyLossTest { @Before public void initializeNarjillos() { - smallerNarjillo = new Narjillo(new DNA("{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}"), new Body(new Head(10, 10, new ColorByte(10), 1, 0.5)), Vector.ZERO, 10000); + smallerNarjillo = new Narjillo(new DNA(1, "{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}"), new Body(new Head(10, 10, new ColorByte(10), 1, 0.5)), Vector.ZERO, 10000); - DNA dna = new DNA("{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}"); + DNA dna = new DNA(2, "{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}{0_255_255_255_255_255_255_255}"); biggerNarjillo = new Narjillo(dna, new Embryo(dna).develop(), Vector.ZERO, 10000); } @@ -34,7 +34,7 @@ public void itLosesEnergyFasterWhileMovingIfItIsBigger() { @Test public void itsEnergyNaturallyDecreasesWithOldAgeEvenWhenItDoesntMove() { - DNA dna = new DNA("{1_1_1_1_1_1_1_1"); + DNA dna = new DNA(1, "{1_1_1_1_1_1_1_1"); Narjillo narjilloThatCannotMove = new Narjillo(dna, new Embryo(dna).develop(), Vector.ZERO, 10000); for (int i = 0; i < Narjillo.MAX_LIFESPAN + 1; i++) diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/ecosystem/EcosystemTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/ecosystem/EcosystemTest.java index 1a0cae52..5130b4f1 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/ecosystem/EcosystemTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/ecosystem/EcosystemTest.java @@ -38,7 +38,7 @@ public void initialize() { } private Narjillo insertNarjillo(Vector position) { - DNA dna = DNA.random(ranGen); + DNA dna = DNA.random(1, ranGen); Narjillo result = new Narjillo(dna, new Embryo(dna).develop(), position, 10000); ecosystem.insertNarjillo(result); return result; diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAAnalysisTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAAnalysisTest.java index a827f9c9..85a10587 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAAnalysisTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAAnalysisTest.java @@ -8,9 +8,9 @@ public class DNAAnalysisTest { @Test public void computesTheDistanceBetweenDNAStrands() { - DNA dna1 = new DNA("001_001_001"); - DNA dna2 = new DNA("001_002_001"); - DNA dna3 = new DNA("001_002_002"); + DNA dna1 = new DNA(1, "001_001_001"); + DNA dna2 = new DNA(2, "001_002_001"); + DNA dna3 = new DNA(3, "001_002_002"); assertEquals(0, dna1.getLevenshteinDistanceFrom(dna1)); assertEquals(1, dna1.getLevenshteinDistanceFrom(dna2)); @@ -19,7 +19,7 @@ public void computesTheDistanceBetweenDNAStrands() { assertEquals(dna3.getLevenshteinDistanceFrom(dna1), dna1.getLevenshteinDistanceFrom(dna3)); - DNA dna4 = new DNA("001_002"); + DNA dna4 = new DNA(4, "001_002"); assertEquals(2, dna1.getLevenshteinDistanceFrom(dna4)); assertEquals(2, dna4.getLevenshteinDistanceFrom(dna1)); diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNADocumentTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNADocumentTest.java index 2d669ae7..a4cd9a81 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNADocumentTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNADocumentTest.java @@ -70,7 +70,7 @@ public void ignoresAnythingAfterTheGenesLine() { @Test public void convertsDNAToADocumentString() { - DNA dna = new DNA("1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_255"); + DNA dna = new DNA(1, "1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_255"); assertEquals("{001_002_003_004_005_006_007_008_009}{010_011_012_013_014_015_016_017_018}{255_000_000_000_000_000_000_000_000}", dna.toString()); } diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAIteratorTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAIteratorTest.java index deef7616..a52a724e 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAIteratorTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAIteratorTest.java @@ -11,7 +11,7 @@ public class DNAIteratorTest { public void iteratesOverChromosomes() { String genes = "{1_2_3_4_5_6_7_8_9}{10_11_12_13_14_15_16_17_18}"; - DNA dna = new DNA(genes); + DNA dna = new DNA(1, genes); DNAIterator iterator = new DNAIterator(dna); assertEquals(new Chromosome(1, 2, 3, 4, 5, 6, 7, 8, 9), iterator.nextChromosome()); @@ -23,7 +23,7 @@ public void iteratesOverChromosomes() { public void padsUnterminatedLastChromosome() { String genes = "{1_2_3_4_5_6_7_8_9}{10_11}"; - DNA dna = new DNA(genes); + DNA dna = new DNA(1, genes); DNAIterator iterator = new DNAIterator(dna); assertEquals(new Chromosome(1, 2, 3, 4, 5, 6, 7, 8, 9), iterator.nextChromosome()); @@ -35,7 +35,7 @@ public void padsUnterminatedLastChromosome() { public void padsUnterminatedSingleChromosome() { String genes = "{1_2_3}"; - DNA dna = new DNA(genes); + DNA dna = new DNA(1, genes); DNAIterator iterator = new DNAIterator(dna); assertEquals(new Chromosome(new int[]{1, 2, 3, 0, 0, 0, 0}), iterator.nextChromosome()); @@ -43,7 +43,7 @@ public void padsUnterminatedSingleChromosome() { } public void alwaysReturnsAtLeastOneChromosome() { - DNA dna = new DNA("{}"); + DNA dna = new DNA(1, "{}"); DNAIterator iterator = new DNAIterator(dna); assertEquals(new Chromosome(new int[]{0, 0, 0, 0, 0, 0, 0}), iterator.nextChromosome()); diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAObserverTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAObserverTest.java deleted file mode 100644 index a6bd5706..00000000 --- a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNAObserverTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.nusco.narjillos.genomics; - -import static org.junit.Assert.assertEquals; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.nusco.narjillos.shared.utilities.RanGen; - -public class DNAObserverTest { - - final String[] log = new String[1]; - - @Before - public void setUpObserver() { - DNA.setObserver(new DNAObserver() { - - @Override - public void created(DNA newDNA, DNA parent) { - log[0] = newDNA + "," + parent; - } - - @Override - public void removed(DNA dna) { - log[0] = "Removed: " + dna; - } - }); - } - - @After - public void tearDownObserver() { - DNA.setObserver(DNAObserver.NULL); - } - - @Test - public void observesCreationgOfNewDNA() { - DNA parentDna = new DNA("{1}"); - - String expected = parentDna.toString() + ",null"; - assertEquals(expected, log[0]); - } - - @Test - public void observesDNACopy() { - DNA parentDna = new DNA("{1}"); - DNA childDNA = parentDna.copyWithMutations(new RanGen(1234)); - - String expected = childDNA.toString() + "," + parentDna.toString(); - assertEquals(expected, log[0]); - } - - @Test - public void observesDNARemoval() { - DNA dna = new DNA("{1}"); - dna.destroy(); - - String expected = "Removed: " + dna.toString(); - assertEquals(expected, log[0]); - } -} diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNATest.java b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNATest.java index a2c9ffad..4bad4276 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNATest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/DNATest.java @@ -10,31 +10,23 @@ public class DNATest { @Test public void hasASerialId() { - DNA dna1 = new DNA("{1_2_3}"); - DNA dna2 = new DNA("{1_2_3}"); + DNA dna = new DNA(42, "{1_2_3}"); - assertEquals(dna2.getId(), dna1.getId() + 1); + assertEquals(dna.getId(), 42); } @Test public void hasAnArrayOfGenes() { - DNA dna = new DNA("{1_2_255}"); + DNA dna = new DNA(1, "{1_2_255}"); assertArrayEquals(new Integer[] {1, 2, 255}, dna.getGenes()); } @Test public void isOnlyEqualIfItHasTheSameId() { - DNA dna1 = new DNA("{1_2_3}"); - DNA dna2 = new DNA("{1_2_3}"); - - final long dna1Id = dna1.getId(); - DNA dna3 = new DNA("{4_5_6}") { - @Override - public long getId() { - return dna1Id; - } - }; + DNA dna1 = new DNA(1, "{1_2_3}"); + DNA dna2 = new DNA(2, "{1_2_3}"); + DNA dna3 = new DNA(1, "{4_5_6}"); assertFalse(dna1.equals(dna2)); assertEquals(dna3, dna1); @@ -42,28 +34,28 @@ public long getId() { @Test public void convertsToADNADocumentString() { - DNA dna = new DNA("1_2_3"); + DNA dna = new DNA(1, "1_2_3"); assertEquals("{001_002_003_000_000_000_000_000_000}", dna.toString()); } @Test public void isNeverEmpty() { - DNA dna = new DNA("{}"); + DNA dna = new DNA(1, "{}"); assertEquals("{000_000_000_000_000_000_000_000_000}", dna.toString()); } @Test public void clipsGenesToByteSizeWhenCreatedWithAnArray() { - DNA dna = new DNA("1_-1_256"); + DNA dna = new DNA(1, "1_-1_256"); assertArrayEquals(new Integer[] {1, 0, 255}, dna.getGenes()); } @Test public void clipsGenesToByteSizeWhenCreatedWithAString() { - DNA dna = new DNA("1_0_256"); + DNA dna = new DNA(1, "1_0_256"); assertArrayEquals(new Integer[] {1, 0, 255}, dna.getGenes()); } @@ -72,7 +64,7 @@ public void clipsGenesToByteSizeWhenCreatedWithAString() { public void createsDNAFromADNADocumentString() { String dnaString = "comment\n" + "1_022_255"; - DNA dna = new DNA(dnaString); + DNA dna = new DNA(1, dnaString); assertArrayEquals(new Integer[] {1, 22, 255}, dna.getGenes()); } diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/GenePoolTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/GenePoolTest.java index ca8e2759..5be91bb8 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/genomics/GenePoolTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/genomics/GenePoolTest.java @@ -5,7 +5,6 @@ import java.util.List; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.nusco.narjillos.shared.utilities.RanGen; @@ -16,36 +15,29 @@ public class GenePoolTest { GenePool genePool = new GenePool(); @Before - public void setUpObserver() { - DNA.setObserver(genePool); + public void setUpGenePool() { genePool.enableTracking(); } - @After - public void tearDownObserver() { - DNA.setObserver(DNAObserver.NULL); - } - @Test public void doesNotTrackByDefault() { GenePool disabledGenePool = new GenePool(); - DNA.setObserver(disabledGenePool); - - new DNA("{0}"); + + disabledGenePool.createDNA("{0}"); assertEquals(0, disabledGenePool.getCurrentPoolSize()); } @Test public void tracksAncestry() { - DNA parent1 = new DNA("{0}"); - parent1.copyWithMutations(ranGen); + DNA parent1 = genePool.createDNA("{0}"); + genePool.mutateDNA(parent1, ranGen); - DNA parent2 = new DNA("{0}"); - DNA child2_1 = parent2.copyWithMutations(ranGen); - parent2.copyWithMutations(ranGen); + DNA parent2 = genePool.createDNA("{0}"); + DNA child2_1 = genePool.mutateDNA(parent2, ranGen); + genePool.mutateDNA(parent2, ranGen); - DNA child2_2_1 = child2_1.copyWithMutations(ranGen); + DNA child2_2_1 = genePool.mutateDNA(child2_1, ranGen); List ancestry = genePool.getAncestry(child2_2_1); @@ -57,11 +49,11 @@ public void tracksAncestry() { @Test public void getsMostSuccessfulDNA() { - new DNA("111_111_111_222_111_000_000_000_000"); - new DNA("111_111_111_111_111_000_000_000_000"); - new DNA("111_111_111_222_222_000_000_000_000"); - new DNA("111_111_222_111_222_000_000_000_000"); - new DNA("111_222_222_222_222_000_000_000_000"); + genePool.createDNA("111_111_111_222_111_000_000_000_000"); + genePool.createDNA("111_111_111_111_111_000_000_000_000"); + genePool.createDNA("111_111_111_222_222_000_000_000_000"); + genePool.createDNA("111_111_222_111_222_000_000_000_000"); + genePool.createDNA("111_222_222_222_222_000_000_000_000"); DNA mostSuccessful = genePool.getMostSuccessfulDNA(); @@ -75,13 +67,13 @@ public void getsNullAsTheMostSuccesfulInAnEmptyPool() { @Test public void canRemoveDNA() { - new DNA("111_111_111_222_111_000_000_000_000"); - DNA thisOneWillDie = new DNA("111_111_111_111_111_000_000_000_000"); - new DNA("111_111_111_222_222_000_000_000_000"); - new DNA("111_111_222_111_222_000_000_000_000"); - new DNA("111_222_222_222_222_000_000_000_000"); + genePool.createDNA("111_111_111_222_111_000_000_000_000"); + DNA thisOneWillDie = genePool.createDNA("111_111_111_111_111_000_000_000_000"); + genePool.createDNA("111_111_111_222_222_000_000_000_000"); + genePool.createDNA("111_111_222_111_222_000_000_000_000"); + genePool.createDNA("111_222_222_222_222_000_000_000_000"); - thisOneWillDie.destroy(); + genePool.remove(thisOneWillDie); DNA mostSuccessful = genePool.getMostSuccessfulDNA(); assertEquals("{111_111_111_222_111_000_000_000_000}", mostSuccessful.toString()); @@ -89,11 +81,10 @@ public void canRemoveDNA() { @Test public void neverRemovesDNAFromHistory() { - RanGen ranGen = new RanGen(42); for (int i = 0; i < 100; i++) { - DNA dna = DNA.random(ranGen); + DNA dna = genePool.createRandomDNA(ranGen); if (i >= 50) - dna.destroy(); + genePool.remove(dna); } assertEquals(50, genePool.getCurrentPoolSize()); diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONDNASerializationTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONDNASerializationTest.java index 3aeec629..4c7d7103 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONDNASerializationTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONDNASerializationTest.java @@ -11,7 +11,7 @@ public class JSONDNASerializationTest { @Test public void serializesAndDeserializesDNA() { - DNA dna = new DNA("{001_002_003_004_005_006_007_008_009}{010_011_012_013_014_15_16_17_18}"); + DNA dna = new DNA(1, "{001_002_003_004_005_006_007_008_009}{010_011_012_013_014_15_16_17_18}"); String json = JSON.toJson(dna, DNA.class); DNA deserialized = JSON.fromJson(json, DNA.class); diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONEcosystemSerializationTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONEcosystemSerializationTest.java index 889d4735..d6e2ee38 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONEcosystemSerializationTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONEcosystemSerializationTest.java @@ -22,9 +22,9 @@ public void serializesAndDeserializesEcosystem() { Ecosystem ecosystem = new Ecosystem(123); FoodPiece food1 = ecosystem.spawnFood(Vector.cartesian(10, 10)); FoodPiece food2 = ecosystem.spawnFood(Vector.cartesian(20, 20)); - Egg egg = ecosystem.spawnEgg(new DNA("{1_2_3_4_5_6_7_8}"), Vector.cartesian(30, 30), new RanGen(0)); + Egg egg = ecosystem.spawnEgg(new DNA(1, "{1_2_3_4_5_6_7_8}"), Vector.cartesian(30, 30), new RanGen(0)); - DNA dna = DNA.random(new RanGen(100)); + DNA dna = DNA.random(1, new RanGen(100)); Narjillo narjillo = new Narjillo(dna, new Embryo(dna).develop(), Vector.cartesian(100, 101), 10000); ecosystem.insertNarjillo(narjillo); diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONGenePoolSerializationTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONGenePoolSerializationTest.java index 672f14fe..ee552307 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONGenePoolSerializationTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONGenePoolSerializationTest.java @@ -4,41 +4,30 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.junit.After; import org.junit.Test; import org.nusco.narjillos.genomics.DNA; -import org.nusco.narjillos.genomics.DNAObserver; import org.nusco.narjillos.genomics.GenePool; import org.nusco.narjillos.shared.utilities.RanGen; public class JSONGenePoolSerializationTest { GenePool genePool = new GenePool(); - - @After - public void tearDownDNAObserver() { - DNA.setObserver(DNAObserver.NULL); - } @Test public void serializesAndDeserializesGenePools() { RanGen ranGen = new RanGen(1234); - DNA.setObserver(genePool); genePool.enableTracking(); - DNA parent = DNA.random(ranGen); - DNA child1 = parent.copyWithMutations(ranGen); - DNA child2 = parent.copyWithMutations(ranGen); - parent.copyWithMutations(ranGen); + DNA parent = genePool.createRandomDNA(ranGen); + DNA child1 = genePool.mutateDNA(parent, ranGen); + DNA child2 = genePool.mutateDNA(parent, ranGen); + genePool.mutateDNA(parent, ranGen); + genePool.remove(child2); - child2.destroy(); - - child1.copyWithMutations(ranGen); - DNA child3 = child1.copyWithMutations(ranGen); + genePool.mutateDNA(child1, ranGen); + DNA child3 = genePool.mutateDNA(child1, ranGen); - DNA.setObserver(DNAObserver.NULL); - String json = JSON.toJson(genePool, GenePool.class); GenePool deserialized = JSON.fromJson(json, GenePool.class); diff --git a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONThingSerializationTest.java b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONThingSerializationTest.java index 28428a84..2ee26d50 100644 --- a/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONThingSerializationTest.java +++ b/narjillos-core/src/test/java/org/nusco/narjillos/serializer/JSONThingSerializationTest.java @@ -28,7 +28,7 @@ public void serializesAndDeserializesFoodPieces() { @Test public void serializesAndDeserializesEggs() { - DNA dna = new DNA("{1_2}"); + DNA dna = new DNA(1, "{1_2}"); Egg egg = new Egg(dna, Vector.cartesian(10, 20), 101, 10); String json = JSON.toJson(egg, Thing.class); @@ -42,7 +42,7 @@ public void serializesAndDeserializesEggs() { @Test public void serializesAndDeserializesNarjillos() { String genes = "{001_002_003_004_005_006_007_008_009}{001_002_003_004_005_006_007_008_009}{001_002_003_004_005_006_007_008_009}{001_002_003_004_005_006_007_008_009}{001_002_003_004_005_006_007_008_009}"; - DNA dna = new DNA(genes); + DNA dna = new DNA(1, genes); Narjillo narjillo = new Narjillo(dna, new Embryo(dna).develop(), Vector.cartesian(10, 20), 10000); narjillo.setTarget(Vector.cartesian(100, 200)); for (int i = 0; i < 10; i++) diff --git a/narjillos-petridish/src/test/java/org/nusco/narjillos/utilities/LocatorTest.java b/narjillos-petridish/src/test/java/org/nusco/narjillos/utilities/LocatorTest.java index ce6e1387..515c684c 100644 --- a/narjillos-petridish/src/test/java/org/nusco/narjillos/utilities/LocatorTest.java +++ b/narjillos-petridish/src/test/java/org/nusco/narjillos/utilities/LocatorTest.java @@ -25,7 +25,7 @@ public void initialize() { } private Narjillo insertNarjillo(Vector position) { - DNA dna = new DNA("{145_227_116_072_163_201_077_221_217}{060_227_157_252_209_149_056_114_167}{250_253_092_189_010_247_016_214_009}{027_039_203_179_042_042_175_110_008}"); + DNA dna = new DNA(1, "{145_227_116_072_163_201_077_221_217}{060_227_157_252_209_149_056_114_167}{250_253_092_189_010_247_016_214_009}{027_039_203_179_042_042_175_110_008}"); Narjillo result = new Narjillo(dna, new Embryo(dna).develop(), position, 10000); ecosystem.insertNarjillo(result); return result;