1
0
mirror of https://github.com/fazo96/AIrium.git synced 2025-01-10 09:34:20 +01:00

numerous improvements

This commit is contained in:
Enrico Fasoli 2015-07-02 17:24:06 +02:00
parent 4f55625056
commit 175b51854c
5 changed files with 77 additions and 49 deletions

View File

@ -8,7 +8,13 @@
</open-files> </open-files>
<editor-bookmarks lastBookmarkId="0" xmlns="http://www.netbeans.org/ns/editor-bookmarks/2"/> <editor-bookmarks lastBookmarkId="0" xmlns="http://www.netbeans.org/ns/editor-bookmarks/2"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2"> <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group/> <group>
<file>file:/home/fazo/Documents/Git/AIrium/core/src/com/mygdx/game/Game.java</file>
<file>file:/home/fazo/Documents/Git/AIrium/core/src/logic/neural/Neuron.java</file>
<file>file:/home/fazo/Documents/Git/AIrium/core/src/logic/Creature.java</file>
<file>file:/home/fazo/Documents/Git/AIrium/core/src/logic/neural/Brain.java</file>
<file>file:/home/fazo/Documents/Git/AIrium/core/src/logic/World.java</file>
</group>
</open-files> </open-files>
</auxiliary> </auxiliary>
</gradle-project-properties> </gradle-project-properties>

View File

@ -4,6 +4,7 @@ import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input; import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import logic.Element; import logic.Element;
import logic.World; import logic.World;
@ -13,14 +14,16 @@ public class Game extends ApplicationAdapter {
private static Game game; private static Game game;
ShapeRenderer shaper; ShapeRenderer shaper;
private World world; private World world;
private float cameraSpeed = 5; private float cameraSpeed = 15;
private BitmapFont font;
@Override @Override
public void create() { public void create() {
game = this; game = this;
world = new World(1920, 1080); world = new World(2500, 2500);
shaper = new ShapeRenderer(); shaper = new ShapeRenderer();
//shaper.setAutoShapeType(true); font = new BitmapFont();
} }
@Override @Override
@ -63,6 +66,7 @@ public class Game extends ApplicationAdapter {
} }
} }
shaper.setColor(0.3f, 0.3f, 0.3f, 1); shaper.setColor(0.3f, 0.3f, 0.3f, 1);
// draw borders
shaper.rect(0, 0, world.getWidth(), world.getHeight()); shaper.rect(0, 0, world.getWidth(), world.getHeight());
shaper.end(); shaper.end();
} }

View File

@ -10,7 +10,6 @@ import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import logic.neural.Brain;
/** /**
* *
@ -18,8 +17,8 @@ import logic.neural.Brain;
*/ */
public class World { public class World {
private int width, height, generation = 0; private final int width, height, nPlants, creatPerGen;
private final int nPlants, creatPerGen; private int generation = 0;
public ArrayList<Element> elements; public ArrayList<Element> elements;
public ArrayList<Creature> creatures; public ArrayList<Creature> creatures;
public ArrayList<Creature> graveyard; public ArrayList<Creature> graveyard;
@ -66,12 +65,6 @@ public class World {
public int compare(Creature t, Creature t1) { public int compare(Creature t, Creature t1) {
// put the highest fitness first (sort in reverse) // put the highest fitness first (sort in reverse)
return (int) (t1.getFitness() - t.getFitness()); return (int) (t1.getFitness() - t.getFitness());
/*if (t.getFitness() < t1.getFitness()) {
return -1;
} else if (t.getFitness() > t1.getFitness()) {
return 1;
}
return 0;*/
} }
}; };
if (graveyard.isEmpty() || restart) { // First gen if (graveyard.isEmpty() || restart) { // First gen
@ -80,42 +73,45 @@ public class World {
spawnCreature(); spawnCreature();
} }
} else { // Evolve previous gen } else { // Evolve previous gen
// Calculate avg fitness graveyard.sort(creatureComp); // sort by fitness
// Prepare best agent list
int topSize = (int) Math.floor(graveyard.size() * 0.1f);
Creature[] top = new Creature[topSize];
// Calculate avg fitness and prepare best agent list
float avgFitness = 0; float avgFitness = 0;
for (Creature c : graveyard) { for (int i = 0; i < graveyard.size(); i++) {
Creature c = graveyard.get(i);
if (i < topSize) {
top[i] = graveyard.get(i);
Log.log(Log.INFO, "Gen " + generation + " Top " + (i + 1) + ": " + c.getFitness());
}
avgFitness += c.getFitness(); avgFitness += c.getFitness();
} }
avgFitness = avgFitness / graveyard.size(); avgFitness = avgFitness / graveyard.size();
Log.log(Log.INFO, "Gen " + generation + " done. Avg fitness: " + avgFitness); Log.log(Log.INFO, "Gen " + generation + " done. Avg fitness: " + avgFitness);
// Start evolution // Generate children
graveyard.sort(creatureComp); for (Creature c : graveyard) {
for (int i = 0; i < creatPerGen / 2; i++) { int first = (int) Math.floor(Math.random() * topSize);
Creature c = graveyard.get(i); int sec = first;
c.reset(); while (sec == first) {
// Mutate sec = (int) Math.floor(Math.random() * topSize);
if (i != 0) { }
float[][][] n = null;
try { try {
// create a child n = top[first].getBrain().breed(top[sec].getBrain().getMap());
float[][][] mind = c.getBrain().breed(graveyard.get(i - 1).getBrain().getMap());
// spawn it
spawnCreature(mind);
} catch (Exception ex) { } catch (Exception ex) {
// Should never happen // Should not happen
Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex);
} }
} Creature ne = spawnCreature(n);
// Mutate parent //ne.getBrain().mutate(0.1f); // mutate children
c.getBrain().remap(c.getBrain().getMutatedMap(0.1f));
// Add it back in
creatures.add(c);
elements.add(c);
} }
graveyard.clear(); graveyard.clear();
generation++; generation++;
} }
} }
private void spawn(boolean isCreature, float[][][] brainMap) { private Element spawn(boolean isCreature, float[][][] brainMap) {
int x, y, r; int x, y, r;
boolean overlaps = false; boolean overlaps = false;
if (isCreature) { if (isCreature) {
@ -141,11 +137,13 @@ public class World {
} }
elements.add(c); elements.add(c);
creatures.add(c); creatures.add(c);
return c;
} else { } else {
Log.log(Log.DEBUG, "New Veg: " + x + " " + y); Log.log(Log.DEBUG, "New Veg: " + x + " " + y);
Vegetable v = new Vegetable(x, y); Vegetable v = new Vegetable(x, y);
elements.add(v); elements.add(v);
plants.add(v); plants.add(v);
return v;
} }
} }
@ -153,12 +151,12 @@ public class World {
spawn(false, null); spawn(false, null);
} }
private void spawnCreature() { private Creature spawnCreature() {
spawn(true, null); return (Creature) spawn(true, null);
} }
private void spawnCreature(float[][][] b) { private Creature spawnCreature(float[][][] b) {
spawn(true, b); return (Creature) spawn(true, b);
} }
public int getWidth() { public int getWidth() {

View File

@ -149,7 +149,7 @@ public class Brain {
/** /**
* Get a map of this brain's mind.. with a mutation * Get a map of this brain's mind.. with a mutation
* *
* @param mutationFactor the highest this number, the bigger the mutation * @param mutationFactor the higher this number, the bigger the mutation
* @return a mutated brain map of this brain's mind * @return a mutated brain map of this brain's mind
*/ */
public float[][][] getMutatedMap(float mutationFactor) { public float[][][] getMutatedMap(float mutationFactor) {
@ -165,6 +165,21 @@ public class Brain {
return res; return res;
} }
/**
* Apply a mutation to this brain
*
* @param mutationFactor the higher this number, the bigger the mutation
*/
public void mutate(float mutationFactor) {
for (int i = 1; i < neurons.length; i++) // layers (skip input layer)
{
for (int j = 0; j < neurons[i].length; j++) // neurons per layer
{
neurons[i][j].setWeights(neurons[i][j].mutate(mutationFactor));
}
}
}
public float[][][] breed(float[][][] map) throws Exception { public float[][][] breed(float[][][] map) throws Exception {
float[][][] res = new float[neurons.length - 1][][]; float[][][] res = new float[neurons.length - 1][][];
if (map.length != neurons.length - 1) { if (map.length != neurons.length - 1) {

View File

@ -5,11 +5,16 @@ import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.mygdx.game.Game; import com.mygdx.game.Game;
public class DesktopLauncher { public class DesktopLauncher {
public static void main(String[] arg) { public static void main(String[] arg) {
LwjglApplicationConfiguration.disableAudio = true;
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.height = 600; config.height = 600;
config.width = 800; config.width = 800;
config.resizable = false; config.resizable = false;
config.vSyncEnabled = false; // Setting to false disables vertical sync
config.foregroundFPS = 60; // Setting to 0 disables foreground fps throttling
config.backgroundFPS = 0; // Setting to 0 disables background fps throttling
new LwjglApplication(new Game(), config); new LwjglApplication(new Game(), config);
} }
} }