/**
*
*/
package eas.users.students.christianNagel.coEvolutionChristian;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import eas.math.geometry.Vector2D;
import eas.simulation.ConstantsSimulation;
import eas.simulation.Wink;
import eas.simulation.agent.AbstractAgent;
import eas.simulation.spatial.sim2D.standardAgents.AbstractAgent2D;
import eas.simulation.spatial.sim2D.standardEnvironments.AbstractEnvironment2D;
import eas.startSetup.ParCollection;
import eas.users.students.christianNagel.neuroBrain.NeuroBrainChristian;
/**
* @author christiannagel
*
*/
public class CoEvolutionEnv extends AbstractEnvironment2D<AbstractAgent2D<?>> {
/**
*
*/
private static final long serialVersionUID = -7573823224662994936L;
private Random random;
/**
* @param ident
* @param params
* @param random
*/
public CoEvolutionEnv(int ident, ParCollection params, Random random) {
super(ident, params);
this.random=random;
}
@Override
public void step(Wink simTime) {
// TODO Comment.
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public boolean replaceBrain(int targetID, Random random){
boolean result =false;
List<SheepAgent> remainingSheepAgents = new LinkedList<SheepAgent>();
for (AbstractAgent<?> agentX: this.getAgents()){
if (agentX.id()>=10 && agentX.id()%2==0 && agentX.id()!=targetID){
if(this.getSimTime().getCurrentTime().getLastTick()-((SheepAgent)agentX).getTimeOfCreation() > this.getParCollection().getParValueLong("minNeuralNetLifetime") || this.getParCollection().getParValueLong("minNeuralNetLifetime")>this.getSimTime().getCurrentTime().getLastTick())
remainingSheepAgents.add((SheepAgent)agentX);
}
}
if(remainingSheepAgents.size()>0){
NeuroBrainChristian<AbstractAgent2D<?>> newBrain = new NeuroBrainChristian<AbstractAgent2D<?>>(this.getAgent(targetID), random);
int randomSheepAgent = random.nextInt(remainingSheepAgents.size());
SheepAgent sheepAgentToCopyBrainFrom = remainingSheepAgents.get(randomSheepAgent);
newBrain.copyFrom((NeuroBrainChristian) sheepAgentToCopyBrainFrom.getBrainControlledAgent().getBrain());
this.getAgent(targetID).getBrainControlledAgent().implantBrain(newBrain);
((SheepAgent) this.getAgent(targetID)).setSheepLifetime();
((SheepAgent) this.getAgent(targetID)).setTimeOfCreation(this.getSimTime().getCurrentTime().getLastTick());
result = true;
}
return result;
}
public boolean setRandomPosition(int targetID, Random random){
boolean result =false, agentCollides = true;
Vector2D position=null;
double angle=0.0;
do {
position = getRandomVector2D(random);
angle = random.nextDouble()*360;
if(!collides(
getAgent(targetID)
, position, angle, null)){
agentCollides=false;
}
} while(agentCollides);
result = setAgentPosition(targetID, getRandomVector2D(random));
return result;
}
/**
* Simuliert einen Unfall, bei dem der Roboter um zufällige Grad gedreht
* und um einige Pixel verschoben wird. Ein Unfall sollte bei einer
* Kollision eingeleitet werden. Die Verschiebung findet nur statt, falls
* eine Kollision NACH dem Unfall vermieden werden kann (der Unfallzähler
* wird in jedem Fall hochgezählt).
*
* @param maxWinkel Der Winkel, um den der Roboter maximal gedreht wird.
* @return Ob der Unfall stattgefunden hat.
*/
public boolean unfallSimulation(AbstractAgent2D<?> agent, final double maxWinkel) {
boolean erfolgreich = false;
double xVersch = 0;
double yVersch = 0;
int modus;
ArrayList<Integer> modi = new ArrayList<Integer>(6);
modi.add(new Integer(0));
modi.add(new Integer(1));
modi.add(new Integer(2));
modi.add(new Integer(3));
modi.add(new Integer(4));
modi.add(new Integer(5));
while (!erfolgreich && modi.size() > 0) {
modus = this.random.nextInt(modi.size());
switch (modi.get(modus)) {
case 0:
xVersch = 1;
yVersch = 0;
break;
case 1:
xVersch = 0;
yVersch = 1;
break;
case 2:
xVersch = 1;
yVersch = 1;
break;
case 3:
xVersch = -1;
yVersch = 0;
break;
case 4:
xVersch = 0;
yVersch = -1;
break;
case 5:
xVersch = -1;
yVersch = -1;
break;
default:
break;
}
Vector2D currentPosition = this.getAgentPosition(agent.id());
if (this.setAgentPosition(agent.id(), new Vector2D(
currentPosition.x+ xVersch * ConstantsSimulation.SCHRITTW,
currentPosition.y+ yVersch * ConstantsSimulation.SCHRITTW))){
erfolgreich = true;
}
modi.remove(modus);
}
if (this.setAgentAngle(agent.id(),
this.getAgentAngle(agent.id()) - (this.random.nextDouble() * maxWinkel))) {
erfolgreich = true;
}
return erfolgreich;
}
public Vector2D getRandomVector2D(Random random){
Vector2D result = null;
result = new Vector2D(24+random.nextDouble()*(476-34), 14+random.nextDouble()*(496-24));
return result;
}
@Override
public boolean collides(AbstractAgent2D<?> agent, Vector2D pos, double angle,
Vector2D scale) {
boolean result;
result = super.collides(agent, pos, angle, scale);
// result = false; //if result is set to false, sheep drive out of the field to avoid getting caught
return result;
}
}