/** Adds new agent to the simulation and sets his audition and sight to the default values. */
  public Agent addAgent(final Agent agent) {

    agent.setAudition(AGENT_AUDITION);
    agent.setSight(AGENT_SIGHT);

    agents.add(agent);

    return agent;
  }
  /** Adds new agent to the simulation and sets its position to given coordinates. */
  public Agent addAgent(Agent agent, int x, int y) {
    addAgent(agent);

    Point agentPosition = agent.getPosition();
    agentPosition.x = x;
    agentPosition.y = y;

    return agent;
  }
  /**
   * Runs the entire simulation.
   *
   * @param maxDays the maximal number of steps of the simulation.
   */
  public void run(int maxDays) {
    int simulationTime = 0;
    while (true) {
      long startTime = new Date().getTime();
      // Log.println("nextday");
      environment.initNextDay();

      for (Agent agent : agents) {
        if (agent.isDead()) continue;

        // learns what he sees
        agent.lookAround();
      }

      for (Agent agent : agents) {
        if (!agent.isDead()) {

          // agent live
          agent.live();

          // agent hunger
          // adds 0.01 to all needs
          for (int foodKind = 0; foodKind < FoodGenerator.getSize(); foodKind++) {
            float amount = agent.getNeed(foodKind);
            amount += 0.001; // 0.0005;
            agent.setNeed(foodKind, amount);
          }
        }

        agent.processMonitors(simulationTime);

        if (!agent.isDead()) {
          IMemory memory = agent.getMemory();
          if (memory != null) {
            memory.run();
          }
        }
      }

      if ((simulationTime % FOOD_SPEED) == 0) {
        // foooood, hungryyy!!!
        for (FoodGenerator generator : generators) {
          generator.seed(environment);
        }
      }

      simulationTime++;
      if (simulationTime > maxDays) {
        break;
      }

      long endTime = new Date().getTime();

      // System.out.println("Cycle time: " + (endTime - startTime) + " ms");

      if (stepPeriod > 0) {
        try {
          Thread.sleep(stepPeriod);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    System.out.println("Simulation stopped after " + (simulationTime - 1) + " days");
  }