mirror of
https://github.com/fazo96/AIrium.git
synced 2025-04-20 01:38:38 +02:00
fixed multicore, now way fast
This commit is contained in:
parent
95f03e8143
commit
93aba50c09
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -18,10 +18,10 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class World implements Runnable {
|
||||
|
||||
private final Comparator<Creature> 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<Element> elements;
|
||||
public ArrayList<Element> toAdd;
|
||||
public ArrayList<Creature> 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<Creature>() {
|
||||
@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<Creature>() {
|
||||
|
||||
@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.");
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user