package alive;

/**
 * <ALIVE Project>
 * Experiment 2 Fish agent
 * Fish swims and eat, controlled by a Neural Net
 * that learns from experience end observation
 */

import javax.vecmath.*;
import javax.media.j3d.*;

public class xp2_Fish extends Agent {

// ----------------------------- Constructors ------------------------------
  public xp2_Fish(Environment env) {  // Environment Contructor
    super.configureToEnvironment(env); // Update references
    // Init vectors & parameters
    param = new double[4];
    paramName = new String[4];
    set(0, "energy", 40);
    set(1, "sucess", 0);
    set(2, "temperature", env.get("temperature"));
    set(3, "reproduction", rnd(80,120));
    color.set(.2f,.0f,.0f);
    speed = generateRandomVector(); speed.scale(.01);
    super.makeAlive();
    System.out.print("P"); // "Agent Created" char code
  }

  public xp2_Fish(xp2_Fish parent) {  // Fish child contructtor
    super.configureToEnvironment(parent.env);
    param = new double[4];
    paramName = new String[4];
    set(0, "energy", 40);
    set(1, "sucess", 0);
    set(2, "temperature", parent.get("temperature")*rnd(.9, 1.1)); // 10% variation
    set(3, "reproduction", parent.get("reproduction")*rnd(.9, 1.1));
    parent.adjust("energy",-50);
    color.set(parent.color);
    position.set(parent.position.x,parent.position.y-2,parent.position.z);
    System.out.print("p"); // "Agent Created" char code
    super.makeAlive();
  }

// ----------------------------- User methods ------------------------------
  public synchronized void reproduce() {
    if (env.nAgents<env.config.POP_LIMIT) {
      xp2_Fish child = new xp2_Fish(this);
      env.addAgent(child);
    }
  }

// --------------------------- Overrided methods ----------------------------

  public void behavior() { //  ***  Main Cycle, evaluate common agent functions
    if (probability(.01))  {
      speed.add(generateRandomVector());
      direction.set(speed.x,speed.y,speed.z);
      direction.normalize();
    }
    if (get("energy") > get("reproduction")) reproduce();
    if (Math.abs(param[0]) < 1)  die();
  }

  public Actor createActor() {
    return new Actor_Fish();
  }

  public void updateActor() {
    size = Math.abs(get("energy")/100);
    actor.set(position,direction,size);
  }
}
