Hi Steven,

I believe the preferred (thread-safe) procedure is to use the Stoppable object returned by scheduleRepeating(), and then call the stop() method on that Stoppable object.

When you create each agent, you can store its corresponding Stoppable object as an instance variable inside the agent.  Then, inside the step() method, when you detect a stopping/"death" condition, simply invoke the stop() method, something like this:

-----------------------------------

public class Agent implements Steppable{

Stoppable killMeNow;

Bag objectsThatReferenceMe;

public Agent() { 
this.objectsThatReferenceMe.add(....);  // add  and Grids, Networks, or other Objects that MIGHT reference me. 
this.objectsThatReferenceMe.add(....); //  They implement *your* Removable interface, which is simply "public void remove(Agent a);" method
        ....
}

public void setStoppable(Stoppable s){
       killMeNow = s;
}

private void removeMe(){
for (int i = 0, objectsThatReferenceMe.numObj, i++){
Removable r = objectsThatReferenceMe.get(i);
r.remove(self);
}

}

public void step( final SimState state ){
        // tests for stopping condition at the start.  Could also do it at the end, or in the middle (with effort)
if (stoppingCondition() {          // avoid null pointer exception. Should never happen with code below! 
      if (killMeNow != Null)  {
removeMe();     // remove references to me in other all other Agents and Objects
                        killMeNow.stop();   // take me off the schedule, and do nothing else this step
} else {

// do what ever this agent is going to do in a normal step
}
    }
}

///##################################################################################################

// In the Initialization method in your SimState object, you create Agents and set their Stoppables

....  // initialization code here

for (int i = 0, i < 10, i ++) {  // create 10 agents
Agent a = new Agent();
Stoppable s = scheduleRepeating(a);    // use any of the scheduleRepeating forms, according to your needs. This is simplest.
a.setStoppable(s);
}

... // more initialization code here

-----------------------------------------------------

Note that I've added a crude "removeMe()" method.  This is necessary if "being alive" means MORE than being scheduled each step (i.e. because other Agents and Objects call it's methods, etc.).  After it is no longer referenced by any object, the JVM garbage collector will remove the dead Agent from memory.

Subtle note: they way you implement the "remove()" method in all your Removable classes will need to fit with your overall activation and synchronization scheme.  In some cases, you will want agents to die and disappear ONLY AFTER ALL OTHER AGENTS HAVE COMPLETED the current step.  Other case, it will be to let them die and disappear at any time, asynchronously -- which is a bit simpler to implement but maybe trickier to test and debug.

Hope this helps,

Russ Thomas


From: MASON Multiagent Simulation Toolkit <[log in to unmask]> on behalf of Steven Pousty <[log in to unmask]>
Reply-To: MASON Multiagent Simulation Toolkit <[log in to unmask]>
Date: Friday, September 16, 2016 at 11:30 AM
To: <[log in to unmask]>
Subject: Getting an agent to kill itself

Greetings all:
I am trying to get an agent to "kill" itself based on some feature of the agent. 

In my example it is when the agent walks "too far" over the edge of the world.
https://github.com/thesteve0/startmason/blob/master/src/org/thesteve0/steptwo/Animal.java#L135

But this doesn't work. I suspect because the Agent still lives on and all I am doing is removing it from being displayed on the grid. 

I have read the docs and looked at the asteroid example. It seems like I need to action kill the agent from the SimState. If this is true then it seems like I should set a flag on the agent like "dead=true" and then at the start of each step iterate through all the agents and Stop() all that are dead. 

Is this correct or is there a way to "kill" an agent from within an agent? I will need to do this in the future if the animal does not eat enough or walks through too much bad habitat.

Thanks again for all the help!
Steve