mirror of
https://github.com/fazo96/AIrium.git
synced 2025-01-10 09:34:20 +01:00
numerous improvements
This commit is contained in:
parent
4f55625056
commit
175b51854c
@ -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>
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user