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

new advanced options and under the hood GUI improvements

This commit is contained in:
Enrico Fasoli 2015-08-08 12:02:28 +02:00
parent 9892070f0c
commit 70d46af962
5 changed files with 167 additions and 112 deletions

View File

@ -17,6 +17,7 @@ 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;
public static String nameBrain(float[][][] brainMap) {
// Compute a unique representation of the brainmap
@ -31,7 +32,7 @@ public class Serializer {
Random gen = new Random(a);
String name = "";
int length = Math.abs(gen.nextInt()) % 5 + 2;
for (int i = 0; i < length; i++){
for (int i = 0; i < length; i++) {
name += sillabe[Math.abs(gen.nextInt()) % sillabe.length];
}
return name;
@ -68,9 +69,7 @@ public class Serializer {
+ "# 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;
if (!e.getKey().equals("fps_limit")) { // dont save this one
a += e.getKey() + " = " + e.getValue() + "\n";
}
a += e.getKey() + " = " + e.getValue() + "\n";
}
return a;
}
@ -164,4 +163,41 @@ public class Serializer {
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"
+ "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;
}
}

View File

@ -14,7 +14,7 @@ import logic.neural.Brain;
*/
public class Creature extends Element implements Runnable {
public static int default_radius = 20, max_hp = 100;
public static int default_radius = 20, max_hp = 100, brain_hidden_layers = 2, brain_hidden_neurons = 10;
public static float max_speed = 3, max_beak = default_radius / 4, fov, sightRange, corpseDecayRate = 0, hpDecay = 0.5f, pointsForEatingPlants = 1f, pointsForAttacking = 2f, hpForAttacking = 1f, hpForEatingPlants = 1f;
public static boolean leaveCorpses = false;
@ -38,7 +38,7 @@ public class Creature extends Element implements Runnable {
speed = 0;
rotSpeed = 0;
fitness = 0;
brain = new Brain(9, 5, 2, 10);
brain = new Brain(9, 5, brain_hidden_layers, brain_hidden_neurons);
sights = new Sight[2];
}
@ -295,8 +295,8 @@ public class Creature extends Element implements Runnable {
// Check if attackable
if (beak > beak / 2 && tempDist < beak * 1.5f && tempAngle < fov / 2) {
// Attacking!
float damage = beak;
hp += damage * hpForAttacking / 2;
float damage = beak * hpForAttacking / 2;
hp += damage;
fitness += pointsForAttacking;
if (hp > max_hp) {
hp = max_hp;

View File

@ -3,6 +3,7 @@ package logic;
import com.mygdx.game.Game;
import com.mygdx.game.Listener;
import com.mygdx.game.Log;
import com.mygdx.game.Serializer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
@ -11,6 +12,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import logic.neural.Brain;
/**
* This class represents an instance of a simulation, its world and its
@ -28,7 +30,7 @@ public class World implements Runnable {
private Map<String, Float> options;
private long ticksSinceGenStart = 0, maximumTicksPerGen = 0;
private Creature selected;
private Comparator creatureComp;
private final Comparator creatureComp;
private final ArrayList<Element> elements;
private final ArrayList<Element> toAdd;
private final ArrayList<Creature> creatures;
@ -67,8 +69,8 @@ public class World implements Runnable {
}
};
}
public void start(){
public void start() {
newGen(true);
}
@ -246,34 +248,46 @@ public class World implements Runnable {
}
}
public void resetDefaultOptions() {
options.clear();
reloadOptions();
}
/**
* Applies current options. Uses default alternatives if options are not
* provided
*/
public void reloadOptions() {
width = Math.round(options.getOrDefault("world_width", 2000f));
height = Math.round(options.getOrDefault("world_height", 2000f));
fpsLimit = Math.round(options.getOrDefault("fps_limit", 60f));
maximumTicksPerGen = Math.round(options.getOrDefault("max_ticks", 0f));
creatPerGen = Math.round(options.getOrDefault("number_of_creatures", (float) Math.min(Math.round(width * height / 20000), 50)));
nPlants = Math.round(options.getOrDefault("number_of_plants", width * height / 5500f));
multithreading = options.getOrDefault("enable_multithreading", -1f) > 0;
Creature.corpseDecayRate = options.getOrDefault("corpse_decay_rate", 0f);
Creature.leaveCorpses = options.getOrDefault("enable_corpses", 0f) > 0;
Creature.default_radius = Math.round(options.getOrDefault("creature_radius", 20f));
Creature.max_hp = Math.round(options.getOrDefault("creature_max_hp", 100f));
Creature.max_speed = Math.round(options.getOrDefault("creature_max_speed", 3f));
Creature.fov = Math.round(options.getOrDefault("creature_fov", (float) Math.PI / 2.5f));
Creature.sightRange = Math.round(options.getOrDefault("creature_sight_range", 100f));
Creature.hpDecay = options.getOrDefault("creature_hp_decay", 0.5f);
Creature.hpForAttacking = options.getOrDefault("creature_hp_for_attacking", 1f);
Creature.hpForEatingPlants = options.getOrDefault("creature_hp_for_eating_plants", 1f);
Creature.pointsForAttacking = options.getOrDefault("creature_points_for_attacking", 2f);
Creature.pointsForEatingPlants = options.getOrDefault("creature_points_for_eating_plants", 1f);
nMutatedBrains = options.getOrDefault("nMutatedBrains", 0.2f);
nMutatedNeurons = options.getOrDefault("nMutatedNeurons", 0.5f);
nMutatedConnections = options.getOrDefault("nMutatedConnections", 0.5f);
mutationFactor = options.getOrDefault("nMutationFactor", 1f);
for (Object o : Serializer.getDefaultSettings().entrySet().toArray()) {
Map.Entry<String, Float> e = (Map.Entry<String, Float>) 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"));
maximumTicksPerGen = Math.round(options.get("max_ticks"));
creatPerGen = Math.round(options.get("number_of_creatures"));
nPlants = 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;
Creature.default_radius = Math.round(options.get("creature_radius"));
Creature.max_hp = Math.round(options.get("creature_max_hp"));
Creature.max_speed = options.get("creature_max_speed");
Creature.fov = options.get("creature_fov");
Creature.sightRange = options.get("creature_sight_range");
Creature.hpDecay = options.get("creature_hp_decay");
Creature.hpForAttacking = options.get("creature_hp_for_attacking");
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"));
Brain.bias = options.get("brain_bias");
nMutatedBrains = options.get("nMutatedBrains");
nMutatedNeurons = options.get("nMutatedNeurons");
nMutatedConnections = options.get("nMutatedConnections");
mutationFactor = options.get("mutationFactor");
}
/**

View File

@ -11,7 +11,7 @@ import com.mygdx.game.Serializer;
*/
public class Brain {
public static final float bias = 0.5f;
public static float bias = 0.5f;
private Neuron[][] neurons;
private String name;

View File

@ -17,15 +17,22 @@ import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultRowSorter;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.RowSorter;
import javax.swing.RowSorter.SortKey;
import javax.swing.SortOrder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import logic.Creature;
import logic.World;
@ -53,18 +60,31 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
Log.addListener(this);
options = new HashMap<String, Float>();
world = new World(options);
updateSettings();
updateSettingsUI();
settingsTable.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
if (updatingTable) {
return;
if (!updatingTable) {
saveTableChanges();
}
saveTableChanges();
updateSettingsUI();
}
});
/*
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();
*/
guiUpdater = new Thread() {
@Override
public void run() {
@ -934,33 +954,14 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
}
private void resetDefaultSettings() {
updatingSliders = true;
fpsLimitSlider.setValue(60);
nCreaturesSlider.setValue(25);
nPlantsSlider.setValue(700);
worldSizeSlider.setValue(2000);
corpseDecaySlider.setValue(0);
topSizeSlider.setValue(0);
sightRangeSlider.setValue(100);
hpDecaySlider.setValue(500);
maxTicksSlider.setValue(0);
nMutatedBrainsSlider.setValue(50);
nMutatedNeuronsSlider.setValue(20);
nMutatedConnectionsSlider.setValue(50);
mutationFactorSlider.setValue(100);
toggleFPSLimitCheckbox.setSelected(false);
multithreadingCheckbox.setSelected(true);
enableCorpsesCheckbox.setSelected(false);
drawSightLines.setSelected(false);
drawViewCones.setSelected(false);
updatingSliders = false;
updateSettings();
world.resetDefaultOptions();
updateSettingsUI();
}
/**
* Adjusts settings using values from the UI
*/
private void updateSettings() {
private void saveSliderChanges() {
if (!updatingSliders) {
options.put("fps_limit", toggleFPSLimitCheckbox.isSelected() ? 0 : (float) fpsLimitSlider.getValue());
options.put("enable_multithreading", multithreadingCheckbox.isSelected() ? 1f : 0f);
@ -982,21 +983,8 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
options.put("nMutatedConnections", (float) nMutatedConnectionsSlider.getValue() / 100);
options.put("mutationFactor", (float) mutationFactorSlider.getValue() / 100);
world.reloadOptions();
updateSettingsTable();
}
currentNMutatedNeurons.setText(String.format("%.2f", (float) nMutatedNeuronsSlider.getValue() / 100) + "%");
currentSightRange.setText(sightRangeSlider.getValue() + "");
currentNMutatedBrains.setText(String.format("%.2f", (float) nMutatedBrainsSlider.getValue() / 100) + "%");
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));
currentFpsLimit.setText("" + fpsLimitSlider.getValue());
currentNCreatures.setText(nCreaturesSlider.getValue() + "");
currentNMutatedConnections.setText(String.format("%.2f", (float) nMutatedConnectionsSlider.getValue() / 100) + "%");
currentNPlants.setText(nPlantsSlider.getValue() + "");
currentCorpseDecay.setText(corpseDecaySlider.getValue() / 1000f + "");
updateSettingsUI();
}
public void setScrollBarToTheBottom() {
@ -1034,15 +1022,15 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
}//GEN-LAST:event_pauseMenuButtonActionPerformed
private void topSizeSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_topSizeSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_topSizeSliderStateChanged
private void corpseDecaySliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_corpseDecaySliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_corpseDecaySliderStateChanged
private void enableCorpsesCheckboxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_enableCorpsesCheckboxStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_enableCorpsesCheckboxStateChanged
private void pauseButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_pauseButtonStateChanged
@ -1050,39 +1038,39 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
}//GEN-LAST:event_pauseButtonStateChanged
private void worldSizeSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_worldSizeSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_worldSizeSliderStateChanged
private void nPlantsSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_nPlantsSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_nPlantsSliderStateChanged
private void nCreaturesSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_nCreaturesSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_nCreaturesSliderStateChanged
private void multithreadingCheckboxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_multithreadingCheckboxStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_multithreadingCheckboxStateChanged
private void toggleFPSLimitCheckboxStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_toggleFPSLimitCheckboxStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_toggleFPSLimitCheckboxStateChanged
private void fpsLimitSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_fpsLimitSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_fpsLimitSliderStateChanged
private void sightRangeSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sightRangeSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_sightRangeSliderStateChanged
private void hpDecaySliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_hpDecaySliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_hpDecaySliderStateChanged
private void maxTicksSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_maxTicksSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_maxTicksSliderStateChanged
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
@ -1090,27 +1078,27 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
}//GEN-LAST:event_jButton1ActionPerformed
private void drawViewConesStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_drawViewConesStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_drawViewConesStateChanged
private void drawSightLinesStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_drawSightLinesStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_drawSightLinesStateChanged
private void nMutatedNeuronsSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_nMutatedNeuronsSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_nMutatedNeuronsSliderStateChanged
private void mutationFactorSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_mutationFactorSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_mutationFactorSliderStateChanged
private void nMutatedBrainsSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_nMutatedBrainsSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_nMutatedBrainsSliderStateChanged
private void nMutatedConnectionsSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_nMutatedConnectionsSliderStateChanged
updateSettings();
saveSliderChanges();
}//GEN-LAST:event_nMutatedConnectionsSliderStateChanged
private File saveDialog() {
return saveDialog(null);
@ -1221,26 +1209,11 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
}
}//GEN-LAST:event_clearSelectedCreatureBtnActionPerformed
private void updateSettingsTable() {
int row = 0;
updatingTable = true;
for (Object o : options.entrySet().toArray()) {
Map.Entry<String, Float> e = (Map.Entry<String, Float>) o;
if (settingsTable.getRowCount() > row) {
settingsTable.getModel().setValueAt(e.getKey(), row, 0);
settingsTable.getModel().setValueAt(e.getValue(), row, 1);
} else {
((DefaultTableModel) settingsTable.getModel()).addRow(new Object[]{e.getKey(), e.getValue()});
}
row++;
}
updatingTable = false;
}
private void saveTableChanges() {
for (int row = 0; row < settingsTable.getRowCount(); row++) {
options.put((String) settingsTable.getValueAt(row, 0), (Float) settingsTable.getValueAt(row, 1));
}
world.reloadOptions();
updateSettingsUI();
}
@ -1249,7 +1222,14 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
*/
private void updateSettingsUI() {
updatingSliders = true;
//fpsLimitSlider.setValue(Math.round(options.get("fps_limit")));
int fps = Math.round(options.get("fps_limit"));
if (fps < 1) {
fpsLimitSlider.setValue(60);
toggleFPSLimitCheckbox.setSelected(true);
} else {
fpsLimitSlider.setValue(fps);
toggleFPSLimitCheckbox.setSelected(false);
}
multithreadingCheckbox.setSelected(options.get("enable_multithreading") > 0f);
nCreaturesSlider.setValue(Math.round(options.get("number_of_creatures")));
topSizeSlider.setMaximum(nCreaturesSlider.getValue());
@ -1267,8 +1247,33 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
nMutatedNeuronsSlider.setValue(Math.round(options.get("nMutatedNeurons") * 100));
nMutatedConnectionsSlider.setValue(Math.round(options.get("nMutatedConnections") * 100));
mutationFactorSlider.setValue(Math.round(options.get("mutationFactor") * 100));
updateSettingsTable();
updatingSliders = false;
currentNMutatedNeurons.setText(String.format("%.2f", (float) nMutatedNeuronsSlider.getValue() / 100) + "%");
currentSightRange.setText(sightRangeSlider.getValue() + "");
currentNMutatedBrains.setText(String.format("%.2f", (float) nMutatedBrainsSlider.getValue() / 100) + "%");
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));
currentFpsLimit.setText("" + fpsLimitSlider.getValue());
currentNCreatures.setText(nCreaturesSlider.getValue() + "");
currentNMutatedConnections.setText(String.format("%.2f", (float) nMutatedConnectionsSlider.getValue() / 100) + "%");
currentNPlants.setText(nPlantsSlider.getValue() + "");
currentCorpseDecay.setText(corpseDecaySlider.getValue() / 1000f + "");
int row = 0;
updatingTable = true;
for (Object o : options.entrySet().toArray()) {
Map.Entry<String, Float> e = (Map.Entry<String, Float>) o;
if (settingsTable.getRowCount() > row) {
settingsTable.getModel().setValueAt(e.getKey(), row, 0);
settingsTable.getModel().setValueAt(e.getValue(), row, 1);
} else {
((DefaultTableModel) settingsTable.getModel()).addRow(new Object[]{e.getKey(), e.getValue()});
}
row++;
}
updatingTable = false;
}
// Variables declaration - do not modify//GEN-BEGIN:variables