From ed7037f35762404dd81004ecf03335f581d00632 Mon Sep 17 00:00:00 2001 From: Tim Falken Date: Fri, 14 Jul 2017 16:40:24 +0200 Subject: [PATCH 01/50] Add extra neuron for heartbeat, add heartbeat Note: This also causes an extra unneccesary neuron to be created in the output layer, but this should be harmless. --- Brain.pde | 13 +++++++++++-- Creature.pde | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Brain.pde b/Brain.pde index 0598d20..351bf15 100644 --- a/Brain.pde +++ b/Brain.pde @@ -1,4 +1,7 @@ class Brain { + float heartbeatStrength = 10; + float heartbeatInterval = 0.1; + float timesUsed = 0; float[][] neurons; Axon[][][] axons; int BRAIN_WIDTH = 0; @@ -86,10 +89,16 @@ class Brain { public void useBrain(Creature owner){ ArrayList n = owner.n; ArrayList m = owner.m; - for(int i = 0; i < n.size(); i++){ - Node ni = n.get(i); + + for(int i = 1; i < n.size(); i++){ + Node ni = n.get(i - 1); neurons[0][i] = dist(ni.x, ni.y, ni.z, foodX, foodY, foodZ); } + + neurons[0][0] = ((sin(timesUsed) / 2) + 0.5) * heartbeatStrength; + + timesUsed += heartbeatInterval; + for(int i = 0; i < m.size(); i++){ Muscle am = m.get(i); Node ni1 = n.get(am.c1); diff --git a/Creature.pde b/Creature.pde index 8857a87..f573a7e 100644 --- a/Creature.pde +++ b/Creature.pde @@ -44,7 +44,7 @@ class Creature { } } int getBrainHeight(){ - return n.size()+m.size()+1; + return n.size()+m.size()+2; } void changeBrainStructure(int rowInsertionIndex, int rowRemovalIndex){ brain.changeBrainStructure(BRAIN_WIDTH, getBrainHeight(), rowInsertionIndex,rowRemovalIndex); From 2bada425933dee16672eae5dcf192960c91ae1f8 Mon Sep 17 00:00:00 2001 From: alamaz Date: Sat, 22 Jul 2017 10:13:30 +0200 Subject: [PATCH 02/50] Create README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..99c10a5 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# evolutionSteer +Evolution simulator of creatures learning how to steer towards food pellets better and better. + +# INSTALL + +1. **Dependencies** : +Please install Processing 2.2.1 by following the link on this website : https://processing.org/download/ + +2. **Download evolutionSteer** : +You can either download zip file or typing the following command into your terminal: `git clone https://github.com/carykh/evolutionSteer.git` + +3. **Launch evolutionSteer** : +You can then open evolutionSteer.pde and press the *RUN* button. That's it ! From 6773a88dd22284b7d367058f8cfb9f5d8258204e Mon Sep 17 00:00:00 2001 From: alamaz Date: Sat, 22 Jul 2017 10:18:57 +0200 Subject: [PATCH 03/50] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 99c10a5..819ec94 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,9 @@ You can either download zip file or typing the following command into your termi 3. **Launch evolutionSteer** : You can then open evolutionSteer.pde and press the *RUN* button. That's it ! + +# Configuration + +Most parameters are set at the beginning of the *evolutionSteer.pde* file. Noticeable parameters are: + +* *windowSizeMultiplier* : set to 1 if window is too big From 484844338b69bc32f87fb43d04dd5efdbddf4a93 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 07:33:49 +0200 Subject: [PATCH 04/50] Added radioactive mode Boosts mutation by pressing "r" --- Creature.pde | 27 ++++++++++++++++----------- evolutionSteer.pde | 16 +++++++++++++++- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Creature.pde b/Creature.pde index 8857a87..758defe 100644 --- a/Creature.pde +++ b/Creature.pde @@ -52,31 +52,36 @@ class Creature { public float sigmoid(float input){ return 1.0/(1.0+pow(2.71828182846,-input)); } - Creature modified(int id) { + Creature modified(int id, float mutationFactor) { + float modMut = mutationFactor * mutability; ArrayList newN = new ArrayList(0); ArrayList newM = new ArrayList(0); for (int i = 0; i < n.size(); i++) { - newN.add(n.get(i).modifyNode(mutability,n.size())); + newN.add(n.get(i).modifyNode(modMut,n.size())); } for (int i = 0; i < m.size(); i++) { - newM.add(m.get(i).modifyMuscle(n.size(), mutability)); + newM.add(m.get(i).modifyMuscle(n.size(), modMut)); } int[] newName = new int[2]; - newName[0] = name[0]; - newName[1] = CREATURES_PER_PATRON[name[0]]; - CREATURES_PER_PATRON[name[0]]++; + if(mutationFactor > 1){ + newName = getNewCreatureName(); + } else { + newName[0] = name[0]; + newName[1] = CREATURES_PER_PATRON[name[0]]; + CREATURES_PER_PATRON[name[0]]++; + } Creature modifiedCreature = new Creature(newName, id, - newN, newM, 0, true, creatureTimer+r()*16*mutability, min(mutability*random(0.8, 1.25), 2), brain.copyMutatedBrain(),null); - if (random(0, 1) < bigMutationChance*mutability || n.size() <= 2) { //Add a node + newN, newM, 0, true, creatureTimer+r()*16*modMut, min(mutability*random(0.8, 1.25), 2), brain.copyMutatedBrain(),null); + if (random(0, 1) < bigMutationChance*modMut || n.size() <= 2) { //Add a node modifiedCreature.addRandomNode(); } - if (random(0, 1) < bigMutationChance*mutability) { //Add a muscle + if (random(0, 1) < bigMutationChance*modMut) { //Add a muscle modifiedCreature.addRandomMuscle(-1, -1); } - if (random(0, 1) < bigMutationChance*mutability && modifiedCreature.n.size() >= 5) { //Remove a node + if (random(0, 1) < bigMutationChance*modMut && modifiedCreature.n.size() >= 5) { //Remove a node modifiedCreature.removeRandomNode(); } - if (random(0, 1) < bigMutationChance*mutability && modifiedCreature.m.size() >= 2) { //Remove a muscle + if (random(0, 1) < bigMutationChance*modMut && modifiedCreature.m.size() >= 2) { //Remove a muscle modifiedCreature.removeRandomMuscle(); } modifiedCreature.checkForOverlap(); diff --git a/evolutionSteer.pde b/evolutionSteer.pde index ea1723a..4af2767 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -102,6 +102,9 @@ int[] p = { final int BRAIN_WIDTH = 3; float STARTING_AXON_VARIABILITY = 1.0; float AXON_START_MUTABILITY = 0.0005; +boolean enableRadioactivity = false; +int radioactiveNumber = 50; +float radioactiveMutator = 5; String[] patronData; int PATRON_COUNT = 75; float TOTAL_PLEDGED = 183.39; @@ -971,6 +974,9 @@ void draw() { fill(0); //text("Survivor Bias: "+percentify(getSB(genSelected)), 437, 50); text("Curve: ±"+nf(foodAngleChange/(2*PI)*360,0,2)+" degrees", 420, 50); + if(enableRadioactivity){ + text("Radioactive mode", 460, 100); + } text("Do 1 step-by-step generation.", 770, 50); text("Do 1 quick generation.", 770, 100); text("Do 1 gen ASAP.", 770, 150); @@ -1304,7 +1310,11 @@ void draw() { Creature cj2 = c2.get(999-j2); c2.set(j2, cj.copyCreature(cj.id+1000,true,false)); //duplicate - c2.set(999-j2, cj.modified(cj2.id+1000)); //mutated offspring 1 + if(enableRadioactivity && j >= 500 - radioactiveNumber){ + c2.set(999-j2, cj.modified(cj2.id+1000, radioactiveMutator)); //radioactive offspring + } else { + c2.set(999-j2, cj.modified(cj2.id+1000, 1.0)); //mutated offspring 1 + } } for (int j = 0; j < 1000; j++) { Creature cj = c2.get(j); @@ -1445,6 +1455,10 @@ void keyPressed(){ foodAngleChange -= 5.0/360.0*(2*PI); setMenu(1); } + if(key == 'r'){ + enableRadioactivity = !enableRadioactivity; + setMenu(1); + } } void drawStats(float x, float y, float z, float size){ textAlign(RIGHT); From 9f995870c0edc0286bedcd28860e7c5c4b096a61 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 15:32:20 +0200 Subject: [PATCH 05/50] Fresh blood Create new creatures in radioactive mode --- Creature.pde | 18 ++++++++--- evolutionSteer.pde | 79 ++++++++++++++++++++++++++-------------------- 2 files changed, 57 insertions(+), 40 deletions(-) diff --git a/Creature.pde b/Creature.pde index 758defe..ce9bc7a 100644 --- a/Creature.pde +++ b/Creature.pde @@ -54,6 +54,7 @@ class Creature { } Creature modified(int id, float mutationFactor) { float modMut = mutationFactor * mutability; + if(mutationFactor > 1.0 && modMut < 1.0){ modMut = 1.5; mutability = 1.0; } ArrayList newN = new ArrayList(0); ArrayList newM = new ArrayList(0); for (int i = 0; i < n.size(); i++) { @@ -62,8 +63,15 @@ class Creature { for (int i = 0; i < m.size(); i++) { newM.add(m.get(i).modifyMuscle(n.size(), modMut)); } + + boolean bigMutAddNode = false, bigMutRemoveNode = false, bigMutAddMuscle = false, bigMutRemoveMuscle = false; + if (random(0, 1) < bigMutationChance*modMut || n.size() <= 2){ bigMutAddNode = true; } + if (random(0, 1) < bigMutationChance*modMut) { bigMutAddMuscle = true; } + if (random(0, 1) < bigMutationChance*modMut && n.size() >= 5) { bigMutRemoveNode = true; } + if (random(0, 1) < bigMutationChance*modMut && m.size() >= 2) { bigMutRemoveMuscle = true; } + int[] newName = new int[2]; - if(mutationFactor > 1){ + if(bigMutAddNode || bigMutRemoveNode || bigMutAddMuscle || bigMutRemoveMuscle){ newName = getNewCreatureName(); } else { newName[0] = name[0]; @@ -72,16 +80,16 @@ class Creature { } Creature modifiedCreature = new Creature(newName, id, newN, newM, 0, true, creatureTimer+r()*16*modMut, min(mutability*random(0.8, 1.25), 2), brain.copyMutatedBrain(),null); - if (random(0, 1) < bigMutationChance*modMut || n.size() <= 2) { //Add a node + if (bigMutAddNode) { //Add a node modifiedCreature.addRandomNode(); } - if (random(0, 1) < bigMutationChance*modMut) { //Add a muscle + if (bigMutAddMuscle) { //Add a muscle modifiedCreature.addRandomMuscle(-1, -1); } - if (random(0, 1) < bigMutationChance*modMut && modifiedCreature.n.size() >= 5) { //Remove a node + if (bigMutRemoveNode) { //Remove a node modifiedCreature.removeRandomNode(); } - if (random(0, 1) < bigMutationChance*modMut && modifiedCreature.m.size() >= 2) { //Remove a muscle + if (bigMutRemoveMuscle) { //Remove a muscle modifiedCreature.removeRandomMuscle(); } modifiedCreature.checkForOverlap(); diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 4af2767..0908c49 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -102,9 +102,12 @@ int[] p = { final int BRAIN_WIDTH = 3; float STARTING_AXON_VARIABILITY = 1.0; float AXON_START_MUTABILITY = 0.0005; + boolean enableRadioactivity = false; -int radioactiveNumber = 50; -float radioactiveMutator = 5; +int radioactiveNumber = 200; // number of highly mutated creatures +int freshBloodNumber = 0; // number of brand new creatures +float radioactiveMutator = 1.5; + String[] patronData; int PATRON_COUNT = 75; float TOTAL_PLEDGED = 183.39; @@ -1002,36 +1005,7 @@ void draw() { creatures = 0; for (int y = 0; y < 25; y++) { for (int x = 0; x < 40; x++) { - int nodeNum = int(random(4, 8)); - int muscleNum = int(random(nodeNum, nodeNum*3)); - ArrayList n = new ArrayList(nodeNum); - ArrayList m = new ArrayList(muscleNum); - for (int i = 0; i < nodeNum; i++) { - n.add(new Node(random(-1, 1), random(-1, 1), random(-1, 1), - 0, 0, 0, 0.4, random(0, 1))); //replaced all nodes' sizes with 0.4, used to be random(0.1,1), random(0,1) - } - for (int i = 0; i < muscleNum; i++) { - int tc1 = 0; - int tc2 = 0; - if (i < nodeNum-1) { - tc1 = i; - tc2 = i+1; - } else { - tc1 = int(random(0, nodeNum)); - tc2 = tc1; - while (tc2 == tc1) { - tc2 = int(random(0, nodeNum)); - } - } - float s = 0.8; - if (i >= 10) { - s *= 1.414; - } - float len = random(0.5,1.5); - m.add(new Muscle(tc1, tc2, len, random(0.015, 0.06))); - } - float heartbeat = random(40, 80); - c[y*40+x] = new Creature(null, y*40+x+1, new ArrayList(n), new ArrayList(m), 0, true, heartbeat, 1.0, null, null); + c[y*40+x] = createNewCreature(y*40+x); c[y*40+x].checkForOverlap(); c[y*40+x].checkForLoneNodes(); c[y*40+x].toStableConfiguration(); @@ -1310,8 +1284,10 @@ void draw() { Creature cj2 = c2.get(999-j2); c2.set(j2, cj.copyCreature(cj.id+1000,true,false)); //duplicate - if(enableRadioactivity && j >= 500 - radioactiveNumber){ - c2.set(999-j2, cj.modified(cj2.id+1000, radioactiveMutator)); //radioactive offspring + if(enableRadioactivity && j >= nbCreatures/2 - freshBloodNumber) { + c2.set(nbCreatures-1-j2, createNewCreature(cj2.id+nbCreatures-1)); //brand new creatures + } else if(enableRadioactivity && j >= nbCreatures/2 - radioactiveNumber - freshBloodNumber){ + c2.set(nbCreatures-1-j2, cj.modified(cj2.id+nbCreatures, radioactiveMutator)); //radioactive offspring } else { c2.set(999-j2, cj.modified(cj2.id+1000, 1.0)); //mutated offspring 1 } @@ -1623,4 +1599,37 @@ float getFitness(){ } void setFitness(int i){ c[i].d = getFitness(); -} +} + +Creature createNewCreature(int index){ + int nodeNum = int(random(4, 8)); + int muscleNum = int(random(nodeNum, nodeNum*3)); + ArrayList n = new ArrayList(nodeNum); + ArrayList m = new ArrayList(muscleNum); + for (int i = 0; i < nodeNum; i++) { + n.add(new Node(random(-1, 1), random(-1, 1), random(-1, 1), + 0, 0, 0, 0.4, random(0, 1))); //replaced all nodes' sizes with 0.4, used to be random(0.1,1), random(0,1) + } + for (int i = 0; i < muscleNum; i++) { + int tc1 = 0; + int tc2 = 0; + if (i < nodeNum-1) { + tc1 = i; + tc2 = i+1; + } else { + tc1 = int(random(0, nodeNum)); + tc2 = tc1; + while (tc2 == tc1) { + tc2 = int(random(0, nodeNum)); + } + } + float s = 0.8; + if (i >= 10) { + s *= 1.414; + } + float len = random(0.5,1.5); + m.add(new Muscle(tc1, tc2, len, random(0.015, 0.06))); + } + float heartbeat = random(40, 80); + return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 0, true, heartbeat, 1.0, null, null); +} From 890299c0e93ae1a9689dcf0200240bfff8b3df63 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 15:35:21 +0200 Subject: [PATCH 06/50] Simulation timer Easier setting for simulation timer. Bonus time when chomping. --- Creature.pde | 7 +++++-- evolutionSteer.pde | 52 +++++++++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/Creature.pde b/Creature.pde index ce9bc7a..5ebf723 100644 --- a/Creature.pde +++ b/Creature.pde @@ -284,7 +284,8 @@ class Creature { n.get(i).vy = 0; } } - void simulate() { + boolean simulate() { + boolean hasEaten = false; brain.useBrain(this); for (int i = 0; i < m.size(); i++) { m.get(i).applyForce(i, n); @@ -297,8 +298,10 @@ class Creature { float distFromFood = dist(ni.x,ni.y,ni.z,foodX,foodY,foodZ); if(distFromFood <= 0.4){ chomps++; + if (chomps < 10){ hasEaten = true; } setFoodLocation(); } } + return hasEaten; } -} +} diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 0908c49..7d1ad35 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -60,6 +60,9 @@ float camZ = 0; float camHA = 0; float camVA = -0.5; int frames = 60; +int simDuration = 5; // in seconds +int maxFrames = simDuration*frames; +int maxSimulationFrames = simDuration*frames; int menu = 0; int gen = -1; float sliderX = 1170; @@ -496,6 +499,7 @@ void mousePressed() { void openMiniSimulation() { simulationTimer = 0; + maxSimulationFrames = simDuration*frames; if (gensToDo == 0) { miniSimulation = true; int id; @@ -569,24 +573,27 @@ void mouseReleased() { setMenu(8); } else if((menu == 5 || menu == 4) && mY >= windowHeight-40){ if(mX < 90){ - for (int s = timer; s < 900; s++) { - simulateCurrentCreature(); + maxFrames = simDuration*frames; + for (int s = timer; s < maxFrames; s++) { + if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } timer = 1021; }else if(mX >= 120 && mX < 360){ speed *= 2; - if(speed == 1024) speed = 900; + if(speed == 1024) speed = simDuration*frames; if(speed >= 1800) speed = 1; }else if(mX >= windowWidth-120){ - for (int s = timer; s < 900; s++) { - simulateCurrentCreature(); + maxFrames = simDuration*frames; + for (int s = timer; s < maxFrames; s++) { + if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } timer = 0; creaturesTested++; for (int i = creaturesTested; i < 1000; i++) { setGlobalVariables(c[i]); - for (int s = 0; s < 900; s++) { - simulateCurrentCreature(); + maxFrames = simDuration*frames; + for (int s = 0; s < maxFrames; s++) { + if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } setAverages(); setFitness(i); @@ -603,11 +610,12 @@ void mouseReleased() { setMenu(1); } } -void simulateCurrentCreature(){ - currentCreature.simulate(); +boolean simulateCurrentCreature(){ + boolean hasEaten = currentCreature.simulate(); averageNodeNausea = totalNodeNausea/currentCreature.n.size(); simulationTimer++; timer++; + return hasEaten; } void drawScreenImage(int stage) { screenImage.beginDraw(); @@ -707,7 +715,7 @@ void drawpopUpImage() { popUpImage.scale(1.0/camZoom/scaleToFixBug); - if (simulationTimer < 900) { + if (simulationTimer < maxSimulationFrames) { popUpImage.background(120, 200, 255); } else { popUpImage.background(60, 100, 128); @@ -845,7 +853,7 @@ void drawStatusWindow(boolean isFirstFrame) { drawBrain(px2-130, py2, 1,5, cj); drawStats(px2+355, py2+239, 1, 0.45); - simulateCurrentCreature(); + if(simulateCurrentCreature()){ maxSimulationFrames += simDuration*frames; } int shouldBeWatching = statusWindow; if (statusWindow <= -1) { cj = creatureDatabase.get((genSelected-1)*3+statusWindow+3); @@ -1047,8 +1055,9 @@ void draw() { if (!stepbystepslow) { for (int i = 0; i < 1000; i++) { setGlobalVariables(c[i]); - for (int s = 0; s < 900; s++) { - simulateCurrentCreature(); + maxFrames = simDuration*frames; + for (int s = 0; s < maxFrames; s++) { + if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } setAverages(); setFitness(i); @@ -1057,13 +1066,14 @@ void draw() { } } if (menu == 5) { //simulate running - if (timer <= 900) { + maxFrames = simDuration*frames; + if (timer <= maxFrames) { keysToMoveCamera(); simulationImage.beginDraw(); simulationImage.background(120, 200, 255); for (int s = 0; s < speed; s++) { - if (timer < 900) { - simulateCurrentCreature(); + if (timer < simDuration*frames) { + if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } } setAverages(); @@ -1097,7 +1107,7 @@ void draw() { drawSkipButton(); drawOtherButtons(); } - if (timer == 900) { + if (timer == maxFrames) { if (speed < 30) { noStroke(); fill(0, 0, 0, 130); @@ -1110,11 +1120,11 @@ void draw() { text("Creature's "+fitnessName+":", windowWidth/2, 300); text(nf(getFitness(),0,2) + " "+fitnessUnit, windowWidth/2, 400); } else { - timer = 1020; + timer = maxFrames+(2*frames); } setFitness(creaturesTested); } - if (timer >= 1020) { + if (timer >= maxFrames+(2*frames)) { setMenu(4); creaturesTested++; if (creaturesTested == 1000) { @@ -1122,7 +1132,7 @@ void draw() { } camX = 0; } - if (timer >= 900) { + if (timer >= simDuration*frames) { timer += speed; } } @@ -1445,7 +1455,7 @@ void drawStats(float x, float y, float z, float size){ scale(size); text(toRealName(currentCreature.name), 0, 32); text("Creature ID: "+currentCreature.id, 0, 64); - text("Time: "+nf(timer/60.0,0,2)+" / 15 sec.", 0, 96); + text("Time: "+nf(float(timer)/float(frames),0,2)+" / "+simDuration+" sec.", 0, 96); text("Playback Speed: x"+max(1,speed), 0, 128); String extraWord = "used"; if(energyDirection == -1){ From 0668a8c76417bc0faf4db73797ff945f71eaced2 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 15:36:40 +0200 Subject: [PATCH 07/50] Creature number Easy change for creature number --- evolutionSteer.pde | 193 +++++++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 87 deletions(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 7d1ad35..e06d779 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -33,6 +33,11 @@ float foodZ = 0; float foodAngle = 0; int chomps = 0; +int nbCreatures = 1000; // please set even number +int gridX = 40; // X * Y must be equal to nbCreatures ! +int gridY = 25; +int thresholdName = 25; // name of species is showed over this threshold + int lastImageSaved = -1; float pressureUnit = 500.0/2.37; float energyUnit = 20; @@ -53,6 +58,7 @@ float lineY2 = 0.35; int windowWidth = 1280; int windowHeight = 720; +int gridHeightCrop = 100; int timer = 0; float camX = 0; float camY = 0; @@ -81,7 +87,7 @@ int overallTimer = 0; boolean miniSimulation = false; int creatureWatching = 0; int simulationTimer = 0; -int[] creaturesInPosition = new int[1000]; +int[] creaturesInPosition = new int[nbCreatures]; float camZoom = 0.015; float gravity = 0.006;//0.007; @@ -98,10 +104,11 @@ int speed; boolean stepbystep; boolean stepbystepslow; boolean slowDies; -int[] p = { +int[] pPercentages = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 910, 920, 930, 940, 950, 960, 970, 980, 990, 999 }; +int[] p = new int[29]; final int BRAIN_WIDTH = 3; float STARTING_AXON_VARIABILITY = 1.0; float AXON_START_MUTABILITY = 0.0005; @@ -253,8 +260,8 @@ void drawGraphImage() { noStroke(); for (int i = 1; i < 101; i++) { int c = s[i]-s[i-1]; - if (c >= 25) { - float y = ((s[i]+s[i-1])/2)/1000.0*100+573; + if (c >= thresholdName) { + float y = ((s[i]+s[i-1])/2)/float(nbCreatures)*100+573; if (i-1 == topSpeciesCounts.get(genSelected)) { stroke(0); strokeWeight(2); @@ -366,10 +373,10 @@ void drawSegBars(int x, int y, int graphWidth, int graphHeight) { for (int j = 0; j < 100; j++) { segBarImage.fill(getColor(j, false)); segBarImage.beginShape(); - segBarImage.vertex(barX1, y+speciesCounts.get(i)[j]/1000.0*graphHeight); - segBarImage.vertex(barX1, y+speciesCounts.get(i)[j+1]/1000.0*graphHeight); - segBarImage.vertex(barX2, y+speciesCounts.get(i2)[j+1]/1000.0*graphHeight); - segBarImage.vertex(barX2, y+speciesCounts.get(i2)[j]/1000.0*graphHeight); + segBarImage.vertex(barX1, y+speciesCounts.get(i)[j]/float(nbCreatures)*graphHeight); + segBarImage.vertex(barX1, y+speciesCounts.get(i)[j+1]/float(nbCreatures)*graphHeight); + segBarImage.vertex(barX2, y+speciesCounts.get(i2)[j+1]/float(nbCreatures)*graphHeight); + segBarImage.vertex(barX2, y+speciesCounts.get(i2)[j]/float(nbCreatures)*graphHeight); segBarImage.endShape(); } } @@ -464,7 +471,7 @@ void setAverages() { averageY = averageY/currentCreature.n.size(); averageZ = averageZ/currentCreature.n.size(); } -Creature[] c = new Creature[1000]; +Creature[] c = new Creature[nbCreatures]; ArrayList c2 = new ArrayList(); void mouseWheel(MouseEvent event) { @@ -589,7 +596,7 @@ void mouseReleased() { } timer = 0; creaturesTested++; - for (int i = creaturesTested; i < 1000; i++) { + for (int i = creaturesTested; i < nbCreatures; i++) { setGlobalVariables(c[i]); maxFrames = simDuration*frames; for (int s = 0; s < maxFrames; s++) { @@ -624,19 +631,21 @@ void drawScreenImage(int stage) { screenImage.smooth(); screenImage.background(gridBGColor); screenImage.noStroke(); - for (int j = 0; j < 1000; j++) { + for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - if (stage == 3) cj = c[cj.id-(gen*1000)-1001]; + if (stage == 3) cj = c[cj.id-(gen*nbCreatures)-(nbCreatures+1)]; int j2 = j; if (stage == 0) { - j2 = cj.id-(gen*1000)-1; + j2 = cj.id-(gen*nbCreatures)-1; creaturesInPosition[j2] = j; } - int x = j2%40; - int y = floor(j2/40); - if (stage >= 1) y++; + int x = j2%gridX; + int y = floor(j2/gridX); + float xWidth = windowWidth / (gridX+1) / 10.0; + float yHeight = (windowHeight - gridHeightCrop) / (gridY+1) / 10.0; + //if (stage >= 1) y++; screenImage.pushMatrix(); - screenImage.translate((x*3+5.5)*scaleToFixBug, (y*2.5+3)*scaleToFixBug, 0); + screenImage.translate(((x+1)*xWidth)*scaleToFixBug, ((y+0.5)*yHeight+(gridHeightCrop/20.0))*scaleToFixBug, 0); cj.drawCreature(screenImage,true); screenImage.popMatrix(); } @@ -654,24 +663,26 @@ void drawScreenImage(int stage) { if (stage == 0) { screenImage.rect(900, 664, 260, 40); screenImage.fill(0); - screenImage.text("All 1,000 creatures have been tested. Now let's sort them!", windowWidth/2-200, 690); + screenImage.text("All "+nbCreatures+" creatures have been tested. Now let's sort them!", windowWidth/2-200, 690); screenImage.text("Sort", windowWidth-250, 690); } else if (stage == 1) { screenImage.rect(900, 670, 260, 40); screenImage.fill(0); screenImage.text("Fastest creatures at the top!", windowWidth/2, 30); screenImage.text("Slowest creatures at the bottom. (Going backward = slow)", windowWidth/2-200, 700); - screenImage.text("Kill 500", windowWidth-250, 700); + screenImage.text("Kill "+(nbCreatures/2), windowWidth-250, 700); } else if (stage == 2) { screenImage.rect(1050, 670, 160, 40); screenImage.fill(0); screenImage.text("Faster creatures are more likely to survive because they can outrun their predators. Slow creatures get eaten.", windowWidth/2, 30); screenImage.text("Because of random chance, a few fast ones get eaten, while a few slow ones survive.", windowWidth/2-130, 700); screenImage.text("Reproduce", windowWidth-150, 700); - for (int j = 0; j < 1000; j++) { + for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - int x = j%40; - int y = floor(j/40)+1; + int x = j%gridX; + int y = floor(j/gridX);//+1; + float xWidth = windowWidth / (gridX+1); + float yHeight = (windowHeight - gridHeightCrop) / (gridY+1); if (cj.alive) { /*screenImage.pushMatrix(); screenImage.scale(10.0*windowSizeMultiplier/scaleToFixBug); @@ -683,17 +694,17 @@ void drawScreenImage(int stage) { } else { screenImage.fill(0); screenImage.beginShape(); - screenImage.vertex(x*30+40, y*25+17,0.01); - screenImage.vertex(x*30+70, y*25+17,0.01); - screenImage.vertex(x*30+70, y*25+42,0.01); - screenImage.vertex(x*30+40, y*25+42,0.01); + screenImage.vertex((x+1)*xWidth-15, (y+0.5)*yHeight+(gridHeightCrop/2)-12,0.01); + screenImage.vertex((x+1)*xWidth+15, (y+0.5)*yHeight+(gridHeightCrop/2)-12,0.01); + screenImage.vertex((x+1)*xWidth+15, (y+0.5)*yHeight+(gridHeightCrop/2)+12,0.01); + screenImage.vertex((x+1)*xWidth-15, (y+0.5)*yHeight+(gridHeightCrop/2)+12,0.01); screenImage.endShape(); } } } else if (stage == 3) { screenImage.rect(1050, 670, 160, 40); screenImage.fill(0); - screenImage.text("These are the 1000 creatures of generation #"+(gen+2)+".", windowWidth/2, 30); + screenImage.text("These are the "+nbCreatures+" creatures of generation #"+(gen+2)+".", windowWidth/2, 30); screenImage.text("What perils will they face? Find out next time!", windowWidth/2-130, 700); screenImage.text("Back", windowWidth-150, 700); } @@ -787,6 +798,8 @@ void drawHistogram(int x, int y, int hw, int hh) { void drawStatusWindow(boolean isFirstFrame) { int x, y, px, py; int rank = (statusWindow+1); + float xWidth = windowWidth / (gridX+1); + float yHeight = (windowHeight - gridHeightCrop) / (gridY+1); Creature cj; stroke(abs(overallTimer%30-15)*17); strokeWeight(3); @@ -794,21 +807,21 @@ void drawStatusWindow(boolean isFirstFrame) { if (statusWindow >= 0) { cj = c2.get(statusWindow); if (menu == 7) { - int id = ((cj.id-1)%1000); - x = id%40; - y = floor(id/40); + int id = ((cj.id-1)%nbCreatures); + x = id%gridX; + y = floor(id/gridX); } else { - x = statusWindow%40; - y = floor(statusWindow/40)+1; + x = statusWindow%gridX; + y = floor(statusWindow/gridX);//+1; } - px = x*30+55; - py = y*25+10; + px = floor((x+1)*xWidth); + py = floor((y+0.5)*yHeight+(gridHeightCrop/2)-19); if (px <= 1140) { px += 80; } else { px -= 80; } - rect(x*30+40, y*25+17, 30, 25); + rect((x+1)*xWidth-15, (y+0.5)*yHeight+(gridHeightCrop/2)-12, 30, 25); } else { cj = creatureDatabase.get((genSelected-1)*3+statusWindow+3); x = 760+(statusWindow+3)*160; @@ -817,7 +830,7 @@ void drawStatusWindow(boolean isFirstFrame) { py = y; rect(x, y, 140, 140); int[] ranks = { - 1000, 500, 1 + nbCreatures, nbCreatures/2, 1 }; rank = ranks[statusWindow+3]; } @@ -877,6 +890,9 @@ void setup() { for(int i = 0; i < PATRON_COUNT; i++){ CREATURES_PER_PATRON[i] = 0; } + for (int i = 1; i < 29; i++) { + p[i] = int(floor(float(pPercentages[i])*float(nbCreatures)/1000.0)); + }; frameRate(60); randomSeed(SEED); noSmooth(); @@ -892,7 +908,7 @@ void setup() { beginBar[i] = 0; } for (int i = 0; i < 101; i++) { - beginSpecies[i] = 500; + beginSpecies[i] = nbCreatures/2; } percentile.add(beginPercentile); @@ -968,7 +984,7 @@ void draw() { fill(100, 200, 100); rect(20, 250, 200, 100); fill(0); - text("Since there are no creatures yet, create 1000 creatures!", 20, 160); + text("Since there are no creatures yet, create "+nbCreatures+" creatures!", 20, 160); text("They will be randomly created, and also very simple.", 20, 200); text("CREATE", 56, 312); } else { @@ -995,7 +1011,7 @@ void draw() { text("Median "+fitnessName, 50, 160); textAlign(CENTER); textAlign(RIGHT); - text(float(round(percentile.get(min(genSelected, percentile.size()-1))[14]*1000))/1000+" "+fitnessUnit, 700, 160); + text(float(round(percentile.get(min(genSelected, percentile.size()-1))[14]*nbCreatures))/nbCreatures+" "+fitnessUnit, 700, 160); drawHistogram(760, 410, 460, 280); drawGraphImage(); //if(saveFramesPerGeneration && gen > lastImageSaved){ @@ -1011,13 +1027,13 @@ void draw() { } }else if (menu == 2) { creatures = 0; - for (int y = 0; y < 25; y++) { - for (int x = 0; x < 40; x++) { - c[y*40+x] = createNewCreature(y*40+x); - c[y*40+x].checkForOverlap(); - c[y*40+x].checkForLoneNodes(); - c[y*40+x].toStableConfiguration(); - c[y*40+x].moveToCenter(); + for (int y = 0; y < gridY; y++) { + for (int x = 0; x < gridX; x++) { + c[y*gridX+x] = createNewCreature(y*gridX+x); + c[y*gridX+x].checkForOverlap(); + c[y*gridX+x].checkForLoneNodes(); + c[y*gridX+x].toStableConfiguration(); + c[y*gridX+x].moveToCenter(); } } creatures = 0; @@ -1026,11 +1042,13 @@ void draw() { screenImage.scale(windowSizeMultiplier); screenImage.pushMatrix(); screenImage.scale(10.0/scaleToFixBug); - for (int y = 0; y < 25; y++) { - for (int x = 0; x < 40; x++) { + float xWidth = windowWidth / (gridX+1) / 10.0; + float yHeight = (windowHeight - gridHeightCrop) / (gridY+1) / 10.0; + for (int y = 0; y < gridY; y++) { + for (int x = 0; x < gridX; x++) { screenImage.pushMatrix(); - screenImage.translate((x*3+5.5)*scaleToFixBug, (y*2.5+3)*scaleToFixBug, 0); - c[y*40+x].drawCreature(screenImage,true); + screenImage.translate(((x+1)*xWidth)*scaleToFixBug, ((y+1)*yHeight+gridHeightCrop/20.0)*scaleToFixBug, 0); + c[y*gridX+x].drawCreature(screenImage,true); screenImage.popMatrix(); } } @@ -1042,7 +1060,7 @@ void draw() { screenImage.fill(0); screenImage.textAlign(CENTER); screenImage.textFont(font, 24); - screenImage.text("Here are your 1000 randomly generated creatures!!!", windowWidth/2-200, 690); + screenImage.text("Here are your "+nbCreatures+" randomly generated creatures!!!", windowWidth/2-200, 690); screenImage.text("Back", windowWidth-250, 690); screenImage.endDraw(); setMenu(3); @@ -1053,7 +1071,7 @@ void draw() { setGlobalVariables(c[creaturesTested]); setMenu(5); if (!stepbystepslow) { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < nbCreatures; i++) { setGlobalVariables(c[i]); maxFrames = simDuration*frames; for (int s = 0; s < maxFrames; s++) { @@ -1127,7 +1145,7 @@ void draw() { if (timer >= maxFrames+(2*frames)) { setMenu(4); creaturesTested++; - if (creaturesTested == 1000) { + if (creaturesTested == nbCreatures) { setMenu(6); } camX = 0; @@ -1139,7 +1157,7 @@ void draw() { if (menu == 6) { //sort c2 = new ArrayList(0); - for(int i = 0; i < 1000; i++){ + for(int i = 0; i < nbCreatures; i++){ c2.add(c[i]); } c2 = quickSort(c2); @@ -1147,8 +1165,8 @@ void draw() { for (int i = 0; i < 29; i++) { percentile.get(gen+1)[i] = c2.get(p[i]).d; } - creatureDatabase.add(c2.get(999).copyCreature(-1,false,false)); - creatureDatabase.add(c2.get(499).copyCreature(-1,false,false)); + creatureDatabase.add(c2.get(nbCreatures-1).copyCreature(-1,false,false)); + creatureDatabase.add(c2.get(nbCreatures/2-1).copyCreature(-1,false,false)); creatureDatabase.add(c2.get(0).copyCreature(-1,false,false)); Integer[] beginBar = new Integer[barLen]; @@ -1160,7 +1178,7 @@ void draw() { for (int i = 0; i < 101; i++) { beginSpecies[i] = 0; } - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < nbCreatures; i++) { int bar = floor(c2.get(i).d*histBarsPerMeter-minBar); if (bar >= 0 && bar < barLen) { barCounts.get(gen+1)[bar]++; @@ -1197,16 +1215,18 @@ void draw() { screenImage.pushMatrix(); screenImage.scale(10.0/scaleToFixBug*windowSizeMultiplier); float transition = 0.5-0.5*cos(min(float(timer)/60, PI)); - for (int j = 0; j < 1000; j++) { + float xWidth = windowWidth / (gridX+1) / 10.0; + float yHeight = (windowHeight - gridHeightCrop) / (gridY+1) / 10.0; + for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - int j2 = cj.id-(gen*1000)-1; - int x1 = j2%40; - int y1 = floor(j2/40); - int x2 = j%40; - int y2 = floor(j/40)+1; + int j2 = cj.id-(gen*nbCreatures)-1; + int x1 = j2%gridX; + int y1 = floor(j2/gridX); + int x2 = j%gridX; + int y2 = floor(j/gridX)+1; float x3 = inter(x1, x2, transition); float y3 = inter(y1, y2, transition); - screenImage.translate((x3*3+5.5)*scaleToFixBug, (y3*2.5+4)*scaleToFixBug, 0); + screenImage.translate(((x3+1)*xWidth)*scaleToFixBug, ((y3+0.5)*yHeight-(gridHeightCrop/2))*scaleToFixBug, 0); cj.drawCreature(screenImage,true); } screenImage.popMatrix(); @@ -1225,20 +1245,19 @@ void draw() { } float mX = mouseX/windowSizeMultiplier; float mY = mouseY/windowSizeMultiplier; + float xWidth = windowWidth / (gridX+1); + float yHeight = (windowHeight - gridHeightCrop) / (gridY+1); prevStatusWindow = statusWindow; if (abs(menu-9) <= 2 && gensToDo == 0 && !drag) { - if (abs(mX-639.5) <= 599.5) { - if (menu == 7 && abs(mY-329) <= 312) { - statusWindow = creaturesInPosition[floor((mX-40)/30)+floor((mY-17)/25)*40]; - } - else if (menu >= 9 && abs(mY-354) <= 312) { - statusWindow = floor((mX-40)/30)+floor((mY-42)/25)*40; - } - else { - statusWindow = -4; - } - } - else { + int mXI = floor((mX-(xWidth/2))/xWidth); + int mYI = floor((mY-(gridHeightCrop/2))/yHeight); + if(mXI < 0 || mXI >= gridX){ mXI = -1; } + if(mYI < 0 || mYI >= gridY){ mYI = -1; } + if (menu == 7 && mXI >= 0 && mYI >= 0) { + statusWindow = creaturesInPosition[mXI+mYI*gridX]; + } else if (menu >= 9 && mXI >= 0 && mYI >= 0) { + statusWindow = mXI+mYI*gridX; + } else { statusWindow = -4; } } else if (menu == 1 && genSelected >= 1 && gensToDo == 0 && !drag) { @@ -1256,9 +1275,9 @@ void draw() { } if (menu == 10) { //Kill! - for (int j = 0; j < 500; j++) { + for (int j = 0; j < nbCreatures/2; j++) { if(random(0,1) < getSB(gen)){ - float f = float(j)/1000; + float f = float(j)/nbCreatures; float rand = (pow(random(-1, 1), 3)+1)/2; //cube function slowDies = (f <= rand); }else{ @@ -1268,9 +1287,9 @@ void draw() { int j3; if (slowDies) { j2 = j; - j3 = 999-j; + j3 = nbCreatures-1-j; } else { - j2 = 999-j; + j2 = nbCreatures-1-j; j3 = j; } Creature cj = c2.get(j2); @@ -1287,24 +1306,24 @@ void draw() { } if (menu == 12) { //Reproduce and mutate justGotBack = true; - for (int j = 0; j < 500; j++) { + for (int j = 0; j < nbCreatures/2; j++) { int j2 = j; - if (!c2.get(j).alive) j2 = 999-j; + if (!c2.get(j).alive) j2 = nbCreatures-1-j; Creature cj = c2.get(j2); - Creature cj2 = c2.get(999-j2); + Creature cj2 = c2.get(nbCreatures-1-j2); - c2.set(j2, cj.copyCreature(cj.id+1000,true,false)); //duplicate + c2.set(j2, cj.copyCreature(cj.id+nbCreatures,true,false)); //duplicate if(enableRadioactivity && j >= nbCreatures/2 - freshBloodNumber) { c2.set(nbCreatures-1-j2, createNewCreature(cj2.id+nbCreatures-1)); //brand new creatures } else if(enableRadioactivity && j >= nbCreatures/2 - radioactiveNumber - freshBloodNumber){ c2.set(nbCreatures-1-j2, cj.modified(cj2.id+nbCreatures, radioactiveMutator)); //radioactive offspring } else { - c2.set(999-j2, cj.modified(cj2.id+1000, 1.0)); //mutated offspring 1 + c2.set(nbCreatures-1-j2, cj.modified(cj2.id+nbCreatures, 1.0)); //mutated offspring 1 } } - for (int j = 0; j < 1000; j++) { + for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - c[cj.id-(gen*1000)-1001] = cj.copyCreature(-1,false,false); + c[cj.id-(gen*nbCreatures)-nbCreatures-1] = cj.copyCreature(-1,false,false); } drawScreenImage(3); gen++; From 893809d470ff1d9cf7fb69aa176c870717ae5d42 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 18:34:11 +0200 Subject: [PATCH 08/50] Processing 3 Compatibility --- evolutionSteer.pde | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index e06d779..848a143 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -300,7 +300,6 @@ color getColor(int i, boolean adjust) { } void drawGraph(int graphWidth, int graphHeight) { graphImage.beginDraw(); - graphImage.smooth(); graphImage.background(220); if (gen >= 1) { drawLines(130, int(graphHeight*0.05), graphWidth-130, int(graphHeight*0.9)); @@ -359,7 +358,6 @@ void drawLines(int x, int y, int graphWidth, int graphHeight) { } void drawSegBars(int x, int y, int graphWidth, int graphHeight) { segBarImage.beginDraw(); - segBarImage.smooth(); segBarImage.noStroke(); segBarImage.colorMode(HSB, 1); segBarImage.background(0, 0, 0.5); @@ -628,7 +626,6 @@ void drawScreenImage(int stage) { screenImage.beginDraw(); screenImage.pushMatrix(); screenImage.scale(10.0*windowSizeMultiplier/scaleToFixBug); - screenImage.smooth(); screenImage.background(gridBGColor); screenImage.noStroke(); for (int j = 0; j < nbCreatures; j++) { @@ -715,7 +712,6 @@ void drawpopUpImage() { setAverages(); moveCamera(); popUpImage.beginDraw(); - popUpImage.smooth(); float camDist = (450/2.0) / tan(PI*30.0 / 180.0); popUpImage.pushMatrix(); @@ -877,6 +873,10 @@ void drawStatusWindow(boolean isFirstFrame) { } } } +void settings(){ + size(int(windowWidth*windowSizeMultiplier), int(windowHeight*windowSizeMultiplier),P3D); + smooth(); +} void setup() { String[] prePatronData = loadStrings("PatronReport_2017-06-12.csv"); patronData = new String[PATRON_COUNT]; @@ -895,8 +895,6 @@ void setup() { }; frameRate(60); randomSeed(SEED); - noSmooth(); - size((int)(windowWidth*windowSizeMultiplier), (int)(windowHeight*windowSizeMultiplier),P3D); ellipseMode(CENTER); Float[] beginPercentile = new Float[29]; Integer[] beginBar = new Integer[barLen]; @@ -922,11 +920,9 @@ void setup() { popUpImage = createGraphics(450, 450, P3D); segBarImage = createGraphics(975, 150); segBarImage.beginDraw(); - segBarImage.smooth(); segBarImage.background(220); segBarImage.endDraw(); popUpImage.beginDraw(); - popUpImage.smooth(); popUpImage.background(220); popUpImage.endDraw(); @@ -1084,6 +1080,7 @@ void draw() { } } if (menu == 5) { //simulate running + background(255); maxFrames = simDuration*frames; if (timer <= maxFrames) { keysToMoveCamera(); @@ -1334,6 +1331,7 @@ void draw() { } } if(menu%2 == 1 && abs(menu-10) <= 3){ + background(gridBGColor); image(screenImage, 0, 0, 1280, 720); } if (menu == 1 || gensToDo >= 1) { From cd342462f3c445f46a330473a25e0f7b48215fd4 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 18:40:54 +0200 Subject: [PATCH 09/50] Moved global variables From nathan29299292 --- Brain.pde | 2 +- Creature.pde | 74 +++++++++++++++++++++++- Muscle.pde | 6 +- evolutionSteer.pde | 136 ++++++++++++++++----------------------------- 4 files changed, 123 insertions(+), 95 deletions(-) diff --git a/Brain.pde b/Brain.pde index 0598d20..f35e62c 100644 --- a/Brain.pde +++ b/Brain.pde @@ -88,7 +88,7 @@ class Brain { ArrayList m = owner.m; for(int i = 0; i < n.size(); i++){ Node ni = n.get(i); - neurons[0][i] = dist(ni.x, ni.y, ni.z, foodX, foodY, foodZ); + neurons[0][i] = dist(ni.x, ni.y, ni.z, owner.foodX, owner.foodY, owner.foodZ); } for(int i = 0; i < m.size(); i++){ Muscle am = m.get(i); diff --git a/Creature.pde b/Creature.pde index 5ebf723..e85cc6e 100644 --- a/Creature.pde +++ b/Creature.pde @@ -9,6 +9,16 @@ class Creature { Brain brain; int[] name; float[][] foodPositions = new float[100][3]; + float foodAngle = 0.0; + float foodX = 0; + float foodY = 0; + float foodZ = 0; + int chomps = 0; + float averageX = 0; + float averageY = 0; + float averageZ = 0; + float energy = baselineEnergy; + Creature(int[] tname, int tid, ArrayList tn, ArrayList tm, float td, boolean talive, float tct, float tmut, Brain newBrain, float[][] tfoodpos) { id = tid; m = tm; @@ -270,10 +280,68 @@ class Creature { img.popMatrix(); } } + void setAverages() { + averageX = 0; + averageY = 0; + averageZ = 0; + for (int i = 0; i < currentCreature.n.size(); i++) { + Node ni = currentCreature.n.get(i); + averageX += ni.x; + averageY += ni.y; + averageZ += ni.z; + } + averageX = averageX/currentCreature.n.size(); + averageY = averageY/currentCreature.n.size(); + averageZ = averageZ/currentCreature.n.size(); + } + void calculateNextFoodLocation() { + setAverages(); + foodAngle += currentCreature.foodPositions[chomps][0]; + float sinA = sin(foodAngle); + float cosA = cos(foodAngle); + float furthestNodeForward = 0; + for(int i = 0; i < currentCreature.n.size(); i++){ + Node ni = currentCreature.n.get(i); + float newX = (ni.x-averageX)*cosA-(ni.z-averageZ)*sinA; + if(newX >= furthestNodeForward){ + furthestNodeForward = newX; + } + } + float d = MIN_FOOD_DISTANCE+(MAX_FOOD_DISTANCE-MIN_FOOD_DISTANCE)*currentCreature.foodPositions[chomps][2]; + foodX = foodX+cos(foodAngle)*(furthestNodeForward+d); + foodZ = foodZ+sin(foodAngle)*(furthestNodeForward+d); + foodY = currentCreature.foodPositions[chomps][1]; + startingFoodDistance = getCurrentFoodDistance(); + } + float getCurrentFoodDistance() { + float closestDist = 9999; + for(int i = 0; i n) { + void applyForce(int i, ArrayList n, Creature owner) { float target = previousTarget; - if(energyDirection == 1 || energy >= 0.0001){ + if(energyDirection == 1 || owner.energy >= 0.0001){ target = len*toMuscleUsable(brainOutput); }else{ target = len; @@ -32,7 +32,7 @@ class Muscle { ni2.vx -= normX*force*rigidity/ni2.m; ni2.vy -= normY*force*rigidity/ni2.m; ni2.vz -= normZ*force*rigidity/ni2.m; - energy = max(energy+energyDirection*abs(previousTarget-target)*rigidity*energyUnit,0); + owner.energy = max(owner.energy+energyDirection*abs(previousTarget-target)*rigidity*energyUnit,0); previousTarget = target; } } diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 848a143..e6a6be7 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -27,11 +27,6 @@ float cumulativeAngularVelocity = 0; boolean saveFramesPerGeneration = true; color gridBGColor = color(220, 253, 102, 255); float foodAngleChange = 0.0; -float foodX = 0; -float foodY = 0; -float foodZ = 0; -float foodAngle = 0; -int chomps = 0; int nbCreatures = 1000; // please set even number int gridX = 40; // X * Y must be equal to nbCreatures ! @@ -97,9 +92,6 @@ float MAX_FOOD_DISTANCE = 2.5; float target; float force; -float averageX; -float averageY; -float averageZ; int speed; boolean stepbystep; boolean stepbystepslow; @@ -134,6 +126,14 @@ int rInt() { return int(random(-0.01, 1.01)); } void drawGround(PGraphics img) { + float averageX = 0; + float averageY = 0; + float averageZ = 0; + if(currentCreature != null) { + averageX = currentCreature.averageX; + averageY = currentCreature.averageY; + averageZ = currentCreature.averageZ; + } int stairDrawStart = max(1,(int)(-averageY/hazelStairs)-10); img.noStroke(); if (haveGround){ @@ -173,6 +173,22 @@ float toMuscleUsable(float f){ return min(max(f,0.8),1.2); } void drawPosts(PGraphics img) { + float averageX = 0; + float averageY = 0; + float averageZ = 0; + if(currentCreature != null) { + averageX = currentCreature.averageX; + averageY = currentCreature.averageY; + averageZ = currentCreature.averageZ; + } + float foodX = 0; + float foodY = 0; + float foodZ = 0; + if(currentCreature != null) { + foodX = currentCreature.foodX; + foodY = currentCreature.foodY; + foodZ = currentCreature.foodZ; + } int startPostY = min(-8,(int)(averageY/4)*4-4); img.noStroke(); img.textAlign(CENTER); @@ -240,7 +256,7 @@ void drawArrow(float x, float y, float z, PGraphics img) { img.vertex(-0.5*scaleToFixBug, -2.7*scaleToFixBug); img.vertex(0.5*scaleToFixBug, -2.7*scaleToFixBug); img.endShape(CLOSE); - String fitnessString = nf(getFitness(),0,2)+" "+fitnessUnit; + String fitnessString = nf(currentCreature.getFitness(),0,2)+" "+fitnessUnit; img.fill(255); img.text(fitnessString, 0, -2.91*scaleToFixBug,0.1*scaleToFixBug); img.popMatrix(); @@ -455,20 +471,6 @@ void adjustToCenter(int nodeNum) { ni.y -= lowY; } } -void setAverages() { - averageX = 0; - averageY = 0; - averageZ = 0; - for (int i = 0; i < currentCreature.n.size(); i++) { - Node ni = currentCreature.n.get(i); - averageX += ni.x; - averageY += ni.y; - averageZ += ni.z; - } - averageX = averageX/currentCreature.n.size(); - averageY = averageY/currentCreature.n.size(); - averageZ = averageZ/currentCreature.n.size(); -} Creature[] c = new Creature[nbCreatures]; ArrayList c2 = new ArrayList(); @@ -600,7 +602,7 @@ void mouseReleased() { for (int s = 0; s < maxFrames; s++) { if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } - setAverages(); + currentCreature.setAverages(); setFitness(i); } setMenu(6); @@ -709,7 +711,7 @@ void drawScreenImage(int stage) { screenImage.endDraw(); } void drawpopUpImage() { - setAverages(); + currentCreature.setAverages(); moveCamera(); popUpImage.beginDraw(); @@ -730,12 +732,20 @@ void drawpopUpImage() { drawPosts(popUpImage); drawGround(popUpImage); currentCreature.drawCreature(popUpImage,false); - drawArrow(averageX,averageY,averageZ,popUpImage); + drawArrow(currentCreature.averageX,currentCreature.averageY,currentCreature.averageZ,popUpImage); popUpImage.noStroke(); popUpImage.endDraw(); popUpImage.popMatrix(); } void moveCamera(){ + float averageX = 0; + float averageY = 0; + float averageZ = 0; + if(currentCreature != null) { + averageX = currentCreature.averageX; + averageY = currentCreature.averageY; + averageZ = currentCreature.averageZ; + } camX += (averageX-camX)*0.2; camY += (averageY-camY)*0.2; camZ += (averageZ-camZ)*0.2; @@ -1073,7 +1083,7 @@ void draw() { for (int s = 0; s < maxFrames; s++) { if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } - setAverages(); + currentCreature.setAverages(); setFitness(i); } setMenu(6); @@ -1091,15 +1101,15 @@ void draw() { if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } } } - setAverages(); + currentCreature.setAverages(); if (speed < 30) { for (int s = 0; s < speed; s++) { moveCamera(); } } else { - camX = averageX; - camY = averageY; - camZ = averageZ; + camX = currentCreature.averageX; + camY = currentCreature.averageY; + camZ = currentCreature.averageZ; } float camDist = (height/2.0) / tan(PI*30.0 / 180.0); simulationImage.pushMatrix(); @@ -1112,7 +1122,7 @@ void draw() { drawPosts(simulationImage); drawGround(simulationImage); currentCreature.drawCreature(simulationImage,false); - drawArrow(averageX,averageY,averageZ,simulationImage); + drawArrow(currentCreature.averageX,currentCreature.averageY,currentCreature.averageZ,simulationImage); simulationImage.popMatrix(); simulationImage.endDraw(); image(simulationImage,0,0,width/windowSizeMultiplier, @@ -1133,7 +1143,7 @@ void draw() { textAlign(CENTER); textFont(font, 96); text("Creature's "+fitnessName+":", windowWidth/2, 300); - text(nf(getFitness(),0,2) + " "+fitnessUnit, windowWidth/2, 400); + text(nf(currentCreature.getFitness(),0,2) + " "+fitnessUnit, windowWidth/2, 400); } else { timer = maxFrames+(2*frames); } @@ -1478,9 +1488,9 @@ void drawStats(float x, float y, float z, float size){ if(energyDirection == -1){ extraWord = "left"; } - text("X: "+nf(averageX/5.0,0,2)+"", 0, 160); - text("Y: "+nf(-averageY/5.0,0,2)+"", 0, 192); - text("Z: "+nf(-averageZ/5.0,0,2)+"", 0, 224); + text("X: "+nf(currentCreature.averageX/5.0,0,2)+"", 0, 160); + text("Y: "+nf(-currentCreature.averageY/5.0,0,2)+"", 0, 192); + text("Z: "+nf(-currentCreature.averageZ/5.0,0,2)+"", 0, 224); //text("Energy "+extraWord+": "+nf(energy,0,2)+" yums", 0, 256); //text("A.N.Nausea: "+nf(averageNodeNausea,0,2)+" blehs", 0, 256); @@ -1540,46 +1550,10 @@ void setGlobalVariables(Creature thisCreature) { camVA = -0.5; camHA = 0.0; simulationTimer = 0; - energy = baselineEnergy; totalNodeNausea = 0; averageNodeNausea = 0; cumulativeAngularVelocity = 0; - foodAngle = 0.0; - chomps = 0; - foodX = 0; - foodY = 0; - foodZ = 0; - setFoodLocation(); -} -void setFoodLocation(){ - setAverages(); - foodAngle += currentCreature.foodPositions[chomps][0]; - float sinA = sin(foodAngle); - float cosA = cos(foodAngle); - float furthestNodeForward = 0; - for(int i = 0; i < currentCreature.n.size(); i++){ - Node ni = currentCreature.n.get(i); - float newX = (ni.x-averageX)*cosA-(ni.z-averageZ)*sinA; - if(newX >= furthestNodeForward){ - furthestNodeForward = newX; - } - } - float d = MIN_FOOD_DISTANCE+(MAX_FOOD_DISTANCE-MIN_FOOD_DISTANCE)*currentCreature.foodPositions[chomps][2]; - foodX = foodX+cos(foodAngle)*(furthestNodeForward+d); - foodZ = foodZ+sin(foodAngle)*(furthestNodeForward+d); - foodY = currentCreature.foodPositions[chomps][1]; - startingFoodDistance = getCurrentFoodDistance(); -} -float getCurrentFoodDistance(){ - float closestDist = 9999; - for(int i = 0; i < currentCreature.n.size(); i++){ - Node n = currentCreature.n.get(i); - float distFromFood = dist(n.x,n.y,n.z,foodX,foodY,foodZ)-0.4; - if(distFromFood < closestDist){ - closestDist = distFromFood; - } - } - return closestDist; + currentCreature.calculateNextFoodLocation(); } int[] getNewCreatureName(){ float indexOfChoice = random(0,TOTAL_PLEDGED); @@ -1610,22 +1584,8 @@ String rankify(int s){ return s+"th"; } } -float getFitness(){ - Boolean hasNodeOffGround = false; - for(int i = 0; i < currentCreature.n.size(); i++){ - if(currentCreature.n.get(i).y <= -0.2001){ - hasNodeOffGround = true; - } - } - if(hasNodeOffGround){ - float withinChomp = max(1.0-getCurrentFoodDistance()/startingFoodDistance,0); - return chomps+withinChomp;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. - }else{ - return 0; - } -} void setFitness(int i){ - c[i].d = getFitness(); + c[i].d = currentCreature.getFitness(); } Creature createNewCreature(int index){ From 9276dfb05c2098f73f52e26d85d41f7fd4b013dc Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 18:46:57 +0200 Subject: [PATCH 10/50] Added timer From nathan29299292 --- evolutionSteer.pde | 3 +++ 1 file changed, 3 insertions(+) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index e6a6be7..c628b41 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1077,6 +1077,7 @@ void draw() { setGlobalVariables(c[creaturesTested]); setMenu(5); if (!stepbystepslow) { + long start = System.nanoTime(); for (int i = 0; i < nbCreatures; i++) { setGlobalVariables(c[i]); maxFrames = simDuration*frames; @@ -1086,6 +1087,8 @@ void draw() { currentCreature.setAverages(); setFitness(i); } + double simulationTime = Math.round((System.nanoTime() - start) / 100000D) / 10; + frame.setTitle("evolutionSteer | simulationTime: " + simulationTime + " ms"); setMenu(6); } } From 156e3a6191a252cd50f4e3ec2b3b3cd34343fc0a Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 18:57:14 +0200 Subject: [PATCH 11/50] Multithread And modification of many classes for thread compatibility --- Brain.pde | 14 +-- Creature.pde | 260 ++++++++++++++++++++++---------------------- Muscle.pde | 36 +++--- Node.pde | 102 ++++++++--------- computingThread.pde | 36 ++++++ evolutionSteer.pde | 74 +++++++------ 6 files changed, 286 insertions(+), 236 deletions(-) create mode 100644 computingThread.pde diff --git a/Brain.pde b/Brain.pde index f35e62c..4af3f04 100644 --- a/Brain.pde +++ b/Brain.pde @@ -80,12 +80,12 @@ class Brain { } } }else{ - neurons = null; + neurons = new float[BRAIN_WIDTH][BRAIN_HEIGHT];//null; } } public void useBrain(Creature owner){ - ArrayList n = owner.n; - ArrayList m = owner.m; + final ArrayList n = owner.n; + final ArrayList m = owner.m; for(int i = 0; i < n.size(); i++){ Node ni = n.get(i); neurons[0][i] = dist(ni.x, ni.y, ni.z, owner.foodX, owner.foodY, owner.foodZ); @@ -117,13 +117,13 @@ class Brain { return 1.0/(1.0+pow(2.71828182846,-input)); } Brain getUsableCopyOfBrain(){ - return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons,true,false); + return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons.clone(),true,false); } Brain copyBrain(){ - return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons,false,false); + return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons.clone(),false,false); } Brain copyMutatedBrain(){ - return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons,false,true); + return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons.clone(),false,true); } public void drawBrain(float scaleUp, Creature owner){ ArrayList n = owner.n; @@ -177,4 +177,4 @@ class Brain { return color(255,255,255); } } -} +} \ No newline at end of file diff --git a/Creature.pde b/Creature.pde index e85cc6e..66261af 100644 --- a/Creature.pde +++ b/Creature.pde @@ -18,46 +18,47 @@ class Creature { float averageY = 0; float averageZ = 0; float energy = baselineEnergy; + float startingFoodDistance = 9999; Creature(int[] tname, int tid, ArrayList tn, ArrayList tm, float td, boolean talive, float tct, float tmut, Brain newBrain, float[][] tfoodpos) { - id = tid; - m = tm; - n = tn; - d = td; - alive = talive; - creatureTimer = tct; - mutability = tmut; + this.id = tid; + this.m = tm; + this.n = tn; + this.d = td; + this.alive = talive; + this.creatureTimer = tct; + this.mutability = tmut; if(newBrain != null){ - brain = newBrain; + this.brain = newBrain; }else{ - brain = new Brain(BRAIN_WIDTH, getBrainHeight()); + this.brain = new Brain(BRAIN_WIDTH, this.getBrainHeight()); } if(tname == null){ - name = getNewCreatureName(); + this.name = getNewCreatureName(); }else{ - name = new int[2]; - name[0] = tname[0]; - name[1] = tname[1]; + this.name = new int[2]; + this.name[0] = tname[0]; + this.name[1] = tname[1]; } if(tfoodpos == null){ for(int i = 0; i < 100; i++){ - foodPositions[i][0] = random(-foodAngleChange,foodAngleChange); - foodPositions[i][1] = random(-1.2,-0.55); - foodPositions[i][2] = random(0,1); + this.foodPositions[i][0] = random(-foodAngleChange,foodAngleChange); + this.foodPositions[i][1] = random(-1.2,-0.55); + this.foodPositions[i][2] = random(0,1); } }else{ for(int i = 0; i < 100; i++){ - foodPositions[i][0] = tfoodpos[i][0]; - foodPositions[i][1] = tfoodpos[i][1]; - foodPositions[i][2] = tfoodpos[i][2]; + this.foodPositions[i][0] = tfoodpos[i][0]; + this.foodPositions[i][1] = tfoodpos[i][1]; + this.foodPositions[i][2] = tfoodpos[i][2]; } } } int getBrainHeight(){ - return n.size()+m.size()+1; + return this.n.size()+m.size()+1; } void changeBrainStructure(int rowInsertionIndex, int rowRemovalIndex){ - brain.changeBrainStructure(BRAIN_WIDTH, getBrainHeight(), rowInsertionIndex,rowRemovalIndex); + this.brain.changeBrainStructure(BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex,rowRemovalIndex); } public float sigmoid(float input){ return 1.0/(1.0+pow(2.71828182846,-input)); @@ -67,18 +68,18 @@ class Creature { if(mutationFactor > 1.0 && modMut < 1.0){ modMut = 1.5; mutability = 1.0; } ArrayList newN = new ArrayList(0); ArrayList newM = new ArrayList(0); - for (int i = 0; i < n.size(); i++) { - newN.add(n.get(i).modifyNode(modMut,n.size())); + for (int i = 0; i < this.n.size(); i++) { + newN.add(this.n.get(i).modifyNode(modMut,this.n.size())); } - for (int i = 0; i < m.size(); i++) { - newM.add(m.get(i).modifyMuscle(n.size(), modMut)); + for (int i = 0; i < this.m.size(); i++) { + newM.add(this.m.get(i).modifyMuscle(this.n.size(), modMut)); } boolean bigMutAddNode = false, bigMutRemoveNode = false, bigMutAddMuscle = false, bigMutRemoveMuscle = false; - if (random(0, 1) < bigMutationChance*modMut || n.size() <= 2){ bigMutAddNode = true; } + if (random(0, 1) < bigMutationChance*modMut || this.n.size() <= 2){ bigMutAddNode = true; } if (random(0, 1) < bigMutationChance*modMut) { bigMutAddMuscle = true; } - if (random(0, 1) < bigMutationChance*modMut && n.size() >= 5) { bigMutRemoveNode = true; } - if (random(0, 1) < bigMutationChance*modMut && m.size() >= 2) { bigMutRemoveMuscle = true; } + if (random(0, 1) < bigMutationChance*modMut && this.n.size() >= 5) { bigMutRemoveNode = true; } + if (random(0, 1) < bigMutationChance*modMut && this.m.size() >= 2) { bigMutRemoveMuscle = true; } int[] newName = new int[2]; if(bigMutAddNode || bigMutRemoveNode || bigMutAddMuscle || bigMutRemoveMuscle){ @@ -89,7 +90,7 @@ class Creature { CREATURES_PER_PATRON[name[0]]++; } Creature modifiedCreature = new Creature(newName, id, - newN, newM, 0, true, creatureTimer+r()*16*modMut, min(mutability*random(0.8, 1.25), 2), brain.copyMutatedBrain(),null); + newN, newM, 0, true, creatureTimer+r()*16*modMut, min(mutability*random(0.8, 1.25), 2), this.brain.copyMutatedBrain(),null); if (bigMutAddNode) { //Add a node modifiedCreature.addRandomNode(); } @@ -111,15 +112,15 @@ class Creature { void moveToCenter(){ float avX = 0; float avZ = 0; - for(int i = 0; i < n.size(); i++) { - avX += n.get(i).x; - avZ += n.get(i).z; + for(int i = 0; i < this.n.size(); i++) { + avX += this.n.get(i).x; + avZ += this.n.get(i).z; } - avX /= n.size(); - avZ /= n.size(); - for(int i = 0; i < n.size(); i++) { - n.get(i).x -= avX; - n.get(i).z -= avZ; + avX /= this.n.size(); + avZ /= this.n.size(); + for(int i = 0; i < this.n.size(); i++) { + this.n.get(i).x -= avX; + this.n.get(i).z -= avZ; } } void checkForOverlap() { @@ -141,25 +142,25 @@ class Creature { int b = bads.get(i)+0; if (b < m.size()) { m.remove(b); - changeBrainStructure(-1,n.size()+b); + changeBrainStructure(-1,this.n.size()+b); } } } void checkForLoneNodes() { - if (n.size() >= 3) { - for (int i = 0; i < n.size(); i++) { + if (this.n.size() >= 3) { + for (int i = 0; i < this.n.size(); i++) { int connections = 0; int connectedTo = -1; - for (int j = 0; j < m.size(); j++) { - if (m.get(j).c1 == i || m.get(j).c2 == i) { + for (int j = 0; j < this.m.size(); j++) { + if (this.m.get(j).c1 == i || this.m.get(j).c2 == i) { connections++; connectedTo = j; } } if (connections <= 1) { - int newConnectionNode = floor(random(0, n.size())); + int newConnectionNode = floor(random(0, this.n.size())); while (newConnectionNode == i || newConnectionNode == connectedTo) { - newConnectionNode = floor(random(0, n.size())); + newConnectionNode = floor(random(0, this.n.size())); } addRandomMuscle(i, newConnectionNode); } @@ -167,96 +168,97 @@ class Creature { } } void addRandomNode() { - int parentNode = floor(random(0, n.size())); + int parentNode = floor(random(0, this.n.size())); float ang1 = random(0, 2*PI); float distance = sqrt(random(0, 1)); float vertical = random(-1,1); - float x = n.get(parentNode).x+cos(ang1)*0.5*distance; - float y = n.get(parentNode).y+vertical*0.5*distance; - float z = n.get(parentNode).y+sin(ang1)*0.5*distance; + float x = this.n.get(parentNode).x+cos(ang1)*0.5*distance; + float y = this.n.get(parentNode).y+vertical*0.5*distance; + float z = this.n.get(parentNode).y+sin(ang1)*0.5*distance; int newNodeCount = n.size()+1; - n.add(new Node(x, y, z, 0, 0, 0, 0.4, random(0, 1))); - changeBrainStructure(n.size()-1,-1); + this.n.add(new Node(x, y, z, 0, 0, 0, 0.4, random(0, 1))); + changeBrainStructure(this.n.size()-1,-1); int nextClosestNode = 0; float record = 100000; - for (int i = 0; i < n.size()-1; i++) { + for (int i = 0; i < this.n.size()-1; i++) { if (i != parentNode) { - float dx = n.get(i).x-x; - float dy = n.get(i).y-y; + float dx = this.n.get(i).x-x; + float dy = this.n.get(i).y-y; if (sqrt(dx*dx+dy*dy) < record) { record = sqrt(dx*dx+dy*dy); nextClosestNode = i; } } } - addRandomMuscle(parentNode, n.size()-1); - addRandomMuscle(nextClosestNode, n.size()-1); + addRandomMuscle(parentNode, this.n.size()-1); + addRandomMuscle(nextClosestNode, this.n.size()-1); } void addRandomMuscle(int tc1, int tc2) { if (tc1 == -1) { - tc1 = int(random(0, n.size())); + tc1 = int(random(0, this.n.size())); tc2 = tc1; - while (tc2 == tc1 && n.size () >= 2) { - tc2 = int(random(0, n.size())); + while (tc2 == tc1 && this.n.size () >= 2) { + tc2 = int(random(0, this.n.size())); } } float len = random(0.5, 1.5); if (tc1 != -1) { - len = dist(n.get(tc1).x, n.get(tc1).y, n.get(tc2).x, n.get(tc2).y); + len = dist(this.n.get(tc1).x, this.n.get(tc1).y, this.n.get(tc2).x, this.n.get(tc2).y); } m.add(new Muscle(tc1, tc2, len, random(0.02, 0.08))); changeBrainStructure(getBrainHeight()-2,-1); } void removeRandomNode() { - int choice = floor(random(0, n.size())); - n.remove(choice); + int choice = floor(random(0, this.n.size())); + this.n.remove(choice); changeBrainStructure(-1,choice); int i = 0; - while (i < m.size ()) { - if (m.get(i).c1 == choice || m.get(i).c2 == choice) { - m.remove(i); - changeBrainStructure(-1,n.size()+i); + while (i < this.m.size ()) { + if (this.m.get(i).c1 == choice || this.m.get(i).c2 == choice) { + this.m.remove(i); + changeBrainStructure(-1,this.n.size()+i); }else{ i++; } } for (int j = 0; j < m.size(); j++) { - if (m.get(j).c1 >= choice) { - m.get(j).c1--; + if (this.m.get(j).c1 >= choice) { + this.m.get(j).c1--; } if (m.get(j).c2 >= choice) { - m.get(j).c2--; + this.m.get(j).c2--; } } } void removeRandomMuscle() { int choice = floor(random(0, m.size())); m.remove(choice); - changeBrainStructure(-1,n.size()+choice); + changeBrainStructure(-1,this.n.size()+choice); } Creature copyCreature(int newID, Boolean changeFood, Boolean withUsableBrain) { - ArrayList n2 = new ArrayList(0); - ArrayList m2 = new ArrayList(0); - for (int i = 0; i < n.size(); i++) { + final ArrayList n2 = new ArrayList(0); + final ArrayList m2 = new ArrayList(0); + for (int i = 0; i < this.n.size(); i++) { n2.add(this.n.get(i).copyNode()); } - for (int i = 0; i < m.size(); i++) { + for (int i = 0; i < this.m.size(); i++) { m2.add(this.m.get(i).copyMuscle()); } if (newID == -1) { - newID = id; + newID = this.id; } float[][] newFoodPositions = null; if(!changeFood){ - newFoodPositions = foodPositions; + newFoodPositions = foodPositions.clone(); } - Brain newBrain = brain.copyBrain(); + Brain newBrain = this.brain.copyBrain(); if(withUsableBrain){ - newBrain = brain.getUsableCopyOfBrain(); + newBrain = this.brain.getUsableCopyOfBrain(); } - return new Creature(name, newID, n2, m2, d, alive, creatureTimer, mutability,newBrain,newFoodPositions); + return new Creature(this.name, newID, n2, m2, this.d, this.alive, this.creatureTimer, + this.mutability,newBrain,newFoodPositions); } void drawCreature(PGraphics img, Boolean putInFrontOfBack) { if(putInFrontOfBack && false){ @@ -270,54 +272,54 @@ class Creature { img.pushMatrix(); img.translate(0,0,-minZ*scaleToFixBug); } - for (int i = 0; i < m.size(); i++) { - m.get(i).drawMuscle(n, img); + for (int i = 0; i < this.m.size(); i++) { + this.m.get(i).drawMuscle(this.n, img); } - for (int i = 0; i < n.size(); i++) { - n.get(i).drawNode(img); + for (int i = 0; i < this.n.size(); i++) { + this.n.get(i).drawNode(img); } if(putInFrontOfBack && false){ img.popMatrix(); } } void setAverages() { - averageX = 0; - averageY = 0; - averageZ = 0; - for (int i = 0; i < currentCreature.n.size(); i++) { - Node ni = currentCreature.n.get(i); - averageX += ni.x; - averageY += ni.y; - averageZ += ni.z; - } - averageX = averageX/currentCreature.n.size(); - averageY = averageY/currentCreature.n.size(); - averageZ = averageZ/currentCreature.n.size(); + this.averageX = 0; + this.averageY = 0; + this.averageZ = 0; + for (int i = 0; i < this.n.size(); i++) { + Node ni = this.n.get(i); + this.averageX += ni.x; + this.averageY += ni.y; + this.averageZ += ni.z; + } + this.averageX = this.averageX/this.n.size(); + this.averageY = this.averageY/this.n.size(); + this.averageZ = this.averageZ/this.n.size(); } void calculateNextFoodLocation() { - setAverages(); - foodAngle += currentCreature.foodPositions[chomps][0]; - float sinA = sin(foodAngle); - float cosA = cos(foodAngle); + this.setAverages(); + this.foodAngle += this.foodPositions[chomps][0]; + float sinA = sin(this.foodAngle); + float cosA = cos(this.foodAngle); float furthestNodeForward = 0; - for(int i = 0; i < currentCreature.n.size(); i++){ - Node ni = currentCreature.n.get(i); - float newX = (ni.x-averageX)*cosA-(ni.z-averageZ)*sinA; + for(int i = 0; i < this.n.size(); i++){ + Node ni = this.n.get(i); + float newX = (ni.x-this.averageX)*cosA-(ni.z-this.averageZ)*sinA; if(newX >= furthestNodeForward){ furthestNodeForward = newX; } } - float d = MIN_FOOD_DISTANCE+(MAX_FOOD_DISTANCE-MIN_FOOD_DISTANCE)*currentCreature.foodPositions[chomps][2]; - foodX = foodX+cos(foodAngle)*(furthestNodeForward+d); - foodZ = foodZ+sin(foodAngle)*(furthestNodeForward+d); - foodY = currentCreature.foodPositions[chomps][1]; - startingFoodDistance = getCurrentFoodDistance(); + this.d = MIN_FOOD_DISTANCE+(MAX_FOOD_DISTANCE-MIN_FOOD_DISTANCE)*this.foodPositions[chomps][2]; + this.foodX = this.foodX+cos(foodAngle)*(furthestNodeForward+d); + this.foodZ = this.foodZ+sin(foodAngle)*(furthestNodeForward+d); + this.foodY = this.foodPositions[chomps][1]; + this.startingFoodDistance = this.getCurrentFoodDistance(); } float getCurrentFoodDistance() { float closestDist = 9999; - for(int i = 0; i = 2)); - float distFromFood = dist(ni.x,ni.y,ni.z,foodX,foodY,foodZ); + float distFromFood = dist(ni.x,ni.y,ni.z,this.foodX,this.foodY,this.foodZ); if(distFromFood <= 0.4){ - chomps++; - if (chomps < 10){ hasEaten = true; } - calculateNextFoodLocation(); + this.chomps++; + if (this.chomps < 10){ hasEaten = true; } + this.calculateNextFoodLocation(); } } return hasEaten; } -} +} \ No newline at end of file diff --git a/Muscle.pde b/Muscle.pde index 46b7121..0f3dd6c 100644 --- a/Muscle.pde +++ b/Muscle.pde @@ -5,27 +5,27 @@ class Muscle { float previousTarget; float brainOutput; Muscle(int tc1, int tc2, float tlen, float trigidity) { - previousTarget = len = tlen; - c1 = tc1; - c2 = tc2; - rigidity = trigidity; - brainOutput = 1; + this.previousTarget = len = tlen; + this.c1 = tc1; + this.c2 = tc2; + this.rigidity = trigidity; + this.brainOutput = 1; } void applyForce(int i, ArrayList n, Creature owner) { float target = previousTarget; if(energyDirection == 1 || owner.energy >= 0.0001){ - target = len*toMuscleUsable(brainOutput); + target = this.len*toMuscleUsable(this.brainOutput); }else{ - target = len; + target = this.len; } - Node ni1 = n.get(c1); - Node ni2 = n.get(c2); + Node ni1 = n.get(this.c1); + Node ni2 = n.get(this.c2); float distance = dist(ni1.x, ni1.y, ni1.z, ni2.x, ni2.y, ni2.z); if(distance >= 0.0001){ float normX = (ni1.x-ni2.x)/distance; float normY = (ni1.y-ni2.y)/distance; float normZ = (ni1.z-ni2.z)/distance; - force = min(max(1-(distance/target), -1.7), 1.7); + float force = min(max(1-(distance/target), -1.7), 1.7); ni1.vx += normX*force*rigidity/ni1.m; ni1.vy += normY*force*rigidity/ni1.m; ni1.vz += normZ*force*rigidity/ni1.m; @@ -33,15 +33,15 @@ class Muscle { ni2.vy -= normY*force*rigidity/ni2.m; ni2.vz -= normZ*force*rigidity/ni2.m; owner.energy = max(owner.energy+energyDirection*abs(previousTarget-target)*rigidity*energyUnit,0); - previousTarget = target; + this.previousTarget = target; } } Muscle copyMuscle() { - return new Muscle(c1, c2, len, rigidity); + return new Muscle(this.c1, this.c2, this.len, this.rigidity); } Muscle modifyMuscle(int nodeNum, float mutability) { - int newc1 = c1; - int newc2 = c2; + int newc1 = this.c1; + int newc2 = this.c2; if(random(0,1) n, PGraphics img) { - Node ni1 = n.get(c1); - Node ni2 = n.get(c2); - float w = toMuscleUsable(brainOutput)*0.15; + Node ni1 = n.get(this.c1); + Node ni2 = n.get(this.c2); + float w = toMuscleUsable(this.brainOutput)*0.15; img.strokeWeight(w*scaleToFixBug); float brownness = rigidity*13; img.stroke(255-180*brownness, 255-210*brownness, 255-255*brownness, 255); @@ -65,4 +65,4 @@ class Muscle { ni2.x*scaleToFixBug, ni2.y*scaleToFixBug, ni2.z*scaleToFixBug); } -} +} \ No newline at end of file diff --git a/Node.pde b/Node.pde index b617c45..6b9d50a 100644 --- a/Node.pde +++ b/Node.pde @@ -5,69 +5,69 @@ class Node { Node(float tx, float ty, float tz, float tvx, float tvy, float tvz, float tm, float tf) { - prevX = x = tx; - prevY = y = ty; - prevZ = z = tz; - pvx = vx = tvx; - pvy = vy = tvy; - pvz = vz = tvz; - m = tm; - f = tf; - pressure = 0; + this.prevX = x = tx; + this.prevY = y = ty; + this.prevZ = z = tz; + this.pvx = vx = tvx; + this.pvy = vy = tvy; + this.pvz = vz = tvz; + this.m = tm; + this.f = tf; + this.pressure = 0; } void applyForces() { - vx *= airFriction; - vy *= airFriction; - vz *= airFriction; - y += vy; - x += vx; - z += vz; + this.vx *= airFriction; + this.vy *= airFriction; + this.vz *= airFriction; + this.y += vy; + this.x += vx; + this.z += vz; float acc = dist(vx,vy,vz,pvx,pvy,pvz); totalNodeNausea += acc*acc*nauseaUnit; - pvx = vx; - pvy = vy; - pvz = vz; + this.pvx = vx; + this.pvy = vy; + this.pvz = vz; } void applyGravity() { - vy += gravity; + this.vy += gravity; } void pressAgainstGround(float groundY){ float dif = y-(groundY-m/2); - pressure += dif*pressureUnit; - y = (groundY-m/2); - vy = 0; - x -= vx*f; - z -= vz*f; - if (vx > 0) { - vx -= f*dif*FRICTION; - if (vx < 0) { - vx = 0; + this.pressure += dif*pressureUnit; + this.y = (groundY-m/2); + this.vy = 0; + this.x -= vx*f; + this.z -= vz*f; + if (this.vx > 0) { + this.vx -= this.f*dif*FRICTION; + if (this.vx < 0) { + this.vx = 0; } } else { - vx += f*dif*FRICTION; - if (vx > 0) { - vx = 0; + this.vx += this.f*dif*FRICTION; + if (this.vx > 0) { + this.vx = 0; } } - if (vz > 0) { - vz -= f*dif*FRICTION; - if (vz < 0) { - vz = 0; + if (this.vz > 0) { + this.vz -= this.f*dif*FRICTION; + if (this.vz < 0) { + this.vz = 0; } } else { - vz += f*dif*FRICTION; + this.vz += this.f*dif*FRICTION; if (vz > 0) { vz = 0; } } } void hitWalls(Boolean addToAngular) { - pressure = 0; + this.pressure = 0; float dif = y+m/2; if (dif >= 0 && haveGround) { pressAgainstGround(0); } - if(y > prevY && hazelStairs >= 0){ + if(this.y > this.prevY && hazelStairs >= 0){ float bottomPointNow = y+m/2; float bottomPointPrev = prevY+m/2; int levelNow = (int)(ceil(bottomPointNow/hazelStairs)); @@ -141,36 +141,36 @@ class Node { } } }*/ - prevY = y; - prevX = x; + this.prevY = this.y; + this.prevX = this.x; } Node copyNode() { - return (new Node(x, y, z, 0, 0, 0, m, f)); + return (new Node(this.x, this.y, this.z, 0, 0, 0, this.m, this.f)); } Node modifyNode(float mutability, int nodeNum) { - float newX = x+r()*0.5*mutability; - float newY = y+r()*0.5*mutability; - float newZ = z+r()*0.5*mutability; + float newX = this.x+r()*0.5*mutability; + float newY = this.y+r()*0.5*mutability; + float newZ = this.z+r()*0.5*mutability; //float newM = m+r()*0.1*mutability; //newM = min(max(newM, 0.3), 0.5); float newM = 0.4; - float newF = min(max(f+r()*0.1*mutability, 0), 1); + float newF = min(max(this.f+r()*0.1*mutability, 0), 1); Node newNode = new Node(newX, newY, newZ, 0, 0, 0, newM, newF); return newNode;//max(m+r()*0.1,0.2),min(max(f+r()*0.1,0),1) } void drawNode(PGraphics img) { color c = color(0,0,0); - if (f <= 0.5) { - c = colorLerp(color(255,255,255),color(180,0,255),f*2); + if (this.f <= 0.5) { + c = colorLerp(color(255,255,255),color(180,0,255),this.f*2); }else{ - c = colorLerp(color(180,0,255),color(0,0,0),f*2-1); + c = colorLerp(color(180,0,255),color(0,0,0),this.f*2-1); } img.fill(c); img.noStroke(); img.lights(); img.pushMatrix(); - img.translate(x*scaleToFixBug, y*scaleToFixBug,z*scaleToFixBug); - img.sphere(m*scaleToFixBug*0.5); + img.translate(this.x*scaleToFixBug, this.y*scaleToFixBug,this.z*scaleToFixBug); + img.sphere(this.m*scaleToFixBug*0.5); img.popMatrix(); //img.ellipse((ni.x+x)*scaleToFixBug, (ni.y+y)*scaleToFixBug, ni.m*scaleToFixBug, ni.m*scaleToFixBug); /*if(ni.f >= 0.5){ @@ -186,4 +186,4 @@ class Node { color colorLerp(color a, color b, float x){ return color(red(a)+(red(b)-red(a))*x, green(a)+(green(b)-green(a))*x, blue(a)+(blue(b)-blue(a))*x); } -} +} \ No newline at end of file diff --git a/computingThread.pde b/computingThread.pde new file mode 100644 index 0000000..bf17976 --- /dev/null +++ b/computingThread.pde @@ -0,0 +1,36 @@ +public class ComputingThread implements Runnable{ + private int beginIndex; + private int endIndex; + private int framePerChomp; + private Creature myCreature; + public ComputingThread(int bi, int ei, int fpc){ + this.beginIndex = bi; + this.endIndex = ei; + this.framePerChomp = fpc; + } + @Override + public void run() { + for(int k = this.beginIndex; k < this.endIndex; k++) { + myCreature = Constants.c[k].copyCreature(-1,false,true); + myCreature.calculateNextFoodLocation(); + int myMaxChomp = this.framePerChomp; + boolean isJumper = false; + for (int sim = 0; sim < myMaxChomp; sim++) { + if(myCreature.simulate()){ // activated when chomped + if(sim <= 30){ isJumper = true; break; } // we kill jumpers + myMaxChomp += this.framePerChomp; + } + } + if(isJumper){ + Constants.c[k].d = 0; + } else { + myCreature.setAverages(); + Constants.c[k].d = myCreature.getFitness(); + } + } + } +} + +interface Constants { + Creature[] c = new Creature[nbCreatures]; +} \ No newline at end of file diff --git a/evolutionSteer.pde b/evolutionSteer.pde index c628b41..2fd4921 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1,5 +1,5 @@ -final float windowSizeMultiplier = 1.4; -final int SEED = 31; //7; ;( +final float windowSizeMultiplier = 1; +final int SEED = 314; //7; ;( PFont font; ArrayList percentile = new ArrayList(0); @@ -28,9 +28,9 @@ boolean saveFramesPerGeneration = true; color gridBGColor = color(220, 253, 102, 255); float foodAngleChange = 0.0; -int nbCreatures = 1000; // please set even number -int gridX = 40; // X * Y must be equal to nbCreatures ! -int gridY = 25; +static int nbCreatures = 2000; // please set even number +int gridX = 50; // X * Y must be equal to nbCreatures ! +int gridY = 40; int thresholdName = 25; // name of species is showed over this threshold int lastImageSaved = -1; @@ -61,7 +61,7 @@ float camZ = 0; float camHA = 0; float camVA = -0.5; int frames = 60; -int simDuration = 5; // in seconds +int simDuration = 15; // in seconds int maxFrames = simDuration*frames; int maxSimulationFrames = simDuration*frames; int menu = 0; @@ -90,8 +90,6 @@ float airFriction = 0.95; float MIN_FOOD_DISTANCE = 1; float MAX_FOOD_DISTANCE = 2.5; -float target; -float force; int speed; boolean stepbystep; boolean stepbystepslow; @@ -106,7 +104,7 @@ float STARTING_AXON_VARIABILITY = 1.0; float AXON_START_MUTABILITY = 0.0005; boolean enableRadioactivity = false; -int radioactiveNumber = 200; // number of highly mutated creatures +int radioactiveNumber = 400; // number of highly mutated creatures int freshBloodNumber = 0; // number of brand new creatures float radioactiveMutator = 1.5; @@ -116,6 +114,8 @@ float TOTAL_PLEDGED = 183.39; int[] CREATURES_PER_PATRON = new int[PATRON_COUNT]; float startingFoodDistance = 0; +int THREAD_COUNT = 14; + float inter(int a, int b, float offset) { return float(a)+(float(b)-float(a))*offset; } @@ -471,7 +471,7 @@ void adjustToCenter(int nodeNum) { ni.y -= lowY; } } -Creature[] c = new Creature[nbCreatures]; +//Creature[] c = new Creature[nbCreatures]; ArrayList c2 = new ArrayList(); void mouseWheel(MouseEvent event) { @@ -597,7 +597,6 @@ void mouseReleased() { timer = 0; creaturesTested++; for (int i = creaturesTested; i < nbCreatures; i++) { - setGlobalVariables(c[i]); maxFrames = simDuration*frames; for (int s = 0; s < maxFrames; s++) { if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } @@ -632,7 +631,7 @@ void drawScreenImage(int stage) { screenImage.noStroke(); for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - if (stage == 3) cj = c[cj.id-(gen*nbCreatures)-(nbCreatures+1)]; + if (stage == 3) cj = Constants.c[cj.id-(gen*nbCreatures)-(nbCreatures+1)]; int j2 = j; if (stage == 0) { j2 = cj.id-(gen*nbCreatures)-1; @@ -1035,11 +1034,11 @@ void draw() { creatures = 0; for (int y = 0; y < gridY; y++) { for (int x = 0; x < gridX; x++) { - c[y*gridX+x] = createNewCreature(y*gridX+x); - c[y*gridX+x].checkForOverlap(); - c[y*gridX+x].checkForLoneNodes(); - c[y*gridX+x].toStableConfiguration(); - c[y*gridX+x].moveToCenter(); + Constants.c[y*gridX+x] = createNewCreature(y*gridX+x); + Constants.c[y*gridX+x].checkForOverlap(); + Constants.c[y*gridX+x].checkForLoneNodes(); + Constants.c[y*gridX+x].toStableConfiguration(); + Constants.c[y*gridX+x].moveToCenter(); } } creatures = 0; @@ -1054,7 +1053,7 @@ void draw() { for (int x = 0; x < gridX; x++) { screenImage.pushMatrix(); screenImage.translate(((x+1)*xWidth)*scaleToFixBug, ((y+1)*yHeight+gridHeightCrop/20.0)*scaleToFixBug, 0); - c[y*gridX+x].drawCreature(screenImage,true); + Constants.c[y*gridX+x].drawCreature(screenImage,true); screenImage.popMatrix(); } } @@ -1074,21 +1073,34 @@ void draw() { background(0,0,255); image(screenImage, 0, 0, 1280, 720); }else if (menu == 4) { - setGlobalVariables(c[creaturesTested]); + setGlobalVariables(Constants.c[creaturesTested]); setMenu(5); if (!stepbystepslow) { long start = System.nanoTime(); - for (int i = 0; i < nbCreatures; i++) { - setGlobalVariables(c[i]); - maxFrames = simDuration*frames; - for (int s = 0; s < maxFrames; s++) { - if(simulateCurrentCreature()){ maxFrames += simDuration*frames; } + Thread[] threads = new Thread[THREAD_COUNT]; + println(""); + int previousLastIndex = 0; + for(int i = 0; i < threads.length; i++) { + int firstIndex = previousLastIndex; + int lastIndex; + if(i == threads.length - 1) { + lastIndex = nbCreatures; + } else { + lastIndex = (int)((i+1) * float(nbCreatures) / threads.length); + } + threads[i] = new Thread(new ComputingThread(firstIndex, lastIndex, simDuration*frames)); + threads[i].start(); + previousLastIndex = lastIndex; + } + for(int i = 0; i < threads.length; i++) { + try { + threads[i].join(); + } catch (InterruptedException ie) { + ie.printStackTrace(); // :( } - currentCreature.setAverages(); - setFitness(i); } double simulationTime = Math.round((System.nanoTime() - start) / 100000D) / 10; - frame.setTitle("evolutionSteer | simulationTime: " + simulationTime + " ms"); + surface.setTitle("evolutionSteer | simulationTime: " + simulationTime + " ms"); setMenu(6); } } @@ -1168,7 +1180,7 @@ void draw() { //sort c2 = new ArrayList(0); for(int i = 0; i < nbCreatures; i++){ - c2.add(c[i]); + c2.add(Constants.c[i]); } c2 = quickSort(c2); percentile.add(new Float[29]); @@ -1333,7 +1345,7 @@ void draw() { } for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - c[cj.id-(gen*nbCreatures)-nbCreatures-1] = cj.copyCreature(-1,false,false); + Constants.c[cj.id-(gen*nbCreatures)-nbCreatures-1] = cj.copyCreature(-1,false,false); } drawScreenImage(3); gen++; @@ -1588,7 +1600,7 @@ String rankify(int s){ } } void setFitness(int i){ - c[i].d = currentCreature.getFitness(); + Constants.c[i].d = currentCreature.getFitness(); } Creature createNewCreature(int index){ @@ -1622,4 +1634,4 @@ Creature createNewCreature(int index){ } float heartbeat = random(40, 80); return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 0, true, heartbeat, 1.0, null, null); -} +} \ No newline at end of file From dd909fae99735a2097cf7dd96b02749d3923d43a Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 22:47:10 +0200 Subject: [PATCH 12/50] Other technique to remove jumpers I hate jumpers --- computingThread.pde | 2 +- evolutionSteer.pde | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/computingThread.pde b/computingThread.pde index bf17976..8f373ab 100644 --- a/computingThread.pde +++ b/computingThread.pde @@ -17,7 +17,7 @@ public class ComputingThread implements Runnable{ boolean isJumper = false; for (int sim = 0; sim < myMaxChomp; sim++) { if(myCreature.simulate()){ // activated when chomped - if(sim <= 30){ isJumper = true; break; } // we kill jumpers + if(sim <= jumperFrames){ isJumper = true; break; } // we kill jumpers myMaxChomp += this.framePerChomp; } } diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 2fd4921..b29cc0f 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -62,8 +62,10 @@ float camHA = 0; float camVA = -0.5; int frames = 60; int simDuration = 15; // in seconds +int jumperDuration = 1; // definition of jumper : chomp < this value (in seconds) int maxFrames = simDuration*frames; int maxSimulationFrames = simDuration*frames; +int jumperFrames = jumperDuration*frames; int menu = 0; int gen = -1; float sliderX = 1170; From d3dbd6e1db47555c9c85a6e8a5212a1820bf6597 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 23:22:45 +0200 Subject: [PATCH 13/50] Mass extinction Just press 'k' --- evolutionSteer.pde | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index b29cc0f..459b289 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -110,6 +110,8 @@ int radioactiveNumber = 400; // number of highly mutated creatures int freshBloodNumber = 0; // number of brand new creatures float radioactiveMutator = 1.5; +boolean massExtinction = false; + String[] patronData; int PATRON_COUNT = 75; float TOTAL_PLEDGED = 183.39; @@ -1025,6 +1027,9 @@ void draw() { // saveFrame("imgs//"+zeros(gen,5)+".png"); // lastImageSaved = gen; //} + if(massExtinction){ + text("MASS EXTINCTION", 400, 210); + } } if (gensToDo >= 1) { gensToDo--; @@ -1336,13 +1341,18 @@ void draw() { Creature cj = c2.get(j2); Creature cj2 = c2.get(nbCreatures-1-j2); - c2.set(j2, cj.copyCreature(cj.id+nbCreatures,true,false)); //duplicate - if(enableRadioactivity && j >= nbCreatures/2 - freshBloodNumber) { - c2.set(nbCreatures-1-j2, createNewCreature(cj2.id+nbCreatures-1)); //brand new creatures - } else if(enableRadioactivity && j >= nbCreatures/2 - radioactiveNumber - freshBloodNumber){ - c2.set(nbCreatures-1-j2, cj.modified(cj2.id+nbCreatures, radioactiveMutator)); //radioactive offspring + if(massExtinction && random(0,1) < 0.5){ // mass extinction + c2.set(j2, createNewCreature(cj.id+nbCreatures-1)); // new creatures arises ! + c2.set(nbCreatures-1-j2, createNewCreature(cj2.id+nbCreatures-1)); } else { - c2.set(nbCreatures-1-j2, cj.modified(cj2.id+nbCreatures, 1.0)); //mutated offspring 1 + c2.set(j2, cj.copyCreature(cj.id+nbCreatures,true,false)); //duplicate + if(enableRadioactivity && j >= nbCreatures/2 - freshBloodNumber) { + c2.set(nbCreatures-1-j2, createNewCreature(cj2.id+nbCreatures-1)); //brand new creatures + } else if(enableRadioactivity && j >= nbCreatures/2 - radioactiveNumber - freshBloodNumber){ + c2.set(nbCreatures-1-j2, cj.modified(cj2.id+nbCreatures, radioactiveMutator)); //radioactive offspring + } else { + c2.set(nbCreatures-1-j2, cj.modified(cj2.id+nbCreatures, 1.0)); //mutated offspring 1 + } } } for (int j = 0; j < nbCreatures; j++) { @@ -1356,6 +1366,7 @@ void draw() { } else { setMenu(1); } + massExtinction = false; } if(menu%2 == 1 && abs(menu-10) <= 3){ background(gridBGColor); @@ -1489,6 +1500,10 @@ void keyPressed(){ enableRadioactivity = !enableRadioactivity; setMenu(1); } + if(key == 'k'){ + massExtinction = true; + setMenu(1); + } } void drawStats(float x, float y, float z, float size){ textAlign(RIGHT); From 086816100478beb0e985afe0bb924129320d40be Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 23 Jul 2017 23:41:40 +0200 Subject: [PATCH 14/50] Adding gitattributes for EOL --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..343642e --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ ++*.pde text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 \ No newline at end of file From 8f7c73e2f2723738d6b4b87a75984036c71f955f Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 08:40:05 +0200 Subject: [PATCH 15/50] Multithread 2 SImplified multithread --- computingThread.pde | 10 +++------- evolutionSteer.pde | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/computingThread.pde b/computingThread.pde index 8f373ab..94ade9f 100644 --- a/computingThread.pde +++ b/computingThread.pde @@ -11,7 +11,7 @@ public class ComputingThread implements Runnable{ @Override public void run() { for(int k = this.beginIndex; k < this.endIndex; k++) { - myCreature = Constants.c[k].copyCreature(-1,false,true); + myCreature = c[k].copyCreature(-1,false,true); myCreature.calculateNextFoodLocation(); int myMaxChomp = this.framePerChomp; boolean isJumper = false; @@ -22,15 +22,11 @@ public class ComputingThread implements Runnable{ } } if(isJumper){ - Constants.c[k].d = 0; + c[k].d = 0; } else { myCreature.setAverages(); - Constants.c[k].d = myCreature.getFitness(); + c[k].d = myCreature.getFitness(); } } } -} - -interface Constants { - Creature[] c = new Creature[nbCreatures]; } \ No newline at end of file diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 459b289..9a4137b 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -85,6 +85,7 @@ boolean miniSimulation = false; int creatureWatching = 0; int simulationTimer = 0; int[] creaturesInPosition = new int[nbCreatures]; +Creature[] c = new Creature[nbCreatures]; float camZoom = 0.015; float gravity = 0.006;//0.007; @@ -635,7 +636,7 @@ void drawScreenImage(int stage) { screenImage.noStroke(); for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - if (stage == 3) cj = Constants.c[cj.id-(gen*nbCreatures)-(nbCreatures+1)]; + if (stage == 3) cj = c[cj.id-(gen*nbCreatures)-(nbCreatures+1)]; int j2 = j; if (stage == 0) { j2 = cj.id-(gen*nbCreatures)-1; @@ -1041,11 +1042,11 @@ void draw() { creatures = 0; for (int y = 0; y < gridY; y++) { for (int x = 0; x < gridX; x++) { - Constants.c[y*gridX+x] = createNewCreature(y*gridX+x); - Constants.c[y*gridX+x].checkForOverlap(); - Constants.c[y*gridX+x].checkForLoneNodes(); - Constants.c[y*gridX+x].toStableConfiguration(); - Constants.c[y*gridX+x].moveToCenter(); + c[y*gridX+x] = createNewCreature(y*gridX+x); + c[y*gridX+x].checkForOverlap(); + c[y*gridX+x].checkForLoneNodes(); + c[y*gridX+x].toStableConfiguration(); + c[y*gridX+x].moveToCenter(); } } creatures = 0; @@ -1060,7 +1061,7 @@ void draw() { for (int x = 0; x < gridX; x++) { screenImage.pushMatrix(); screenImage.translate(((x+1)*xWidth)*scaleToFixBug, ((y+1)*yHeight+gridHeightCrop/20.0)*scaleToFixBug, 0); - Constants.c[y*gridX+x].drawCreature(screenImage,true); + c[y*gridX+x].drawCreature(screenImage,true); screenImage.popMatrix(); } } @@ -1080,7 +1081,7 @@ void draw() { background(0,0,255); image(screenImage, 0, 0, 1280, 720); }else if (menu == 4) { - setGlobalVariables(Constants.c[creaturesTested]); + setGlobalVariables(c[creaturesTested]); setMenu(5); if (!stepbystepslow) { long start = System.nanoTime(); @@ -1112,9 +1113,9 @@ void draw() { } } if (menu == 5) { //simulate running - background(255); maxFrames = simDuration*frames; if (timer <= maxFrames) { + background(255); keysToMoveCamera(); simulationImage.beginDraw(); simulationImage.background(120, 200, 255); @@ -1187,7 +1188,7 @@ void draw() { //sort c2 = new ArrayList(0); for(int i = 0; i < nbCreatures; i++){ - c2.add(Constants.c[i]); + c2.add(c[i]); } c2 = quickSort(c2); percentile.add(new Float[29]); @@ -1357,7 +1358,7 @@ void draw() { } for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - Constants.c[cj.id-(gen*nbCreatures)-nbCreatures-1] = cj.copyCreature(-1,false,false); + c[cj.id-(gen*nbCreatures)-nbCreatures-1] = cj.copyCreature(-1,false,false); } drawScreenImage(3); gen++; @@ -1617,7 +1618,7 @@ String rankify(int s){ } } void setFitness(int i){ - Constants.c[i].d = currentCreature.getFitness(); + c[i].d = currentCreature.getFitness(); } Creature createNewCreature(int index){ From 45ab38b85a4ffa4a4b2704c8dfa3c5ff7fb2dfec Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 08:42:00 +0200 Subject: [PATCH 16/50] Savable issued from darkracer branch --- Axon.pde | 16 +++- Brain.pde | 61 +++++++++++++- Creature.pde | 75 +++++++++++++++++- ISavable.pde | 5 ++ Muscle.pde | 23 +++++- Node.pde | 43 +++++++++- evolutionSteer.pde | 193 ++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 406 insertions(+), 10 deletions(-) create mode 100644 ISavable.pde diff --git a/Axon.pde b/Axon.pde index 7ca19b4..19f8a9a 100644 --- a/Axon.pde +++ b/Axon.pde @@ -1,4 +1,4 @@ -class Axon{ +class Axon implements ISavable{ final double MUTABILITY_MUTABILITY = 0.7; final int mutatePower = 9; final double MUTATE_MULTI; @@ -21,4 +21,16 @@ class Axon{ public double pmRan(){ return (Math.random()*2-1); } -} + + public JSONObject saveToJson(){ + JSONObject object = new JSONObject(); + object.setDouble("weight", weight); + object.setDouble("mutability", mutability); + return object; + } + + public void loadFromJson(JSONObject parent){ + weight = parent.getDouble("weight", weight); + mutability = parent.getDouble("mutability", mutability); + } +} \ No newline at end of file diff --git a/Brain.pde b/Brain.pde index 4af3f04..14587fe 100644 --- a/Brain.pde +++ b/Brain.pde @@ -1,4 +1,4 @@ -class Brain { +class Brain implements ISavable{ float[][] neurons; Axon[][][] axons; int BRAIN_WIDTH = 0; @@ -177,4 +177,63 @@ class Brain { return color(255,255,255); } } + + public JSONObject saveToJson(){ + JSONObject object = new JSONObject(); + object.setInt("width", BRAIN_WIDTH); + object.setInt("height", BRAIN_HEIGHT); + JSONArray axonArray = new JSONArray(); + if(axons != null){ + for (int i = 0; i < axons.length; i++){ + JSONArray iArray = new JSONArray(); + for(int j = 0; j < axons[i].length; j++){ + JSONArray jArray = new JSONArray(); + for(int k = 0; k < axons[i][j].length; k++){ + jArray.setJSONObject(k, axons[i][j][k].saveToJson()); + } + iArray.setJSONArray(j, jArray); + } + axonArray.setJSONArray(i, iArray); + } + } + object.setJSONArray("axons", axonArray); + JSONArray neuronArray = new JSONArray(); + if(neurons != null){ + for(int i = 0; i < neurons.length; i++){ + JSONArray iArray = new JSONArray(); + for(int j = 0; j < neurons[i].length; j++){ + iArray.setFloat(j, neurons[i][j]); + } + neuronArray.setJSONArray(i, iArray); + } + } + object.setJSONArray("neurons", neuronArray); + return object; + } + + public void loadFromJson(JSONObject parent){ + BRAIN_WIDTH = parent.getInt("width"); + BRAIN_HEIGHT = parent.getInt("height"); + axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + JSONArray axonArray = parent.getJSONArray("axons"); + for(int i = 0; i < axonArray.size(); i++){ + JSONArray iArray = axonArray.getJSONArray(i); + for(int j = 0; j < iArray.size(); j++){ + JSONArray jArray = iArray.getJSONArray(j); + for(int k = 0; k < jArray.size(); k++){ + axons[i][j][k] = new Axon(0,0); + axons[i][j][k].loadFromJson(jArray.getJSONObject(k)); + } + } + } + neurons = new float[BRAIN_WIDTH][BRAIN_HEIGHT]; + JSONArray neuronArray = parent.getJSONArray("neurons"); + for(int i = 0; i < neuronArray.size(); i++){ + JSONArray iArray = neuronArray.getJSONArray(i); + for(int j = 0; j < iArray.size(); j++){ + neurons[i][j] = iArray.getFloat(j); + } + } + } + } \ No newline at end of file diff --git a/Creature.pde b/Creature.pde index 66261af..60e8d87 100644 --- a/Creature.pde +++ b/Creature.pde @@ -1,4 +1,4 @@ -class Creature { +class Creature implements ISavable { ArrayList n; ArrayList m; float d; @@ -374,4 +374,77 @@ class Creature { } return hasEaten; } + + public JSONObject saveToJson(){ + JSONObject object = new JSONObject(); + JSONArray nodeArray = new JSONArray(); + if(n != null){ + for(int i = 0 ; i < this.n.size(); i++){ + nodeArray.setJSONObject(i, this.n.get(i).saveToJson()); + } + } + object.setJSONArray("nodes", nodeArray); + JSONArray muscleArray = new JSONArray(); + for(int i = 0; i < this.m.size(); i++){ + muscleArray.setJSONObject(i, this.m.get(i).saveToJson()); + } + object.setJSONArray("muscles", muscleArray); + object.setFloat("d", d); + object.setInt("id", id); + object.setBoolean("alive", alive); + object.setFloat("creatureTimer", creatureTimer); + object.setFloat("mutability", mutability); + object.setJSONObject("brain", brain.saveToJson()); + JSONArray nameArray = new JSONArray(); + for(int i = 0; i < name.length; i++){ + nameArray.setInt(i, name[i]); + } + object.setJSONArray("name", nameArray); + JSONArray foodArray = new JSONArray(); + for(int i = 0; i < foodPositions.length; i++){ + JSONArray iArray = new JSONArray(); + for(int j = 0; j < foodPositions[i].length; j++){ + iArray.setFloat(j, foodPositions[i][j]); + } + foodArray.setJSONArray(i, iArray); + } + object.setJSONArray("food", foodArray); + return object; + } + public void loadFromJson(JSONObject parent){ + JSONArray nodeArray = parent.getJSONArray("nodes"); + n = new ArrayList(); + for(int i = 0; i < nodeArray.size(); i++){ + Node node = new Node(0, 0, 0, 0, 0, 0, 0, 0); + node.loadFromJson(nodeArray.getJSONObject(i)); + n.add(node); + } + JSONArray muscleArray = parent.getJSONArray("muscles"); + m = new ArrayList(); + for(int i = 0; i < muscleArray.size(); i++){ + Muscle muscle = new Muscle(0, 0, 0, 0); + muscle.loadFromJson(muscleArray.getJSONObject(i)); + m.add(muscle); + } + d = parent.getFloat("d"); + id = parent.getInt("id"); + alive = parent.getBoolean("alive"); + creatureTimer = parent.getFloat("creatureTimer"); + mutability = parent.getFloat("mutability"); + brain = new Brain(1, 1); + brain.loadFromJson(parent.getJSONObject("brain")); + JSONArray nameArray = parent.getJSONArray("name"); + name = new int[nameArray.size()]; + for(int i = 0; i < nameArray.size(); i++){ + name[i] = nameArray.getInt(i); + } + JSONArray foodArray = parent.getJSONArray("food"); + foodPositions = new float[foodArray.size()][foodArray.getJSONArray(0).size()]; + for(int i = 0; i < foodArray.size(); i++){ + JSONArray iArray = foodArray.getJSONArray(i); + for(int j = 0; j < iArray.size(); j++){ + foodPositions[i][j] = iArray.getFloat(j); + } + } + } } \ No newline at end of file diff --git a/ISavable.pde b/ISavable.pde new file mode 100644 index 0000000..63fd620 --- /dev/null +++ b/ISavable.pde @@ -0,0 +1,5 @@ +interface ISavable{ + public JSONObject saveToJson(); + + public void loadFromJson(JSONObject object); +} \ No newline at end of file diff --git a/Muscle.pde b/Muscle.pde index 0f3dd6c..00d2012 100644 --- a/Muscle.pde +++ b/Muscle.pde @@ -1,4 +1,4 @@ -class Muscle { +class Muscle implements ISavable { int c1, c2; float len; float rigidity; @@ -65,4 +65,25 @@ class Muscle { ni2.x*scaleToFixBug, ni2.y*scaleToFixBug, ni2.z*scaleToFixBug); } + + public JSONObject saveToJson(){ + JSONObject object = new JSONObject(); + object.setInt("c1", c1); + object.setInt("c2", c2); + object.setFloat("len", len); + object.setFloat("rigidity", rigidity); + object.setFloat("previousTarget", previousTarget); + object.setFloat("brainOutput", brainOutput); + return object; + } + + public void loadFromJson(JSONObject parent){ + c1 = parent.getInt("c1"); + c2 = parent.getInt("c2"); + len = parent.getFloat("len"); + rigidity = parent.getFloat("rigidity"); + previousTarget = parent.getFloat("previousTarget"); + brainOutput = parent.getFloat("brainOutput"); + } + } \ No newline at end of file diff --git a/Node.pde b/Node.pde index 6b9d50a..0350e2b 100644 --- a/Node.pde +++ b/Node.pde @@ -1,4 +1,4 @@ -class Node { +class Node implements ISavable{ float x, y, z, vx, vy, vz, prevX, prevY, prevZ, pvx, pvy, pvz, m, f; boolean safeInput; float pressure; @@ -186,4 +186,45 @@ class Node { color colorLerp(color a, color b, float x){ return color(red(a)+(red(b)-red(a))*x, green(a)+(green(b)-green(a))*x, blue(a)+(blue(b)-blue(a))*x); } + + public JSONObject saveToJson(){ + JSONObject object = new JSONObject(); + object.setFloat("x", x); + object.setFloat("y", y); + object.setFloat("z", z); + object.setFloat("vx", vx); + object.setFloat("vy", vy); + object.setFloat("vz", vz); + object.setFloat("prevX", prevX); + object.setFloat("prevY", prevY); + object.setFloat("prevZ", prevZ); + object.setFloat("pvx", pvx); + object.setFloat("pvy", pvy); + object.setFloat("pvz", pvz); + object.setFloat("m", m); + object.setFloat("f", f); + object.setBoolean("safeInput", safeInput); + object.setFloat("pressure", pressure); + return object; + } + + public void loadFromJson(JSONObject parent){ + x = parent.getFloat("x"); + y = parent.getFloat("y"); + z = parent.getFloat("z"); + vx = parent.getFloat("vx"); + vy = parent.getFloat("vy"); + vz = parent.getFloat("vz"); + prevX = parent.getFloat("prevX"); + prevY = parent.getFloat("prevY"); + prevZ = parent.getFloat("prevZ"); + pvx = parent.getFloat("pvx"); + pvy = parent.getFloat("pvy"); + pvz = parent.getFloat("pvz"); + m = parent.getFloat("m"); + f = parent.getFloat("f"); + safeInput = parent.getBoolean("safeInput"); + pressure = parent.getFloat("pressure"); + } + } \ No newline at end of file diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 9a4137b..feb65de 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1,3 +1,9 @@ +import java.io.*; +import java.io.BufferedReader; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + + final float windowSizeMultiplier = 1; final int SEED = 314; //7; ;( @@ -553,7 +559,9 @@ void mouseReleased() { float mX = mouseX/windowSizeMultiplier; float mY = mouseY/windowSizeMultiplier; if (menu == 0 && abs(mX-windowWidth/2) <= 200 && abs(mY-400) <= 100) { - setMenu(1); + setMenu(1);//TODO add extra button click + }else if(menu == 0 && abs(mX -windowWidth/2) <=150 && abs(mY - 600) <=50){ + selectInput("Select a file to load", "fileSelected"); }else if (menu == 1 && gen == -1 && abs(mX-120) <= 100 && abs(mY-300) <= 50) { setMenu(2); }else if (menu == 1 && gen >= 0 && abs(mX-990) <= 230) { @@ -578,6 +586,8 @@ void mouseReleased() { } startASAP(); } + }else if(menu == 1 && gen != -1 && abs(mX - 650) <= 50 && abs(mY - 90) <= 20){ + selectOutput("Select file to save simulation to", "saveSelected"); }else if (menu == 3 && abs(mX-1030) <= 130 && abs(mY-684) <= 20) { gen = 0; setMenu(1); @@ -891,6 +901,11 @@ void settings(){ size(int(windowWidth*windowSizeMultiplier), int(windowHeight*windowSizeMultiplier),P3D); smooth(); } +void initPercentiles(){ + for (int i = 1; i < 29; i++) { + p[i] = int(floor(float(pPercentages[i])*float(nbCreatures)/1000.0)); + }; +} void setup() { String[] prePatronData = loadStrings("PatronReport_2017-06-12.csv"); patronData = new String[PATRON_COUNT]; @@ -904,9 +919,7 @@ void setup() { for(int i = 0; i < PATRON_COUNT; i++){ CREATURES_PER_PATRON[i] = 0; } - for (int i = 1; i < 29; i++) { - p[i] = int(floor(float(pPercentages[i])*float(nbCreatures)/1000.0)); - }; + initPercentiles(); frameRate(60); randomSeed(SEED); ellipseMode(CENTER); @@ -978,9 +991,13 @@ void draw() { fill(100, 200, 100); noStroke(); rect(windowWidth/2-200, 300, 400, 200); + rect(windowWidth/2-150, 550, 300, 100); fill(0); + textSize(60); text("EVOLUTION!", windowWidth/2, 200); text("START", windowWidth/2, 430); + textSize(26); + text("Load simulation", windowWidth/2, 600); }else if (menu == 1) { noStroke(); fill(0); @@ -1002,6 +1019,7 @@ void draw() { rect(760, 20, 460, 40); rect(760, 70, 460, 40); rect(760, 120, 230, 40); + rect(600, 70, 100, 40); if (gensToDo >= 2) { fill(128, 255, 128); } else { @@ -1019,6 +1037,7 @@ void draw() { text("Do 1 gen ASAP.", 770, 150); text("Do gens ALAP.", 1000, 150); text("Median "+fitnessName, 50, 160); + text("Save", 610, 100); textAlign(CENTER); textAlign(RIGHT); text(float(round(percentile.get(min(genSelected, percentile.size()-1))[14]*nbCreatures))/nbCreatures+" "+fitnessUnit, 700, 160); @@ -1652,4 +1671,170 @@ Creature createNewCreature(int index){ } float heartbeat = random(40, 80); return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 0, true, heartbeat, 1.0, null, null); +} + +public void fileSelected(File file){ + if(file != null){ + try{ + FileInputStream in = new FileInputStream(file.getAbsolutePath()); + BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(in), "UTF-8")); + StringBuilder out = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { out.append(line); } + JSONObject object = parseJSONObject(out.toString()); + reader.close(); + loadFromJson(object); + setMenu(1); + randomSeed(SEED); + //redraw(); + }catch(Exception e){ + String[] error = new String[100]; + error[0] = e.toString(); + for(int i = 0; i < e.getStackTrace().length; i++){ + error[i+1] = e.getStackTrace()[i].toString(); + } + saveStrings("error.log", error); + } + } +} + +public void saveSelected(File file){ + if(file != null){ + try{ + JSONObject object = saveToJson(); + FileOutputStream out = new FileOutputStream(file.getAbsolutePath()); + Writer writer = new OutputStreamWriter(new GZIPOutputStream(out), "UTF-8"); + writer.write(object.toString()); + writer.close(); + }catch(Exception e){ + String[] error = new String[100]; + error[0] = e.toString(); + for(int i = 0; i < e.getStackTrace().length; i++){ + error[i+1] = e.getStackTrace()[i].toString(); + } + saveStrings("error.log", error); + } + } +} + +public JSONObject saveToJson(){ + JSONObject object = new JSONObject(); + object.setInt("seed", SEED); + JSONArray creatureArray = new JSONArray(); + println("creature",creatureDatabase.size()); + for(int i = 0; i < creatureDatabase.size(); i++){ + if(creatureDatabase.get(i) != null){ + //println(creatureDatabase.get(i)); + creatureArray.setJSONObject(i, creatureDatabase.get(i).saveToJson()); + } + } + object.setJSONArray("creatures", creatureArray); + println("bars",barCounts.size()); + JSONArray bars = new JSONArray(); + for(int i = 0; i < barCounts.size(); i++){ + JSONArray iArray = new JSONArray(); + for(int j = 0; j < barCounts.get(i).length; j++){ + iArray.setInt(j, barCounts.get(i)[j]); + } + bars.setJSONArray(i,iArray); + } + object.setJSONArray("bars", bars); + println("percentiles",percentile.size()); + JSONArray percentiles = new JSONArray(); + for(int i = 0; i < percentile.size(); i++){ + JSONArray iArray = new JSONArray(); + for(int j = 0; j < percentile.get(i).length; j++){ + iArray.setFloat(j, percentile.get(i)[j]); + } + percentiles.setJSONArray(i,iArray); + } + object.setJSONArray("percentiles", percentiles); + println("species",speciesCounts.size()); + JSONArray species = new JSONArray(); + for(int i = 0; i < speciesCounts.size(); i++){ + JSONArray iArray = new JSONArray(); + for(int j = 0; j < speciesCounts.get(i).length; j++){ + iArray.setInt(j, speciesCounts.get(i)[j]); + } + species.setJSONArray(i,iArray); + } + object.setJSONArray("species", species); + JSONArray cArray = new JSONArray(); + for(int i = 0; i < c.length; i++){ + cArray.setJSONObject(i, c[i].saveToJson()); + } + JSONArray topSpeciesArray = new JSONArray(); + for(int i = 0; i < topSpeciesCounts.size(); i++){ + topSpeciesArray.setInt(i, topSpeciesCounts.get(i)); + } + object.setJSONArray("topSpecies", topSpeciesArray); + object.setJSONArray("c", cArray); + + object.setFloat("foodChange", foodAngleChange); + object.setInt("gen", gen); + object.setInt("nbcreatures", nbCreatures); + object.setInt("gridX", gridX); + object.setInt("gridY", gridY); + return object; +} + +public void loadFromJson(JSONObject parent){ + SEED = parent.getInt("seed"); + creatureDatabase.clear(); + JSONArray creatureArray = parent.getJSONArray("creatures"); + for(int i = 0; i < creatureArray.size(); i++){ + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); + creature.loadFromJson(creatureArray.getJSONObject(i)); + creatureDatabase.add(creature); + } + barCounts.clear(); + JSONArray bars = parent.getJSONArray("bars"); + for(int i = 0; i < bars.size(); i++){ + JSONArray iArray = bars.getJSONArray(i); + Integer[] array = new Integer[iArray.size()]; + for(int j = 0; j < iArray.size(); j++){ + array[j] = iArray.getInt(j); + } + barCounts.add(array); + } + percentile.clear(); + JSONArray percentiles = parent.getJSONArray("percentiles"); + for(int i = 0; i < percentiles.size(); i++){ + JSONArray iArray = percentiles.getJSONArray(i); + Float[] array = new Float[iArray.size()]; + for(int j = 0; j < iArray.size(); j++){ + array[j] = iArray.getFloat(j); + } + percentile.add(array); + } + speciesCounts.clear(); + JSONArray species = parent.getJSONArray("species"); + for(int i = 0; i < species.size(); i++){ + JSONArray iArray = species.getJSONArray(i); + Integer[] array = new Integer[iArray.size()]; + for(int j = 0; j < iArray.size(); j++){ + array[j] = iArray.getInt(j); + } + speciesCounts.add(array); + } + nbCreatures = parent.getInt("nbcreatures"); + gridX = parent.getInt("gridX"); + gridY = parent.getInt("gridY"); + initPercentiles(); + c = new Creature[nbCreatures]; + JSONArray cArray = parent.getJSONArray("c"); + for(int i = 0; i < cArray.size(); i++){ + Creature temp = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); + temp.loadFromJson(cArray.getJSONObject(i)); + c[i] = temp; + c2.add(c[i]); + } + topSpeciesCounts.clear(); + JSONArray topSpeciesArray = parent.getJSONArray("topSpecies"); + for(int i = 0; i < topSpeciesArray.size(); i++){ + topSpeciesCounts.add(topSpeciesArray.getInt(i)); + } + foodAngleChange = parent.getFloat("foodChange"); + gen = parent.getInt("gen"); + genSelected = gen; } \ No newline at end of file From 6619429e8914688a4e09fbd82ab8e3cf43ef4fac Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 09:01:54 +0200 Subject: [PATCH 17/50] Save screen Added save and load screens --- evolutionSteer.pde | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index feb65de..28e637c 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -559,9 +559,10 @@ void mouseReleased() { float mX = mouseX/windowSizeMultiplier; float mY = mouseY/windowSizeMultiplier; if (menu == 0 && abs(mX-windowWidth/2) <= 200 && abs(mY-400) <= 100) { - setMenu(1);//TODO add extra button click + setMenu(1); }else if(menu == 0 && abs(mX -windowWidth/2) <=150 && abs(mY - 600) <=50){ - selectInput("Select a file to load", "fileSelected"); + setMenu(14); + selectInput("Select a file to load", "fileSelected"); }else if (menu == 1 && gen == -1 && abs(mX-120) <= 100 && abs(mY-300) <= 50) { setMenu(2); }else if (menu == 1 && gen >= 0 && abs(mX-990) <= 230) { @@ -587,6 +588,7 @@ void mouseReleased() { startASAP(); } }else if(menu == 1 && gen != -1 && abs(mX - 650) <= 50 && abs(mY - 90) <= 20){ + setMenu(15); selectOutput("Select file to save simulation to", "saveSelected"); }else if (menu == 3 && abs(mX-1030) <= 130 && abs(mY-684) <= 20) { gen = 0; @@ -1291,6 +1293,16 @@ void draw() { drawScreenImage(1); setMenu(9); } + } else if(menu == 14){ + fill(0); + background(255, 200, 130); + textSize(60); + text("Please wait while loading...", windowWidth/2, 200); + } else if(menu == 15){ + fill(0); + background(255, 200, 130); + textSize(60); + text("Please wait while saving...", windowWidth/2, 200); } float mX = mouseX/windowSizeMultiplier; float mY = mouseY/windowSizeMultiplier; @@ -1706,6 +1718,7 @@ public void saveSelected(File file){ Writer writer = new OutputStreamWriter(new GZIPOutputStream(out), "UTF-8"); writer.write(object.toString()); writer.close(); + setMenu(1); }catch(Exception e){ String[] error = new String[100]; error[0] = e.toString(); From 50add5cc5d3471833b2c8430fc71d92dd23b03ad Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 09:06:56 +0200 Subject: [PATCH 18/50] Interface glitch COmpatibility between radioactivity and save --- evolutionSteer.pde | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 28e637c..be90c63 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1032,7 +1032,7 @@ void draw() { //text("Survivor Bias: "+percentify(getSB(genSelected)), 437, 50); text("Curve: ±"+nf(foodAngleChange/(2*PI)*360,0,2)+" degrees", 420, 50); if(enableRadioactivity){ - text("Radioactive mode", 460, 100); + text("Radioactive mode", 460, 130); } text("Do 1 step-by-step generation.", 770, 50); text("Do 1 quick generation.", 770, 100); From 8684a6f221df02dd295697b349530c398c740336 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 09:26:44 +0200 Subject: [PATCH 19/50] Autosave Added autosave capabilities --- evolutionSteer.pde | 47 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index be90c63..f50b6e0 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -2,6 +2,9 @@ import java.io.*; import java.io.BufferedReader; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; final float windowSizeMultiplier = 1; @@ -39,6 +42,9 @@ int gridX = 50; // X * Y must be equal to nbCreatures ! int gridY = 40; int thresholdName = 25; // name of species is showed over this threshold +int autoSave = 100; // autosave every x generation in ASAP mode +boolean hasAutosaveWorked = false; + int lastImageSaved = -1; float pressureUnit = 500.0/2.37; float energyUnit = 20; @@ -1393,12 +1399,27 @@ void draw() { } drawScreenImage(3); gen++; + massExtinction = false; if (stepbystep) { setMenu(13); } else { + if(autoSave > 0 && gen > 0){ + if(gen%autoSave == 0){ + hasAutosaveWorked = false; + saveSelected(new File(dataPath("")+"/autosave-tmp.gz")); + if(hasAutosaveWorked){ + try{ + Path source = Paths.get(dataPath("")+"/autosave-tmp.gz"); + new File(source.resolveSibling("autosave.gz").toString()).delete(); + Files.move(source, source.resolveSibling("autosave.gz")); + } catch(Exception e){ + writeToErrorLog(e); + } + } + } + } setMenu(1); } - massExtinction = false; } if(menu%2 == 1 && abs(menu-10) <= 3){ background(gridBGColor); @@ -1684,7 +1705,14 @@ Creature createNewCreature(int index){ float heartbeat = random(40, 80); return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 0, true, heartbeat, 1.0, null, null); } - +public void writeToErrorLog(Exception e){ + String[] error = new String[100]; + error[0] = e.toString(); + for(int i = 0; i < e.getStackTrace().length; i++){ + error[i+1] = e.getStackTrace()[i].toString(); + } + saveStrings("error.log", error); +} public void fileSelected(File file){ if(file != null){ try{ @@ -1700,12 +1728,7 @@ public void fileSelected(File file){ randomSeed(SEED); //redraw(); }catch(Exception e){ - String[] error = new String[100]; - error[0] = e.toString(); - for(int i = 0; i < e.getStackTrace().length; i++){ - error[i+1] = e.getStackTrace()[i].toString(); - } - saveStrings("error.log", error); + writeToErrorLog(e); } } } @@ -1718,14 +1741,10 @@ public void saveSelected(File file){ Writer writer = new OutputStreamWriter(new GZIPOutputStream(out), "UTF-8"); writer.write(object.toString()); writer.close(); + hasAutosaveWorked = true; setMenu(1); }catch(Exception e){ - String[] error = new String[100]; - error[0] = e.toString(); - for(int i = 0; i < e.getStackTrace().length; i++){ - error[i+1] = e.getStackTrace()[i].toString(); - } - saveStrings("error.log", error); + writeToErrorLog(e); } } } From e627564c19415d9fcde159fa209af37b30d6a758 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 09:40:56 +0200 Subject: [PATCH 20/50] Autosave 2 Bug fix --- .gitignore | 4 ++++ evolutionSteer.pde | 15 ++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..91a70dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +data/autosave\.gz + +error\.log diff --git a/evolutionSteer.pde b/evolutionSteer.pde index f50b6e0..6a48a2a 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -7,8 +7,8 @@ import java.nio.file.Path; import java.nio.file.Paths; -final float windowSizeMultiplier = 1; -final int SEED = 314; //7; ;( +float windowSizeMultiplier = 1; +int SEED = 314; //7; ;( PFont font; ArrayList percentile = new ArrayList(0); @@ -1113,7 +1113,6 @@ void draw() { if (!stepbystepslow) { long start = System.nanoTime(); Thread[] threads = new Thread[THREAD_COUNT]; - println(""); int previousLastIndex = 0; for(int i = 0; i < threads.length; i++) { int firstIndex = previousLastIndex; @@ -1410,7 +1409,10 @@ void draw() { if(hasAutosaveWorked){ try{ Path source = Paths.get(dataPath("")+"/autosave-tmp.gz"); - new File(source.resolveSibling("autosave.gz").toString()).delete(); + File autosaveGenuine = new File(source.resolveSibling("autosave.gz").toString()); + if(autosaveGenuine.isFile()) { + autosaveGenuine.delete(); + } Files.move(source, source.resolveSibling("autosave.gz")); } catch(Exception e){ writeToErrorLog(e); @@ -1753,15 +1755,12 @@ public JSONObject saveToJson(){ JSONObject object = new JSONObject(); object.setInt("seed", SEED); JSONArray creatureArray = new JSONArray(); - println("creature",creatureDatabase.size()); for(int i = 0; i < creatureDatabase.size(); i++){ if(creatureDatabase.get(i) != null){ - //println(creatureDatabase.get(i)); creatureArray.setJSONObject(i, creatureDatabase.get(i).saveToJson()); } } object.setJSONArray("creatures", creatureArray); - println("bars",barCounts.size()); JSONArray bars = new JSONArray(); for(int i = 0; i < barCounts.size(); i++){ JSONArray iArray = new JSONArray(); @@ -1771,7 +1770,6 @@ public JSONObject saveToJson(){ bars.setJSONArray(i,iArray); } object.setJSONArray("bars", bars); - println("percentiles",percentile.size()); JSONArray percentiles = new JSONArray(); for(int i = 0; i < percentile.size(); i++){ JSONArray iArray = new JSONArray(); @@ -1781,7 +1779,6 @@ public JSONObject saveToJson(){ percentiles.setJSONArray(i,iArray); } object.setJSONArray("percentiles", percentiles); - println("species",speciesCounts.size()); JSONArray species = new JSONArray(); for(int i = 0; i < speciesCounts.size(); i++){ JSONArray iArray = new JSONArray(); From 35c39b8176aba93018429389a5f1d03c01f71639 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 09:56:42 +0200 Subject: [PATCH 21/50] Autosave timecoded To create various files with timecode --- .gitignore | 1 + evolutionSteer.pde | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 91a70dc..046c613 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ data/autosave\.gz +data/autosave-*\.gz error\.log diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 6a48a2a..9b01524 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -43,6 +43,7 @@ int gridY = 40; int thresholdName = 25; // name of species is showed over this threshold int autoSave = 100; // autosave every x generation in ASAP mode +boolean autoSaveTimecode = true; // set to false is disk space limited boolean hasAutosaveWorked = false; int lastImageSaved = -1; @@ -1407,13 +1408,19 @@ void draw() { hasAutosaveWorked = false; saveSelected(new File(dataPath("")+"/autosave-tmp.gz")); if(hasAutosaveWorked){ + String finalfilename = ""; + if(autoSaveTimecode){ + finalfilename = dataPath("")+"/autosave-"+year()+"-"+month()+"-"+day()+"_"+hour()+"-"+minute()+"-"+second()+".gz"; + } else { + finalfilename = dataPath("")+"/autosave.gz"; + } try{ Path source = Paths.get(dataPath("")+"/autosave-tmp.gz"); - File autosaveGenuine = new File(source.resolveSibling("autosave.gz").toString()); + File autosaveGenuine = new File(finalfilename); if(autosaveGenuine.isFile()) { autosaveGenuine.delete(); } - Files.move(source, source.resolveSibling("autosave.gz")); + Files.move(source, Paths.get(finalfilename)); } catch(Exception e){ writeToErrorLog(e); } From 4a1320d68ee01ffc37d44e2754df537a14924a39 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Mon, 24 Jul 2017 10:07:49 +0200 Subject: [PATCH 22/50] AutoPause Little tweak allows you to leave your computer --- evolutionSteer.pde | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 9b01524..bd4ab09 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -42,9 +42,10 @@ int gridX = 50; // X * Y must be equal to nbCreatures ! int gridY = 40; int thresholdName = 25; // name of species is showed over this threshold -int autoSave = 100; // autosave every x generation in ASAP mode +int autoSave = 100; // autosave every x generation in ALAP mode boolean autoSaveTimecode = true; // set to false is disk space limited boolean hasAutosaveWorked = false; +int autoPause = 10000; // pauses ALAP each x generation int lastImageSaved = -1; float pressureUnit = 500.0/2.37; @@ -1427,6 +1428,11 @@ void draw() { } } } + if(autoPause > 0){ + if(gen%autoPause == 0){ + gensToDo = 0; + } + } setMenu(1); } } From 4385614b2a3fb4e793091c05db52fffc7d635691 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Tue, 25 Jul 2017 23:25:00 +0200 Subject: [PATCH 23/50] Saving 2 Update saving capabilities (rule out memory heap size problem) --- .gitignore | 2 + Axon.pde | 28 +- Brain.pde | 134 +++++---- Creature.pde | 164 +++++----- ISavable.pde | 5 - Muscle.pde | 44 +-- Node.pde | 84 +++--- code/jackson-core-2.9.0.pr4.jar | Bin 0 -> 316575 bytes code/jackson-dataformat-smile-2.9.0.pr4.jar | Bin 0 -> 84022 bytes evolutionSteer.pde | 313 +++++++++++--------- 10 files changed, 453 insertions(+), 321 deletions(-) delete mode 100644 ISavable.pde create mode 100644 code/jackson-core-2.9.0.pr4.jar create mode 100644 code/jackson-dataformat-smile-2.9.0.pr4.jar diff --git a/.gitignore b/.gitignore index 046c613..a5643f7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ data/autosave\.gz data/autosave-*\.gz error\.log + +data/tempfile\.gz diff --git a/Axon.pde b/Axon.pde index 19f8a9a..7a08fae 100644 --- a/Axon.pde +++ b/Axon.pde @@ -1,4 +1,4 @@ -class Axon implements ISavable{ +class Axon { final double MUTABILITY_MUTABILITY = 0.7; final int mutatePower = 9; final double MUTATE_MULTI; @@ -22,15 +22,25 @@ class Axon implements ISavable{ return (Math.random()*2-1); } - public JSONObject saveToJson(){ - JSONObject object = new JSONObject(); - object.setDouble("weight", weight); - object.setDouble("mutability", mutability); - return object; + public void saveToJson(JsonGenerator g){ + try { + g.writeNumberField("weight", weight); + g.writeNumberField("mutability", mutability); + } catch(Exception e){ + writeToErrorLog(e); + } } - public void loadFromJson(JSONObject parent){ - weight = parent.getDouble("weight", weight); - mutability = parent.getDouble("mutability", mutability); + public void loadFromJson(JsonParser p){ + try{ + while(p.nextToken() != JsonToken.END_OBJECT){ + String fieldName = p.getCurrentName(); + p.nextToken(); + if(fieldName.equals("weight")){ this.weight = p.getDoubleValue(); } + else if(fieldName.equals("mutability")){ this.mutability = p.getDoubleValue(); } + } + } catch(Exception e){ + writeToErrorLog(e); + } } } \ No newline at end of file diff --git a/Brain.pde b/Brain.pde index 14587fe..c69eeb1 100644 --- a/Brain.pde +++ b/Brain.pde @@ -1,4 +1,4 @@ -class Brain implements ISavable{ +class Brain { float[][] neurons; Axon[][][] axons; int BRAIN_WIDTH = 0; @@ -178,61 +178,89 @@ class Brain implements ISavable{ } } - public JSONObject saveToJson(){ - JSONObject object = new JSONObject(); - object.setInt("width", BRAIN_WIDTH); - object.setInt("height", BRAIN_HEIGHT); - JSONArray axonArray = new JSONArray(); - if(axons != null){ - for (int i = 0; i < axons.length; i++){ - JSONArray iArray = new JSONArray(); - for(int j = 0; j < axons[i].length; j++){ - JSONArray jArray = new JSONArray(); - for(int k = 0; k < axons[i][j].length; k++){ - jArray.setJSONObject(k, axons[i][j][k].saveToJson()); - } - iArray.setJSONArray(j, jArray); - } - axonArray.setJSONArray(i, iArray); - } - } - object.setJSONArray("axons", axonArray); - JSONArray neuronArray = new JSONArray(); - if(neurons != null){ - for(int i = 0; i < neurons.length; i++){ - JSONArray iArray = new JSONArray(); - for(int j = 0; j < neurons[i].length; j++){ - iArray.setFloat(j, neurons[i][j]); - } - neuronArray.setJSONArray(i, iArray); - } - } - object.setJSONArray("neurons", neuronArray); - return object; - } - - public void loadFromJson(JSONObject parent){ - BRAIN_WIDTH = parent.getInt("width"); - BRAIN_HEIGHT = parent.getInt("height"); - axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; - JSONArray axonArray = parent.getJSONArray("axons"); - for(int i = 0; i < axonArray.size(); i++){ - JSONArray iArray = axonArray.getJSONArray(i); - for(int j = 0; j < iArray.size(); j++){ - JSONArray jArray = iArray.getJSONArray(j); - for(int k = 0; k < jArray.size(); k++){ - axons[i][j][k] = new Axon(0,0); - axons[i][j][k].loadFromJson(jArray.getJSONObject(k)); - } + public void saveToJson(JsonGenerator g){ + try{ + g.writeNumberField("width", BRAIN_WIDTH); + g.writeNumberField("height", BRAIN_HEIGHT); + if(axons != null){ + g.writeArrayFieldStart("axons"); + for (int i = 0; i < axons.length; i++){ + g.writeStartArray(); + for(int j = 0; j < axons[i].length; j++){ + g.writeStartArray(); + for(int k = 0; k < axons[i][j].length; k++){ + g.writeStartObject(); axons[i][j][k].saveToJson(g); g.writeEndObject(); + } + g.writeEndArray(); + } + g.writeEndArray(); + } + g.writeEndArray(); } + if(neurons != null){ + g.writeArrayFieldStart("neurons"); + for(int i = 0; i < neurons.length; i++){ + g.writeStartArray(); + for(int j = 0; j < neurons[i].length; j++){ + g.writeNumber(neurons[i][j]); + } + g.writeEndArray(); + } + g.writeEndArray(); + } + } catch(Exception e){ + writeToErrorLog(e); } - neurons = new float[BRAIN_WIDTH][BRAIN_HEIGHT]; - JSONArray neuronArray = parent.getJSONArray("neurons"); - for(int i = 0; i < neuronArray.size(); i++){ - JSONArray iArray = neuronArray.getJSONArray(i); - for(int j = 0; j < iArray.size(); j++){ - neurons[i][j] = iArray.getFloat(j); + } + + public void loadFromJson(JsonParser p){ + try{ + while(p.nextToken() != JsonToken.END_OBJECT){ + String fieldName = p.getCurrentName(); + JsonToken token = p.nextToken(); + if(fieldName.equals("width")){ this.BRAIN_WIDTH = p.getIntValue(); } + else if(fieldName.equals("height")){ this.BRAIN_HEIGHT = p.getIntValue(); } + else if(fieldName.equals("axons")){ + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + int i = 0; + axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_ARRAY){ + int j = 0; + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_ARRAY){ + int k = 0; + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token != JsonToken.START_OBJECT) { throw new Exception("Expected Object"); } + axons[i][j][k] = new Axon(0,0); + axons[i][j][k].loadFromJson(p); + k += 1; + } + } + j += 1; + } + } + i += 1; + } + } + else if(fieldName.equals("neurons")){ + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + int i = 0; + neurons = new float[BRAIN_WIDTH][BRAIN_HEIGHT]; + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_ARRAY){ + int j = 0; + while(p.nextToken() != JsonToken.END_ARRAY){ + neurons[i][j] = p.getFloatValue(); + j += 1; + } + } + i += 1; + } + } } + } catch(Exception e){ + writeToErrorLog(e); } } diff --git a/Creature.pde b/Creature.pde index 60e8d87..9b6e6bd 100644 --- a/Creature.pde +++ b/Creature.pde @@ -1,4 +1,4 @@ -class Creature implements ISavable { +class Creature { ArrayList n; ArrayList m; float d; @@ -375,76 +375,104 @@ class Creature implements ISavable { return hasEaten; } - public JSONObject saveToJson(){ - JSONObject object = new JSONObject(); - JSONArray nodeArray = new JSONArray(); - if(n != null){ - for(int i = 0 ; i < this.n.size(); i++){ - nodeArray.setJSONObject(i, this.n.get(i).saveToJson()); + public void saveToJson(JsonGenerator g){ + try{ + g.writeNumberField("d", d); + g.writeNumberField("id", id); + g.writeBooleanField("alive", alive); + g.writeNumberField("creatureTimer", creatureTimer); + g.writeNumberField("mutability", mutability); + g.writeArrayFieldStart("name");g.writeNumber(name[0]);g.writeNumber(name[1]);g.writeEndArray(); + if(n != null){ + g.writeArrayFieldStart("nodes"); + for(int i = 0 ; i < this.n.size(); i++){ + g.writeStartObject(); this.n.get(i).saveToJson(g); g.writeEndObject(); + } + g.writeEndArray(); } - } - object.setJSONArray("nodes", nodeArray); - JSONArray muscleArray = new JSONArray(); - for(int i = 0; i < this.m.size(); i++){ - muscleArray.setJSONObject(i, this.m.get(i).saveToJson()); - } - object.setJSONArray("muscles", muscleArray); - object.setFloat("d", d); - object.setInt("id", id); - object.setBoolean("alive", alive); - object.setFloat("creatureTimer", creatureTimer); - object.setFloat("mutability", mutability); - object.setJSONObject("brain", brain.saveToJson()); - JSONArray nameArray = new JSONArray(); - for(int i = 0; i < name.length; i++){ - nameArray.setInt(i, name[i]); - } - object.setJSONArray("name", nameArray); - JSONArray foodArray = new JSONArray(); - for(int i = 0; i < foodPositions.length; i++){ - JSONArray iArray = new JSONArray(); - for(int j = 0; j < foodPositions[i].length; j++){ - iArray.setFloat(j, foodPositions[i][j]); + if(m != null){ + g.writeArrayFieldStart("muscles"); + for(int i = 0 ; i < this.m.size(); i++){ + g.writeStartObject(); this.m.get(i).saveToJson(g); g.writeEndObject(); + } + g.writeEndArray(); } - foodArray.setJSONArray(i, iArray); - } - object.setJSONArray("food", foodArray); - return object; - } - public void loadFromJson(JSONObject parent){ - JSONArray nodeArray = parent.getJSONArray("nodes"); - n = new ArrayList(); - for(int i = 0; i < nodeArray.size(); i++){ - Node node = new Node(0, 0, 0, 0, 0, 0, 0, 0); - node.loadFromJson(nodeArray.getJSONObject(i)); - n.add(node); - } - JSONArray muscleArray = parent.getJSONArray("muscles"); - m = new ArrayList(); - for(int i = 0; i < muscleArray.size(); i++){ - Muscle muscle = new Muscle(0, 0, 0, 0); - muscle.loadFromJson(muscleArray.getJSONObject(i)); - m.add(muscle); - } - d = parent.getFloat("d"); - id = parent.getInt("id"); - alive = parent.getBoolean("alive"); - creatureTimer = parent.getFloat("creatureTimer"); - mutability = parent.getFloat("mutability"); - brain = new Brain(1, 1); - brain.loadFromJson(parent.getJSONObject("brain")); - JSONArray nameArray = parent.getJSONArray("name"); - name = new int[nameArray.size()]; - for(int i = 0; i < nameArray.size(); i++){ - name[i] = nameArray.getInt(i); - } - JSONArray foodArray = parent.getJSONArray("food"); - foodPositions = new float[foodArray.size()][foodArray.getJSONArray(0).size()]; - for(int i = 0; i < foodArray.size(); i++){ - JSONArray iArray = foodArray.getJSONArray(i); - for(int j = 0; j < iArray.size(); j++){ - foodPositions[i][j] = iArray.getFloat(j); + g.writeArrayFieldStart("foodPositions"); + for(int i = 0; i < foodPositions.length; i++){ + g.writeStartArray(); + for(int j = 0; j < foodPositions[i].length; j++){ + g.writeNumber(foodPositions[i][j]); + } + g.writeEndArray(); } + g.writeEndArray(); + g.writeObjectFieldStart("brain"); this.brain.saveToJson(g); g.writeEndObject(); + } catch(Exception e){ + writeToErrorLog(e); } + + } + public void loadFromJson(JsonParser p){ + try{ + while(p.nextToken() != JsonToken.END_OBJECT){ + String fieldName = p.getCurrentName(); + JsonToken token = p.nextToken(); + if(fieldName.equals("d")){ d = p.getFloatValue(); } + else if(fieldName.equals("id")){ id = p.getIntValue(); } + else if(fieldName.equals("alive")){ alive = p.getBooleanValue(); } + else if(fieldName.equals("creatureTimer")){ creatureTimer = p.getFloatValue(); } + else if(fieldName.equals("mutability")){ mutability = p.getFloatValue(); } + else if(fieldName.equals("name")){ + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + int i = 0; + while(p.nextToken() != JsonToken.END_ARRAY){ + name[i] = p.getIntValue(); + i += 1; + } + } + else if(fieldName.equals("nodes")){ + this.n = new ArrayList(); + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_OBJECT){ + Node node = new Node(0, 0, 0, 0, 0, 0, 0, 0); + node.loadFromJson(p); + this.n.add(node); + } + } + } + else if(fieldName.equals("muscles")){ + this.m = new ArrayList(); + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_OBJECT){ + Muscle muscle = new Muscle(0, 0, 0, 0); + muscle.loadFromJson(p); + this.m.add(muscle); + } + } + } + else if(fieldName.equals("brain")){ + if (token != JsonToken.START_OBJECT) { throw new IOException("Expected Object"); } + brain = new Brain(1, 1); + brain.loadFromJson(p); + } + else if(fieldName.equals("foodPositions")){ + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + int i = 0; + foodPositions = new float[100][3]; + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_ARRAY){ + int j = 0; + while(p.nextToken() != JsonToken.END_ARRAY){ + foodPositions[i][j] = p.getFloatValue(); + j += 1; + } + } + i += 1; + } + } + } + } catch(Exception e) { writeToErrorLog(e); } } } \ No newline at end of file diff --git a/ISavable.pde b/ISavable.pde deleted file mode 100644 index 63fd620..0000000 --- a/ISavable.pde +++ /dev/null @@ -1,5 +0,0 @@ -interface ISavable{ - public JSONObject saveToJson(); - - public void loadFromJson(JSONObject object); -} \ No newline at end of file diff --git a/Muscle.pde b/Muscle.pde index 00d2012..cd87053 100644 --- a/Muscle.pde +++ b/Muscle.pde @@ -1,4 +1,4 @@ -class Muscle implements ISavable { +class Muscle { int c1, c2; float len; float rigidity; @@ -66,24 +66,34 @@ class Muscle implements ISavable { ni2.z*scaleToFixBug); } - public JSONObject saveToJson(){ - JSONObject object = new JSONObject(); - object.setInt("c1", c1); - object.setInt("c2", c2); - object.setFloat("len", len); - object.setFloat("rigidity", rigidity); - object.setFloat("previousTarget", previousTarget); - object.setFloat("brainOutput", brainOutput); - return object; + public void saveToJson(JsonGenerator g){ + try{ + g.writeNumberField("c1", this.c1); + g.writeNumberField("c2", this.c2); + g.writeNumberField("len", this.len); + g.writeNumberField("rigidity", this.rigidity); + g.writeNumberField("previousTarget", this.previousTarget); + g.writeNumberField("brainOutput", this.brainOutput); + } catch(Exception e){ + writeToErrorLog(e); + } } - public void loadFromJson(JSONObject parent){ - c1 = parent.getInt("c1"); - c2 = parent.getInt("c2"); - len = parent.getFloat("len"); - rigidity = parent.getFloat("rigidity"); - previousTarget = parent.getFloat("previousTarget"); - brainOutput = parent.getFloat("brainOutput"); + public void loadFromJson(JsonParser p){ + try{ + while(p.nextToken() != JsonToken.END_OBJECT){ + String fieldName = p.getCurrentName(); + p.nextToken(); + if(fieldName.equals("c1")){ this.c1 = p.getIntValue(); } + else if(fieldName.equals("c2")){ this.c2 = p.getIntValue(); } + else if(fieldName.equals("len")){ this.len = p.getFloatValue(); } + else if(fieldName.equals("rigidity")){ this.rigidity = p.getFloatValue(); } + else if(fieldName.equals("previousTarget")){ this.previousTarget = p.getFloatValue(); } + else if(fieldName.equals("brainOutput")){ this.brainOutput = p.getFloatValue(); } + } + } catch(Exception e){ + writeToErrorLog(e); + } } } \ No newline at end of file diff --git a/Node.pde b/Node.pde index 0350e2b..03b16ab 100644 --- a/Node.pde +++ b/Node.pde @@ -1,4 +1,4 @@ -class Node implements ISavable{ +class Node { float x, y, z, vx, vy, vz, prevX, prevY, prevZ, pvx, pvy, pvz, m, f; boolean safeInput; float pressure; @@ -187,44 +187,54 @@ class Node implements ISavable{ return color(red(a)+(red(b)-red(a))*x, green(a)+(green(b)-green(a))*x, blue(a)+(blue(b)-blue(a))*x); } - public JSONObject saveToJson(){ - JSONObject object = new JSONObject(); - object.setFloat("x", x); - object.setFloat("y", y); - object.setFloat("z", z); - object.setFloat("vx", vx); - object.setFloat("vy", vy); - object.setFloat("vz", vz); - object.setFloat("prevX", prevX); - object.setFloat("prevY", prevY); - object.setFloat("prevZ", prevZ); - object.setFloat("pvx", pvx); - object.setFloat("pvy", pvy); - object.setFloat("pvz", pvz); - object.setFloat("m", m); - object.setFloat("f", f); - object.setBoolean("safeInput", safeInput); - object.setFloat("pressure", pressure); - return object; + public void saveToJson(JsonGenerator g){ + try{ + g.writeNumberField("x", this.x); + g.writeNumberField("y", this.y); + g.writeNumberField("z", this.z); + g.writeNumberField("vx", this.vx); + g.writeNumberField("vy", this.vy); + g.writeNumberField("vz", this.vz); + g.writeNumberField("prevX", this.prevX); + g.writeNumberField("prevY", this.prevY); + g.writeNumberField("prevZ", this.prevZ); + g.writeNumberField("pvx", this.pvx); + g.writeNumberField("pvy", this.pvy); + g.writeNumberField("pvz", this.pvz); + g.writeNumberField("m", this.m); + g.writeNumberField("f", this.f); + g.writeBooleanField("safeInput", this.safeInput); + g.writeNumberField("pressure", this.pressure); + } catch(Exception e){ + writeToErrorLog(e); + } } - public void loadFromJson(JSONObject parent){ - x = parent.getFloat("x"); - y = parent.getFloat("y"); - z = parent.getFloat("z"); - vx = parent.getFloat("vx"); - vy = parent.getFloat("vy"); - vz = parent.getFloat("vz"); - prevX = parent.getFloat("prevX"); - prevY = parent.getFloat("prevY"); - prevZ = parent.getFloat("prevZ"); - pvx = parent.getFloat("pvx"); - pvy = parent.getFloat("pvy"); - pvz = parent.getFloat("pvz"); - m = parent.getFloat("m"); - f = parent.getFloat("f"); - safeInput = parent.getBoolean("safeInput"); - pressure = parent.getFloat("pressure"); + public void loadFromJson(JsonParser p){ + try{ + while(p.nextToken() != JsonToken.END_OBJECT){ + String fieldName = p.getCurrentName(); + p.nextToken(); + if(fieldName.equals("x")){ this.x = p.getFloatValue(); } + else if(fieldName.equals("y")){ this.y = p.getFloatValue(); } + else if(fieldName.equals("z")){ this.z = p.getFloatValue(); } + else if(fieldName.equals("vx")){ this.vx = p.getFloatValue(); } + else if(fieldName.equals("vy")){ this.vy = p.getFloatValue(); } + else if(fieldName.equals("vz")){ this.vz = p.getFloatValue(); } + else if(fieldName.equals("prevX")){ this.prevX = p.getFloatValue(); } + else if(fieldName.equals("prevY")){ this.prevY = p.getFloatValue(); } + else if(fieldName.equals("prevZ")){ this.prevZ = p.getFloatValue(); } + else if(fieldName.equals("pvx")){ this.pvx = p.getFloatValue(); } + else if(fieldName.equals("pvy")){ this.pvy = p.getFloatValue(); } + else if(fieldName.equals("pvz")){ this.pvz = p.getFloatValue(); } + else if(fieldName.equals("m")){ this.m = p.getFloatValue(); } + else if(fieldName.equals("f")){ this.f = p.getFloatValue(); } + else if(fieldName.equals("safeInput")){ this.safeInput = p.getBooleanValue(); } + else if(fieldName.equals("pressure")){ this.pressure = p.getFloatValue(); } + } + } catch(Exception e){ + writeToErrorLog(e); + } } } \ No newline at end of file diff --git a/code/jackson-core-2.9.0.pr4.jar b/code/jackson-core-2.9.0.pr4.jar new file mode 100644 index 0000000000000000000000000000000000000000..dbf541d1f34ad0ed2c24dde3174680437532e630 GIT binary patch literal 316575 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

L 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%0DogG=?LoZib_s(iUTtGL>^qS48HI8KL`$ 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%0D5Lcn;vO}%TWk-p}=?*0~P5RD* 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%0DPdU^^OynqPo9=?UrJ9_ptRUml>hWN_W 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

OZ18dvGit8X@+m&KkM+)Bj$ZhJxn0aW0s#9C` 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 Iu~z~8FRC#vJ^%m! literal 0 HcmV?d00001 diff --git a/evolutionSteer.pde b/evolutionSteer.pde index bd4ab09..9bda3b3 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -5,6 +5,12 @@ import java.util.zip.GZIPOutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonEncoding; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.dataformat.smile.SmileGenerator; +import com.fasterxml.jackson.dataformat.smile.SmileFactory; float windowSizeMultiplier = 1; @@ -42,7 +48,7 @@ int gridX = 50; // X * Y must be equal to nbCreatures ! int gridY = 40; int thresholdName = 25; // name of species is showed over this threshold -int autoSave = 100; // autosave every x generation in ALAP mode +int autoSave = 200; // autosave every x generation in ALAP mode boolean autoSaveTimecode = true; // set to false is disk space limited boolean hasAutosaveWorked = false; int autoPause = 10000; // pauses ALAP each x generation @@ -1423,6 +1429,7 @@ void draw() { } Files.move(source, Paths.get(finalfilename)); } catch(Exception e){ + println(e); writeToErrorLog(e); } } @@ -1728,155 +1735,197 @@ public void writeToErrorLog(Exception e){ } saveStrings("error.log", error); } + public void fileSelected(File file){ if(file != null){ try{ - FileInputStream in = new FileInputStream(file.getAbsolutePath()); - BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(in), "UTF-8")); - StringBuilder out = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { out.append(line); } - JSONObject object = parseJSONObject(out.toString()); - reader.close(); - loadFromJson(object); - setMenu(1); - randomSeed(SEED); - //redraw(); + JsonFactory factory = new SmileFactory(); + JsonParser p = factory.createParser(new GZIPInputStream(new FileInputStream(file.getAbsolutePath()))); + loadFromJson(p); + setMenu(1); + randomSeed(SEED); }catch(Exception e){ writeToErrorLog(e); } + } else { + setMenu(1); } } public void saveSelected(File file){ if(file != null){ try{ - JSONObject object = saveToJson(); - FileOutputStream out = new FileOutputStream(file.getAbsolutePath()); - Writer writer = new OutputStreamWriter(new GZIPOutputStream(out), "UTF-8"); - writer.write(object.toString()); - writer.close(); - hasAutosaveWorked = true; - setMenu(1); + JsonFactory factory = new SmileFactory(); + GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(file.getAbsolutePath())); + JsonGenerator generator = factory.createGenerator(out, JsonEncoding.UTF8); + generator.writeStartObject(); + saveToJson(generator); + generator.writeEndObject(); + generator.close(); + out.close(); + hasAutosaveWorked = true; + setMenu(1); }catch(Exception e){ writeToErrorLog(e); } + } else { + setMenu(1); } } -public JSONObject saveToJson(){ - JSONObject object = new JSONObject(); - object.setInt("seed", SEED); - JSONArray creatureArray = new JSONArray(); - for(int i = 0; i < creatureDatabase.size(); i++){ - if(creatureDatabase.get(i) != null){ - creatureArray.setJSONObject(i, creatureDatabase.get(i).saveToJson()); - } - } - object.setJSONArray("creatures", creatureArray); - JSONArray bars = new JSONArray(); - for(int i = 0; i < barCounts.size(); i++){ - JSONArray iArray = new JSONArray(); - for(int j = 0; j < barCounts.get(i).length; j++){ - iArray.setInt(j, barCounts.get(i)[j]); - } - bars.setJSONArray(i,iArray); - } - object.setJSONArray("bars", bars); - JSONArray percentiles = new JSONArray(); - for(int i = 0; i < percentile.size(); i++){ - JSONArray iArray = new JSONArray(); - for(int j = 0; j < percentile.get(i).length; j++){ - iArray.setFloat(j, percentile.get(i)[j]); - } - percentiles.setJSONArray(i,iArray); - } - object.setJSONArray("percentiles", percentiles); - JSONArray species = new JSONArray(); - for(int i = 0; i < speciesCounts.size(); i++){ - JSONArray iArray = new JSONArray(); - for(int j = 0; j < speciesCounts.get(i).length; j++){ - iArray.setInt(j, speciesCounts.get(i)[j]); - } - species.setJSONArray(i,iArray); - } - object.setJSONArray("species", species); - JSONArray cArray = new JSONArray(); - for(int i = 0; i < c.length; i++){ - cArray.setJSONObject(i, c[i].saveToJson()); - } - JSONArray topSpeciesArray = new JSONArray(); - for(int i = 0; i < topSpeciesCounts.size(); i++){ - topSpeciesArray.setInt(i, topSpeciesCounts.get(i)); - } - object.setJSONArray("topSpecies", topSpeciesArray); - object.setJSONArray("c", cArray); - - object.setFloat("foodChange", foodAngleChange); - object.setInt("gen", gen); - object.setInt("nbcreatures", nbCreatures); - object.setInt("gridX", gridX); - object.setInt("gridY", gridY); - return object; +public void saveToJson(JsonGenerator g){ + try{ + g.writeNumberField("version", 1); + g.writeNumberField("seed", SEED); + g.writeNumberField("foodChange", foodAngleChange); + g.writeNumberField("gen", gen); + g.writeNumberField("nbcreatures", nbCreatures); + g.writeNumberField("gridX", gridX); + g.writeNumberField("gridY", gridY); + g.writeArrayFieldStart("creatureDatabase"); + for(int i = 0; i < creatureDatabase.size(); i++){ + if(creatureDatabase.get(i) != null){ + g.writeStartObject(); creatureDatabase.get(i).saveToJson(g); g.writeEndObject(); + } + } + g.writeEndArray(); + g.writeArrayFieldStart("barCounts"); + for(int i = 0; i < barCounts.size(); i++){ + g.writeStartArray(); + for(int j = 0; j < barCounts.get(i).length; j++){ + g.writeNumber(barCounts.get(i)[j]); + } + g.writeEndArray(); + } + g.writeEndArray(); + g.writeArrayFieldStart("percentiles"); + for(int i = 0; i < percentile.size(); i++){ + g.writeStartArray(); + for(int j = 0; j < percentile.get(i).length; j++){ + g.writeNumber(percentile.get(i)[j]); + } + g.writeEndArray(); + } + g.writeEndArray(); + g.writeArrayFieldStart("species"); + for(int i = 0; i < speciesCounts.size(); i++){ + g.writeStartArray(); + for(int j = 0; j < speciesCounts.get(i).length; j++){ + g.writeNumber(speciesCounts.get(i)[j]); + } + g.writeEndArray(); + } + g.writeEndArray(); + g.writeArrayFieldStart("creatureArray"); + for(int i = 0; i < c.length; i++){ + g.writeStartObject(); c[i].saveToJson(g); g.writeEndObject(); + } + g.writeEndArray(); + g.writeArrayFieldStart("topSpecies"); + for(int i = 0; i < topSpeciesCounts.size(); i++){ + g.writeNumber(topSpeciesCounts.get(i)); + } + g.writeEndArray(); + } catch(Exception e){ + writeToErrorLog(e); + } } -public void loadFromJson(JSONObject parent){ - SEED = parent.getInt("seed"); - creatureDatabase.clear(); - JSONArray creatureArray = parent.getJSONArray("creatures"); - for(int i = 0; i < creatureArray.size(); i++){ - Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); - creature.loadFromJson(creatureArray.getJSONObject(i)); - creatureDatabase.add(creature); - } - barCounts.clear(); - JSONArray bars = parent.getJSONArray("bars"); - for(int i = 0; i < bars.size(); i++){ - JSONArray iArray = bars.getJSONArray(i); - Integer[] array = new Integer[iArray.size()]; - for(int j = 0; j < iArray.size(); j++){ - array[j] = iArray.getInt(j); - } - barCounts.add(array); - } - percentile.clear(); - JSONArray percentiles = parent.getJSONArray("percentiles"); - for(int i = 0; i < percentiles.size(); i++){ - JSONArray iArray = percentiles.getJSONArray(i); - Float[] array = new Float[iArray.size()]; - for(int j = 0; j < iArray.size(); j++){ - array[j] = iArray.getFloat(j); - } - percentile.add(array); - } - speciesCounts.clear(); - JSONArray species = parent.getJSONArray("species"); - for(int i = 0; i < species.size(); i++){ - JSONArray iArray = species.getJSONArray(i); - Integer[] array = new Integer[iArray.size()]; - for(int j = 0; j < iArray.size(); j++){ - array[j] = iArray.getInt(j); - } - speciesCounts.add(array); - } - nbCreatures = parent.getInt("nbcreatures"); - gridX = parent.getInt("gridX"); - gridY = parent.getInt("gridY"); - initPercentiles(); - c = new Creature[nbCreatures]; - JSONArray cArray = parent.getJSONArray("c"); - for(int i = 0; i < cArray.size(); i++){ - Creature temp = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); - temp.loadFromJson(cArray.getJSONObject(i)); - c[i] = temp; - c2.add(c[i]); - } - topSpeciesCounts.clear(); - JSONArray topSpeciesArray = parent.getJSONArray("topSpecies"); - for(int i = 0; i < topSpeciesArray.size(); i++){ - topSpeciesCounts.add(topSpeciesArray.getInt(i)); - } - foodAngleChange = parent.getFloat("foodChange"); - gen = parent.getInt("gen"); - genSelected = gen; +public void loadFromJson(JsonParser p){ + try{ + if (p.nextToken() != JsonToken.START_OBJECT) { + throw new IOException("Expected data to start with an Object"); + } + while(p.nextToken() != JsonToken.END_OBJECT){ + String fieldName = p.getCurrentName(); + JsonToken token = p.nextToken(); + if(fieldName.equals("seed")){ SEED = p.getIntValue(); } + else if(fieldName.equals("foodChange")){ foodAngleChange = p.getFloatValue(); } + else if(fieldName.equals("gen")){ gen = p.getIntValue(); genSelected = gen; } + else if(fieldName.equals("nbcreatures")){ nbCreatures = p.getIntValue(); initPercentiles(); } + else if(fieldName.equals("gridX")){ gridX = p.getIntValue(); } + else if(fieldName.equals("gridY")){ gridX = p.getIntValue(); } + else if(fieldName.equals("creatureDatabase")){ + creatureDatabase.clear(); + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_OBJECT){ + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); + creature.loadFromJson(p); + creatureDatabase.add(creature); + } + } + } + else if(fieldName.equals("barCounts")){ + barCounts.clear(); + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + int i = 0; + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_ARRAY){ + int j = 0; + Integer[] tmpBar = new Integer[barLen]; + while(p.nextToken() != JsonToken.END_ARRAY){ + tmpBar[j] = p.getIntValue(); + j += 1; + } + barCounts.add(tmpBar); + i += 1; + } + } + } + else if(fieldName.equals("percentiles")){ + percentile.clear(); + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_ARRAY){ + int j = 0; + Float[] tmpPercentile = new Float[29]; + while(p.nextToken() != JsonToken.END_ARRAY){ + tmpPercentile[j] = p.getFloatValue(); + j += 1; + } + percentile.add(tmpPercentile); + } + } + } + else if(fieldName.equals("species")){ + speciesCounts.clear(); + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_ARRAY){ + int j = 0; + Integer[] tmpSpecies = new Integer[101]; + while(p.nextToken() != JsonToken.END_ARRAY){ + tmpSpecies[j] = p.getIntValue(); + j += 1; + } + speciesCounts.add(tmpSpecies); + } + } + } + else if(fieldName.equals("topSpecies")){ + topSpeciesCounts.clear(); + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + while(p.nextToken() != JsonToken.END_ARRAY){ + topSpeciesCounts.add(p.getIntValue()); + } + } + else if(fieldName.equals("creatureArray")){ + c = new Creature[nbCreatures]; + if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } + int i = 0; + while((token = p.nextToken()) != JsonToken.END_ARRAY){ + if (token == JsonToken.START_OBJECT){ + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); + creature.loadFromJson(p); + c[i] = creature; + c2.add(c[i]); + i += 1; + } + } + } + } + } catch(Exception e){ + writeToErrorLog(e); + } } \ No newline at end of file From e0de5fc629e2bb7b854fe2b014749e29645798dc Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Wed, 26 Jul 2017 02:00:52 +0200 Subject: [PATCH 24/50] Optimisation Approximate sigmoid function for speed improvement --- Brain.pde | 17 ++++++++++++++++- Creature.pde | 3 --- evolutionSteer.pde | 13 ++++++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Brain.pde b/Brain.pde index c69eeb1..f337354 100644 --- a/Brain.pde +++ b/Brain.pde @@ -114,7 +114,22 @@ class Brain { } } public float sigmoid(float input){ - return 1.0/(1.0+pow(2.71828182846,-input)); + //return 1.0/(1.0+pow(2.71828182846,-input)); + if(input >= -1 && input <= 1){ + return 0.25*input+0.5; + } else if(input >= -3 && input < -1){ + return 0.105*input+0.1192; + } else if(input > 1 && input <= 3){ + return 0.105*input+0.8808; + } else if(input >= -5 && input < -3){ + return 0.0177*input+0.018; + } else if(input > 3 && input <= 5){ + return 0.0177*input+0.982; + } else if(input < -5){ + return 0; + } else { + return 1; + } } Brain getUsableCopyOfBrain(){ return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons.clone(),true,false); diff --git a/Creature.pde b/Creature.pde index 9b6e6bd..f15c937 100644 --- a/Creature.pde +++ b/Creature.pde @@ -60,9 +60,6 @@ class Creature { void changeBrainStructure(int rowInsertionIndex, int rowRemovalIndex){ this.brain.changeBrainStructure(BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex,rowRemovalIndex); } - public float sigmoid(float input){ - return 1.0/(1.0+pow(2.71828182846,-input)); - } Creature modified(int id, float mutationFactor) { float modMut = mutationFactor * mutability; if(mutationFactor > 1.0 && modMut < 1.0){ modMut = 1.5; mutability = 1.0; } diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 9bda3b3..a2acdc4 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -140,6 +140,7 @@ int[] CREATURES_PER_PATRON = new int[PATRON_COUNT]; float startingFoodDistance = 0; int THREAD_COUNT = 14; +boolean activateMultiThreading = true; float inter(int a, int b, float offset) { return float(a)+(float(b)-float(a))*offset; @@ -1131,18 +1132,25 @@ void draw() { lastIndex = (int)((i+1) * float(nbCreatures) / threads.length); } threads[i] = new Thread(new ComputingThread(firstIndex, lastIndex, simDuration*frames)); - threads[i].start(); + if(activateMultiThreading){ + threads[i].start(); + } previousLastIndex = lastIndex; } for(int i = 0; i < threads.length; i++) { try { - threads[i].join(); + if(activateMultiThreading){ + threads[i].join(); + } else { + threads[i].run(); + } } catch (InterruptedException ie) { ie.printStackTrace(); // :( } } double simulationTime = Math.round((System.nanoTime() - start) / 100000D) / 10; surface.setTitle("evolutionSteer | simulationTime: " + simulationTime + " ms"); + //println(simulationTime); setMenu(6); } } @@ -1429,7 +1437,6 @@ void draw() { } Files.move(source, Paths.get(finalfilename)); } catch(Exception e){ - println(e); writeToErrorLog(e); } } From 085a50515d0412328d38b2857f7b4971368781c0 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Wed, 26 Jul 2017 11:35:03 +0200 Subject: [PATCH 25/50] Expanded brain Can add one layer when mutating --- Axon.pde | 3 +++ Brain.pde | 20 +++++++++++++++++++- Creature.pde | 26 ++++++++++++++++++-------- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Axon.pde b/Axon.pde index 7a08fae..4db79a0 100644 --- a/Axon.pde +++ b/Axon.pde @@ -11,6 +11,9 @@ class Axon { MUTATE_MULTI = Math.pow(0.5,mutatePower); } + public Axon copyAxon(){ + return new Axon(this.weight,this.mutability); + } public Axon mutateAxon(){ double mutabilityMutate = Math.pow(0.5,pmRan()*MUTABILITY_MUTABILITY); return new Axon(weight+r()*mutability/MUTATE_MULTI,mutability*mutabilityMutate); diff --git a/Brain.pde b/Brain.pde index f337354..0e2078b 100644 --- a/Brain.pde +++ b/Brain.pde @@ -18,7 +18,7 @@ class Brain { for(int x = 0; x < BRAIN_WIDTH-1; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ for(int z = 0; z < BRAIN_HEIGHT-1; z++){ - axons[x][y][z] = new Axon(templateAxons[x][y][z].weight,templateAxons[x][y][z].mutability); + axons[x][y][z] = templateAxons[x][y][z].copyAxon(); } } } @@ -140,6 +140,24 @@ class Brain { Brain copyMutatedBrain(){ return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons.clone(),false,true); } + Brain copyExpandedBrain(){ + Axon[][][] extaxons = new Axon[BRAIN_WIDTH][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + for(int x = 0; x < BRAIN_WIDTH; x++){ + for(int y = 0; y < BRAIN_HEIGHT; y++){ + for(int z = 0; z < BRAIN_HEIGHT-1; z++){ + if(x < BRAIN_WIDTH - 1){ extaxons[x][y][z] = axons[x][y][z].copyAxon(); } + if(x == BRAIN_WIDTH - 1){ + if(y == z){ + extaxons[x][y][z] = new Axon(1.0,AXON_START_MUTABILITY); + } else { + extaxons[x][y][z] = new Axon(0.0,AXON_START_MUTABILITY); + } + } + } + } + } + return new Brain(BRAIN_WIDTH+1,BRAIN_HEIGHT,extaxons.clone(),false,false); + } public void drawBrain(float scaleUp, Creature owner){ ArrayList n = owner.n; ArrayList m = owner.m; diff --git a/Creature.pde b/Creature.pde index f15c937..460fe25 100644 --- a/Creature.pde +++ b/Creature.pde @@ -61,8 +61,9 @@ class Creature { this.brain.changeBrainStructure(BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex,rowRemovalIndex); } Creature modified(int id, float mutationFactor) { - float modMut = mutationFactor * mutability; - if(mutationFactor > 1.0 && modMut < 1.0){ modMut = 1.5; mutability = 1.0; } + float modMut; + if(mutationFactor == 1.0){ mutationFactor = mutability; modMut = mutability; } + else{ modMut = mutability; } ArrayList newN = new ArrayList(0); ArrayList newM = new ArrayList(0); for (int i = 0; i < this.n.size(); i++) { @@ -73,21 +74,30 @@ class Creature { } boolean bigMutAddNode = false, bigMutRemoveNode = false, bigMutAddMuscle = false, bigMutRemoveMuscle = false; - if (random(0, 1) < bigMutationChance*modMut || this.n.size() <= 2){ bigMutAddNode = true; } - if (random(0, 1) < bigMutationChance*modMut) { bigMutAddMuscle = true; } - if (random(0, 1) < bigMutationChance*modMut && this.n.size() >= 5) { bigMutRemoveNode = true; } - if (random(0, 1) < bigMutationChance*modMut && this.m.size() >= 2) { bigMutRemoveMuscle = true; } + boolean bigMutExpandBrain = false; + if (random(0, 1) < bigMutationChance*mutationFactor || this.n.size() <= 2){ bigMutAddNode = true; } + if (random(0, 1) < bigMutationChance*mutationFactor) { bigMutAddMuscle = true; } + if (random(0, 1) < bigMutationChance*mutationFactor && this.n.size() >= 5) { bigMutRemoveNode = true; } + if (random(0, 1) < bigMutationChance*mutationFactor && this.m.size() >= 2) { bigMutRemoveMuscle = true; } + if (random(0, 1) < bigMutationChance*mutationFactor && this.brain.BRAIN_WIDTH < 5) { bigMutExpandBrain = true; } int[] newName = new int[2]; - if(bigMutAddNode || bigMutRemoveNode || bigMutAddMuscle || bigMutRemoveMuscle){ + if(bigMutAddNode || bigMutRemoveNode || bigMutAddMuscle || bigMutRemoveMuscle || bigMutExpandBrain){ newName = getNewCreatureName(); } else { newName[0] = name[0]; newName[1] = CREATURES_PER_PATRON[name[0]]; CREATURES_PER_PATRON[name[0]]++; } + + Brain tmpBrain; + if(bigMutExpandBrain){ + tmpBrain = this.brain.copyExpandedBrain(); + } else { + tmpBrain = this.brain.copyMutatedBrain(); + } Creature modifiedCreature = new Creature(newName, id, - newN, newM, 0, true, creatureTimer+r()*16*modMut, min(mutability*random(0.8, 1.25), 2), this.brain.copyMutatedBrain(),null); + newN, newM, 0, true, creatureTimer+r()*16*modMut, min(mutability*random(0.8, 1.25), 2), tmpBrain,null); if (bigMutAddNode) { //Add a node modifiedCreature.addRandomNode(); } From d16253953e5765f5abdfe438d36c79cf007c24d7 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:21:15 +0200 Subject: [PATCH 26/50] Ignore all gz files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a5643f7..00de0bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ data/autosave\.gz -data/autosave-*\.gz +data/*\.gz error\.log From de5d440f4ebb20a41b81ff146b37c597ce2fce95 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:31:57 +0200 Subject: [PATCH 27/50] Light save --- Creature.pde | 7 +++--- evolutionSteer.pde | 59 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/Creature.pde b/Creature.pde index 460fe25..d63bbfa 100644 --- a/Creature.pde +++ b/Creature.pde @@ -58,7 +58,7 @@ class Creature { return this.n.size()+m.size()+1; } void changeBrainStructure(int rowInsertionIndex, int rowRemovalIndex){ - this.brain.changeBrainStructure(BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex,rowRemovalIndex); + this.brain.changeBrainStructure(this.brain.BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex,rowRemovalIndex); } Creature modified(int id, float mutationFactor) { float modMut; @@ -382,10 +382,11 @@ class Creature { return hasEaten; } - public void saveToJson(JsonGenerator g){ + public void saveToJson(JsonGenerator g, int overwriteId){ try{ g.writeNumberField("d", d); - g.writeNumberField("id", id); + if(overwriteId == -1) { g.writeNumberField("id", id); } + else { g.writeNumberField("id", overwriteId); } g.writeBooleanField("alive", alive); g.writeNumberField("creatureTimer", creatureTimer); g.writeNumberField("mutability", mutability); diff --git a/evolutionSteer.pde b/evolutionSteer.pde index a2acdc4..ff816a7 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -605,6 +605,9 @@ void mouseReleased() { }else if(menu == 1 && gen != -1 && abs(mX - 650) <= 50 && abs(mY - 90) <= 20){ setMenu(15); selectOutput("Select file to save simulation to", "saveSelected"); + }else if(menu == 1 && gen != -1 && abs(mX - 505) <= 85 && abs(mY - 90) <= 20){ + setMenu(15); + selectOutput("Select file to save simulation to", "saveSelectedLight"); }else if (menu == 3 && abs(mX-1030) <= 130 && abs(mY-684) <= 20) { gen = 0; setMenu(1); @@ -1021,7 +1024,7 @@ void draw() { background(255, 200, 130); textFont(font, 32); textAlign(LEFT); - textFont(font, 96); + textFont(font, 72); text("GEN "+max(genSelected, 0), 20, 100); textFont(font, 28); if (gen == -1) { @@ -1037,6 +1040,7 @@ void draw() { rect(760, 70, 460, 40); rect(760, 120, 230, 40); rect(600, 70, 100, 40); + rect(420, 70, 170, 40); if (gensToDo >= 2) { fill(128, 255, 128); } else { @@ -1055,6 +1059,7 @@ void draw() { text("Do gens ALAP.", 1000, 150); text("Median "+fitnessName, 50, 160); text("Save", 610, 100); + text("Light save", 430, 100); textAlign(CENTER); textAlign(RIGHT); text(float(round(percentile.get(min(genSelected, percentile.size()-1))[14]*nbCreatures))/nbCreatures+" "+fitnessUnit, 700, 160); @@ -1374,10 +1379,8 @@ void draw() { j2 = nbCreatures-1-j; j3 = j; } - Creature cj = c2.get(j2); - cj.alive = true; - Creature ck = c2.get(j3); - ck.alive = false; + c2.get(j2).alive = true; + c2.get(j3).alive = false; } if (stepbystep) { drawScreenImage(2); @@ -1760,13 +1763,19 @@ public void fileSelected(File file){ } public void saveSelected(File file){ + saveFunc(file, false); +} +public void saveSelectedLight(File file){ + saveFunc(file, true); +} +public void saveFunc(File file, boolean light){ if(file != null){ try{ JsonFactory factory = new SmileFactory(); GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(file.getAbsolutePath())); JsonGenerator generator = factory.createGenerator(out, JsonEncoding.UTF8); generator.writeStartObject(); - saveToJson(generator); + saveToJson(generator, light); generator.writeEndObject(); generator.close(); out.close(); @@ -1780,24 +1789,32 @@ public void saveSelected(File file){ } } -public void saveToJson(JsonGenerator g){ +public void saveToJson(JsonGenerator g, boolean light){ try{ g.writeNumberField("version", 1); g.writeNumberField("seed", SEED); g.writeNumberField("foodChange", foodAngleChange); - g.writeNumberField("gen", gen); + if(light) { g.writeNumberField("gen", 1); } + else { g.writeNumberField("gen", gen); } g.writeNumberField("nbcreatures", nbCreatures); g.writeNumberField("gridX", gridX); g.writeNumberField("gridY", gridY); + + int l = 0, l2 = -1; + if(light) { l = creatureDatabase.size() - 6; } g.writeArrayFieldStart("creatureDatabase"); - for(int i = 0; i < creatureDatabase.size(); i++){ + for(int i = l; i < creatureDatabase.size(); i++){ if(creatureDatabase.get(i) != null){ - g.writeStartObject(); creatureDatabase.get(i).saveToJson(g); g.writeEndObject(); + if(light) { l2 = i - creatureDatabase.size() + 6; } + g.writeStartObject(); creatureDatabase.get(i).saveToJson(g, l2); g.writeEndObject(); } } g.writeEndArray(); + + l = 0; + if(light) { l = barCounts.size() - 2; } g.writeArrayFieldStart("barCounts"); - for(int i = 0; i < barCounts.size(); i++){ + for(int i = l; i < barCounts.size(); i++){ g.writeStartArray(); for(int j = 0; j < barCounts.get(i).length; j++){ g.writeNumber(barCounts.get(i)[j]); @@ -1805,8 +1822,11 @@ public void saveToJson(JsonGenerator g){ g.writeEndArray(); } g.writeEndArray(); + + l = 0; + if(light) { l = percentile.size() - 2; } g.writeArrayFieldStart("percentiles"); - for(int i = 0; i < percentile.size(); i++){ + for(int i = l; i < percentile.size(); i++){ g.writeStartArray(); for(int j = 0; j < percentile.get(i).length; j++){ g.writeNumber(percentile.get(i)[j]); @@ -1814,8 +1834,11 @@ public void saveToJson(JsonGenerator g){ g.writeEndArray(); } g.writeEndArray(); + + l = 0; + if(light) { l = speciesCounts.size() - 2; } g.writeArrayFieldStart("species"); - for(int i = 0; i < speciesCounts.size(); i++){ + for(int i = l; i < speciesCounts.size(); i++){ g.writeStartArray(); for(int j = 0; j < speciesCounts.get(i).length; j++){ g.writeNumber(speciesCounts.get(i)[j]); @@ -1823,13 +1846,19 @@ public void saveToJson(JsonGenerator g){ g.writeEndArray(); } g.writeEndArray(); + + l2 = -1; g.writeArrayFieldStart("creatureArray"); for(int i = 0; i < c.length; i++){ - g.writeStartObject(); c[i].saveToJson(g); g.writeEndObject(); + if(light) { l2 = i + nbCreatures + 1; } + g.writeStartObject(); c[i].saveToJson(g, l2); g.writeEndObject(); } g.writeEndArray(); + + l = 0; + if(light) { l = topSpeciesCounts.size() - 2; } g.writeArrayFieldStart("topSpecies"); - for(int i = 0; i < topSpeciesCounts.size(); i++){ + for(int i = l; i < topSpeciesCounts.size(); i++){ g.writeNumber(topSpeciesCounts.get(i)); } g.writeEndArray(); From d5435753102a56a0fe276c936fb33c7d4a9ee3ea Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:39:09 +0200 Subject: [PATCH 28/50] Gift function --- computingThread.pde | 9 ++--- evolutionSteer.pde | 91 ++++++++++++++++++++++++++++----------------- 2 files changed, 61 insertions(+), 39 deletions(-) diff --git a/computingThread.pde b/computingThread.pde index 94ade9f..7f01946 100644 --- a/computingThread.pde +++ b/computingThread.pde @@ -3,22 +3,21 @@ public class ComputingThread implements Runnable{ private int endIndex; private int framePerChomp; private Creature myCreature; - public ComputingThread(int bi, int ei, int fpc){ + public ComputingThread(int bi, int ei){ this.beginIndex = bi; this.endIndex = ei; - this.framePerChomp = fpc; } @Override public void run() { for(int k = this.beginIndex; k < this.endIndex; k++) { myCreature = c[k].copyCreature(-1,false,true); myCreature.calculateNextFoodLocation(); - int myMaxChomp = this.framePerChomp; + int myMaxFrames = maxFrames; boolean isJumper = false; - for (int sim = 0; sim < myMaxChomp; sim++) { + for (int sim = 0; sim < myMaxFrames; sim++) { if(myCreature.simulate()){ // activated when chomped if(sim <= jumperFrames){ isJumper = true; break; } // we kill jumpers - myMaxChomp += this.framePerChomp; + myMaxFrames += giftForChompFrames; } } if(isJumper){ diff --git a/evolutionSteer.pde b/evolutionSteer.pde index ff816a7..5c71e06 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -84,8 +84,10 @@ int frames = 60; int simDuration = 15; // in seconds int jumperDuration = 1; // definition of jumper : chomp < this value (in seconds) int maxFrames = simDuration*frames; -int maxSimulationFrames = simDuration*frames; +int maxSimulationFrames = maxFrames; int jumperFrames = jumperDuration*frames; +float giftForChompSec = 15; +int giftForChompFrames = ceil(giftForChompSec*frames); int menu = 0; int gen = -1; float sliderX = 1170; @@ -602,10 +604,10 @@ void mouseReleased() { } startASAP(); } - }else if(menu == 1 && gen != -1 && abs(mX - 650) <= 50 && abs(mY - 90) <= 20){ + }else if(menu == 1 && gen != -1 && abs(mX - 650) <= 50 && abs(mY - 48) <= 20){ setMenu(15); selectOutput("Select file to save simulation to", "saveSelected"); - }else if(menu == 1 && gen != -1 && abs(mX - 505) <= 85 && abs(mY - 90) <= 20){ + }else if(menu == 1 && gen != -1 && abs(mX - 505) <= 85 && abs(mY - 48) <= 20){ setMenu(15); selectOutput("Select file to save simulation to", "saveSelectedLight"); }else if (menu == 3 && abs(mX-1030) <= 130 && abs(mY-684) <= 20) { @@ -906,7 +908,7 @@ void drawStatusWindow(boolean isFirstFrame) { drawBrain(px2-130, py2, 1,5, cj); drawStats(px2+355, py2+239, 1, 0.45); - if(simulateCurrentCreature()){ maxSimulationFrames += simDuration*frames; } + if(simulateCurrentCreature()){ maxSimulationFrames += giftForChompFrames; } int shouldBeWatching = statusWindow; if (statusWindow <= -1) { cj = creatureDatabase.get((genSelected-1)*3+statusWindow+3); @@ -1017,7 +1019,7 @@ void draw() { text("EVOLUTION!", windowWidth/2, 200); text("START", windowWidth/2, 430); textSize(26); - text("Load simulation", windowWidth/2, 600); + text("Load simulation", windowWidth/2, 610); }else if (menu == 1) { noStroke(); fill(0); @@ -1039,8 +1041,8 @@ void draw() { rect(760, 20, 460, 40); rect(760, 70, 460, 40); rect(760, 120, 230, 40); - rect(600, 70, 100, 40); - rect(420, 70, 170, 40); + rect(600, 20, 100, 40); + rect(420, 20, 170, 40); if (gensToDo >= 2) { fill(128, 255, 128); } else { @@ -1049,17 +1051,18 @@ void draw() { rect(990, 120, 230, 40); fill(0); //text("Survivor Bias: "+percentify(getSB(genSelected)), 437, 50); - text("Curve: ±"+nf(foodAngleChange/(2*PI)*360,0,2)+" degrees", 420, 50); + text("Curve: ±"+nf(foodAngleChange/(2*PI)*360,0,2)+" degrees", 420, 110); + text("Gift: +"+nf(giftForChompSec)+" seconds", 470, 135); if(enableRadioactivity){ - text("Radioactive mode", 460, 130); + text("Radioactive mode", 460, 85); } text("Do 1 step-by-step generation.", 770, 50); text("Do 1 quick generation.", 770, 100); text("Do 1 gen ASAP.", 770, 150); text("Do gens ALAP.", 1000, 150); text("Median "+fitnessName, 50, 160); - text("Save", 610, 100); - text("Light save", 430, 100); + text("Save", 620, 48); + text("Light save", 435, 48); textAlign(CENTER); textAlign(RIGHT); text(float(round(percentile.get(min(genSelected, percentile.size()-1))[14]*nbCreatures))/nbCreatures+" "+fitnessUnit, 700, 160); @@ -1136,7 +1139,7 @@ void draw() { } else { lastIndex = (int)((i+1) * float(nbCreatures) / threads.length); } - threads[i] = new Thread(new ComputingThread(firstIndex, lastIndex, simDuration*frames)); + threads[i] = new Thread(new ComputingThread(firstIndex, lastIndex)); if(activateMultiThreading){ threads[i].start(); } @@ -1413,10 +1416,11 @@ void draw() { } for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - c[cj.id-(gen*nbCreatures)-nbCreatures-1] = cj.copyCreature(-1,false,false); + c[cj.id%nbCreatures] = cj.copyCreature(-1,false,false); } drawScreenImage(3); gen++; + genSelected = gen; recalcSlider(); massExtinction = false; if (stepbystep) { setMenu(13); @@ -1463,12 +1467,14 @@ void draw() { noStroke(); if (gen >= 1) { textAlign(CENTER); - if (gen >= 5) { - genSelected = round((sliderX-760)*(gen-1)/410)+1; - } else { - genSelected = round((sliderX-760)*gen/410); + if(drag){ + if (gen >= 5) { + genSelected = round((sliderX-760)*(gen-1)/410)+1; + } else { + genSelected = round((sliderX-760)*gen/410); + } + sliderX = min(max(sliderX+(mX-25-sliderX)*0.2, 760), 1170); } - if (drag) sliderX = min(max(sliderX+(mX-25-sliderX)*0.2, 760), 1170); fill(100); rect(760, 340, 460, 50); fill(220); @@ -1535,6 +1541,9 @@ float getSB(int g){ return 1.0; //return 0.7+0.3*cos(g*(2*PI)/50.0); } +void recalcSlider() { + sliderX = 760+(genSelected*410/gen); +} void keysToMoveCamera(){ if(keyPressed){ if(key == 'w'){ @@ -1573,21 +1582,31 @@ void keysToMoveCamera(){ camVA = min(max(camVA,-PI*0.499),-PI*0.001); } void keyPressed(){ - if(key == 't'){ - foodAngleChange += 5.0/360.0*(2*PI); - setMenu(1); - } - if(key == 'g'){ - foodAngleChange -= 5.0/360.0*(2*PI); - setMenu(1); - } - if(key == 'r'){ - enableRadioactivity = !enableRadioactivity; - setMenu(1); - } - if(key == 'k'){ - massExtinction = true; - setMenu(1); + if (key == CODED) { + if (keyCode == LEFT) { + genSelected -= 1; + if(genSelected < 0) { genSelected = 0; } + } else if (keyCode == RIGHT) { + genSelected += 1; + if(genSelected > gen) { genSelected = gen; } + } + } else { + if(key == 't'){ + foodAngleChange += 5.0/360.0*(2*PI); + setMenu(1); + } + if(key == 'g'){ + foodAngleChange -= 5.0/360.0*(2*PI); + setMenu(1); + } + if(key == 'r'){ + enableRadioactivity = !enableRadioactivity; + setMenu(1); + } + if(key == 'k'){ + massExtinction = true; + setMenu(1); + } } } void drawStats(float x, float y, float z, float size){ @@ -1791,9 +1810,10 @@ public void saveFunc(File file, boolean light){ public void saveToJson(JsonGenerator g, boolean light){ try{ - g.writeNumberField("version", 1); + g.writeNumberField("version", 2); g.writeNumberField("seed", SEED); g.writeNumberField("foodChange", foodAngleChange); + g.writeNumberField("giftForChompSec", giftForChompSec); if(light) { g.writeNumberField("gen", 1); } else { g.writeNumberField("gen", gen); } g.writeNumberField("nbcreatures", nbCreatures); @@ -1881,6 +1901,9 @@ public void loadFromJson(JsonParser p){ else if(fieldName.equals("nbcreatures")){ nbCreatures = p.getIntValue(); initPercentiles(); } else if(fieldName.equals("gridX")){ gridX = p.getIntValue(); } else if(fieldName.equals("gridY")){ gridX = p.getIntValue(); } + else if(fieldName.equals("giftForChompSec")){ + giftForChompSec = p.getFloatValue(); giftForChompFrames = ceil(giftForChompSec*frames); + } else if(fieldName.equals("creatureDatabase")){ creatureDatabase.clear(); if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } From 2f8d5b606ebbbce6afa8f634ee726639b2b0b7a5 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:40:33 +0200 Subject: [PATCH 29/50] Update mutation comportement loss function for large brains --- Creature.pde | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Creature.pde b/Creature.pde index d63bbfa..7952328 100644 --- a/Creature.pde +++ b/Creature.pde @@ -79,7 +79,7 @@ class Creature { if (random(0, 1) < bigMutationChance*mutationFactor) { bigMutAddMuscle = true; } if (random(0, 1) < bigMutationChance*mutationFactor && this.n.size() >= 5) { bigMutRemoveNode = true; } if (random(0, 1) < bigMutationChance*mutationFactor && this.m.size() >= 2) { bigMutRemoveMuscle = true; } - if (random(0, 1) < bigMutationChance*mutationFactor && this.brain.BRAIN_WIDTH < 5) { bigMutExpandBrain = true; } + if (random(0, 1) < bigMutationChance*mutationFactor*(5-this.brain.BRAIN_WIDTH)/2 && this.brain.BRAIN_WIDTH < 5) { bigMutExpandBrain = true; } int[] newName = new int[2]; if(bigMutAddNode || bigMutRemoveNode || bigMutAddMuscle || bigMutRemoveMuscle || bigMutExpandBrain){ @@ -96,8 +96,14 @@ class Creature { } else { tmpBrain = this.brain.copyMutatedBrain(); } + float newMut; + if(mutationFactor > 1){ + newMut = max(min(mutability*random((float)0.8, (float)1.25), 2), (float)0.2); + } else { + newMut = min(mutability*random((float)0.8, (float)1.25), 2); + } Creature modifiedCreature = new Creature(newName, id, - newN, newM, 0, true, creatureTimer+r()*16*modMut, min(mutability*random(0.8, 1.25), 2), tmpBrain,null); + newN, newM, 0, true, creatureTimer+r()*16*modMut, newMut, tmpBrain,null); if (bigMutAddNode) { //Add a node modifiedCreature.addRandomNode(); } @@ -342,7 +348,8 @@ class Creature { } if(hasNodeOffGround){ float withinChomp = max(1.0-this.getCurrentFoodDistance()/this.startingFoodDistance,0); - return chomps+withinChomp;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. + float loss = (this.brain.BRAIN_WIDTH - 2)*(float)0.05; // loss function for brain width + return chomps+withinChomp-loss;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. }else{ return 0; } From 553b8fd50eb68ecb35fd3ef870fe6ec16b526912 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:41:53 +0200 Subject: [PATCH 30/50] Changed default parameters --- evolutionSteer.pde | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 5c71e06..5541349 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -43,13 +43,13 @@ boolean saveFramesPerGeneration = true; color gridBGColor = color(220, 253, 102, 255); float foodAngleChange = 0.0; -static int nbCreatures = 2000; // please set even number -int gridX = 50; // X * Y must be equal to nbCreatures ! -int gridY = 40; +static int nbCreatures = 250; // please set even number +int gridX = 25; // X * Y must be equal to nbCreatures ! +int gridY = 10; int thresholdName = 25; // name of species is showed over this threshold int autoSave = 200; // autosave every x generation in ALAP mode -boolean autoSaveTimecode = true; // set to false is disk space limited +boolean autoSaveTimecode = false; // set to false is disk space limited boolean hasAutosaveWorked = false; int autoPause = 10000; // pauses ALAP each x generation @@ -124,13 +124,13 @@ int[] pPercentages = { 100, 200, 300, 400, 500, 600, 700, 800, 900, 910, 920, 930, 940, 950, 960, 970, 980, 990, 999 }; int[] p = new int[29]; -final int BRAIN_WIDTH = 3; +final int BRAIN_WIDTH = 2; float STARTING_AXON_VARIABILITY = 1.0; float AXON_START_MUTABILITY = 0.0005; -boolean enableRadioactivity = false; -int radioactiveNumber = 400; // number of highly mutated creatures -int freshBloodNumber = 0; // number of brand new creatures +boolean enableRadioactivity = true; +int radioactiveNumber = 20; // number of highly mutated creatures +int freshBloodNumber = 10; // number of brand new creatures float radioactiveMutator = 1.5; boolean massExtinction = false; From a6b662d5161dd3296451287f961f6b6116c44edf Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:42:30 +0200 Subject: [PATCH 31/50] Update readme file --- README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 819ec94..bdecd74 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,37 @@ You can then open evolutionSteer.pde and press the *RUN* button. That's it ! Most parameters are set at the beginning of the *evolutionSteer.pde* file. Noticeable parameters are: -* *windowSizeMultiplier* : set to 1 if window is too big +* **windowSizeMultiplier** : set to 1 if window is too big +* **nbCreatures** : define the number of creatures created at each generation. please verify that the value is even, and that the parameters *gridX* and *gridY* are set accordingly so that `gridX * gridY = nbCreatures` +* **thresholdName** : the name of the creature will be shown in the bottom graph if the number of creatures in this species is greater than this value +* **autoSave** : in ALAP mode, this option will automatically save your work. The number set in the *autoSave* variable will define the frequency of these saves +* **autoSaveTimecode** : if set to *true*, the periodical autosave will have a different name each time, with timecode included (data/autosave-2017-7-26_7-58-5.gz for example). If set to *false*, the autosave will have a fixed name (data/autosave.gz). As the files can be pretty large, please set this value to *false* if you don't have enough disk space. +* **autoPause** : because each man needs its pause, you can ask **evolutionSteer** to stop working after a given number of generations +* **simDuration** : the base duration (in seconds) of the simulation +* **jumperDuration** : if the first food blob is found too early (before this value, in seconds), the creature wil be defined as a jumper and thus destroyed +* **giftForChompSec** : gift (in simulation overtime) given to the creature when it found a food blob. +* **radioactiveNumber** : when Radioactive mode is enabled, this number of creatures will see its mutation rate increase by a given factor (**radioactiveMutator**) +* **freshBloodNumber** : when Radioactive mode is enabled, this number of creatures will be created from scratch each generation +* **THREAD_COUNT** : set accordingly to the number of cores in your computer. Multithreading will be activated if you set **activateMultiThreading** to *true* + +# Features + +First have a look to green commands in the upper right panel : + +* Click **Do 1 step-by-step generation** button to launch the details of the generation process of new creatures. This will explain you how the creatures are generated and show you your creatures trying and failing to eat. +* Click **Do 1 quick generation** in order to follow the same steps but avoiding to see each of your creatures pathetically dying +* Click **Do 1 gen ASAP** in order to quickly generate *one* generation +* Click **Do gens ALAP** in order to continuously generate creatures. This will stop only when (your computer will crash or) you click anywhere else in the window. + +You can press certain commands during execution + +* Press **"r"** to activate *Radioactive mode*. This mode will increase the mutation rate of your creature and hopefully lead to new species +* Press **'"t"** to increase the variability of the food generation process. The food blob will be created relatively to the creature given a random angle which is contained between + and - the angle shown in the interface. You can reduce the variability by pressing **"g"** +* Press **"y"** to reduce the gift (in seconds of supplemental simulation) given to the creature each time it encounters a food blob. Press **"h"** to increase this gift. +* Press **left** and **right** arrow to select previous/next generation. Alternatively, you can use the slider in the interface. + +At last you can save you creatures : + +* If you press the **Save** button, everything contained in the window ill be saved, including past (sometimes *ancient*) creatures (3 per generation). However this can lead to very big files according to : the number of creatures simulated, the size of their brain and the number of generations. +* If you press the **Light save**, you will save only the two last generations. This has the advantage to create lighter files +* NB the files are gzipped files, and the format is a binary json file format named [Smile](https://en.wikipedia.org/wiki/Smile_(data_interchange_format)). \ No newline at end of file From 31b940160794f053b7be9fd44194dae57603dbdd Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:44:20 +0200 Subject: [PATCH 32/50] Readme update for install --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index bdecd74..9760610 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ You can either download zip file or typing the following command into your termi 3. **Launch evolutionSteer** : You can then open evolutionSteer.pde and press the *RUN* button. That's it ! +4. Installing JacksonCore : +If the program doesn’t launch because of dependancies trouble, please drag and drop the two .jar files in the *code* subdirectory onto the Processing window. + # Configuration Most parameters are set at the beginning of the *evolutionSteer.pde* file. Noticeable parameters are: From 4ed0941b7f2f1fc1b75757918035235cdc2706da Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:49:44 +0200 Subject: [PATCH 33/50] added commands for reducing and increasing gift --- evolutionSteer.pde | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 5541349..4972750 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1603,6 +1603,18 @@ void keyPressed(){ enableRadioactivity = !enableRadioactivity; setMenu(1); } + if(key == 'y'){ + giftForChompSec -= 0.5; + if(giftForChompSec < 0.5) { giftForChompSec = (float)0.5; } + giftForChompFrames = ceil(giftForChompSec*frames); + setMenu(1); + } + if(key == 'h'){ + giftForChompSec += 0.5; + giftForChompFrames = ceil(giftForChompSec*frames); + setMenu(1); + } + if(key == 'k'){ massExtinction = true; setMenu(1); From 5b3f5bc8995449385648d9a9e6dd9001461efea6 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:51:28 +0200 Subject: [PATCH 34/50] added "k" in readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9760610..0b71e9f 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ You can press certain commands during execution * Press **'"t"** to increase the variability of the food generation process. The food blob will be created relatively to the creature given a random angle which is contained between + and - the angle shown in the interface. You can reduce the variability by pressing **"g"** * Press **"y"** to reduce the gift (in seconds of supplemental simulation) given to the creature each time it encounters a food blob. Press **"h"** to increase this gift. * Press **left** and **right** arrow to select previous/next generation. Alternatively, you can use the slider in the interface. +* Press **"k"** to instantly kill half your population. It is fun. At last you can save you creatures : From 0875f0617cbddb0484d8e2175c3a3096400980f4 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 18:53:31 +0200 Subject: [PATCH 35/50] Modified mutation properties Won't mutate brain and body at the same time --- Creature.pde | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Creature.pde b/Creature.pde index 7952328..af5dc5e 100644 --- a/Creature.pde +++ b/Creature.pde @@ -79,7 +79,10 @@ class Creature { if (random(0, 1) < bigMutationChance*mutationFactor) { bigMutAddMuscle = true; } if (random(0, 1) < bigMutationChance*mutationFactor && this.n.size() >= 5) { bigMutRemoveNode = true; } if (random(0, 1) < bigMutationChance*mutationFactor && this.m.size() >= 2) { bigMutRemoveMuscle = true; } - if (random(0, 1) < bigMutationChance*mutationFactor*(5-this.brain.BRAIN_WIDTH)/2 && this.brain.BRAIN_WIDTH < 5) { bigMutExpandBrain = true; } + if (random(0, 1) < bigMutationChance*mutationFactor*(5-this.brain.BRAIN_WIDTH)/2 && this.brain.BRAIN_WIDTH < 5) { + bigMutExpandBrain = true; + bigMutAddNode = false; bigMutRemoveNode = false; bigMutAddMuscle = false; bigMutRemoveMuscle = false; + } int[] newName = new int[2]; if(bigMutAddNode || bigMutRemoveNode || bigMutAddMuscle || bigMutRemoveMuscle || bigMutExpandBrain){ From 7be6c0ebf96559302a3c877b5c1984cd2bb860e4 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Thu, 27 Jul 2017 20:29:34 +0200 Subject: [PATCH 36/50] Mass extinction percentage Can choose the percentage for KILL func --- evolutionSteer.pde | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 4972750..7bdaedf 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -134,6 +134,7 @@ int freshBloodNumber = 10; // number of brand new creatures float radioactiveMutator = 1.5; boolean massExtinction = false; +float massExtinctionPercentage = 0.99; String[] patronData; int PATRON_COUNT = 75; @@ -1400,7 +1401,7 @@ void draw() { Creature cj = c2.get(j2); Creature cj2 = c2.get(nbCreatures-1-j2); - if(massExtinction && random(0,1) < 0.5){ // mass extinction + if(massExtinction && random(0,1) < massExtinctionPercentage){ // mass extinction c2.set(j2, createNewCreature(cj.id+nbCreatures-1)); // new creatures arises ! c2.set(nbCreatures-1-j2, createNewCreature(cj2.id+nbCreatures-1)); } else { From 536950642ee4aa8cd6936e9ff493519ad74da792 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:12:22 +0200 Subject: [PATCH 37/50] Brain improvement Full height and rewritten sigmoid curve --- Axon.pde | 2 +- Brain.pde | 60 +++++++++++++++++++++++----------------------- Muscle.pde | 9 ++++--- evolutionSteer.pde | 5 +++- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/Axon.pde b/Axon.pde index 4db79a0..91363c0 100644 --- a/Axon.pde +++ b/Axon.pde @@ -8,7 +8,7 @@ class Axon { public Axon(double w, double m){ weight = w; mutability = m; - MUTATE_MULTI = Math.pow(0.5,mutatePower); + MUTATE_MULTI = Math.pow(0.8,mutatePower); } public Axon copyAxon(){ diff --git a/Brain.pde b/Brain.pde index 0e2078b..76e4369 100644 --- a/Brain.pde +++ b/Brain.pde @@ -5,11 +5,11 @@ class Brain { int BRAIN_HEIGHT = 0; Brain(int bw, int bh, Axon[][][] templateAxons, Boolean haveNeurons, Boolean mutate){ //This is to copy a brain EXACTLY. setUpBasics(bw,bh,haveNeurons); - axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT]; if(mutate){ for(int x = 0; x < BRAIN_WIDTH-1; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ - for(int z = 0; z < BRAIN_HEIGHT-1; z++){ + for(int z = 0; z < BRAIN_HEIGHT; z++){ axons[x][y][z] = templateAxons[x][y][z].mutateAxon(); } } @@ -17,7 +17,7 @@ class Brain { }else{ for(int x = 0; x < BRAIN_WIDTH-1; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ - for(int z = 0; z < BRAIN_HEIGHT-1; z++){ + for(int z = 0; z < BRAIN_HEIGHT; z++){ axons[x][y][z] = templateAxons[x][y][z].copyAxon(); } } @@ -26,12 +26,12 @@ class Brain { } Brain(int bw, int bh){ setUpBasics(bw,bh,false); - axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT]; for(int x = 0; x < BRAIN_WIDTH-1; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ - for(int z = 0; z < BRAIN_HEIGHT-1; z++){ + for(int z = 0; z < BRAIN_HEIGHT; z++){ double startingWeight = 0; - if(y == BRAIN_HEIGHT-1){ + if(y == BRAIN_HEIGHT - 1){ startingWeight = (Math.random()*2-1)*STARTING_AXON_VARIABILITY; } axons[x][y][z] = new Axon(startingWeight,AXON_START_MUTABILITY); @@ -42,10 +42,10 @@ class Brain { void changeBrainStructure(int bw, int bh, int rowInsertionIndex, int rowRemovalIndex){ setUpBasics(bw,bh,false); Axon[][][] oldAxons = axons; - axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT]; for(int x = 0; x < BRAIN_WIDTH-1; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ - for(int z = 0; z < BRAIN_HEIGHT-1; z++){ + for(int z = 0; z < BRAIN_HEIGHT; z++){ if(y == rowInsertionIndex || z == rowInsertionIndex){ double startingWeight = 0; if(y == BRAIN_HEIGHT-1 || true){ @@ -97,34 +97,34 @@ class Brain { neurons[0][n.size()+i] = dist(ni1.x, ni1.y, ni1.z, ni2.x, ni2.y, ni2.z)/am.len; } for(int x = 1; x < BRAIN_WIDTH; x++){ - for(int y = 0; y < BRAIN_HEIGHT-1; y++){ + for(int y = 0; y < BRAIN_HEIGHT; y++){ float total = 0; for(int input = 0; input < BRAIN_HEIGHT; input++){ total += neurons[x-1][input]*axons[x-1][input][y].weight; } - if(x == BRAIN_WIDTH-1){ - neurons[x][y] = total; - }else{ - neurons[x][y] = sigmoid(total); - } + neurons[x][y] = sigmoid(total); } } + for(int i = 0; i < n.size(); i++){ + n.get(i).brainOutput = neurons[BRAIN_WIDTH-1][i]; + } for(int i = 0; i < m.size(); i++){ m.get(i).brainOutput = neurons[BRAIN_WIDTH-1][n.size()+i]; } } public float sigmoid(float input){ - //return 1.0/(1.0+pow(2.71828182846,-input)); - if(input >= -1 && input <= 1){ - return 0.25*input+0.5; - } else if(input >= -3 && input < -1){ - return 0.105*input+0.1192; - } else if(input > 1 && input <= 3){ - return 0.105*input+0.8808; - } else if(input >= -5 && input < -3){ - return 0.0177*input+0.018; + //return -1.0+(2.0/(1.0+pow(2.71828182846,-input))); + // Sigmoid centered on 0 and giving response between -1 and +1 + if(input >= -1.1779 && input <= 1.1779){ + return 0.5*input; + } else if(input >= -2.7537 && input < -1.1779){ + return 0.210*input-0.3416; + } else if(input > 1.1779 && input <= 2.7537){ + return 0.210*input+0.3416; + } else if(input >= -5 && input < -2.7537){ + return 0.0354*input-0.8224; } else if(input > 3 && input <= 5){ - return 0.0177*input+0.982; + return 0.0354*input+0.8224; } else if(input < -5){ return 0; } else { @@ -141,18 +141,18 @@ class Brain { return new Brain(BRAIN_WIDTH,BRAIN_HEIGHT,axons.clone(),false,true); } Brain copyExpandedBrain(){ - Axon[][][] extaxons = new Axon[BRAIN_WIDTH][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + Axon[][][] extaxons = new Axon[BRAIN_WIDTH][BRAIN_HEIGHT][BRAIN_HEIGHT]; for(int x = 0; x < BRAIN_WIDTH; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ - for(int z = 0; z < BRAIN_HEIGHT-1; z++){ - if(x < BRAIN_WIDTH - 1){ extaxons[x][y][z] = axons[x][y][z].copyAxon(); } + for(int z = 0; z < BRAIN_HEIGHT; z++){ if(x == BRAIN_WIDTH - 1){ if(y == z){ - extaxons[x][y][z] = new Axon(1.0,AXON_START_MUTABILITY); + extaxons[x][y][z] = new Axon(2.0,AXON_START_MUTABILITY); } else { extaxons[x][y][z] = new Axon(0.0,AXON_START_MUTABILITY); } } + else{ extaxons[x][y][z] = axons[x][y][z].copyAxon(); } } } } @@ -186,7 +186,7 @@ class Brain { } for(int x = 0; x < BRAIN_WIDTH-1; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ - for(int z = 0; z < BRAIN_HEIGHT-1; z++){ + for(int z = 0; z < BRAIN_HEIGHT; z++){ drawAxon(x,y,x+1,z,scaleUp); } } @@ -256,7 +256,7 @@ class Brain { else if(fieldName.equals("axons")){ if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } int i = 0; - axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT-1]; + axons = new Axon[BRAIN_WIDTH-1][BRAIN_HEIGHT][BRAIN_HEIGHT]; while((token = p.nextToken()) != JsonToken.END_ARRAY){ if (token == JsonToken.START_ARRAY){ int j = 0; diff --git a/Muscle.pde b/Muscle.pde index cd87053..e87df65 100644 --- a/Muscle.pde +++ b/Muscle.pde @@ -9,12 +9,12 @@ class Muscle { this.c1 = tc1; this.c2 = tc2; this.rigidity = trigidity; - this.brainOutput = 1; + this.brainOutput = 0; } void applyForce(int i, ArrayList n, Creature owner) { float target = previousTarget; if(energyDirection == 1 || owner.energy >= 0.0001){ - target = this.len*toMuscleUsable(this.brainOutput); + target = this.len*toMuscleUsable(); }else{ target = this.len; } @@ -53,10 +53,13 @@ class Muscle { return new Muscle(newc1, newc2, newLen, newR); } + float toMuscleUsable(){ + return (this.brainOutput/5)+1; // brain output should be a number between -1 and 1 + } void drawMuscle(ArrayList n, PGraphics img) { Node ni1 = n.get(this.c1); Node ni2 = n.get(this.c2); - float w = toMuscleUsable(this.brainOutput)*0.15; + float w = toMuscleUsable()*0.15; img.strokeWeight(w*scaleToFixBug); float brownness = rigidity*13; img.stroke(255-180*brownness, 255-210*brownness, 255-255*brownness, 255); diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 7bdaedf..f693886 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1823,7 +1823,7 @@ public void saveFunc(File file, boolean light){ public void saveToJson(JsonGenerator g, boolean light){ try{ - g.writeNumberField("version", 2); + g.writeNumberField("version", 3); g.writeNumberField("seed", SEED); g.writeNumberField("foodChange", foodAngleChange); g.writeNumberField("giftForChompSec", giftForChompSec); @@ -1909,6 +1909,9 @@ public void loadFromJson(JsonParser p){ String fieldName = p.getCurrentName(); JsonToken token = p.nextToken(); if(fieldName.equals("seed")){ SEED = p.getIntValue(); } + else if(fieldName.equals("version")){ + if(p.getFloatValue() < 3){ println("WARNING file may be incompatible"); } + } else if(fieldName.equals("foodChange")){ foodAngleChange = p.getFloatValue(); } else if(fieldName.equals("gen")){ gen = p.getIntValue(); genSelected = gen; } else if(fieldName.equals("nbcreatures")){ nbCreatures = p.getIntValue(); initPercentiles(); } From 98976a3929d0b2ed263524129a575c00e196bd69 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:13:04 +0200 Subject: [PATCH 38/50] Chomp limitation to 100 --- Creature.pde | 5 ++++- computingThread.pde | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Creature.pde b/Creature.pde index af5dc5e..c7c653a 100644 --- a/Creature.pde +++ b/Creature.pde @@ -351,8 +351,11 @@ class Creature { } if(hasNodeOffGround){ float withinChomp = max(1.0-this.getCurrentFoodDistance()/this.startingFoodDistance,0); + if(withinChomp >= 1){ withinChomp = 0.99; } float loss = (this.brain.BRAIN_WIDTH - 2)*(float)0.05; // loss function for brain width - return chomps+withinChomp-loss;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. + float fit = chomps+withinChomp-loss;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. + if(fit >= 100){ fit = 100; } + return fit; }else{ return 0; } diff --git a/computingThread.pde b/computingThread.pde index 7f01946..75afa3c 100644 --- a/computingThread.pde +++ b/computingThread.pde @@ -13,11 +13,14 @@ public class ComputingThread implements Runnable{ myCreature = c[k].copyCreature(-1,false,true); myCreature.calculateNextFoodLocation(); int myMaxFrames = maxFrames; + int currentChomp = 0; boolean isJumper = false; for (int sim = 0; sim < myMaxFrames; sim++) { if(myCreature.simulate()){ // activated when chomped if(sim <= jumperFrames){ isJumper = true; break; } // we kill jumpers myMaxFrames += giftForChompFrames; + currentChomp++; + if(currentChomp > 100){ break; } } } if(isJumper){ From 6a2a577961f9d99b981012db87d5122730511874 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:19:12 +0200 Subject: [PATCH 39/50] Save v4 Simplified save files --- Creature.pde | 41 +++++------------------------------------ Muscle.pde | 4 ---- evolutionSteer.pde | 22 +++++++++------------- 3 files changed, 14 insertions(+), 53 deletions(-) diff --git a/Creature.pde b/Creature.pde index c7c653a..4e4c9d3 100644 --- a/Creature.pde +++ b/Creature.pde @@ -4,7 +4,6 @@ class Creature { float d; int id; boolean alive; - float creatureTimer; float mutability; Brain brain; int[] name; @@ -20,13 +19,13 @@ class Creature { float energy = baselineEnergy; float startingFoodDistance = 9999; - Creature(int[] tname, int tid, ArrayList tn, ArrayList tm, float td, boolean talive, float tct, float tmut, Brain newBrain, float[][] tfoodpos) { + Creature(int[] tname, int tid, ArrayList tn, ArrayList tm, float td, boolean talive, float tmut, Brain newBrain, float[][] tfoodpos) { this.id = tid; this.m = tm; this.n = tn; this.d = td; this.alive = talive; - this.creatureTimer = tct; + //this.creatureTimer = tct; this.mutability = tmut; if(newBrain != null){ this.brain = newBrain; @@ -47,11 +46,7 @@ class Creature { this.foodPositions[i][2] = random(0,1); } }else{ - for(int i = 0; i < 100; i++){ - this.foodPositions[i][0] = tfoodpos[i][0]; - this.foodPositions[i][1] = tfoodpos[i][1]; - this.foodPositions[i][2] = tfoodpos[i][2]; - } + this.foodPositions = tfoodpos.clone(); } } int getBrainHeight(){ @@ -106,7 +101,7 @@ class Creature { newMut = min(mutability*random((float)0.8, (float)1.25), 2); } Creature modifiedCreature = new Creature(newName, id, - newN, newM, 0, true, creatureTimer+r()*16*modMut, newMut, tmpBrain,null); + newN, newM, 0, true, newMut, tmpBrain,null); if (bigMutAddNode) { //Add a node modifiedCreature.addRandomNode(); } @@ -273,7 +268,7 @@ class Creature { if(withUsableBrain){ newBrain = this.brain.getUsableCopyOfBrain(); } - return new Creature(this.name, newID, n2, m2, this.d, this.alive, this.creatureTimer, + return new Creature(this.name, newID, n2, m2, this.d, this.alive, this.mutability,newBrain,newFoodPositions); } void drawCreature(PGraphics img, Boolean putInFrontOfBack) { @@ -401,7 +396,6 @@ class Creature { if(overwriteId == -1) { g.writeNumberField("id", id); } else { g.writeNumberField("id", overwriteId); } g.writeBooleanField("alive", alive); - g.writeNumberField("creatureTimer", creatureTimer); g.writeNumberField("mutability", mutability); g.writeArrayFieldStart("name");g.writeNumber(name[0]);g.writeNumber(name[1]);g.writeEndArray(); if(n != null){ @@ -418,15 +412,6 @@ class Creature { } g.writeEndArray(); } - g.writeArrayFieldStart("foodPositions"); - for(int i = 0; i < foodPositions.length; i++){ - g.writeStartArray(); - for(int j = 0; j < foodPositions[i].length; j++){ - g.writeNumber(foodPositions[i][j]); - } - g.writeEndArray(); - } - g.writeEndArray(); g.writeObjectFieldStart("brain"); this.brain.saveToJson(g); g.writeEndObject(); } catch(Exception e){ writeToErrorLog(e); @@ -441,7 +426,6 @@ class Creature { if(fieldName.equals("d")){ d = p.getFloatValue(); } else if(fieldName.equals("id")){ id = p.getIntValue(); } else if(fieldName.equals("alive")){ alive = p.getBooleanValue(); } - else if(fieldName.equals("creatureTimer")){ creatureTimer = p.getFloatValue(); } else if(fieldName.equals("mutability")){ mutability = p.getFloatValue(); } else if(fieldName.equals("name")){ if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } @@ -478,21 +462,6 @@ class Creature { brain = new Brain(1, 1); brain.loadFromJson(p); } - else if(fieldName.equals("foodPositions")){ - if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } - int i = 0; - foodPositions = new float[100][3]; - while((token = p.nextToken()) != JsonToken.END_ARRAY){ - if (token == JsonToken.START_ARRAY){ - int j = 0; - while(p.nextToken() != JsonToken.END_ARRAY){ - foodPositions[i][j] = p.getFloatValue(); - j += 1; - } - } - i += 1; - } - } } } catch(Exception e) { writeToErrorLog(e); } } diff --git a/Muscle.pde b/Muscle.pde index e87df65..2d16f59 100644 --- a/Muscle.pde +++ b/Muscle.pde @@ -75,8 +75,6 @@ class Muscle { g.writeNumberField("c2", this.c2); g.writeNumberField("len", this.len); g.writeNumberField("rigidity", this.rigidity); - g.writeNumberField("previousTarget", this.previousTarget); - g.writeNumberField("brainOutput", this.brainOutput); } catch(Exception e){ writeToErrorLog(e); } @@ -91,8 +89,6 @@ class Muscle { else if(fieldName.equals("c2")){ this.c2 = p.getIntValue(); } else if(fieldName.equals("len")){ this.len = p.getFloatValue(); } else if(fieldName.equals("rigidity")){ this.rigidity = p.getFloatValue(); } - else if(fieldName.equals("previousTarget")){ this.previousTarget = p.getFloatValue(); } - else if(fieldName.equals("brainOutput")){ this.brainOutput = p.getFloatValue(); } } } catch(Exception e){ writeToErrorLog(e); diff --git a/evolutionSteer.pde b/evolutionSteer.pde index f693886..9372dff 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -9,8 +9,8 @@ import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.dataformat.smile.SmileGenerator; -import com.fasterxml.jackson.dataformat.smile.SmileFactory; +//import com.fasterxml.jackson.dataformat.smile.SmileGenerator; +//import com.fasterxml.jackson.dataformat.smile.SmileFactory; float windowSizeMultiplier = 1; @@ -198,9 +198,6 @@ void drawGround(PGraphics img) { } }*/ } -float toMuscleUsable(float f){ - return min(max(f,0.8),1.2); -} void drawPosts(PGraphics img) { float averageX = 0; float averageY = 0; @@ -1766,8 +1763,7 @@ Creature createNewCreature(int index){ float len = random(0.5,1.5); m.add(new Muscle(tc1, tc2, len, random(0.015, 0.06))); } - float heartbeat = random(40, 80); - return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 0, true, heartbeat, 1.0, null, null); + return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 0, true, 1.0, null, null); } public void writeToErrorLog(Exception e){ String[] error = new String[100]; @@ -1781,7 +1777,7 @@ public void writeToErrorLog(Exception e){ public void fileSelected(File file){ if(file != null){ try{ - JsonFactory factory = new SmileFactory(); + JsonFactory factory = new JsonFactory(); JsonParser p = factory.createParser(new GZIPInputStream(new FileInputStream(file.getAbsolutePath()))); loadFromJson(p); setMenu(1); @@ -1803,7 +1799,7 @@ public void saveSelectedLight(File file){ public void saveFunc(File file, boolean light){ if(file != null){ try{ - JsonFactory factory = new SmileFactory(); + JsonFactory factory = new JsonFactory(); GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(file.getAbsolutePath())); JsonGenerator generator = factory.createGenerator(out, JsonEncoding.UTF8); generator.writeStartObject(); @@ -1823,7 +1819,7 @@ public void saveFunc(File file, boolean light){ public void saveToJson(JsonGenerator g, boolean light){ try{ - g.writeNumberField("version", 3); + g.writeNumberField("version", 4); g.writeNumberField("seed", SEED); g.writeNumberField("foodChange", foodAngleChange); g.writeNumberField("giftForChompSec", giftForChompSec); @@ -1910,7 +1906,7 @@ public void loadFromJson(JsonParser p){ JsonToken token = p.nextToken(); if(fieldName.equals("seed")){ SEED = p.getIntValue(); } else if(fieldName.equals("version")){ - if(p.getFloatValue() < 3){ println("WARNING file may be incompatible"); } + if(p.getFloatValue() < 4){ println("WARNING file may be incompatible"); } } else if(fieldName.equals("foodChange")){ foodAngleChange = p.getFloatValue(); } else if(fieldName.equals("gen")){ gen = p.getIntValue(); genSelected = gen; } @@ -1925,7 +1921,7 @@ public void loadFromJson(JsonParser p){ if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } while((token = p.nextToken()) != JsonToken.END_ARRAY){ if (token == JsonToken.START_OBJECT){ - Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, null, null); creature.loadFromJson(p); creatureDatabase.add(creature); } @@ -1991,7 +1987,7 @@ public void loadFromJson(JsonParser p){ int i = 0; while((token = p.nextToken()) != JsonToken.END_ARRAY){ if (token == JsonToken.START_OBJECT){ - Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, 0, null, new float[100][3]); + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, null, new float[100][3]); creature.loadFromJson(p); c[i] = creature; c2.add(c[i]); From 3eaf1bb32509b708a0f860a4aa8c059edb8498fd Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:19:28 +0200 Subject: [PATCH 40/50] Brainiac mode Activate by pressing 'b' --- evolutionSteer.pde | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 9372dff..f744f4b 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1589,6 +1589,9 @@ void keyPressed(){ if(genSelected > gen) { genSelected = gen; } } } else { + if(key == 'b'){ + brainiac(); + } if(key == 't'){ foodAngleChange += 5.0/360.0*(2*PI); setMenu(1); @@ -1734,6 +1737,15 @@ void setFitness(int i){ c[i].d = currentCreature.getFitness(); } +void brainiac(){ + for(int i = 0; i < c.length; i++){ + c[i] = c[i].copyCreature(-1,true,false); + c[i].brain = c[i].brain.copyExpandedBrain(); + //c[i] = c[i].modified(c[i].id, 1); + } + setMenu(4); +} + Creature createNewCreature(int index){ int nodeNum = int(random(4, 8)); int muscleNum = int(random(nodeNum, nodeNum*3)); From f2c7eb7b0eda43da4521577c964889b14abe8473 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:20:17 +0200 Subject: [PATCH 41/50] Variable friction According to neural network --- Node.pde | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/Node.pde b/Node.pde index 03b16ab..aa2b9e8 100644 --- a/Node.pde +++ b/Node.pde @@ -1,7 +1,6 @@ class Node { - float x, y, z, vx, vy, vz, prevX, prevY, prevZ, pvx, pvy, pvz, m, f; - boolean safeInput; - float pressure; + float x, y, z, vx, vy, vz, prevX, prevY, prevZ, pvx, pvy, pvz, m, initf, f; + float pressure, brainOutput; Node(float tx, float ty, float tz, float tvx, float tvy, float tvz, float tm, float tf) { @@ -12,10 +11,13 @@ class Node { this.pvy = vy = tvy; this.pvz = vz = tvz; this.m = tm; - this.f = tf; + this.initf = tf; + this.f = this.initf; this.pressure = 0; + this.brainOutput = (2*this.initf)-1; } void applyForces() { + this.f = toNodeUsable(); this.vx *= airFriction; this.vy *= airFriction; this.vz *= airFriction; @@ -28,6 +30,9 @@ class Node { this.pvy = vy; this.pvz = vz; } + float toNodeUsable(){ + return (this.brainOutput+1)/2; + } void applyGravity() { this.vy += gravity; } @@ -154,7 +159,7 @@ class Node { //float newM = m+r()*0.1*mutability; //newM = min(max(newM, 0.3), 0.5); float newM = 0.4; - float newF = min(max(this.f+r()*0.1*mutability, 0), 1); + float newF = min(max(this.initf+r()*0.1*mutability, 0), 1); Node newNode = new Node(newX, newY, newZ, 0, 0, 0, newM, newF); return newNode;//max(m+r()*0.1,0.2),min(max(f+r()*0.1,0),1) } @@ -195,16 +200,8 @@ class Node { g.writeNumberField("vx", this.vx); g.writeNumberField("vy", this.vy); g.writeNumberField("vz", this.vz); - g.writeNumberField("prevX", this.prevX); - g.writeNumberField("prevY", this.prevY); - g.writeNumberField("prevZ", this.prevZ); - g.writeNumberField("pvx", this.pvx); - g.writeNumberField("pvy", this.pvy); - g.writeNumberField("pvz", this.pvz); g.writeNumberField("m", this.m); - g.writeNumberField("f", this.f); - g.writeBooleanField("safeInput", this.safeInput); - g.writeNumberField("pressure", this.pressure); + g.writeNumberField("f", this.initf); } catch(Exception e){ writeToErrorLog(e); } @@ -221,15 +218,11 @@ class Node { else if(fieldName.equals("vx")){ this.vx = p.getFloatValue(); } else if(fieldName.equals("vy")){ this.vy = p.getFloatValue(); } else if(fieldName.equals("vz")){ this.vz = p.getFloatValue(); } - else if(fieldName.equals("prevX")){ this.prevX = p.getFloatValue(); } - else if(fieldName.equals("prevY")){ this.prevY = p.getFloatValue(); } - else if(fieldName.equals("prevZ")){ this.prevZ = p.getFloatValue(); } - else if(fieldName.equals("pvx")){ this.pvx = p.getFloatValue(); } - else if(fieldName.equals("pvy")){ this.pvy = p.getFloatValue(); } - else if(fieldName.equals("pvz")){ this.pvz = p.getFloatValue(); } else if(fieldName.equals("m")){ this.m = p.getFloatValue(); } - else if(fieldName.equals("f")){ this.f = p.getFloatValue(); } - else if(fieldName.equals("safeInput")){ this.safeInput = p.getBooleanValue(); } + else if(fieldName.equals("f")){ + this.f = this.initf = p.getFloatValue(); + this.brainOutput = (2*this.initf)-1; + } else if(fieldName.equals("pressure")){ this.pressure = p.getFloatValue(); } } } catch(Exception e){ From 595cd3c047195ae3dce6b136bdf718aa9de25652 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:27:13 +0200 Subject: [PATCH 42/50] Save v4b bugfix in v4 loading --- Creature.pde | 1 - evolutionSteer.pde | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Creature.pde b/Creature.pde index 4e4c9d3..984158c 100644 --- a/Creature.pde +++ b/Creature.pde @@ -25,7 +25,6 @@ class Creature { this.n = tn; this.d = td; this.alive = talive; - //this.creatureTimer = tct; this.mutability = tmut; if(newBrain != null){ this.brain = newBrain; diff --git a/evolutionSteer.pde b/evolutionSteer.pde index f744f4b..f8ce28c 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1999,7 +1999,7 @@ public void loadFromJson(JsonParser p){ int i = 0; while((token = p.nextToken()) != JsonToken.END_ARRAY){ if (token == JsonToken.START_OBJECT){ - Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, null, new float[100][3]); + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, null, null); creature.loadFromJson(p); c[i] = creature; c2.add(c[i]); From ead646624045110f87467022e916372d2a520c5a Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:33:57 +0200 Subject: [PATCH 43/50] Updated readme for Brainiac --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0b71e9f..63fb7d2 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ You can press certain commands during execution * Press **"y"** to reduce the gift (in seconds of supplemental simulation) given to the creature each time it encounters a food blob. Press **"h"** to increase this gift. * Press **left** and **right** arrow to select previous/next generation. Alternatively, you can use the slider in the interface. * Press **"k"** to instantly kill half your population. It is fun. +* Press **"b"** to activate **BRAINIAC** mode. This will instantly add a neutron layer to each of your creatures. Be cautious as it is computationally intensive, irreversible and can lead to numerous deaths in your population. At last you can save you creatures : From ff17500f314668a46ccebfb2433bc3c86461b679 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 00:52:15 +0200 Subject: [PATCH 44/50] Bugfix Removed potential crash sources --- evolutionSteer.pde | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/evolutionSteer.pde b/evolutionSteer.pde index f8ce28c..439b72f 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -666,7 +666,7 @@ void drawScreenImage(int stage) { screenImage.noStroke(); for (int j = 0; j < nbCreatures; j++) { Creature cj = c2.get(j); - if (stage == 3) cj = c[cj.id-(gen*nbCreatures)-(nbCreatures+1)]; + if (stage == 3) cj = c[cj.id%nbCreatures]; int j2 = j; if (stage == 0) { j2 = cj.id-(gen*nbCreatures)-1; @@ -1615,7 +1615,6 @@ void keyPressed(){ giftForChompFrames = ceil(giftForChompSec*frames); setMenu(1); } - if(key == 'k'){ massExtinction = true; setMenu(1); @@ -1741,7 +1740,6 @@ void brainiac(){ for(int i = 0; i < c.length; i++){ c[i] = c[i].copyCreature(-1,true,false); c[i].brain = c[i].brain.copyExpandedBrain(); - //c[i] = c[i].modified(c[i].id, 1); } setMenu(4); } From 5f5557c20fc5aedb0b3aaa6db922e9f4876b2c05 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 07:45:23 +0200 Subject: [PATCH 45/50] maxChomp Variable max number of chomps --- Creature.pde | 11 ++++++----- computingThread.pde | 2 +- evolutionSteer.pde | 1 + 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Creature.pde b/Creature.pde index 984158c..b1bdd17 100644 --- a/Creature.pde +++ b/Creature.pde @@ -7,7 +7,7 @@ class Creature { float mutability; Brain brain; int[] name; - float[][] foodPositions = new float[100][3]; + float[][] foodPositions = new float[maxChomp][3]; float foodAngle = 0.0; float foodX = 0; float foodY = 0; @@ -39,7 +39,7 @@ class Creature { this.name[1] = tname[1]; } if(tfoodpos == null){ - for(int i = 0; i < 100; i++){ + for(int i = 0; i < maxChomp; i++){ this.foodPositions[i][0] = random(-foodAngleChange,foodAngleChange); this.foodPositions[i][1] = random(-1.2,-0.55); this.foodPositions[i][2] = random(0,1); @@ -348,7 +348,7 @@ class Creature { if(withinChomp >= 1){ withinChomp = 0.99; } float loss = (this.brain.BRAIN_WIDTH - 2)*(float)0.05; // loss function for brain width float fit = chomps+withinChomp-loss;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. - if(fit >= 100){ fit = 100; } + if(fit >= maxChomp){ fit = maxChomp; } return fit; }else{ return 0; @@ -382,8 +382,9 @@ class Creature { float distFromFood = dist(ni.x,ni.y,ni.z,this.foodX,this.foodY,this.foodZ); if(distFromFood <= 0.4){ this.chomps++; - if (this.chomps < 10){ hasEaten = true; } - this.calculateNextFoodLocation(); + hasEaten = true; + if(chomps >= maxChomp){ chomps = maxChomp; } + else { this.calculateNextFoodLocation(); } } } return hasEaten; diff --git a/computingThread.pde b/computingThread.pde index 75afa3c..e93ac6e 100644 --- a/computingThread.pde +++ b/computingThread.pde @@ -20,7 +20,7 @@ public class ComputingThread implements Runnable{ if(sim <= jumperFrames){ isJumper = true; break; } // we kill jumpers myMaxFrames += giftForChompFrames; currentChomp++; - if(currentChomp > 100){ break; } + if(currentChomp >= maxChomp){ break; } } } if(isJumper){ diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 439b72f..645b584 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -88,6 +88,7 @@ int maxSimulationFrames = maxFrames; int jumperFrames = jumperDuration*frames; float giftForChompSec = 15; int giftForChompFrames = ceil(giftForChompSec*frames); +int maxChomp = 100; // maximum number of chomps before simulation ends int menu = 0; int gen = -1; float sliderX = 1170; From 75b6fcebee52b1f67c98baafa12884fa4bda4b22 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 07:46:43 +0200 Subject: [PATCH 46/50] Jumper truncature Remove jumper limitation when the gift is < than 12 sec --- computingThread.pde | 4 +++- evolutionSteer.pde | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/computingThread.pde b/computingThread.pde index e93ac6e..0fa1538 100644 --- a/computingThread.pde +++ b/computingThread.pde @@ -17,7 +17,9 @@ public class ComputingThread implements Runnable{ boolean isJumper = false; for (int sim = 0; sim < myMaxFrames; sim++) { if(myCreature.simulate()){ // activated when chomped - if(sim <= jumperFrames){ isJumper = true; break; } // we kill jumpers + if(simDuration > jumperTruncate){ + if(sim <= jumperFrames){ isJumper = true; break; } // we kill jumpers + } myMaxFrames += giftForChompFrames; currentChomp++; if(currentChomp >= maxChomp){ break; } diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 645b584..52ccebd 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -83,6 +83,7 @@ float camVA = -0.5; int frames = 60; int simDuration = 15; // in seconds int jumperDuration = 1; // definition of jumper : chomp < this value (in seconds) +int jumperTruncate = 12; // remove jumper limitation when giftForChompSec is < to this value int maxFrames = simDuration*frames; int maxSimulationFrames = maxFrames; int jumperFrames = jumperDuration*frames; From 952a02cb3e311f616ecbde019f453b039bf71aef Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 07:47:10 +0200 Subject: [PATCH 47/50] PowerDouble added powerdouble function (cf readme) --- README.md | 1 + evolutionSteer.pde | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/README.md b/README.md index 63fb7d2..808f4a3 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ You can press certain commands during execution * Press **left** and **right** arrow to select previous/next generation. Alternatively, you can use the slider in the interface. * Press **"k"** to instantly kill half your population. It is fun. * Press **"b"** to activate **BRAINIAC** mode. This will instantly add a neutron layer to each of your creatures. Be cautious as it is computationally intensive, irreversible and can lead to numerous deaths in your population. +* Press **"p"** to instantly double the number of creatures in you batch. This will reset the timeline and hopefully double the computation time for each generation. Be careful for what you wish ! At last you can save you creatures : diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 52ccebd..79f919a 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1621,6 +1621,9 @@ void keyPressed(){ massExtinction = true; setMenu(1); } + if(key == 'p'){ + powerDouble(); + } } } void drawStats(float x, float y, float z, float size){ @@ -1745,6 +1748,36 @@ void brainiac(){ } setMenu(4); } +void powerDouble(){ + Creature firstC = creatureDatabase.get((gen-1)*3); + Creature middleC = creatureDatabase.get((gen-1)*3+1); + Creature lastC = creatureDatabase.get((gen-1)*3+2); + Integer[] lastBarcount = barCounts.get(barCounts.size()-1); + Float[] lastPercentile = percentile.get(percentile.size()-1); + Integer[] lastSpeciesCounts = speciesCounts.get(speciesCounts.size()-1); + Integer lastTopSpeciesCounts = topSpeciesCounts.get(topSpeciesCounts.size()-1); + + gridY = gridY*2; + nbCreatures = nbCreatures*2; initPercentiles(); + gen = 0; + genSelected = 0; + creaturesInPosition = new int[nbCreatures]; + c2 = new ArrayList(); + for(int i = 0; i < c.length; i++){ + c2.add(c[i]); + } + c = new Creature[nbCreatures]; + for(int i = 0; i < c2.size(); i++){ + c[i] = c[i+nbCreatures/2] = c2.get(i); + } + + creatureDatabase.clear(); + barCounts.clear(); barCounts.add(lastBarcount); + percentile.clear(); percentile.add(lastPercentile); + speciesCounts.clear(); speciesCounts.add(lastSpeciesCounts); + topSpeciesCounts.clear(); topSpeciesCounts.add(lastTopSpeciesCounts); + setMenu(4); +} Creature createNewCreature(int index){ int nodeNum = int(random(4, 8)); From 42c8f9eebbfbebb56b598f06614760f46265daf7 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sat, 29 Jul 2017 08:09:30 +0200 Subject: [PATCH 48/50] Heartbeat neuron Courtesy of Master2112 --- Brain.pde | 7 +++++++ Creature.pde | 2 +- evolutionSteer.pde | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Brain.pde b/Brain.pde index 76e4369..0e29914 100644 --- a/Brain.pde +++ b/Brain.pde @@ -1,4 +1,6 @@ class Brain { + float heartbeatInterval = (float)(Math.PI/12); + float timesUsed; float[][] neurons; Axon[][][] axons; int BRAIN_WIDTH = 0; @@ -66,6 +68,7 @@ class Brain { } } void setUpBasics(int bw, int bh, Boolean haveNeurons){ + timesUsed = 0; BRAIN_WIDTH = bw; BRAIN_HEIGHT = bh; if(haveNeurons){ @@ -96,6 +99,10 @@ class Brain { Node ni2 = n.get(am.c2); neurons[0][n.size()+i] = dist(ni1.x, ni1.y, ni1.z, ni2.x, ni2.y, ni2.z)/am.len; } + + neurons[0][n.size()+m.size()] = sin(heartbeatInterval*timesUsed); + timesUsed += 1; + for(int x = 1; x < BRAIN_WIDTH; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ float total = 0; diff --git a/Creature.pde b/Creature.pde index b1bdd17..ce49b88 100644 --- a/Creature.pde +++ b/Creature.pde @@ -49,7 +49,7 @@ class Creature { } } int getBrainHeight(){ - return this.n.size()+m.size()+1; + return this.n.size()+this.m.size()+2; } void changeBrainStructure(int rowInsertionIndex, int rowRemovalIndex){ this.brain.changeBrainStructure(this.brain.BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex,rowRemovalIndex); diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 79f919a..3d113a9 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -1864,7 +1864,7 @@ public void saveFunc(File file, boolean light){ public void saveToJson(JsonGenerator g, boolean light){ try{ - g.writeNumberField("version", 4); + g.writeNumberField("version", 5); g.writeNumberField("seed", SEED); g.writeNumberField("foodChange", foodAngleChange); g.writeNumberField("giftForChompSec", giftForChompSec); @@ -1951,7 +1951,7 @@ public void loadFromJson(JsonParser p){ JsonToken token = p.nextToken(); if(fieldName.equals("seed")){ SEED = p.getIntValue(); } else if(fieldName.equals("version")){ - if(p.getFloatValue() < 4){ println("WARNING file may be incompatible"); } + if(p.getFloatValue() < 5){ println("WARNING file may be incompatible"); } } else if(fieldName.equals("foodChange")){ foodAngleChange = p.getFloatValue(); } else if(fieldName.equals("gen")){ gen = p.getIntValue(); genSelected = gen; } From 9005f127c4b1dbde443b2cfae3ecc76b074158be Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Sun, 30 Jul 2017 03:22:57 +0200 Subject: [PATCH 49/50] Linear transform for brain Allows to create imilar brains with more neurons --- Brain.pde | 23 +++++++++++++++++++---- Creature.pde | 2 +- evolutionSteer.pde | 5 +++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Brain.pde b/Brain.pde index 642c758..3a22187 100644 --- a/Brain.pde +++ b/Brain.pde @@ -110,7 +110,11 @@ class Brain { for(int input = 0; input < BRAIN_HEIGHT; input++){ total += neurons[x-1][input]*axons[x-1][input][y].weight; } - neurons[x][y] = sigmoid(total); + if(x == BRAIN_WIDTH - 1){ + neurons[x][y] = sigmoid(total); + } else { + neurons[x][y] = linear(total); + } } } for(int i = 0; i < n.size(); i++){ @@ -120,6 +124,17 @@ class Brain { m.get(i).brainOutput = neurons[BRAIN_WIDTH-1][n.size()+i]; } } + public float linear(float input){ + if(input >= -5 || input <= 5){ + return input/5; + } + else if(input < -5){ + return -1; + } + else{ + return 1; + } + } public float sigmoid(float input){ //return -1.0+(2.0/(1.0+pow(2.71828182846,-input))); // Sigmoid centered on 0 and giving response between -1 and +1 @@ -153,14 +168,14 @@ class Brain { for(int x = 0; x < BRAIN_WIDTH; x++){ for(int y = 0; y < BRAIN_HEIGHT; y++){ for(int z = 0; z < BRAIN_HEIGHT; z++){ - if(x == BRAIN_WIDTH - 1){ + if(x == 0){ if(y == z){ - extaxons[x][y][z] = new Axon(2.0,AXON_START_MUTABILITY); + extaxons[x][y][z] = new Axon(5.0,AXON_START_MUTABILITY); } else { extaxons[x][y][z] = new Axon(0.0,AXON_START_MUTABILITY); } } - else{ extaxons[x][y][z] = axons[x][y][z].copyAxon(); } + else{ extaxons[x][y][z] = axons[x-1][y][z].copyAxon(); } } } } diff --git a/Creature.pde b/Creature.pde index ce49b88..d24f31a 100644 --- a/Creature.pde +++ b/Creature.pde @@ -346,7 +346,7 @@ class Creature { if(hasNodeOffGround){ float withinChomp = max(1.0-this.getCurrentFoodDistance()/this.startingFoodDistance,0); if(withinChomp >= 1){ withinChomp = 0.99; } - float loss = (this.brain.BRAIN_WIDTH - 2)*(float)0.05; // loss function for brain width + float loss = (this.brain.BRAIN_WIDTH - 2)*lossPerLayer; // loss function for brain width float fit = chomps+withinChomp-loss;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. if(fit >= maxChomp){ fit = maxChomp; } return fit; diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 3d113a9..8b16682 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -129,6 +129,7 @@ int[] p = new int[29]; final int BRAIN_WIDTH = 2; float STARTING_AXON_VARIABILITY = 1.0; float AXON_START_MUTABILITY = 0.0005; +float lossPerLayer = 1; //chomp lost by layer of neurons added boolean enableRadioactivity = true; int radioactiveNumber = 20; // number of highly mutated creatures @@ -1864,7 +1865,7 @@ public void saveFunc(File file, boolean light){ public void saveToJson(JsonGenerator g, boolean light){ try{ - g.writeNumberField("version", 5); + g.writeNumberField("version", 6); g.writeNumberField("seed", SEED); g.writeNumberField("foodChange", foodAngleChange); g.writeNumberField("giftForChompSec", giftForChompSec); @@ -1951,7 +1952,7 @@ public void loadFromJson(JsonParser p){ JsonToken token = p.nextToken(); if(fieldName.equals("seed")){ SEED = p.getIntValue(); } else if(fieldName.equals("version")){ - if(p.getFloatValue() < 5){ println("WARNING file may be incompatible"); } + if(p.getFloatValue() < 6){ println("WARNING file may be incompatible"); } } else if(fieldName.equals("foodChange")){ foodAngleChange = p.getFloatValue(); } else if(fieldName.equals("gen")){ gen = p.getIntValue(); genSelected = gen; } From 606bf96357bcfd47eb20204c57fa2a5b8e2b1d72 Mon Sep 17 00:00:00 2001 From: Joseph_MBP Date: Tue, 1 Aug 2017 00:35:32 +0200 Subject: [PATCH 50/50] Complex fitness improvement Fitness is defined by speed and chomps Food angulation is increased progressively so that evolution naturally leads to steering Supplemental heartbeat, faster Jumper truncation removed --- Brain.pde | 9 ++++-- Creature.pde | 68 ++++++++++++++++++++++++++++++++++----------- computingThread.pde | 6 ++-- evolutionSteer.pde | 59 +++++++++++++++++++++++---------------- 4 files changed, 96 insertions(+), 46 deletions(-) diff --git a/Brain.pde b/Brain.pde index 3a22187..a46a81a 100644 --- a/Brain.pde +++ b/Brain.pde @@ -1,6 +1,6 @@ class Brain { float heartbeatInterval = (float)(Math.PI/12); - float timesUsed; + int timesUsed; float[][] neurons; Axon[][][] axons; int BRAIN_WIDTH = 0; @@ -102,6 +102,7 @@ class Brain { } neurons[0][n.size()+m.size()] = sin(heartbeatInterval*timesUsed); + neurons[0][n.size()+m.size()+1] = cos(2*heartbeatInterval*timesUsed); timesUsed += 1; for(int x = 1; x < BRAIN_WIDTH; x++){ @@ -111,7 +112,7 @@ class Brain { total += neurons[x-1][input]*axons[x-1][input][y].weight; } if(x == BRAIN_WIDTH - 1){ - neurons[x][y] = sigmoid(total); + neurons[x][y] = sigmoidapprox(total); } else { neurons[x][y] = linear(total); } @@ -136,8 +137,10 @@ class Brain { } } public float sigmoid(float input){ - //return -1.0+(2.0/(1.0+pow(2.71828182846,-input))); + return -1.0+(2.0/(1.0+pow(2.71828182846,-input))); // Sigmoid centered on 0 and giving response between -1 and +1 + } + public float sigmoidapprox(float input){ if(input >= -1.1779 && input <= 1.1779){ return 0.5*input; } else if(input >= -2.7537 && input < -1.1779){ diff --git a/Creature.pde b/Creature.pde index d24f31a..73d48b5 100644 --- a/Creature.pde +++ b/Creature.pde @@ -13,19 +13,22 @@ class Creature { float foodY = 0; float foodZ = 0; int chomps = 0; + float timePerChomp = 0; float averageX = 0; float averageY = 0; float averageZ = 0; float energy = baselineEnergy; float startingFoodDistance = 9999; + int lastChompTime = 0; - Creature(int[] tname, int tid, ArrayList tn, ArrayList tm, float td, boolean talive, float tmut, Brain newBrain, float[][] tfoodpos) { + Creature(int[] tname, int tid, ArrayList tn, ArrayList tm, float tmut, Brain newBrain, float[][] tfoodpos) { this.id = tid; this.m = tm; this.n = tn; - this.d = td; - this.alive = talive; + this.d = 0; + this.alive = true; this.mutability = tmut; + this.initParameters(); if(newBrain != null){ this.brain = newBrain; }else{ @@ -40,19 +43,28 @@ class Creature { } if(tfoodpos == null){ for(int i = 0; i < maxChomp; i++){ - this.foodPositions[i][0] = random(-foodAngleChange,foodAngleChange); + if(i < angleMultiplier.length){ + this.foodPositions[i][0] = angleMultiplier[i]*random(-foodAngleChange,foodAngleChange); + } else { + this.foodPositions[i][0] = random(-foodAngleChange,foodAngleChange); + } this.foodPositions[i][1] = random(-1.2,-0.55); this.foodPositions[i][2] = random(0,1); } - }else{ + } else { this.foodPositions = tfoodpos.clone(); } } + void initParameters(){ + this.chomps = 0; + this.lastChompTime = 0; + this.timePerChomp = 0; + } int getBrainHeight(){ - return this.n.size()+this.m.size()+2; + return this.n.size()+this.m.size()+3; } void changeBrainStructure(int rowInsertionIndex, int rowRemovalIndex){ - this.brain.changeBrainStructure(this.brain.BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex,rowRemovalIndex); + this.brain.changeBrainStructure(this.brain.BRAIN_WIDTH, this.getBrainHeight(), rowInsertionIndex, rowRemovalIndex); } Creature modified(int id, float mutationFactor) { float modMut; @@ -99,8 +111,7 @@ class Creature { } else { newMut = min(mutability*random((float)0.8, (float)1.25), 2); } - Creature modifiedCreature = new Creature(newName, id, - newN, newM, 0, true, newMut, tmpBrain,null); + Creature modifiedCreature = new Creature(newName, id, newN, newM, newMut, tmpBrain, null); if (bigMutAddNode) { //Add a node modifiedCreature.addRandomNode(); } @@ -267,8 +278,12 @@ class Creature { if(withUsableBrain){ newBrain = this.brain.getUsableCopyOfBrain(); } - return new Creature(this.name, newID, n2, m2, this.d, this.alive, - this.mutability,newBrain,newFoodPositions); + Creature copiedCreature = new Creature(this.name, newID, n2, m2, this.mutability, newBrain, newFoodPositions); + copiedCreature.d = this.d; + copiedCreature.chomps = this.chomps; + copiedCreature.timePerChomp = this.timePerChomp; + copiedCreature.alive = this.alive; + return copiedCreature; } void drawCreature(PGraphics img, Boolean putInFrontOfBack) { if(putInFrontOfBack && false){ @@ -307,6 +322,7 @@ class Creature { this.averageZ = this.averageZ/this.n.size(); } void calculateNextFoodLocation() { + if(this.chomps >= maxChomp){ return; } this.setAverages(); this.foodAngle += this.foodPositions[chomps][0]; float sinA = sin(this.foodAngle); @@ -346,10 +362,26 @@ class Creature { if(hasNodeOffGround){ float withinChomp = max(1.0-this.getCurrentFoodDistance()/this.startingFoodDistance,0); if(withinChomp >= 1){ withinChomp = 0.99; } + float chompfit; + if(this.chomps >= maxChomp){ chompfit = this.chomps; } + else { chompfit = this.chomps+withinChomp; } + + float speedfit = 0; + if(this.chomps > 0){ + timePerChomp = float(lastChompTime/frames)/float(this.chomps); + if(this.chomps > angleMultiplier.length){ + if(lastChompTime/frames <= 1){ speedfit = 0; } + else if(timePerChomp < 1 && lastChompTime > 0){ speedfit = timePerChompWeight; } + else if(timePerChomp > timePerChompWeight/timePerChompSlope+1){ speedfit = 0; } + else if(lastChompTime == 0 || timePerChomp == 0){ speedfit = 0; } + else{ speedfit = -timePerChompSlope*(timePerChomp-(timePerChompWeight/timePerChompSlope)-1); } + } + } + float loss = (this.brain.BRAIN_WIDTH - 2)*lossPerLayer; // loss function for brain width - float fit = chomps+withinChomp-loss;//cumulativeAngularVelocity/(n.size()-2)/pow(averageNodeNausea,0.3);// /(2*PI)/(n.size()-2); //dist(0,0,averageX,averageZ)*0.2; // Multiply by 0.2 because a meter is 5 units for some weird reason. - if(fit >= maxChomp){ fit = maxChomp; } - return fit; + if(this.chomps >= maxChomp/2){ loss = 0; } + + return 100*(chompfit+speedfit-loss)/(maxChomp+timePerChompWeight); }else{ return 0; } @@ -382,9 +414,9 @@ class Creature { float distFromFood = dist(ni.x,ni.y,ni.z,this.foodX,this.foodY,this.foodZ); if(distFromFood <= 0.4){ this.chomps++; + lastChompTime = this.brain.timesUsed; hasEaten = true; - if(chomps >= maxChomp){ chomps = maxChomp; } - else { this.calculateNextFoodLocation(); } + this.calculateNextFoodLocation(); } } return hasEaten; @@ -397,6 +429,8 @@ class Creature { else { g.writeNumberField("id", overwriteId); } g.writeBooleanField("alive", alive); g.writeNumberField("mutability", mutability); + g.writeNumberField("chomps", chomps); + g.writeNumberField("timePerChomp", timePerChomp); g.writeArrayFieldStart("name");g.writeNumber(name[0]);g.writeNumber(name[1]);g.writeEndArray(); if(n != null){ g.writeArrayFieldStart("nodes"); @@ -424,6 +458,8 @@ class Creature { String fieldName = p.getCurrentName(); JsonToken token = p.nextToken(); if(fieldName.equals("d")){ d = p.getFloatValue(); } + if(fieldName.equals("chomps")){ chomps = p.getIntValue(); } + if(fieldName.equals("timePerChomp")){ timePerChomp = p.getFloatValue(); } else if(fieldName.equals("id")){ id = p.getIntValue(); } else if(fieldName.equals("alive")){ alive = p.getBooleanValue(); } else if(fieldName.equals("mutability")){ mutability = p.getFloatValue(); } diff --git a/computingThread.pde b/computingThread.pde index 0fa1538..27e536e 100644 --- a/computingThread.pde +++ b/computingThread.pde @@ -11,15 +11,13 @@ public class ComputingThread implements Runnable{ public void run() { for(int k = this.beginIndex; k < this.endIndex; k++) { myCreature = c[k].copyCreature(-1,false,true); + myCreature.initParameters(); myCreature.calculateNextFoodLocation(); int myMaxFrames = maxFrames; int currentChomp = 0; boolean isJumper = false; for (int sim = 0; sim < myMaxFrames; sim++) { if(myCreature.simulate()){ // activated when chomped - if(simDuration > jumperTruncate){ - if(sim <= jumperFrames){ isJumper = true; break; } // we kill jumpers - } myMaxFrames += giftForChompFrames; currentChomp++; if(currentChomp >= maxChomp){ break; } @@ -30,6 +28,8 @@ public class ComputingThread implements Runnable{ } else { myCreature.setAverages(); c[k].d = myCreature.getFitness(); + c[k].chomps = myCreature.chomps; + c[k].timePerChomp = myCreature.timePerChomp; } } } diff --git a/evolutionSteer.pde b/evolutionSteer.pde index 8b16682..fe909ec 100644 --- a/evolutionSteer.pde +++ b/evolutionSteer.pde @@ -41,7 +41,11 @@ float hazelStairs = -1; float cumulativeAngularVelocity = 0; boolean saveFramesPerGeneration = true; color gridBGColor = color(220, 253, 102, 255); -float foodAngleChange = 0.0; +float foodAngleChange = PI; +float[] angleMultiplier = { // angle increases progressively according to the values in this array + 0.0326, 0.0526, 0.0839, 0.1312, 0.1993, 0.291, 0.4036, 0.5273, 0.6478, + 0.752, 0.8333, 0.8918, 0.9315, 0.9573, 0.9736, 0.9838, 0.9901, 0.994 +}; static int nbCreatures = 250; // please set even number int gridX = 25; // X * Y must be equal to nbCreatures ! @@ -82,14 +86,13 @@ float camHA = 0; float camVA = -0.5; int frames = 60; int simDuration = 15; // in seconds -int jumperDuration = 1; // definition of jumper : chomp < this value (in seconds) -int jumperTruncate = 12; // remove jumper limitation when giftForChompSec is < to this value int maxFrames = simDuration*frames; int maxSimulationFrames = maxFrames; -int jumperFrames = jumperDuration*frames; float giftForChompSec = 15; int giftForChompFrames = ceil(giftForChompSec*frames); -int maxChomp = 100; // maximum number of chomps before simulation ends +int maxChomp = 50; // maximum number of chomps before simulation ends +int timePerChompWeight = 20; // weight for creature speed in fitness calculation +int timePerChompSlope = 2; // slope for speed in fitness calculation int menu = 0; int gen = -1; float sliderX = 1170; @@ -129,7 +132,7 @@ int[] p = new int[29]; final int BRAIN_WIDTH = 2; float STARTING_AXON_VARIABILITY = 1.0; float AXON_START_MUTABILITY = 0.0005; -float lossPerLayer = 1; //chomp lost by layer of neurons added +float lossPerLayer = 0.5; //chomp lost by layer of neurons added boolean enableRadioactivity = true; int radioactiveNumber = 20; // number of highly mutated creatures @@ -347,8 +350,8 @@ void drawGraph(int graphWidth, int graphHeight) { graphImage.beginDraw(); graphImage.background(220); if (gen >= 1) { - drawLines(130, int(graphHeight*0.05), graphWidth-130, int(graphHeight*0.9)); - drawSegBars(130, 0, graphWidth-130, 150); + drawLines(80, int(graphHeight*0.05), graphWidth-80, int(graphHeight*0.9)); + drawSegBars(80, 0, graphWidth-80, 150); } graphImage.endDraw(); } @@ -368,7 +371,7 @@ void drawLines(int x, int y, int graphWidth, int graphHeight) { for (float i = ceil((worst-(best-worst)/18.0)/unit)*unit; i < best+(best-worst)/18.0;i+=unit) { float lineY = y-i*meterHeight+zero; graphImage.line(x, lineY, graphWidth+x, lineY); - graphImage.text(showUnit(i, unit)+" "+fitnessUnit, x-5, lineY+4); + graphImage.text(showUnit(i, unit)+" %", x-5, lineY+4); } graphImage.stroke(0); for (int i = 0; i < 29; i++) { @@ -879,17 +882,19 @@ void drawStatusWindow(boolean isFirstFrame) { } noStroke(); fill(255); - rect(px-60, py, 120, 52); + rect(px-60, py, 120, 58); fill(0); textFont(font, 12); textAlign(CENTER); - text("#"+rank, px, py+12); - text("ID: "+cj.id, px, py+24); - text("Fitness: "+nf(cj.d, 0, 3), px, py+36); + text("#"+rank, px, py+10); + text("ID: "+cj.id, px, py+19); + text("Fitness: "+nf(cj.d, 0, 3), px, py+28); + text("Chomps: "+cj.chomps, px, py+37); + text("Time/Chomp: "+nf(cj.timePerChomp, 0, 3), px, py+46); colorMode(HSB, 1); int sp = (cj.n.size()%10)*10+(cj.m.size()%10); fill(getColor(sp, true)); - text("Species: S"+(cj.n.size()%10)+""+(cj.m.size()%10), px, py+48); + text("Species: S"+(cj.n.size()%10)+""+(cj.m.size()%10), px, py+55); colorMode(RGB, 255); if (miniSimulation) { keysToMoveCamera(); @@ -1052,21 +1057,24 @@ void draw() { rect(990, 120, 230, 40); fill(0); //text("Survivor Bias: "+percentify(getSB(genSelected)), 437, 50); - text("Curve: ±"+nf(foodAngleChange/(2*PI)*360,0,2)+" degrees", 420, 110); - text("Gift: +"+nf(giftForChompSec)+" seconds", 470, 135); + textAlign(RIGHT); + if(foodAngleChange < PI){ + text("Curve: ±"+nf(foodAngleChange/(2*PI)*360,0,2)+" degrees", 700, 120); + } + if(giftForChompSec < 15){ + text("Gift: +"+nf(giftForChompSec)+" seconds", 700, 145); + } if(enableRadioactivity){ - text("Radioactive mode", 460, 85); + text("Radioactive mode",700, 95); } + textAlign(LEFT); text("Do 1 step-by-step generation.", 770, 50); text("Do 1 quick generation.", 770, 100); text("Do 1 gen ASAP.", 770, 150); text("Do gens ALAP.", 1000, 150); - text("Median "+fitnessName, 50, 160); text("Save", 620, 48); text("Light save", 435, 48); - textAlign(CENTER); - textAlign(RIGHT); - text(float(round(percentile.get(min(genSelected, percentile.size()-1))[14]*nbCreatures))/nbCreatures+" "+fitnessUnit, 700, 160); + text("Median fit : "+float(round(percentile.get(min(genSelected, percentile.size()-1))[14]*nbCreatures))/nbCreatures+"%", 50, 160); drawHistogram(760, 410, 460, 280); drawGraphImage(); //if(saveFramesPerGeneration && gen > lastImageSaved){ @@ -1707,6 +1715,7 @@ void setGlobalVariables(Creature thisCreature) { totalNodeNausea = 0; averageNodeNausea = 0; cumulativeAngularVelocity = 0; + currentCreature.initParameters(); currentCreature.calculateNextFoodLocation(); } int[] getNewCreatureName(){ @@ -1740,6 +1749,8 @@ String rankify(int s){ } void setFitness(int i){ c[i].d = currentCreature.getFitness(); + c[i].chomps = currentCreature.chomps; + c[i].timePerChomp = currentCreature.timePerChomp; } void brainiac(){ @@ -1809,7 +1820,7 @@ Creature createNewCreature(int index){ float len = random(0.5,1.5); m.add(new Muscle(tc1, tc2, len, random(0.015, 0.06))); } - return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 0, true, 1.0, null, null); + return new Creature(null, index+1, new ArrayList(n), new ArrayList(m), 1.0, null, null); } public void writeToErrorLog(Exception e){ String[] error = new String[100]; @@ -1967,7 +1978,7 @@ public void loadFromJson(JsonParser p){ if (token != JsonToken.START_ARRAY) { throw new IOException("Expected Array"); } while((token = p.nextToken()) != JsonToken.END_ARRAY){ if (token == JsonToken.START_OBJECT){ - Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, null, null); + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 1.0, null, null); creature.loadFromJson(p); creatureDatabase.add(creature); } @@ -2033,7 +2044,7 @@ public void loadFromJson(JsonParser p){ int i = 0; while((token = p.nextToken()) != JsonToken.END_ARRAY){ if (token == JsonToken.START_OBJECT){ - Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 0, false, 0, null, null); + Creature creature = new Creature(new int[2], 0, new ArrayList(), new ArrayList(), 1.0, null, null); creature.loadFromJson(p); c[i] = creature; c2.add(c[i]);