package agent;
import constants.EventConstants;
import environment.Cell;
import environment.World;
import java.util.Observable;
import java.awt.Color;
import parameters.LocalWorldParams;
import time.TimeEventDispatcher;
import units.LivingBiologicalUnit;
import units.Occupant;
/**
*
* @author Marco Celesti
*/
public abstract class Agent extends Observable implements Runnable {
private String event = "";
private String lastEvent = "";
private boolean alive;
private Thread thisThread;
// World reference
private World world;
private LocalWorldParams params;
// Only one LivingBiologicalUnit, at the moment
private LivingBiologicalUnit unit;
// Agent name
private short id;
private short progenitor;
// DNAparameters
private DNAparameters dnaParam;
private short direction;
private short lastDirection = direction;
private short border = 0;
private float thrshld = 0.07f;
private short leftOrRight;
private boolean duplicating;
private int divisor;
private Cell birthCell;
private Cell deathCell;
private int speedCounter;
/**
* Constructor used to kill agents
* @param progenitor
* @param id
* @param idWorld
*/
public Agent(short progenitor, short id, short idWorld) {
this.id = id;
this.progenitor = progenitor;
dnaParam = null;
}
public Agent(World world, DNAparameters dnaParam, Cell cell, short id, short progenitor) {
this.world = world;
params = world.getParams();
divisor = params.isExternalAgent() ? 20 : 10;
this.progenitor = progenitor;
this.id = id;
this.dnaParam = dnaParam;
alive = true;
duplicating = false;
unit = new LivingBiologicalUnit(world, cell);
unit.setLastOccupiedCell(cell);
direction = (short) (Math.random() * 8);
leftOrRight = (short) ((Math.random() > 0.5) ? -1 : 1);
speedCounter = 0;
}
public int getId() {
return id;
}
public short getProgenitor() {
return progenitor;
}
public Occupant getUnit() {
return unit;
}
public DNAparameters getDnaParams() {
return dnaParam;
}
public World getWorld() {
return world;
}
public short getBorder() {
return border;
}
public void setBorder(short border) {
this.border = border;
}
public short getDirection() {
return direction;
}
public void setDirection(short direction) {
this.direction = direction;
}
public short getLastDirection() {
return lastDirection;
}
public void setLastDirection(short lastDirection) {
this.lastDirection = lastDirection;
}
public short getLeftOrRight() {
return leftOrRight;
}
public Color getInternalColor() {
return dnaParam.getColor();
}
public boolean isDuplicating() {
return duplicating;
}
public void setDuplicating(boolean duplicating) {
this.duplicating = duplicating;
}
public float getThrshld() {
return thrshld;
}
public void setThrshld(float thrshld) {
this.thrshld = thrshld;
}
public void setDeathCell(Cell deathCell) {
this.deathCell = deathCell;
}
public LocalWorldParams getParams() {
return params;
}
public int getDivisor() {
return divisor;
}
public void startThread() {
alive = true;
thisThread = new Thread(this);
thisThread.setPriority(Thread.MIN_PRIORITY);
thisThread.setName("" + world.getId() + ":" + progenitor + "_" + id);
TimeEventDispatcher.getInstance().addThread(thisThread.getName());
thisThread.start();
}
public void stopThread() {
alive = false;
TimeEventDispatcher.getInstance().deleteThread(thisThread.getName());
}
public void run() {
while (alive) {
event = TimeEventDispatcher.getInstance().getEvent(thisThread.getName());
if (event != null && !event.isEmpty() && !event.equals(lastEvent)) {
lastEvent = event;
if (event.startsWith("minute") || event.startsWith("hour") || event.startsWith("day") || event.startsWith("month") || event.startsWith("year")) {
executeActions("minute");
if (event.startsWith("hour")) {
executeActions("hour");
}
if (event.startsWith("day")) {
executeActions("hour");
executeActions("day");
}
if (event.startsWith("month")) {
executeActions("hour");
executeActions("day");
executeActions("month");
}
if (event.startsWith("year")) {
executeActions("hour");
executeActions("day");
executeActions("month");
executeActions("year");
}
}
agentChanged();
}
}
}
@Override
public boolean equals(Object o) {
if (o instanceof Agent) {
Agent agent = (Agent) o;
if (agent.getWorld().getId() == this.getWorld().getId() && agent.getId() == this.getId() && agent.getProgenitor() == this.getProgenitor()) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 5;
hash = 89 * hash + (this.world != null ? this.world.hashCode() : 0);
hash = 89 * hash + this.id;
hash = 89 * hash + this.progenitor;
return hash;
}
@Override
public String toString() {
return getWorld().getId() + ":" + progenitor + "_" + id;
}
public boolean isAlive() {
return alive;
}
public Cell getBirthCell() {
return birthCell;
}
public void setBirthCell(Cell birthCell) {
this.birthCell = birthCell;
}
public Cell getDeathCell() {
return deathCell;
}
public int getSpeedCounter() {
return speedCounter;
}
public void setSpeedCounter(int speedCounter) {
this.speedCounter = speedCounter;
}
protected void agentChanged() {
setChanged();
notifyObservers(EventConstants.AGENT_EVENT);
}
protected abstract void executeActions(String time);
}