From 93aba50c099d2b1717a6ef6c838508ffa573165c Mon Sep 17 00:00:00 2001 From: Enrico Fasoli Date: Fri, 3 Jul 2015 21:50:49 +0200 Subject: [PATCH] fixed multicore, now way fast --- core/src/com/mygdx/game/Game.java | 6 +++- core/src/com/mygdx/game/Log.java | 2 +- core/src/logic/Creature.java | 51 +++++++++++++++++++--------- core/src/logic/Element.java | 10 ++++++ core/src/logic/World.java | 56 +++++++------------------------ core/src/logic/neural/Brain.java | 7 ++++ core/src/logic/neural/Neuron.java | 2 +- 7 files changed, 72 insertions(+), 62 deletions(-) diff --git a/core/src/com/mygdx/game/Game.java b/core/src/com/mygdx/game/Game.java index b6fea20..d5ed2d6 100644 --- a/core/src/com/mygdx/game/Game.java +++ b/core/src/com/mygdx/game/Game.java @@ -17,6 +17,7 @@ public class Game extends ApplicationAdapter { private World world; private float cameraSpeed = 15; private BitmapFont font; + private Thread worldThread; private boolean paused = false; @Override @@ -26,7 +27,10 @@ public class Game extends ApplicationAdapter { shaper = new ShapeRenderer(); shaper.setAutoShapeType(true); font = new BitmapFont(); - new Thread(world).start(); + worldThread = new Thread(world); + worldThread.setPriority(Thread.MAX_PRIORITY); + world.newGen(true); + worldThread.start(); } @Override diff --git a/core/src/com/mygdx/game/Log.java b/core/src/com/mygdx/game/Log.java index cc74048..5b1f62b 100644 --- a/core/src/com/mygdx/game/Log.java +++ b/core/src/com/mygdx/game/Log.java @@ -15,7 +15,7 @@ public class Log { public static final int INFO = 1; public static final int DEBUG = 2; - private static int logLevel = 1; + private static int logLevel = 0; public static void log(int level, String msg) { if (level <= logLevel) { diff --git a/core/src/logic/Creature.java b/core/src/logic/Creature.java index 33a70ea..3abe378 100644 --- a/core/src/logic/Creature.java +++ b/core/src/logic/Creature.java @@ -19,7 +19,7 @@ public class Creature extends Element implements Runnable { private Brain brain; private float dir, hp, prevHp, speed, sightRange, fov, fitness, rotSpeed, beak; - private boolean eating = false, killing = false, done = false; + private boolean eating = false, killing = false, done = true; private Sight[] sights; private Thread thread; @@ -35,8 +35,6 @@ public class Creature extends Element implements Runnable { fitness = 0; brain = new Brain(10, 5, 2, 10); sights = new Sight[2]; - thread = new Thread(this); - thread.start(); } @Override @@ -44,21 +42,24 @@ public class Creature extends Element implements Runnable { for (;;) { while (Game.get().getWorld() == null || Game.get().getWorld().isBusy()) { /*try { - Thread.sleep(30); - } catch (InterruptedException ex) { - Logger.getLogger(Creature.class.getName()).log(Level.SEVERE, null, ex); - }*/ + Thread.sleep(30); + } catch (InterruptedException ex) { + Logger.getLogger(Creature.class.getName()).log(Level.SEVERE, null, ex); + }*/ Thread.yield(); } - if (!done && !update()) { + if (done) { + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + //Logger.getLogger(Creature.class.getName()).log(Level.SEVERE, null, ex); + } + } else if (!update()) { // Dead - break; + Game.get().getWorld().getGraveyard().add(this); } done = true; } - done = true; - // Dead - Game.get().getWorld().getGraveyard().add(this); } @Override @@ -140,6 +141,9 @@ public class Creature extends Element implements Runnable { return true; } + /** + * Applies the creature's desired movements to the world + */ public void applyToWorld() { if (speed > max_speed) { speed = max_speed; @@ -199,6 +203,11 @@ public class Creature extends Element implements Runnable { s.arc((float) relX * getSize() + getX(), (float) relY * getSize() + getY(), sightRange, orient, degrees); } + /** + * Reads data from sensors and applies eat/kill mechanics + * + * @return sensor data + */ public Sight[] interactWithWorld() { eating = false; Sight[] sights = new Sight[2]; @@ -290,6 +299,20 @@ public class Creature extends Element implements Runnable { return sights; } + public void resume() { + if (!done) { + Log.log(Log.ERROR, "Tried to resume running worker!"); + } else { + done = false; + if (thread == null) { + thread = new Thread(this); + thread.start(); + } else { + thread.interrupt(); + } + } + } + public Brain getBrain() { return brain; } @@ -311,10 +334,6 @@ public class Creature extends Element implements Runnable { return done; } - public void setDone(boolean done) { - this.done = done; - } - public float getHp() { return hp; } diff --git a/core/src/logic/Element.java b/core/src/logic/Element.java index 9a4d8a0..efd257a 100644 --- a/core/src/logic/Element.java +++ b/core/src/logic/Element.java @@ -42,8 +42,18 @@ public abstract class Element { y += deltaY; } + /** + * Update element logic + * + * @return true if element is still alive + */ public abstract boolean update(); + /** + * Draw the element + * + * @param s the instance used to draw shapes + */ public abstract void render(ShapeRenderer s); public float getX() { diff --git a/core/src/logic/World.java b/core/src/logic/World.java index 7ff41d6..4c09d73 100644 --- a/core/src/logic/World.java +++ b/core/src/logic/World.java @@ -18,10 +18,10 @@ import java.util.logging.Logger; */ public class World implements Runnable { + private final Comparator creatureComp; private final int width, height, nPlants, creatPerGen; private int generation = 1; - private boolean busy = true, workerDone = false; - private final Thread worker; + private boolean busy = true; public ArrayList elements; public ArrayList toAdd; public ArrayList creatures; @@ -40,28 +40,13 @@ public class World implements Runnable { plants = new ArrayList(); deadPlants = new ArrayList(); graveyard = new ArrayList(); - worker = new Thread() { + creatureComp = new Comparator() { @Override - public void run() { - for (;;) { - if (!workerDone) { - for (Vegetable v : plants) { - v.update(); - } - workerDone = true; - } else { - Thread.yield(); - /*try { - Thread.sleep(30); - } catch (InterruptedException ex) { - Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); - }*/ - } - } + public int compare(Creature t, Creature t1) { + // put the highest fitness first (sort in reverse) + return (int) (t1.getFitness() - t.getFitness()); } }; - worker.start(); - newGen(true); } @Override @@ -105,12 +90,14 @@ public class World implements Runnable { while (plants.size() < nPlants) { spawnVegetable(); } - for (Creature c : creatures) { - c.setDone(false); + for (Vegetable v : plants) { + v.update(); } - workerDone = false; - busy = false; Log.log(Log.DEBUG, "Launching Creature workers"); + for (Creature c : creatures) { + c.resume(); + } + busy = false; int readyCount = 0; Thread.yield(); do { @@ -120,17 +107,8 @@ public class World implements Runnable { readyCount++; } } - Log.log(Log.DEBUG, "DoneCount: " + readyCount + " out of " + creatures.size()); + //Log.log(Log.DEBUG, "DoneCount: " + readyCount + " out of " + creatures.size()); } while (readyCount < creatures.size()); - Log.log(Log.DEBUG, "Done creatures, awaiting veg worker..."); - while (!workerDone) { - Thread.yield(); - /*try { - Thread.sleep(30); - } catch (InterruptedException ex) { - Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); - }*/ - } busy = true; Log.log(Log.DEBUG, "Paused workers. Applying modifications to world... "); for (Creature c : creatures) { @@ -143,14 +121,6 @@ public class World implements Runnable { elements.removeAll(creatures); graveyard.addAll(creatures); creatures.clear(); - Comparator creatureComp = new Comparator() { - - @Override - public int compare(Creature t, Creature t1) { - // put the highest fitness first (sort in reverse) - return (int) (t1.getFitness() - t.getFitness()); - } - }; if (graveyard.isEmpty() || restart) { // First gen generation = 1; Log.log(Log.INFO, "Starting from generation 1: spawning " + creatPerGen + " creatures."); diff --git a/core/src/logic/neural/Brain.java b/core/src/logic/neural/Brain.java index 2add9ad..57acc5e 100644 --- a/core/src/logic/neural/Brain.java +++ b/core/src/logic/neural/Brain.java @@ -180,6 +180,13 @@ public class Brain { } } + /** + * Use this brain's neural map and another one to create a unique child + * + * @param map the other parent of the child + * @return a unique child mind + * @throws Exception if the brains have a different layout + */ public float[][][] breed(float[][][] map) throws Exception { float[][][] res = new float[neurons.length - 1][][]; if (map.length != neurons.length - 1) { diff --git a/core/src/logic/neural/Neuron.java b/core/src/logic/neural/Neuron.java index 3e4a44b..855a55a 100644 --- a/core/src/logic/neural/Neuron.java +++ b/core/src/logic/neural/Neuron.java @@ -70,7 +70,7 @@ public class Neuron { } // sigmoid function float res = (float) (1 / (1 + Math.pow(Math.E, a * -1))); - Log.log(Log.DEBUG, "Computed Value " + res + " for neuron"); + //Log.log(Log.DEBUG, "Computed Value " + res + " for neuron"); return res; }