mirror of
https://github.com/fazo96/AIrium.git
synced 2025-01-10 09:34:20 +01:00
Optimization and bug fixing
This commit is contained in:
parent
5c44b30cc6
commit
b0251e1626
@ -8,7 +8,6 @@ import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.badlogic.gdx.math.Vector3;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Map;
|
||||
import logic.creatures.Creature;
|
||||
import logic.Element;
|
||||
import logic.World;
|
||||
|
@ -1,204 +1,204 @@
|
||||
package com.mygdx.game;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Hangles File I/O for AIrium components.
|
||||
*
|
||||
* @author fazo
|
||||
*/
|
||||
public class Serializer {
|
||||
|
||||
private static final String[] sillabe = {"ba", "de", "ka", "mo", "shi", "du", "ro", "te", "mi", "lo", "pa"};
|
||||
private static Map<String, Float> defaults;
|
||||
|
||||
public static String nameBrain(float[][][] brainMap) {
|
||||
// Compute a unique representation of the brainmap
|
||||
long a = 0;
|
||||
for (int i = 0; i < brainMap.length; i++) {
|
||||
for (int j = 0; j < brainMap[i].length; j++) {
|
||||
for (int z = 0; z < brainMap[i][j].length; z++) {
|
||||
a += brainMap[i][j][z] * i * j * z;
|
||||
}
|
||||
}
|
||||
}
|
||||
Random gen = new Random(a);
|
||||
String name = "";
|
||||
int length = Math.abs(gen.nextInt()) % 5 + 2;
|
||||
for (int i = 0; i < length; i++) {
|
||||
name += sillabe[Math.abs(gen.nextInt()) % sillabe.length];
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void saveToFile(File f, String content) {
|
||||
PrintWriter fw = null;
|
||||
try {
|
||||
fw = new PrintWriter(f);
|
||||
} catch (IOException ex) {
|
||||
Log.log(Log.ERROR, ex.getMessage());
|
||||
}
|
||||
fw.print(content);
|
||||
fw.flush();
|
||||
fw.close();
|
||||
}
|
||||
|
||||
public static String loadFromFile(File f) {
|
||||
String s, a = "";
|
||||
try {
|
||||
BufferedReader bf = new BufferedReader(new FileReader(f));
|
||||
while ((s = bf.readLine()) != null) {
|
||||
a += s + "\n";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(Log.ERROR, e.getMessage());
|
||||
System.out.println(e + "");
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static String serializeSettings(Map<String, Float> options) {
|
||||
String a = "# Settings file for use with AIrium.\n"
|
||||
+ "# More information at http://github.com/fazo96/AIrium\n";
|
||||
for (Object o : options.entrySet().toArray()) {
|
||||
Map.Entry<String, Float> e = (Map.Entry<String, Float>) o;
|
||||
a += e.getKey() + " = " + e.getValue() + "\n";
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static Map<String, Float> readSettings(String fileContent) {
|
||||
int line = 0;
|
||||
Map<String, Float> m = new HashMap<String, Float>();
|
||||
for (String s : fileContent.split("\n")) {
|
||||
line++;
|
||||
if (s.startsWith("#")) {
|
||||
// Skip comment
|
||||
continue;
|
||||
}
|
||||
String[] ss = s.trim().split(" = ");
|
||||
try {
|
||||
if (ss.length != 2) {
|
||||
throw new Exception("Invalid string at line " + line);
|
||||
}
|
||||
Log.log(Log.DEBUG, "Loading setting \"" + ss[0].trim() + "\" with value \"" + Float.parseFloat(ss[1].trim()) + "\"");
|
||||
m.put(ss[0].trim(), Float.parseFloat(ss[1].trim()));
|
||||
} catch (Exception e) {
|
||||
Log.log(Log.ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
public static String serializeBrain(float brainMap[][][]) {
|
||||
String s = "# Neural Map for use with AIrium.\n"
|
||||
+ "# More information at http://github.com/fazo96/AIrium\n"
|
||||
+ "Layers: " + (brainMap.length + 1);
|
||||
s += "\nInput Neurons: " + brainMap[0][0].length;
|
||||
s += "\n# Layer 1 Skipped because it's the input layer.";
|
||||
// layers (input layer not included in brain map)
|
||||
for (int i = 0; i < brainMap.length; i++) {
|
||||
s += "\nLayer " + (i + 2) + " has " + brainMap[i].length + " neurons";
|
||||
for (int j = 0; j < brainMap[i].length; j++) { // neurons
|
||||
s += "\nWeights for Layer " + (i + 2) + " Neuron " + (j + 1) + " = ";
|
||||
for (int z = 0; z < brainMap[i][j].length; z++) { // connections
|
||||
s += brainMap[i][j][z] + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public static float[][][] loadBrain(String s) {
|
||||
float brainMap[][][] = null;
|
||||
Log.log(Log.INFO, "Loading brain from String with " + s.split("\n").length + " lines");
|
||||
for (String l : s.split("\n")) {
|
||||
l = l.trim();
|
||||
if (l.isEmpty() || l.startsWith("#")) {
|
||||
// Skip comment
|
||||
} else if (l.startsWith("Layers: ")) {
|
||||
// Set Layer number
|
||||
int layers = Integer.parseInt(l.split(" ")[1]) - 1;
|
||||
brainMap = new float[layers][][];
|
||||
Log.log(Log.INFO, "Loaded NLayers: " + layers);
|
||||
} else if (l.startsWith("Input Neurons")) {
|
||||
int in = Integer.parseInt(l.split(" ")[2]);
|
||||
brainMap[0] = new float[in][0];
|
||||
Log.log(Log.INFO, "Loaded NInputNeurons: " + in);
|
||||
} else if (l.startsWith("Layer ")) {
|
||||
// Set neuron number for given layer
|
||||
String ll[] = l.split(" ");
|
||||
int layer = Integer.parseInt(ll[1]) - 2;
|
||||
int n = Integer.parseInt(ll[3]);
|
||||
brainMap[layer] = new float[n][];//[layer>0?brainMap[layer-1].length:0];
|
||||
} else if (l.startsWith("Weights ")) {
|
||||
// Set weights
|
||||
String ll[] = l.split(" ");
|
||||
int layer = Integer.parseInt(ll[3]) - 2;
|
||||
int neuron = Integer.parseInt(ll[5]) - 1;
|
||||
int nWeights = ll.length - 7;
|
||||
brainMap[layer][neuron] = new float[nWeights];
|
||||
if (layer == 0) {
|
||||
Log.log(Log.DEBUG, "This weightmap is for brains with " + (nWeights) + " input neurons.");
|
||||
} else if (nWeights != brainMap[layer - 1].length) {
|
||||
Log.log(Log.ERROR, "WRONG WEIGHT NUMBER: prev layer has "
|
||||
+ brainMap[layer - 1].length + " neurons, but only "
|
||||
+ (nWeights)
|
||||
+ " weights are supplied to this neuron");
|
||||
}
|
||||
for (int i = 7; i < ll.length; i++) {
|
||||
brainMap[layer][neuron][i - 7] = Float.parseFloat(ll[i]);
|
||||
Log.log(Log.DEBUG, "Loading L" + layer + "N" + neuron + "W" + (i - 7) + " = " + brainMap[layer][neuron][i - 7]);
|
||||
}
|
||||
Log.log(Log.DEBUG, "Loaded " + (nWeights) + " Weights for Layer " + layer + " Neuron " + neuron);
|
||||
}
|
||||
}
|
||||
Log.log(Log.INFO, "Loading complete.");
|
||||
return brainMap;
|
||||
}
|
||||
|
||||
public static Map<String, Float> getDefaultSettings() {
|
||||
if (defaults == null) {
|
||||
String s = "corpse_decay_rate = 0.0\n"
|
||||
+ "mutationFactor = 1.0\n"
|
||||
+ "fps_limit = 60.0\n"
|
||||
+ "creature_hp_decay = 0.5\n"
|
||||
+ "enable_multithreading = 1.0\n"
|
||||
+ "max_ticks = 0.0\n"
|
||||
+ "parents_count = 0.0\n"
|
||||
+ "draw_view_cones = 0.0\n"
|
||||
+ "world_width = 2000.0\n"
|
||||
+ "world_height = 2000.0\n"
|
||||
+ "number_of_plants = 700.0\n"
|
||||
+ "nMutatedNeurons = 0.2\n"
|
||||
+ "enable_corpses = 0.0\n"
|
||||
+ "nMutatedBrains = 0.5\n"
|
||||
+ "nMutatedConnections = 0.5\n"
|
||||
+ "number_of_creatures = 25.0\n"
|
||||
+ "draw_sight_lines = 0.0\n"
|
||||
+ "vegetable_size = 5\n"
|
||||
+ "creature_max_hp = 100\n"
|
||||
+ "creature_fov = 1.5\n"
|
||||
+ "creature_hp_decay = 0.5\n"
|
||||
+ "creature_max_speed = 3.0\n"
|
||||
+ "creature_hp_for_attacking = 1.0\n"
|
||||
+ "creature_hp_for_eating_plants = 1.0\n"
|
||||
+ "creature_points_for_eating_plants = 1.0\n"
|
||||
+ "creature_points_for_attacking = 2.0\n"
|
||||
+ "creature_sight_range = 100.0\n"
|
||||
+ "creature_radius = 20.0\n"
|
||||
+ "brain_hidden_neurons = 10.0\n"
|
||||
+ "brain_hidden_layers = 2.0\n"
|
||||
+ "brain_bias = 0.5\n";
|
||||
defaults = Serializer.readSettings(s);
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
}
|
||||
package com.mygdx.game;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Hangles File I/O for AIrium components.
|
||||
*
|
||||
* @author fazo
|
||||
*/
|
||||
public class Serializer {
|
||||
|
||||
private static final String[] sillabe = {"ba", "de", "ka", "mo", "shi", "du", "ro", "te", "mi", "lo", "pa"};
|
||||
private static Map<String, Float> defaults;
|
||||
|
||||
public static String nameBrain(float[][][] brainMap) {
|
||||
// Compute a unique representation of the brainmap
|
||||
long a = 0;
|
||||
for (int i = 0; i < brainMap.length; i++) {
|
||||
for (int j = 0; j < brainMap[i].length; j++) {
|
||||
for (int z = 0; z < brainMap[i][j].length; z++) {
|
||||
a += brainMap[i][j][z] * i * j * z;
|
||||
}
|
||||
}
|
||||
}
|
||||
Random gen = new Random(a);
|
||||
String name = "";
|
||||
int length = Math.abs(gen.nextInt()) % 5 + 2;
|
||||
for (int i = 0; i < length; i++) {
|
||||
name += sillabe[Math.abs(gen.nextInt()) % sillabe.length];
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void saveToFile(File f, String content) {
|
||||
PrintWriter fw = null;
|
||||
try {
|
||||
fw = new PrintWriter(f);
|
||||
} catch (IOException ex) {
|
||||
Log.log(Log.ERROR, ex.getMessage());
|
||||
}
|
||||
fw.print(content);
|
||||
fw.flush();
|
||||
fw.close();
|
||||
}
|
||||
|
||||
public static String loadFromFile(File f) {
|
||||
String s, a = "";
|
||||
try {
|
||||
BufferedReader bf = new BufferedReader(new FileReader(f));
|
||||
while ((s = bf.readLine()) != null) {
|
||||
a += s + "\n";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(Log.ERROR, e.getMessage());
|
||||
System.out.println(e + "");
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static String serializeSettings(Map<String, Float> options) {
|
||||
String a = "# Settings file for use with AIrium.\n"
|
||||
+ "# More information at http://github.com/fazo96/AIrium\n";
|
||||
for (Object o : options.entrySet().toArray()) {
|
||||
Map.Entry<String, Float> e = (Map.Entry<String, Float>) o;
|
||||
a += e.getKey() + " = " + e.getValue() + "\n";
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static Map<String, Float> readSettings(String fileContent) {
|
||||
int line = 0;
|
||||
Map<String, Float> m = new HashMap<String, Float>();
|
||||
for (String s : fileContent.split("\n")) {
|
||||
line++;
|
||||
if (s.startsWith("#")) {
|
||||
// Skip comment
|
||||
continue;
|
||||
}
|
||||
String[] ss = s.trim().split(" = ");
|
||||
try {
|
||||
if (ss.length != 2) {
|
||||
throw new Exception("Invalid string at line " + line);
|
||||
}
|
||||
Log.log(Log.DEBUG, "Loading setting \"" + ss[0].trim() + "\" with value \"" + Float.parseFloat(ss[1].trim()) + "\"");
|
||||
m.put(ss[0].trim(), Float.parseFloat(ss[1].trim()));
|
||||
} catch (Exception e) {
|
||||
Log.log(Log.ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
public static String serializeBrain(float brainMap[][][]) {
|
||||
String s = "# Neural Map for use with AIrium.\n"
|
||||
+ "# More information at http://github.com/fazo96/AIrium\n"
|
||||
+ "Layers: " + (brainMap.length + 1);
|
||||
s += "\nInput Neurons: " + brainMap[0][0].length;
|
||||
s += "\n# Layer 1 Skipped because it's the input layer.";
|
||||
// layers (input layer not included in brain map)
|
||||
for (int i = 0; i < brainMap.length; i++) {
|
||||
s += "\nLayer " + (i + 2) + " has " + brainMap[i].length + " neurons";
|
||||
for (int j = 0; j < brainMap[i].length; j++) { // neurons
|
||||
s += "\nWeights for Layer " + (i + 2) + " Neuron " + (j + 1) + " = ";
|
||||
for (int z = 0; z < brainMap[i][j].length; z++) { // connections
|
||||
s += brainMap[i][j][z] + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public static float[][][] loadBrain(String s) {
|
||||
float brainMap[][][] = null;
|
||||
Log.log(Log.INFO, "Loading brain from String with " + s.split("\n").length + " lines");
|
||||
for (String l : s.split("\n")) {
|
||||
l = l.trim();
|
||||
if (l.isEmpty() || l.startsWith("#")) {
|
||||
// Skip comment
|
||||
} else if (l.startsWith("Layers: ")) {
|
||||
// Set Layer number
|
||||
int layers = Integer.parseInt(l.split(" ")[1]) - 1;
|
||||
brainMap = new float[layers][][];
|
||||
Log.log(Log.INFO, "Loaded NLayers: " + layers);
|
||||
} else if (l.startsWith("Input Neurons")) {
|
||||
int in = Integer.parseInt(l.split(" ")[2]);
|
||||
brainMap[0] = new float[in][0];
|
||||
Log.log(Log.INFO, "Loaded NInputNeurons: " + in);
|
||||
} else if (l.startsWith("Layer ")) {
|
||||
// Set neuron number for given layer
|
||||
String ll[] = l.split(" ");
|
||||
int layer = Integer.parseInt(ll[1]) - 2;
|
||||
int n = Integer.parseInt(ll[3]);
|
||||
brainMap[layer] = new float[n][];//[layer>0?brainMap[layer-1].length:0];
|
||||
} else if (l.startsWith("Weights ")) {
|
||||
// Set weights
|
||||
String ll[] = l.split(" ");
|
||||
int layer = Integer.parseInt(ll[3]) - 2;
|
||||
int neuron = Integer.parseInt(ll[5]) - 1;
|
||||
int nWeights = ll.length - 7;
|
||||
brainMap[layer][neuron] = new float[nWeights];
|
||||
if (layer == 0) {
|
||||
Log.log(Log.DEBUG, "This weightmap is for brains with " + (nWeights) + " input neurons.");
|
||||
} else if (nWeights != brainMap[layer - 1].length) {
|
||||
Log.log(Log.ERROR, "WRONG WEIGHT NUMBER: prev layer has "
|
||||
+ brainMap[layer - 1].length + " neurons, but only "
|
||||
+ (nWeights)
|
||||
+ " weights are supplied to this neuron");
|
||||
}
|
||||
for (int i = 7; i < ll.length; i++) {
|
||||
brainMap[layer][neuron][i - 7] = Float.parseFloat(ll[i]);
|
||||
Log.log(Log.DEBUG, "Loading L" + layer + "N" + neuron + "W" + (i - 7) + " = " + brainMap[layer][neuron][i - 7]);
|
||||
}
|
||||
Log.log(Log.DEBUG, "Loaded " + (nWeights) + " Weights for Layer " + layer + " Neuron " + neuron);
|
||||
}
|
||||
}
|
||||
Log.log(Log.INFO, "Loading complete.");
|
||||
return brainMap;
|
||||
}
|
||||
|
||||
public static Map<String, Float> getDefaultSettings() {
|
||||
if (defaults == null) {
|
||||
String s = "corpse_decay_rate = 0.0\n"
|
||||
+ "mutationFactor = 1.0\n"
|
||||
+ "fps_limit = 60.0\n"
|
||||
+ "creature_hp_decay = 0.5\n"
|
||||
+ "enable_multithreading = 1.0\n"
|
||||
+ "max_ticks = 0.0\n"
|
||||
+ "parents_count = 0.0\n"
|
||||
+ "draw_view_cones = 0.0\n"
|
||||
+ "world_width = 2000.0\n"
|
||||
+ "world_height = 2000.0\n"
|
||||
+ "number_of_plants = 200.0\n"
|
||||
+ "nMutatedNeurons = 0.2\n"
|
||||
+ "enable_corpses = 0.0\n"
|
||||
+ "nMutatedBrains = 0.5\n"
|
||||
+ "nMutatedConnections = 0.5\n"
|
||||
+ "number_of_creatures = 15.0\n"
|
||||
+ "draw_sight_lines = 0.0\n"
|
||||
+ "vegetable_size = 20\n"
|
||||
+ "creature_max_hp = 100\n"
|
||||
+ "creature_fov = 1.5\n"
|
||||
+ "creature_hp_decay = 0.5\n"
|
||||
+ "creature_max_speed = 3.0\n"
|
||||
+ "creature_hp_for_attacking = 1.0\n"
|
||||
+ "creature_hp_for_eating_plants = 1.0\n"
|
||||
+ "creature_points_for_eating_plants = 1.0\n"
|
||||
+ "creature_points_for_attacking = 2.0\n"
|
||||
+ "creature_sight_range = 100.0\n"
|
||||
+ "creature_radius = 20.0\n"
|
||||
+ "brain_hidden_neurons = 20.0\n"
|
||||
+ "brain_hidden_layers = 3.0\n"
|
||||
+ "brain_bias = 0.5\n";
|
||||
defaults = Serializer.readSettings(s);
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ public class Creature extends Element implements Runnable {
|
||||
|
||||
private final Brain brain;
|
||||
private final Torso torso;
|
||||
private final Beak beak;
|
||||
private final ArrayList<BodyPart> bodyParts;
|
||||
private float dir, fitness = 0;
|
||||
private boolean workerDone = false, killWorker = false;
|
||||
@ -40,7 +39,7 @@ public class Creature extends Element implements Runnable {
|
||||
dir = (float) (Math.random() * 2 * Math.PI);
|
||||
bodyParts = new ArrayList<BodyPart>();
|
||||
bodyParts.add(torso = new Torso(this));
|
||||
bodyParts.add(beak = new Beak(0, this));
|
||||
bodyParts.add(new Beak(0, this));
|
||||
bodyParts.add(new Eye(5, 0, this));
|
||||
bodyParts.add(new Movement(this));
|
||||
brain = new Brain(howManyInputNeurons(), howManyOutputNeurons(), brain_hidden_layers, brain_hidden_neurons);
|
||||
@ -191,6 +190,19 @@ public class Creature extends Element implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public float getDangerLevel() {
|
||||
int beaks = 0;
|
||||
float danger = 0;
|
||||
for (BodyPart b : bodyParts) {
|
||||
if (b instanceof Beak) {
|
||||
beaks++;
|
||||
danger += (((Beak)b).getLength() - Beak.min_length) / Beak.max_length;
|
||||
}
|
||||
}
|
||||
if(beaks == 0) return 0;
|
||||
return danger / beaks;
|
||||
}
|
||||
|
||||
public Brain getBrain() {
|
||||
return brain;
|
||||
}
|
||||
@ -207,10 +219,6 @@ public class Creature extends Element implements Runnable {
|
||||
return fitness;
|
||||
}
|
||||
|
||||
public float getBeak() {
|
||||
return beak.getLength();
|
||||
}
|
||||
|
||||
public Torso getTorso() {
|
||||
return torso;
|
||||
}
|
||||
|
@ -1,120 +1,120 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package logic.creatures;
|
||||
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.mygdx.game.Game;
|
||||
import com.mygdx.game.Log;
|
||||
import logic.Element;
|
||||
import logic.Vegetable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fazo
|
||||
*/
|
||||
public class Eye extends BodyPart {
|
||||
|
||||
private Sight sights[];
|
||||
private int farthest = -1, seen;
|
||||
private float farthestDistance = 0;
|
||||
public static float fov = 2, sightRange = 30;
|
||||
|
||||
public Eye(int nSights, float angle, Creature creature) {
|
||||
super(6 * nSights, 0, angle, 0.8f, creature);
|
||||
sights = new Sight[nSights];
|
||||
seen = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] act() {
|
||||
float ret[] = new float[inputNeuronsUsed];
|
||||
int j = 0;
|
||||
for (int i = 0; i < sights.length; i++) {
|
||||
if (i < seen) {
|
||||
// Saw something
|
||||
ret[j] = 1;
|
||||
ret[j + 1] = sights[i].getElement() instanceof Creature ? 1 : 0;
|
||||
ret[j + 2] = sights[i].getDistance() / sightRange;
|
||||
ret[j + 3] = sights[i].getAngle();
|
||||
if (sights[i].getElement() instanceof Creature) {
|
||||
ret[i + 4] = ((Creature) sights[i].getElement()).getBeak() / Beak.max_length;
|
||||
ret[i + 5] = ((Creature) sights[i].getElement()).getTorso().getHp() / Torso.max_hp;
|
||||
} else {
|
||||
ret[i + 4] = ((Vegetable) sights[i].getElement()).getSize() / Vegetable.default_radius;
|
||||
ret[i + 5] = 0;
|
||||
}
|
||||
} else {
|
||||
// Saw nothing
|
||||
for (int z = 0; z < 6; z++) {
|
||||
ret[j + z] = 0;
|
||||
}
|
||||
}
|
||||
j += 6;
|
||||
}
|
||||
seen = 0;
|
||||
farthest = -1;
|
||||
farthestDistance = 0;
|
||||
sights = new Sight[sights.length];
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interactWithElement(Element e, float distance, float angle) {
|
||||
if (e != creature && distance < sightRange && (distance < farthestDistance || seen < sights.length) && Math.abs(angle) < fov / 2) {
|
||||
if (seen < sights.length) {
|
||||
sights[seen] = new Sight(e, distance, angle);
|
||||
Log.log(Log.DEBUG,"Adding Sight number "+seen);
|
||||
seen++;
|
||||
} else {
|
||||
Log.log(Log.DEBUG,"Substituting Farthest");
|
||||
sights[farthest] = new Sight(e, distance, angle);
|
||||
farthest = -1;
|
||||
}
|
||||
for (int i = 0; i < seen; i++) {
|
||||
Sight s = sights[i];
|
||||
if (s.getDistance() > farthestDistance || farthest < 0) {
|
||||
farthestDistance = s.getDistance();
|
||||
farthest = i;
|
||||
}
|
||||
}
|
||||
Log.log(Log.DEBUG,"Seen " + seen + "/" + sights.length + ". Farthest is now " + farthest + " at " + farthestDistance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void draw(ShapeRenderer s, float relX, float relY) {
|
||||
// Draw eye
|
||||
s.setColor(1, 1, 1, 1);
|
||||
s.circle(creature.getX() + relX, creature.getY() + relY, 3);
|
||||
// Draw FOV cone
|
||||
float degrees = fov * 360f / (float) Math.PI;
|
||||
float orient = (creature.getDirection() + angle) * 180f / (float) Math.PI - degrees / 2;
|
||||
if (Game.get().getWorld().getOptions().getOrDefault("draw_view_cones", 0f) > 0) {
|
||||
s.setColor(0.3f, 0.3f, 0.3f, 1);
|
||||
s.arc((float) relX + creature.getX(), (float) relY + creature.getY(), sightRange, orient, degrees);
|
||||
}
|
||||
// Sight Lines
|
||||
float c = 0;
|
||||
if (Game.get().getWorld().getOptions().getOrDefault("draw_sight_lines", 0f) > 0) {
|
||||
for (Sight sight : sights) {
|
||||
if (sight != null) {
|
||||
c = sight.getDistance() / sightRange * 2 + sightRange;
|
||||
if (sight.getElement() instanceof Creature) {
|
||||
s.setColor(c, 0, 0, 1);
|
||||
} else if (sight.getElement() instanceof Vegetable) {
|
||||
s.setColor(0, c, 0, 1);
|
||||
}
|
||||
s.line(relX + creature.getX(), creature.getY() + relY, sight.getElement().getX(), sight.getElement().getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBrain(float[] data) {
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package logic.creatures;
|
||||
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.mygdx.game.Game;
|
||||
import com.mygdx.game.Log;
|
||||
import logic.Element;
|
||||
import logic.Vegetable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fazo
|
||||
*/
|
||||
public class Eye extends BodyPart {
|
||||
|
||||
private Sight sights[];
|
||||
private int farthest = -1, seen;
|
||||
private float farthestDistance = 0;
|
||||
public static float fov = 2, sightRange = 30;
|
||||
|
||||
public Eye(int nSights, float angle, Creature creature) {
|
||||
super(6 * nSights, 0, angle, 0.8f, creature);
|
||||
sights = new Sight[nSights];
|
||||
seen = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] act() {
|
||||
float ret[] = new float[inputNeuronsUsed];
|
||||
int j = 0;
|
||||
for (int i = 0; i < sights.length; i++) {
|
||||
if (i < seen) {
|
||||
// Saw something
|
||||
ret[j] = 1;
|
||||
ret[j + 1] = sights[i].getElement() instanceof Creature ? 1 : 0;
|
||||
ret[j + 2] = sights[i].getDistance() / sightRange;
|
||||
ret[j + 3] = sights[i].getAngle();
|
||||
if (sights[i].getElement() instanceof Creature) {
|
||||
ret[i + 4] = ((Creature) sights[i].getElement()).getTorso().getHp() / Torso.max_hp;
|
||||
ret[i + 5] = ((Creature) sights[i].getElement()).getDangerLevel();
|
||||
} else {
|
||||
ret[i + 4] = ((Vegetable) sights[i].getElement()).getSize() / Vegetable.default_radius;
|
||||
ret[i + 5] = 0;
|
||||
}
|
||||
} else {
|
||||
// Saw nothing
|
||||
for (int z = 0; z < 6; z++) {
|
||||
ret[j + z] = 0;
|
||||
}
|
||||
}
|
||||
j += 6;
|
||||
}
|
||||
seen = 0;
|
||||
farthest = -1;
|
||||
farthestDistance = 0;
|
||||
sights = new Sight[sights.length];
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interactWithElement(Element e, float distance, float angle) {
|
||||
if (e != creature && distance < sightRange && (distance < farthestDistance || seen < sights.length) && Math.abs(angle) < fov / 2) {
|
||||
if (seen < sights.length) {
|
||||
sights[seen] = new Sight(e, distance, angle);
|
||||
Log.log(Log.DEBUG,"Adding Sight number "+seen);
|
||||
seen++;
|
||||
} else {
|
||||
Log.log(Log.DEBUG,"Substituting Farthest");
|
||||
sights[farthest] = new Sight(e, distance, angle);
|
||||
farthest = -1;
|
||||
}
|
||||
for (int i = 0; i < seen; i++) {
|
||||
Sight s = sights[i];
|
||||
if (s.getDistance() > farthestDistance || farthest < 0) {
|
||||
farthestDistance = s.getDistance();
|
||||
farthest = i;
|
||||
}
|
||||
}
|
||||
Log.log(Log.DEBUG,"Seen " + seen + "/" + sights.length + ". Farthest is now " + farthest + " at " + farthestDistance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void draw(ShapeRenderer s, float relX, float relY) {
|
||||
// Draw eye
|
||||
s.setColor(1, 1, 1, 1);
|
||||
s.circle(creature.getX() + relX, creature.getY() + relY, 3);
|
||||
// Draw FOV cone
|
||||
float degrees = fov * 360f / (float) Math.PI;
|
||||
float orient = (creature.getDirection() + angle) * 180f / (float) Math.PI - degrees / 2;
|
||||
if (Game.get().getWorld().getOptions().getOrDefault("draw_view_cones", 0f) > 0) {
|
||||
s.setColor(0.3f, 0.3f, 0.3f, 1);
|
||||
s.arc((float) relX + creature.getX(), (float) relY + creature.getY(), sightRange, orient, degrees);
|
||||
}
|
||||
// Sight Lines
|
||||
float c = 0;
|
||||
if (Game.get().getWorld().getOptions().getOrDefault("draw_sight_lines", 0f) > 0) {
|
||||
for (Sight sight : sights) {
|
||||
if (sight != null) {
|
||||
c = sight.getDistance() / sightRange * 2 + sightRange;
|
||||
if (sight.getElement() instanceof Creature) {
|
||||
s.setColor(c, 0, 0, 1);
|
||||
} else if (sight.getElement() instanceof Vegetable) {
|
||||
s.setColor(0, c, 0, 1);
|
||||
}
|
||||
s.line(relX + creature.getX(), creature.getY() + relY, sight.getElement().getX(), sight.getElement().getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBrain(float[] data) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
@ -71,20 +72,20 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
|
||||
}
|
||||
});
|
||||
/*
|
||||
ArrayList<SortKey> sk = new ArrayList<SortKey>();
|
||||
sk.add(new SortKey(0, SortOrder.ASCENDING));
|
||||
DefaultRowSorter rs = new DefaultRowSorter() {};
|
||||
settingsTable.setRowSorter(rs);
|
||||
rs.setSortKeys(sk);
|
||||
rs.setComparator(0, new Comparator() {
|
||||
ArrayList<SortKey> sk = new ArrayList<SortKey>();
|
||||
sk.add(new SortKey(0, SortOrder.ASCENDING));
|
||||
DefaultRowSorter rs = new DefaultRowSorter() {};
|
||||
settingsTable.setRowSorter(rs);
|
||||
rs.setSortKeys(sk);
|
||||
rs.setComparator(0, new Comparator() {
|
||||
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
return ((String)o1).compareToIgnoreCase((String)o2);
|
||||
}
|
||||
});
|
||||
rs.sort();
|
||||
*/
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
return ((String)o1).compareToIgnoreCase((String)o2);
|
||||
}
|
||||
});
|
||||
rs.sort();
|
||||
*/
|
||||
guiUpdater = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -934,16 +935,20 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
|
||||
private void setCreatureList() {
|
||||
String list[] = new String[world.getCreatures().size()];
|
||||
int selected = -1;
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (i >= world.getCreatures().size()) {
|
||||
return;
|
||||
}
|
||||
list[i] = world.getCreatures().get(i).getBrain().getName()
|
||||
+ " - Fitness: "
|
||||
+ world.getCreatures().get(i).getFitness();
|
||||
if (world.getCreatures().get(i) == world.getSelectedCreature()) {
|
||||
selected = i;
|
||||
try {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (i >= world.getCreatures().size()) {
|
||||
return;
|
||||
}
|
||||
list[i] = world.getCreatures().get(i).getBrain().getName()
|
||||
+ " - Fitness: "
|
||||
+ world.getCreatures().get(i).getFitness();
|
||||
if (world.getCreatures().get(i) == world.getSelectedCreature()) {
|
||||
selected = i;
|
||||
}
|
||||
}
|
||||
} catch (IndexOutOfBoundsException ex) {
|
||||
} catch (ConcurrentModificationException ex) {
|
||||
}
|
||||
creatureList.setListData(list);
|
||||
if (selected >= 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user