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

moved from single precision floating point to double precision

This commit is contained in:
Enrico Fasoli 2016-03-01 15:50:48 +01:00
parent 7650ff44eb
commit dd76b3acc3
16 changed files with 231 additions and 231 deletions

View File

@ -148,7 +148,7 @@ public class Game extends ApplicationAdapter {
Creature c = world.getSelectedCreature();
renderer.setColor(1, 1, 1, 1);
// Draw selection rectangle
renderer.rect(c.getX() - c.getSize(), c.getY() - c.getSize(), c.getSize() * 2, c.getSize() * 2);
renderer.rect((float) (c.getX() - c.getSize()), (float) (c.getY() - c.getSize()), (float) (c.getSize() * 2), (float) (c.getSize() * 2));
// Draw brain
overlayRenderer.begin();
c.getBrain().render(overlayRenderer);

View File

@ -17,9 +17,9 @@ import java.util.Random;
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;
private static Map<String, Double> defaults;
public static String nameBrain(float[][][] brainMap) {
public static String nameBrain(double[][][] brainMap) {
// Compute a unique representation of the brainmap
long a = 0;
for (int i = 0; i < brainMap.length; i++) {
@ -64,19 +64,19 @@ public class Serializer {
return a;
}
public static String serializeSettings(Map<String, Float> options) {
public static String serializeSettings(Map<String, Double> 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;
Map.Entry<String, Double> e = (Map.Entry<String, Double>) o;
a += e.getKey() + " = " + e.getValue() + "\n";
}
return a;
}
public static Map<String, Float> readSettings(String fileContent) {
public static Map<String, Double> readSettings(String fileContent) {
int line = 0;
Map<String, Float> m = new HashMap<String, Float>();
Map<String, Double> m = new HashMap<String, Double>();
for (String s : fileContent.split("\n")) {
line++;
if (s.startsWith("#")) {
@ -88,8 +88,8 @@ public class Serializer {
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()));
Log.log(Log.DEBUG, "Loading setting \"" + ss[0].trim() + "\" with value \"" + Double.parseDouble(ss[1].trim()) + "\"");
m.put(ss[0].trim(), Double.parseDouble(ss[1].trim()));
} catch (Exception e) {
Log.log(Log.ERROR, e.getMessage());
}
@ -97,7 +97,7 @@ public class Serializer {
return m;
}
public static String serializeBrain(float brainMap[][][]) {
public static String serializeBrain(double brainMap[][][]) {
String s = "# Neural Map for use with AIrium.\n"
+ "# More information at http://github.com/fazo96/AIrium\n"
+ "Layers: " + (brainMap.length + 1);
@ -116,8 +116,8 @@ public class Serializer {
return s;
}
public static float[][][] loadBrain(String s) {
float brainMap[][][] = null;
public static double[][][] loadBrain(String s) {
double 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();
@ -126,25 +126,25 @@ public class Serializer {
} else if (l.startsWith("Layers: ")) {
// Set Layer number
int layers = Integer.parseInt(l.split(" ")[1]) - 1;
brainMap = new float[layers][][];
brainMap = new double[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];
brainMap[0] = new double[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];
brainMap[layer] = new double[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];
brainMap[layer][neuron] = new double[nWeights];
if (layer == 0) {
Log.log(Log.DEBUG, "This weightmap is for brains with " + (nWeights) + " input neurons.");
} else if (nWeights != brainMap[layer - 1].length) {
@ -154,7 +154,7 @@ public class Serializer {
+ " weights are supplied to this neuron");
}
for (int i = 7; i < ll.length; i++) {
brainMap[layer][neuron][i - 7] = Float.parseFloat(ll[i]);
brainMap[layer][neuron][i - 7] = Double.parseDouble(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);
@ -164,7 +164,7 @@ public class Serializer {
return brainMap;
}
public static Map<String, Float> getDefaultSettings() {
public static Map<String, Double> getDefaultSettings() {
if (defaults == null) {
String s = "corpse_decay_rate = 0.0\n"
+ "mutationFactor = 1.0\n"

View File

@ -9,7 +9,7 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
*/
public abstract class Element {
private float x, y, size;
private double x, y, size;
/**
* Create an element at given position with given radius. Elements have a
@ -19,7 +19,7 @@ public abstract class Element {
* @param y the y position
* @param size the element body radius
*/
public Element(float x, float y, float size) {
public Element(double x, double y, double size) {
this.x = x;
this.y = y;
this.size = size;
@ -35,8 +35,8 @@ public abstract class Element {
* @return the distance from the element. It's 0 if they are just touching,
* negative if they are colliding and positive if they are not
*/
public float distanceFrom(Element e) {
return (float) Math.sqrt(Math.pow(e.x - x, 2) + Math.pow(e.y - y, 2)) - getSize() - e.getSize();
public double distanceFrom(Element e) {
return Math.sqrt(Math.pow(e.x - x, 2) + Math.pow(e.y - y, 2)) - getSize() - e.getSize();
}
/**
@ -58,8 +58,8 @@ public abstract class Element {
* @param radius the radius of the circular object
* @return true if the object overlaps this one
*/
public boolean overlaps(float x, float y, float radius) {
return (float) Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2)) < getSize() + radius;
public boolean overlaps(double x, double y, double radius) {
return Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2)) < getSize() + radius;
}
/**
@ -69,7 +69,7 @@ public abstract class Element {
* @param y the y position of the point to check
* @return true if the point is part of this object's area
*/
public boolean overlaps(float x, float y) {
public boolean overlaps(double x, double y) {
return overlaps(x, y, 1);
}
@ -79,7 +79,7 @@ public abstract class Element {
* @param deltaX x translation
* @param deltaY y translation
*/
public void move(float deltaX, float deltaY) {
public void move(double deltaX, double deltaY) {
x += deltaX;
y += deltaY;
}
@ -96,27 +96,27 @@ public abstract class Element {
*/
public abstract void render(ShapeRenderer s);
public float getX() {
public double getX() {
return x;
}
public float getY() {
public double getY() {
return y;
}
public float getSize() {
public double getSize() {
return size;
}
public void setX(float x) {
public void setX(double x) {
this.x = x;
}
public void setY(float y) {
public void setY(double y) {
this.y = y;
}
public void setSize(float size) {
public void setSize(double size) {
this.size = size;
}

View File

@ -9,10 +9,10 @@ import com.mygdx.game.Game;
*/
public class Vegetable extends Element {
public static float default_radius = 5;
private float decayRate = 0;
public static double default_radius = 5;
private double decayRate = 0;
public Vegetable(float x, float y) {
public Vegetable(double x, double y) {
super(x, y, default_radius);
}
@ -27,14 +27,14 @@ public class Vegetable extends Element {
@Override
public void render(ShapeRenderer s) {
s.setColor(1, 1, 1, 1);
s.circle(getX(), getY(), getSize());
s.circle((float) getX(), (float) getY(), (float) getSize());
}
public float getDecayRate() {
public double getDecayRate() {
return decayRate;
}
public void setDecayRate(float decayRate) {
public void setDecayRate(double decayRate) {
this.decayRate = decayRate;
}
}

View File

@ -30,11 +30,11 @@ import logic.neural.Brain;
public class World implements Runnable {
private int width, height, nPlants, creatPerGen;
private float nMutatedBrains = 0.2f, nMutatedNeurons = 0.5f, nMutatedConnections = 0.5f, mutationFactor = 1f;
private double nMutatedBrains = 0.2f, nMutatedNeurons = 0.5f, nMutatedConnections = 0.5f, mutationFactor = 1f;
private int generation = 1;
private boolean multithreading, cmdLaunchNewGen = false, cmdRestart = false;
private int fpsLimit, fps = 0;
private Map<String, Float> options;
private Map<String, Double> options;
private long ticksSinceGenStart = 0, maximumTicksPerGen = 0;
private Creature selected;
private Queue<Integer> events = new LinkedList<>();
@ -52,9 +52,9 @@ public class World implements Runnable {
* @param options customization options. Can be null. See the
* "reloadOptions" function for possible options
*/
public World(Map<String, Float> options) {
public World(Map<String, Double> options) {
if (options == null) {
this.options = new HashMap<String, Float>();
this.options = new HashMap<String, Double>();
} else {
this.options = options;
}
@ -224,7 +224,7 @@ public class World implements Runnable {
}
Creature[] top = new Creature[topSize];
// Calculate avg fitness and prepare best agent list
float avgFitness = 0;
double avgFitness = 0;
for (int i = 0; i < graveyard.size(); i++) {
Creature c = graveyard.get(i);
if (i < topSize) {
@ -243,7 +243,7 @@ public class World implements Runnable {
while (sec == first && topSize > 1) {
sec = (int) Math.floor(Math.random() * topSize);
}
float[][][] n = null;
double[][][] n = null;
try {
n = top[first].getBrain().breed(top[sec].getBrain().getMap());
} catch (Exception ex) {
@ -274,15 +274,15 @@ public class World implements Runnable {
*/
public void reloadOptions() {
for (Object o : Serializer.getDefaultSettings().entrySet().toArray()) {
Map.Entry<String, Float> e = (Map.Entry<String, Float>) o;
Map.Entry<String, Double> e = (Map.Entry<String, Double>) o;
options.putIfAbsent(e.getKey(), e.getValue());
}
width = Math.round(options.get("world_width"));
height = Math.round(options.get("world_height"));
fpsLimit = Math.round(options.get("fps_limit"));
width = (int) Math.round(options.get("world_width"));
height = (int) Math.round(options.get("world_height"));
fpsLimit = (int) Math.round(options.get("fps_limit"));
maximumTicksPerGen = Math.round(options.get("max_ticks"));
creatPerGen = Math.round(options.get("number_of_creatures"));
nPlants = Math.round(options.get("number_of_plants"));
creatPerGen = (int) Math.round(options.get("number_of_creatures"));
nPlants = (int) Math.round(options.get("number_of_plants"));
multithreading = options.get("enable_multithreading") > 0;
Creature.corpseDecayRate = options.get("corpse_decay_rate");
Creature.leaveCorpses = options.get("enable_corpses") > 0;
@ -297,8 +297,8 @@ public class World implements Runnable {
Creature.hpForEatingPlants = options.get("creature_hp_for_eating_plants");
Creature.pointsForAttacking = options.get("creature_points_for_attacking");
Creature.pointsForEatingPlants = options.get("creature_points_for_eating_plants");
Creature.brain_hidden_layers = Math.round(options.get("brain_hidden_layers"));
Creature.brain_hidden_neurons = Math.round(options.get("brain_hidden_neurons"));
Creature.brain_hidden_layers = (int) Math.round(options.get("brain_hidden_layers"));
Creature.brain_hidden_neurons = (int) Math.round(options.get("brain_hidden_neurons"));
Brain.bias = options.get("brain_bias");
nMutatedBrains = options.get("nMutatedBrains");
nMutatedNeurons = options.get("nMutatedNeurons");
@ -314,9 +314,9 @@ public class World implements Runnable {
* null, a random mind will be created
* @return the spawned element
*/
private Element spawn(boolean isCreature, float[][][] brainMap) {
private Element spawn(boolean isCreature, double[][][] brainMap) {
int x, y;
float r;
double r;
boolean overlaps;
if (isCreature) {
r = Torso.default_radius;
@ -394,10 +394,10 @@ public class World implements Runnable {
events.add(eventCode);
}
public Queue<Integer> getEventQueue(){
public Queue<Integer> getEventQueue() {
return events;
}
public void spawnVegetable() {
spawn(false, null);
}
@ -406,7 +406,7 @@ public class World implements Runnable {
return (Creature) spawn(true, null);
}
public Creature spawnCreature(float[][][] b) {
public Creature spawnCreature(double[][][] b) {
return (Creature) spawn(true, b);
}
@ -446,7 +446,7 @@ public class World implements Runnable {
return plants;
}
public float getFpsLimit() {
public double getFpsLimit() {
return fpsLimit;
}
@ -454,11 +454,11 @@ public class World implements Runnable {
this.fpsLimit = fpsLimit;
}
public float getFps() {
public double getFps() {
return fps;
}
public Map<String, Float> getOptions() {
public Map<String, Double> getOptions() {
return options;
}
@ -478,7 +478,7 @@ public class World implements Runnable {
this.multithreading = multithreading;
}
public void replaceOptions(Map<String, Float> options) {
public void replaceOptions(Map<String, Double> options) {
this.options = options;
reloadOptions();
}

View File

@ -14,18 +14,18 @@ import logic.Element;
*/
public class Beak extends BodyPart {
private float length;
private double length;
private boolean attacking = false;
public static float max_length = Torso.default_radius / 4, min_length = max_length / 4;
public static double max_length = Torso.default_radius / 4, min_length = max_length / 4;
public Beak(float angle, Creature creature) {
public Beak(double angle, Creature creature) {
super(3, 1, angle, 1, creature);
length = min_length;
}
@Override
public float[] act() {
float r[] = new float[]{
public double[] act() {
double r[] = new double[]{
length / max_length, // current beak length
length > max_length / 2 ? 1f : 0f, // wether the beak is doing damage
attacking ? 1f : 0f
@ -35,7 +35,7 @@ public class Beak extends BodyPart {
}
@Override
public void interactWithElement(Element e, float distance, float relAngle) {
public void interactWithElement(Element e, double distance, double relAngle) {
if (e instanceof Creature && distance < length && length > max_length / 2 && Math.abs(relAngle) < 0.3f) {
// Can attack
creature.praise(Creature.pointsForAttacking);
@ -46,10 +46,10 @@ public class Beak extends BodyPart {
}
@Override
protected void draw(ShapeRenderer s, float relX, float relY) {
protected void draw(ShapeRenderer s, double relX, double relY) {
s.set(ShapeRenderer.ShapeType.Line);
// Draw Beak
s.setColor(getLength() / Beak.max_length, 1 - getLength() / Beak.max_length, 0, 1);
s.setColor((float) (getLength() / Beak.max_length), (float) (1 - getLength() / Beak.max_length), 0, 1);
s.line((float) (relX + creature.getX()), (float) (relY + creature.getY()), (float) (relX * (1.5f + getLength() / Beak.max_length) + creature.getX()), (float) (relY * (1.5f + getLength() / Beak.max_length) + creature.getY()));
if (attacking) {
s.circle((float) (relX * (1.5f + getLength() / Beak.max_length) + creature.getX()), (float) (relY * (1.5f + getLength() / Beak.max_length) + creature.getY()), 0.3f);
@ -57,7 +57,7 @@ public class Beak extends BodyPart {
}
@Override
public void readFromBrain(float[] outputs) {
public void readFromBrain(double[] outputs) {
length = outputs[0] * max_length;
if (length > max_length) {
length = max_length;
@ -66,7 +66,7 @@ public class Beak extends BodyPart {
}
}
public float getLength() {
public double getLength() {
return length;
}

View File

@ -12,8 +12,8 @@ import logic.Element;
public abstract class BodyPart {
protected int inputNeuronsUsed;
protected float angle, distFromCenter;
protected float outputs[];
protected double angle, distFromCenter;
protected double outputs[];
protected Creature creature;
/**
@ -26,12 +26,12 @@ public abstract class BodyPart {
* this body part
* @param creature the creature that owns this body part
*/
public BodyPart(int inputNeuronsUsed, int outputNeuronsUsed, float angle, float distFromCenter, Creature creature) {
public BodyPart(int inputNeuronsUsed, int outputNeuronsUsed, double angle, double distFromCenter, Creature creature) {
this.inputNeuronsUsed = inputNeuronsUsed;
this.angle = angle;
this.distFromCenter = distFromCenter;
this.creature = creature;
outputs = new float[outputNeuronsUsed];
outputs = new double[outputNeuronsUsed];
}
/**
@ -40,7 +40,7 @@ public abstract class BodyPart {
*
* @return the data to send to the brain, must be inputNeuronsUsed long
*/
public abstract float[] act();
public abstract double[] act();
/**
* Interact with another element. This will be called every time the body
@ -52,7 +52,7 @@ public abstract class BodyPart {
* @param distance the distance
* @param relAngle the relative angle
*/
public abstract void interactWithElement(Element e, float distance, float relAngle);
public abstract void interactWithElement(Element e, double distance, double relAngle);
/**
* Receive some data from the brain. This is called once every frame, after
@ -61,7 +61,7 @@ public abstract class BodyPart {
* @param data the data received from the brain, will be outputNeuronsUsed
* long
*/
public abstract void readFromBrain(float data[]);
public abstract void readFromBrain(double data[]);
/**
* This will be called when the
@ -72,7 +72,7 @@ public abstract class BodyPart {
* @param relY the Y position of this bodypart relative to the center its
* creature
*/
protected abstract void draw(ShapeRenderer s, float relX, float relY);
protected abstract void draw(ShapeRenderer s, double relX, double relY);
/**
* Prepares data and calls draw
@ -82,7 +82,7 @@ public abstract class BodyPart {
public final void render(ShapeRenderer s) {
double relX = Math.cos(creature.getDirection() + angle) * creature.getTorso().getRadius() * distFromCenter;
double relY = Math.sin(creature.getDirection() + angle) * creature.getTorso().getRadius() * distFromCenter;
draw(s, (float) relX, (float) relY);
draw(s, (double) relX, (double) relY);
}
/**
@ -105,11 +105,11 @@ public abstract class BodyPart {
*
* @return the angle of this bodypart relative to the center of the creature
*/
public float getAngle() {
public double getAngle() {
return angle;
}
public float getDistanceFromCreatureCenter() {
public double getDistanceFromCreatureCenter() {
return distFromCenter;
}

View File

@ -20,13 +20,13 @@ import logic.neural.Brain;
public abstract class Creature extends Element implements Runnable {
public static int brain_hidden_layers = 2, brain_hidden_neurons = 10;
public static float corpseDecayRate = 0, pointsForEatingPlants = 1f, pointsForAttacking = 2f, hpForAttacking = 1f, hpForEatingPlants = 1f;
public static double corpseDecayRate = 0, pointsForEatingPlants = 1f, pointsForAttacking = 2f, hpForAttacking = 1f, hpForEatingPlants = 1f;
public static boolean leaveCorpses = false;
private final Brain brain;
private final Torso torso;
private final ArrayList<BodyPart> bodyParts;
private float dir, fitness = 0;
private double dir, fitness = 0;
private boolean workerDone = false, killWorker = false;
private Thread workerThread;
@ -36,9 +36,9 @@ public abstract class Creature extends Element implements Runnable {
* @param x
* @param y
*/
public Creature(float x, float y) {
public Creature(double x, double y) {
super(x, y, Torso.default_radius);
dir = (float) (Math.random() * 2 * Math.PI);
dir = (double) (Math.random() * 2 * Math.PI);
bodyParts = new ArrayList<BodyPart>();
bodyParts.add(torso = new Torso(this));
buildBody();
@ -77,10 +77,10 @@ public abstract class Creature extends Element implements Runnable {
return;
}
// collect inputs
float values[] = new float[howManyInputNeurons()];
double values[] = new double[howManyInputNeurons()];
int i = 0;
for (BodyPart b : bodyParts) {
for (float v : b.act()) {
for (double v : b.act()) {
values[i] = v;
i++;
}
@ -88,7 +88,7 @@ public abstract class Creature extends Element implements Runnable {
// read from sensors and interact with world
interactWithWorld();
// compute behavior
float[] actions = null;
double[] actions = null;
try {
actions = brain.compute(values);
} catch (Exception ex) {
@ -99,7 +99,7 @@ public abstract class Creature extends Element implements Runnable {
// Save brain outputs to body parts
for (BodyPart b : bodyParts) {
int n = 0;
float data[] = new float[b.getOutputNeuronsUsed()];
double data[] = new double[b.getOutputNeuronsUsed()];
while (n < b.getOutputNeuronsUsed()) {
data[n] = actions[i];
i++;
@ -122,8 +122,8 @@ public abstract class Creature extends Element implements Runnable {
*/
public void interactWithWorld() {
for (Element e : Game.get().getWorld().getElements()) {
float distance = distanceFrom(e);
float angle = (float) (Math.atan2(getY() - e.getY(), getX() - e.getX())) - (dir - (float) Math.PI);
double distance = distanceFrom(e);
double angle = (double) (Math.atan2(getY() - e.getY(), getX() - e.getX())) - (dir - (double) Math.PI);
for (BodyPart b : bodyParts) {
b.interactWithElement(e, distance, angle);
}
@ -146,7 +146,7 @@ public abstract class Creature extends Element implements Runnable {
return n;
}
public void rotate(float amount) {
public void rotate(double amount) {
dir += amount;
if (dir > 2 * Math.PI) {
dir -= 2 * Math.PI;
@ -161,7 +161,7 @@ public abstract class Creature extends Element implements Runnable {
*
* @param amount how much
*/
public void praise(float amount) {
public void praise(double amount) {
fitness += amount;
}
@ -189,9 +189,9 @@ public abstract class Creature extends Element implements Runnable {
}
}
public float getDangerLevel() {
public double getDangerLevel() {
int beaks = 0;
float danger = 0;
double danger = 0;
for (BodyPart b : bodyParts) {
if (b instanceof Beak) {
beaks++;
@ -217,15 +217,15 @@ public abstract class Creature extends Element implements Runnable {
return brain;
}
public void setDirection(float dir) {
public void setDirection(double dir) {
this.dir = dir;
}
public float getDirection() {
public double getDirection() {
return dir;
}
public float getFitness() {
public double getFitness() {
return fitness;
}

View File

@ -19,18 +19,18 @@ public class Eye extends BodyPart {
private Sight sights[];
private int farthest = -1, seen;
private float farthestDistance = 0;
public static float fov = 2, sightRange = 30;
private double farthestDistance = 0;
public static double fov = 2, sightRange = 30;
public Eye(int nSights, float angle, Creature creature) {
public Eye(int nSights, double 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];
public double[] act() {
double ret[] = new double[inputNeuronsUsed];
int j = 0;
for (int i = 0; i < sights.length; i++) {
if (i < seen) {
@ -62,7 +62,7 @@ public class Eye extends BodyPart {
}
@Override
public void interactWithElement(Element e, float distance, float angle) {
public void interactWithElement(Element e, double distance, double 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);
@ -85,36 +85,36 @@ public class Eye extends BodyPart {
}
@Override
protected void draw(ShapeRenderer s, float relX, float relY) {
protected void draw(ShapeRenderer s, double relX, double relY) {
// Draw eye
s.setColor(1, 1, 1, 1);
s.circle(creature.getX() + relX, creature.getY() + relY, 3);
s.circle((float) (creature.getX() + relX), (float) (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) {
double degrees = fov * 360f / (double) Math.PI;
double orient = (creature.getDirection() + angle) * 180f / (double) Math.PI - degrees / 2;
if (Game.get().getWorld().getOptions().getOrDefault("draw_view_cones", 0d) > 0) {
s.setColor(0.3f, 0.3f, 0.3f, 1);
s.arc((float) relX + creature.getX(), (float) relY + creature.getY(), sightRange, orient, degrees);
s.arc((float) (relX + creature.getX()), (float) (relY + creature.getY()), (float) sightRange, (float) orient, (float) degrees);
}
// Sight Lines
float c = 0;
if (Game.get().getWorld().getOptions().getOrDefault("draw_sight_lines", 0f) > 0) {
double c = 0;
if (Game.get().getWorld().getOptions().getOrDefault("draw_sight_lines", 0d) > 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);
s.setColor((float) c, 0, 0, 1);
} else if (sight.getElement() instanceof Vegetable) {
s.setColor(0, c, 0, 1);
s.setColor(0, (float) c, 0, 1);
}
s.line(relX + creature.getX(), creature.getY() + relY, sight.getElement().getX(), sight.getElement().getY());
s.line((float) (relX + creature.getX()), (float) (creature.getY() + relY), (float) (sight.getElement().getX()), (float) (sight.getElement().getY()));
}
}
}
}
@Override
public void readFromBrain(float[] data) {
public void readFromBrain(double[] data) {
}
}

View File

@ -16,15 +16,15 @@ import logic.Element;
*/
public class Movement extends BodyPart {
private float speed = 0, rotSpeed = 0;
public static float max_speed = 3;
private double speed = 0, rotSpeed = 0;
public static double max_speed = 3;
public Movement(Creature creature) {
super(0, 4, 0, 0, creature);
}
@Override
public float[] act() {
public double[] act() {
if (speed > max_speed) {
speed = max_speed;
}
@ -32,7 +32,7 @@ public class Movement extends BodyPart {
speed = -max_speed;
}
// apply speed
float xMul = (float) Math.cos(creature.getDirection()), yMul = (float) Math.sin(creature.getDirection());
double xMul = (double) Math.cos(creature.getDirection()), yMul = (double) Math.sin(creature.getDirection());
creature.move(xMul * speed, yMul * speed);
if (creature.getX() < 0) {
creature.setX(Game.get().getWorld().getWidth() + creature.getX());
@ -45,19 +45,19 @@ public class Movement extends BodyPart {
creature.setY(creature.getY() - Game.get().getWorld().getHeight());
}
creature.rotate(rotSpeed);
return new float[]{};
return new double[]{};
}
@Override
public void interactWithElement(Element e, float distance, float relAngle) {
public void interactWithElement(Element e, double distance, double relAngle) {
}
@Override
protected void draw(ShapeRenderer s, float relX, float relY) {
protected void draw(ShapeRenderer s, double relX, double relY) {
}
@Override
public void readFromBrain(float[] data) {
public void readFromBrain(double[] data) {
Log.log(Log.DEBUG, "Fowward: " + data[0] + "Back: " + data[1] + " Rot: " + data[2] + " RotAnti: " + data[3]);
speed = (data[0] * 2 - data[1] / 2) * max_speed;
rotSpeed = data[2] - data[3];

View File

@ -10,9 +10,9 @@ import logic.Element;
public class Sight {
private Element seen;
private float distance, angle;
private double distance, angle;
public Sight(Element seen, float distance, float angle) {
public Sight(Element seen, double distance, double angle) {
this.seen = seen;
this.distance = distance;
this.angle = angle;
@ -22,11 +22,11 @@ public class Sight {
return seen;
}
public float getDistance() {
public double getDistance() {
return distance;
}
public float getAngle() {
public double getAngle() {
return angle;
}

View File

@ -10,8 +10,8 @@ import logic.Vegetable;
*/
public class Torso extends BodyPart {
private float hp, prevHp, radius, pain = 0;
public static float default_radius = 20, max_hp = 100, hpDecay = 0.5f, eatingSpeed = 0.1f;
private double hp, prevHp, radius, pain = 0;
public static double default_radius = 20, max_hp = 100, hpDecay = 0.5f, eatingSpeed = 0.1f;
private boolean eating = false;
public Torso(Creature c) {
@ -22,9 +22,9 @@ public class Torso extends BodyPart {
}
@Override
public void draw(ShapeRenderer s, float x, float y) {
s.setColor(1 - (hp / max_hp), hp / max_hp, 0, 1);
s.circle(x + creature.getX(), y + creature.getY(), radius);
public void draw(ShapeRenderer s, double x, double y) {
s.setColor((float) (1 - (hp / max_hp)), (float) (hp / max_hp), 0, 1);
s.circle((float) (x + creature.getX()), (float) (y + creature.getY()), (float) radius);
// Draw damage/heal marks
s.set(ShapeRenderer.ShapeType.Filled);
if (getReceivedDamage() > 0) {
@ -35,15 +35,15 @@ public class Torso extends BodyPart {
s.setColor(0, 1, 0, 1);
}
if (getReceivedDamage() != 0 || eating) {
s.circle(x + creature.getX(), y + creature.getY(), 5);
s.circle((float) (x + creature.getX()), (float) (y + creature.getY()), 5);
}
}
@Override
public float[] act() {
public double[] act() {
// apply hunger
hp -= hpDecay;
float r[] = new float[]{
double r[] = new double[]{
hp/max_hp,
eating ? 1f : 0f,
pain
@ -55,7 +55,7 @@ public class Torso extends BodyPart {
}
@Override
public void interactWithElement(Element e, float distance, float relAngle) {
public void interactWithElement(Element e, double distance, double relAngle) {
if (e instanceof Vegetable && distance < 0 && hp < max_hp) {
e.setSize(e.getSize() - eatingSpeed);
if (e.getSize() == 0) {
@ -68,7 +68,7 @@ public class Torso extends BodyPart {
}
@Override
public void readFromBrain(float[] data) {
public void readFromBrain(double[] data) {
if (getReceivedDamage() > 0) {
pain = -1;
} else if (getReceivedDamage() < 0) {
@ -87,7 +87,7 @@ public class Torso extends BodyPart {
*
* @param amount how much to heal/damage
*/
public void heal(float amount) {
public void heal(double amount) {
hp += amount;
if (hp < 0) {
hp = 0;
@ -97,23 +97,23 @@ public class Torso extends BodyPart {
}
}
public float getReceivedDamage() {
public double getReceivedDamage() {
return prevHp - hp;
}
public float getRadius() {
public double getRadius() {
return radius;
}
public void setRadius(float radius) {
public void setRadius(double radius) {
this.radius = radius;
}
public float getHp() {
public double getHp() {
return hp;
}
public void setHp(float hp) {
public void setHp(double hp) {
this.hp = hp;
}

View File

@ -11,7 +11,7 @@ import com.mygdx.game.Serializer;
*/
public class Brain {
public static float bias = 0.5f;
public static double bias = 0.5f;
private Neuron[][] neurons;
private String name;
@ -41,7 +41,7 @@ public class Brain {
*
* @param brainMap the new brain map to apply
*/
public void remap(float[][][] brainMap) {
public void remap(double[][][] brainMap) {
for (int i = 0; i < brainMap.length; i++) { // for each layer (skip input)
for (int j = 0; j < brainMap[i].length; j++) { // for each neuron
// skip input layer
@ -89,17 +89,17 @@ public class Brain {
//s.set(ShapeRenderer.ShapeType.Line);
for (int j = 0; j < neurons[i].length; j++) {
// get neuron result first so cache system can kick in and save some calculations
float nr = neurons[i][j].compute();
double nr = neurons[i][j].compute();
// Draw neuron links
float[] links = neurons[i][j].getWeights();
double[] links = neurons[i][j].getWeights();
if (links != null) {
for (int f = 0; f < links.length; f++) {
s.setColor(links[f] < 0 ? links[f] / 2 * -1 : 0, links[f] > 0 ? links[f] / 2 : 0, 0, 1);
s.setColor((float) (links[f] < 0 ? links[f] / 2 * -1 : 0), (float) (links[f] > 0 ? links[f] / 2 : 0), 0, 1);
s.line(i * sepX + offset, j * sepY + offset, (i - 1) * sepX + offset, f * sepY + offset);
}
}
// Draw neuron
s.setColor(1 - nr, nr, 0, 1);
s.setColor((float) (1 - nr), (float) nr, 0, 1);
s.circle(i * sepX + offset, j * sepY + offset, 15);
}
}
@ -113,7 +113,7 @@ public class Brain {
* @throws Exception if the number of inputs given differs from the number
* of input neurons of this brain
*/
public void input(float[] values) throws Exception {
public void input(double[] values) throws Exception {
if (values.length != neurons[0].length) {
throw new Exception("Brain has " + neurons[0].length
+ " input neurons," + " but was supplied with "
@ -130,9 +130,9 @@ public class Brain {
* @return an array as long as the number of output neurons, containing the
* result
*/
public float[] compute() {
public double[] compute() {
clearCache(); // unnecessary if already called when changing inputs
float[] res = new float[neurons[neurons.length - 1].length];
double[] res = new double[neurons[neurons.length - 1].length];
for (int i = 0; i < neurons[neurons.length - 1].length; i++) {
res[i] = neurons[neurons.length - 1][i].compute();
}
@ -147,7 +147,7 @@ public class Brain {
* @throws Exception if the number of inputs given differs from the number
* of input neurons of this brain
*/
public float[] compute(float[] values) throws Exception {
public double[] compute(double[] values) throws Exception {
input(values);
return compute();
}
@ -158,11 +158,11 @@ public class Brain {
* @return a tridimensional floating point number array representing a full
* mind
*/
public float[][][] getMap() {
float[][][] res = new float[neurons.length - 1][][];
public double[][][] getMap() {
double[][][] res = new double[neurons.length - 1][][];
for (int i = 1; i < neurons.length; i++) // layers (skip input layer)
{
res[i - 1] = new float[neurons[i].length][];
res[i - 1] = new double[neurons[i].length][];
for (int j = 0; j < neurons[i].length; j++) // neurons per layer
{
res[i - 1][j] = neurons[i][j].getWeights();
@ -181,11 +181,11 @@ public class Brain {
* of mutated neurons (range: from 0 to 1)
* @return a mutated brain map of this brain's mind
*/
public float[][][] getMutatedMap(float mutationProbability, float connectionMutationProbability, float mutationFactor) {
float[][][] res = new float[neurons.length - 1][][];
public double[][][] getMutatedMap(double mutationProbability, double connectionMutationProbability, double mutationFactor) {
double[][][] res = new double[neurons.length - 1][][];
for (int i = 1; i < neurons.length; i++) // layers (skip input layer)
{
res[i - 1] = new float[neurons[i].length][];
res[i - 1] = new double[neurons[i].length][];
for (int j = 0; j < neurons[i].length; j++) // neurons per layer
{
if (Math.random() <= mutationProbability) {
@ -205,7 +205,7 @@ public class Brain {
* of mutated neurons (range: from 0 to 1)
* @param mutationFactor the higher this number, the bigger the mutation
*/
public void mutate(float mutationProbability, float connectionMutationProbability, float mutationFactor) {
public void mutate(double mutationProbability, double connectionMutationProbability, double 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
@ -228,20 +228,20 @@ public class Brain {
* @throws Exception if the brains don't have identical neuron and layer
* numbers
*/
public float[][][] breed(float[][][] map) throws Exception {
float[][][] res = new float[neurons.length - 1][][];
public double[][][] breed(double[][][] map) throws Exception {
double[][][] res = new double[neurons.length - 1][][];
if (map.length != neurons.length - 1) {
throw new Exception("incompatible brains");
}
for (int i = 1; i < neurons.length; i++) // layers (skip input layer)
{
res[i - 1] = new float[neurons[i].length][];
res[i - 1] = new double[neurons[i].length][];
if (map[i - 1].length != neurons[i].length) {
throw new Exception("incompatible brains");
}
for (int j = 0; j < neurons[i].length; j++) // neurons per layer
{
res[i - 1][j] = new float[neurons[i][j].getWeights().length];
res[i - 1][j] = new double[neurons[i][j].getWeights().length];
if (map[i - 1][j].length != neurons[i][j].getWeights().length) {
throw new Exception("incompatible brains");
}

View File

@ -11,9 +11,9 @@ import java.util.logging.Logger;
*/
public class Neuron {
private float[] weights;
private double[] weights;
private NeuronCache cache;
private float bias, output;
private double bias, output;
private boolean isInputNeuron;
private int layer, receivesFromLayer;
private Brain brain;
@ -28,7 +28,7 @@ public class Neuron {
* neurons)
* @param brain the brain which contains this neuron
*/
public Neuron(int layer, int receivesFromLayer, float bias, Brain brain) {
public Neuron(int layer, int receivesFromLayer, double bias, Brain brain) {
this(layer, receivesFromLayer, bias, brain, null);
}
@ -43,7 +43,7 @@ public class Neuron {
* @param brain the brain which contains this neuron
* @param weights the weights to use to configure this neuron
*/
public Neuron(int layer, int receivesFromLayer, float bias, Brain brain, float[] weights) {
public Neuron(int layer, int receivesFromLayer, double bias, Brain brain, double[] weights) {
this.brain = brain;
this.layer = layer;
this.receivesFromLayer = receivesFromLayer;
@ -65,14 +65,14 @@ public class Neuron {
private void scramble() {
// init weights
if (layer > 0) {
weights = new float[brain.getNeurons()[receivesFromLayer].length];
weights = new double[brain.getNeurons()[receivesFromLayer].length];
} else { // layer 0 or negative
isInputNeuron = true;
weights = new float[0];
weights = new double[0];
}
// Put random weights
for (int i = 0; i < weights.length; i++) {
weights[i] = (float) (Math.random() * 5 - 2.5f);
weights[i] = (double) (Math.random() * 5 - 2.5f);
}
}
@ -84,7 +84,7 @@ public class Neuron {
*
* @return the output of this neuron.
*/
public float compute() {
public double compute() {
if (weights == null || weights.length == 0) {
isInputNeuron = true;
}
@ -94,7 +94,7 @@ public class Neuron {
if (cache.hasCachedOutput()) {
return cache.getCachedOutput();
}
float a = bias * -1; // activation
double a = bias * -1; // activation
for (int i = 0; i < weights.length; i++) {
if (cache.has(i)) {
try {
@ -105,13 +105,13 @@ public class Neuron {
}
} else {
Neuron n = brain.getNeurons()[receivesFromLayer][i];
float v = n.compute() * weights[i];
double v = n.compute() * weights[i];
a += v;
cache.put(i, v);
}
}
// sigmoid function
float res = (float) (1 / (1 + Math.pow(Math.E, a * -1)));
double res = (double) (1 / (1 + Math.pow(Math.E, a * -1)));
cache.setCachedOutput(res);
Log.log(Log.DEBUG, "Computed Value " + res + " for neuron");
return res;
@ -124,11 +124,11 @@ public class Neuron {
* @param mutationFactor controls how much weights mutate
* @return the new weights
*/
public float[] getMutatedWeights(float mutationProbability, float mutationFactor) {
float[] mutatedWeights = new float[weights.length];
public double[] getMutatedWeights(double mutationProbability, double mutationFactor) {
double[] mutatedWeights = new double[weights.length];
for (int i = 0; i < weights.length; i++) {
if (Math.random() <= mutationProbability) {
mutatedWeights[i] = weights[i] + (float) (Math.random() * mutationFactor) - mutationFactor / 2;
mutatedWeights[i] = weights[i] + (double) (Math.random() * mutationFactor) - mutationFactor / 2;
} else {
mutatedWeights[i] = weights[i];
}
@ -141,16 +141,16 @@ public class Neuron {
*
* @param output the output you want to set
*/
public void setOutput(float output) {
public void setOutput(double output) {
isInputNeuron = true;
this.output = output;
}
public float getBias() {
public double getBias() {
return bias;
}
public void setBias(float bias) {
public void setBias(double bias) {
this.bias = bias;
}
@ -166,7 +166,7 @@ public class Neuron {
this.layer = layer;
}
public float[] getWeights() {
public double[] getWeights() {
return weights;
}
@ -175,7 +175,7 @@ public class Neuron {
*
* @param weights the new weights to put
*/
public void setWeights(float[] weights) {
public void setWeights(double[] weights) {
this.weights = weights;
// Changing the neuron makes the cache invalid
clearCache();

View File

@ -7,8 +7,8 @@ package logic.neural;
*/
public class NeuronCache {
private float[] cache;
private float cachedOutput;
private double[] cache;
private double cachedOutput;
private boolean cachedOutputValid;
private boolean[] validity;
@ -18,7 +18,7 @@ public class NeuronCache {
* @param size how many inputs the requiring neuron has.
*/
public NeuronCache(int size) {
cache = new float[size];
cache = new double[size];
validity = new boolean[size];
clear();
}
@ -29,7 +29,7 @@ public class NeuronCache {
* @param index the index of the value
* @param value the value itself
*/
public void put(int index, float value) {
public void put(int index, double value) {
validity[index] = true;
cache[index] = value;
}
@ -41,7 +41,7 @@ public class NeuronCache {
* @return the value required
* @throws Exception if value not stored or declared invalid
*/
public float get(int index) throws Exception {
public double get(int index) throws Exception {
if (validity[index]) {
return cache[index];
} else {
@ -59,7 +59,7 @@ public class NeuronCache {
return validity[index];
}
public float getCachedOutput() {
public double getCachedOutput() {
return cachedOutput;
}
@ -67,7 +67,7 @@ public class NeuronCache {
return cachedOutputValid;
}
public void setCachedOutput(float cachedOutput) {
public void setCachedOutput(double cachedOutput) {
this.cachedOutput = cachedOutput;
}

View File

@ -49,7 +49,7 @@ public class GUI extends javax.swing.JFrame implements LogListener {
private boolean shouldUpdateGUI = false;
private final Thread guiUpdater;
private final Listener listener;
private Map<String, Float> options;
private Map<String, Double> options;
private boolean updatingSliders = false, updatingTable = false;
/**
@ -67,7 +67,7 @@ public class GUI extends javax.swing.JFrame implements LogListener {
updateGUI();
}
};
options = new HashMap<String, Float>();
options = new HashMap<String, Double>();
world = new World(options);
updateSettingsUI();
settingsTable.getModel().addTableModelListener(new TableModelListener() {
@ -965,25 +965,25 @@ public class GUI extends javax.swing.JFrame implements LogListener {
*/
private void saveSliderChanges() {
if (!updatingSliders) {
options.put("fps_limit", toggleFPSLimitCheckbox.isSelected() ? 0 : (float) fpsLimitSlider.getValue());
options.put("enable_multithreading", multithreadingCheckbox.isSelected() ? 1f : 0f);
options.put("number_of_creatures", (float) nCreaturesSlider.getValue());
options.put("number_of_plants", (float) nPlantsSlider.getValue());
options.put("corpse_decay_rate", corpseDecaySlider.getValue() / 1000f);
options.put("enable_corpses", enableCorpsesCheckbox.isSelected() ? 1f : 0f);
options.put("world_width", (float) worldSizeSlider.getValue());
options.put("world_height", (float) worldSizeSlider.getValue());
options.put("fps_limit", toggleFPSLimitCheckbox.isSelected() ? 0d : fpsLimitSlider.getValue());
options.put("enable_multithreading", multithreadingCheckbox.isSelected() ? 1d : 0d);
options.put("number_of_creatures", (double) nCreaturesSlider.getValue());
options.put("number_of_plants", (double) nPlantsSlider.getValue());
options.put("corpse_decay_rate", (double) corpseDecaySlider.getValue() / 1000d);
options.put("enable_corpses", enableCorpsesCheckbox.isSelected() ? 1d : 0d);
options.put("world_width", (double) worldSizeSlider.getValue());
options.put("world_height", (double) worldSizeSlider.getValue());
topSizeSlider.setMaximum(nCreaturesSlider.getValue());
options.put("parents_count", (float) topSizeSlider.getValue());
options.put("creature_sight_range", (float) sightRangeSlider.getValue());
options.put("creature_hp_decay", (float) hpDecaySlider.getValue() / 1000);
options.put("max_ticks", (float) maxTicksSlider.getValue());
options.put("draw_view_cones", drawViewCones.isSelected() ? 1f : 0);
options.put("draw_sight_lines", drawSightLines.isSelected() ? 1f : 0);
options.put("nMutatedBrains", (float) nMutatedBrainsSlider.getValue() / 100);
options.put("nMutatedNeurons", (float) nMutatedNeuronsSlider.getValue() / 100);
options.put("nMutatedConnections", (float) nMutatedConnectionsSlider.getValue() / 100);
options.put("mutationFactor", (float) mutationFactorSlider.getValue() / 100);
options.put("parents_count", (double) topSizeSlider.getValue());
options.put("creature_sight_range", (double) sightRangeSlider.getValue());
options.put("creature_hp_decay", hpDecaySlider.getValue() / 1000d);
options.put("max_ticks", (double) maxTicksSlider.getValue());
options.put("draw_view_cones", drawViewCones.isSelected() ? 1d : 0d);
options.put("draw_sight_lines", drawSightLines.isSelected() ? 1d : 0d);
options.put("nMutatedBrains", nMutatedBrainsSlider.getValue() / 100d);
options.put("nMutatedNeurons", nMutatedNeuronsSlider.getValue() / 100d);
options.put("nMutatedConnections", nMutatedConnectionsSlider.getValue() / 100d);
options.put("mutationFactor", mutationFactorSlider.getValue() / 100d);
world.reloadOptions();
}
updateSettingsUI();
@ -1167,7 +1167,7 @@ public class GUI extends javax.swing.JFrame implements LogListener {
if (f == null) {
return;
}
float map[][][] = Serializer.loadBrain(Serializer.loadFromFile(f));
double map[][][] = Serializer.loadBrain(Serializer.loadFromFile(f));
Creature c = (Creature) world.spawnCreature(map);
world.selectCreature(c);
updateGUI();
@ -1213,7 +1213,7 @@ public class GUI extends javax.swing.JFrame implements LogListener {
private void saveTableChanges() {
for (int row = 0; row < settingsTable.getRowCount(); row++) {
options.put((String) settingsTable.getValueAt(row, 0), (Float) settingsTable.getValueAt(row, 1));
options.put((String) settingsTable.getValueAt(row, 0), Double.parseDouble((String) settingsTable.getValueAt(row, 1)));
}
world.reloadOptions();
updateSettingsUI();
@ -1224,7 +1224,7 @@ public class GUI extends javax.swing.JFrame implements LogListener {
*/
private void updateSettingsUI() {
updatingSliders = true;
int fps = Math.round(options.get("fps_limit"));
int fps = (int) Math.round(options.get("fps_limit"));
if (fps < 1) {
fpsLimitSlider.setValue(60);
toggleFPSLimitCheckbox.setSelected(true);
@ -1233,34 +1233,34 @@ public class GUI extends javax.swing.JFrame implements LogListener {
toggleFPSLimitCheckbox.setSelected(false);
}
multithreadingCheckbox.setSelected(options.get("enable_multithreading") > 0f);
nCreaturesSlider.setValue(Math.round(options.get("number_of_creatures")));
nCreaturesSlider.setValue((int) Math.round(options.get("number_of_creatures")));
topSizeSlider.setMaximum(nCreaturesSlider.getValue());
topSizeSlider.setValue(Math.round(options.get("parents_count")));
nPlantsSlider.setValue(Math.round(options.get("number_of_plants")));
corpseDecaySlider.setValue(Math.round(options.get("corpse_decay_rate") * 1000));
topSizeSlider.setValue((int) Math.round(options.get("parents_count")));
nPlantsSlider.setValue((int) Math.round(options.get("number_of_plants")));
corpseDecaySlider.setValue((int) Math.round(options.get("corpse_decay_rate") * 1000));
enableCorpsesCheckbox.setSelected(options.get("enable_corpses") > 0f);
worldSizeSlider.setValue(Math.round(options.get("world_height")));
sightRangeSlider.setValue(Math.round(options.get("creature_sight_range")));
hpDecaySlider.setValue(Math.round(options.get("creature_hp_decay") * 1000));
maxTicksSlider.setValue(Math.round(options.get("max_ticks")));
worldSizeSlider.setValue((int) Math.round(options.get("world_height")));
sightRangeSlider.setValue((int) Math.round(options.get("creature_sight_range")));
hpDecaySlider.setValue((int) Math.round(options.get("creature_hp_decay") * 1000));
maxTicksSlider.setValue((int) Math.round(options.get("max_ticks")));
drawViewCones.setSelected(options.get("draw_view_cones") > 0f);
drawSightLines.setSelected(options.get("draw_sight_lines") > 0f);
nMutatedBrainsSlider.setValue(Math.round(options.get("nMutatedBrains") * 100));
nMutatedNeuronsSlider.setValue(Math.round(options.get("nMutatedNeurons") * 100));
nMutatedConnectionsSlider.setValue(Math.round(options.get("nMutatedConnections") * 100));
mutationFactorSlider.setValue(Math.round(options.get("mutationFactor") * 100));
nMutatedBrainsSlider.setValue((int) Math.round(options.get("nMutatedBrains") * 100));
nMutatedNeuronsSlider.setValue((int) Math.round(options.get("nMutatedNeurons") * 100));
nMutatedConnectionsSlider.setValue((int) Math.round(options.get("nMutatedConnections") * 100));
mutationFactorSlider.setValue((int) Math.round(options.get("mutationFactor") * 100));
updatingSliders = false;
currentNMutatedNeurons.setText(String.format("%.2f", (float) nMutatedNeuronsSlider.getValue() / 100) + "%");
currentNMutatedNeurons.setText(String.format("%.2f", nMutatedNeuronsSlider.getValue() / 100d) + "%");
currentSightRange.setText(sightRangeSlider.getValue() + "");
currentNMutatedBrains.setText(String.format("%.2f", (float) nMutatedBrainsSlider.getValue() / 100) + "%");
currentNMutatedBrains.setText(String.format("%.2f", nMutatedBrainsSlider.getValue() / 100d) + "%");
currentWorldSize.setText(worldSizeSlider.getValue() + "");
currentTopSize.setText(topSizeSlider.getValue() + (topSizeSlider.getValue() <= 0 ? " (Auto)" : ""));
currentMaxTicks.setText(maxTicksSlider.getValue() + "");
currentHpDecay.setText(hpDecaySlider.getValue() / 1000f + "");
currentMutationFactor.setText(String.format("%.2f", (float) mutationFactorSlider.getValue() / 100));
currentMutationFactor.setText(String.format("%.2f", mutationFactorSlider.getValue() / 100d));
currentFpsLimit.setText("" + fpsLimitSlider.getValue());
currentNCreatures.setText(nCreaturesSlider.getValue() + "");
currentNMutatedConnections.setText(String.format("%.2f", (float) nMutatedConnectionsSlider.getValue() / 100) + "%");
currentNMutatedConnections.setText(String.format("%.2f", nMutatedConnectionsSlider.getValue() / 100d) + "%");
currentNPlants.setText(nPlantsSlider.getValue() + "");
currentCorpseDecay.setText(corpseDecaySlider.getValue() / 1000f + "");
int row = 0;