package eas.users.students.christianNagel.neuroBrain;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import eas.simulation.Wink;
import eas.simulation.agent.AbstractAgent;
import eas.simulation.brain.AbstractBrain;
import eas.simulation.spatial.sim2D.standardEnvironments.AbstractEnvironment2D;
import eas.startSetup.SingleParameter;
import eas.startSetup.parameterDatatypes.Datatypes;
import eas.users.students.christianNagel.coEvolutionChristian.SheepAgent;
/**
* @author christiannagel
*/
public class NeuroBrainChristian<AgentType extends AbstractAgent<?>> extends AbstractBrain<AgentType> { //implements Comparable<NeuroBrain>
private static final long serialVersionUID = -3246303849579911024L;
private Random random;
public SparseNetChristian net;
private final int defaultBrainSize =3;
private final long defaultBrainMutationInterval = 50;
private final long defaultMinNeuralNetLifetime = 0;
@SuppressWarnings("rawtypes")
public NeuroBrainChristian(AgentType brainsBody, Random random) {
super(brainsBody);
if (brainsBody!=null){
this.random=random;
int intialBrainSize = ((AbstractEnvironment2D) brainsBody.getEnvironment()).getParCollection().getParValueInt("brainSize");
net = new SparseNetChristian(brainsBody.getSensors().size(), 2, intialBrainSize); //2 outputs
for(int i = 0; i < 1000; i++){
net.mutate(random);
}
}
}
@Override
public List<SingleParameter> getParameters() {
List<SingleParameter> list = new ArrayList<SingleParameter> ();
list.add(new SingleParameter("brainSize", Datatypes.INTEGER, defaultBrainSize, "initial number of hidden neurons in neural net (changes dynamically in the course of evolution)", this.getClass().getName().toUpperCase()));
list.add(new SingleParameter("brainMutationInterval", Datatypes.LONG, defaultBrainMutationInterval , "mutation interval of the neural network (in ticks)", this.getClass().getName().toUpperCase()));
list.add(new SingleParameter("minNeuralNetLifetime", Datatypes.LONG, defaultMinNeuralNetLifetime, "minimal lifetime of the neural network required to propagate (in ticks)", this.getClass().getName().toUpperCase()));
return list;
}
@SuppressWarnings("rawtypes")
@Override
public void decideAndReact(Wink time) {
double[] ins = new double[getMyBody().getSensors().size()];
// for (int i =0; i<getMyBody().getSensors().size(); i++){
// if(i==0||i==1||i==3)
// ins[i] = (1/500.0)*(Double)this.getMyBody().sense(i);
// else
// ins[i] = (1/360.0)*(Double)this.getMyBody().sense(i);
// }
double[] outs = new double[2];
// put inputs (distances etc.) in the neural network and get outputs (motor control values)
net.propagate(ins, outs);
// this sets the motor speeds according to the output neurons' output values
double speedLeft, speedRight;
speedLeft = Math.min(0.5 + outs[0]*((SheepAgent) this.getMyBody()).getSpeed(), ((SheepAgent) this.getMyBody()).getSpeed());
speedRight = Math.min(0.5 + outs[1]*((SheepAgent) this.getMyBody()).getSpeed(), ((SheepAgent) this.getMyBody()).getSpeed());
((AbstractEnvironment2D) this.getMyBody().getEnvironment()).setWheelSpeedLeft(this.getMyBody().id(), speedLeft);
((AbstractEnvironment2D) this.getMyBody().getEnvironment()).setWheelSpeedRight(this.getMyBody().id(), speedRight);
// rob.sensors[0].setAngle(outs[2]);
// for(Sensor s: rob.sensors)
// {
// fitness += s.value;//a.rob.sensors[0].value;
// }
//fitness -= 0.2*rob.getCollisions();
//rob.resetCollisions();
this.getMyBody().actuate("drive");
}
// @Override
// public int compareTo(NeuroBrain a) {
// int result = 0;
//
// if(((AbstractEvolvableAgent2D) a.getMyBody()).getEvaluation() > ((AbstractEvolvableAgent2D) this.getMyBody()).getEvaluation()){
// result = 1;
// }
// else if(((AbstractEvolvableAgent2D) a.getMyBody()).getEvaluation() == ((AbstractEvolvableAgent2D) this.getMyBody()).getEvaluation()){
// result = 0;
// }
// else{
// result = -1;
// }
//
// return result;
// }
public void deriveFrom(NeuroBrainChristian<AgentType> mom, @SuppressWarnings("unused") NeuroBrainChristian<AgentType> dad){
net.copyFrom(mom.net);
}
public void copyFrom(NeuroBrainChristian<AgentType> mom){
//fitness = mom.getFitness();
net.copyFrom(mom.net);
net.reset();
}
@Override
public boolean mutate(final Wink time) {
net.mutate(random);
return true;
}
public void reset(){
//fitness = 0.0;
//rob.resetAnzUnf();
net.reset();
}
@Override
public BufferedImage generateMRTImage() {
BufferedImage netImg = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g = netImg.createGraphics();
g.setColor(Color.lightGray);
g.fillRect(0, 0, netImg.getWidth(), netImg.getHeight());
g.translate(10, 10);
for(int i = 0; i < net.neurons.size(); i++){
for(int j = 0; j < net.neurons.size(); j++){
// if(i%2==0) g.setColor(new Color(120, 122, 125));
// else if(j%2==0) g.setColor(new Color(130, 132, 35));
// else g.setColor(new Color(140, 142, 145));
if(i < net.inputs+1) {
g.setColor(Color.white);
// g.drawRect(j*16+5, i*16+5, 6, 6);
g.fillRect(j*16+10, i*16+10, 3, 3);
}
else{
if(j < net.inputs+1) {
g.setColor(Color.white);
g.fillRect(j*16+5, i*16+5, 6, 6);
}
else{
if(j>=i){
// g.setColor(new Color(80, 80, 80));
g.setColor(Color.black);
// g.setStroke(new BasicStroke(2));
g.drawRect(j*16+5, i*16+5, 6, 6);
}
else{
g.setColor(Color.black);
g.fillRect(j*16+5, i*16+5, 6, 6);
}
}
}
}
for(NeuralLinkChristian l : net.neurons.get(i).links){
int j = l.neuron;
if(i < net.inputs+1) {
g.setColor(Color.white);
g.drawRect(j*16, i*16, 14, 14);
}
else{
if(j < net.inputs+1) {
g.setColor(Color.white);
g.fillRect(j*16, i*16, 14, 14);
}
else{
if(j>=i){
// g.setColor(new Color(80, 80, 80));
g.setColor(Color.black);
g.drawRect(j*16, i*16, 13, 13);
// g.fillRect(j*16, i*16, 14, 14);
}
else{
g.setColor(Color.black);
g.fillRect(j*16, i*16, 14, 14);
}
}
}
double w = l.weight;
if(w > 0){
w *= 50.0;
w = Math.min(w, 255.0);
g.setColor(new Color(/*(int)w*/255, (int)(/*255.0-*/w), 0/*(int)(255.0-w)*/));
}
else{
w *= -50.0;
w = Math.min(w, 255.0);
g.setColor(new Color(/*(int)(255.0-w)*/0, (int)(/*255.0-*/w), /*(int)w)*/255));
}
g.fillRect(l.neuron*16+2,i*16+2, 10, 10);
}
}
return netImg;
}
}