«prev1 2 3 4next»

Programming the behavior

Here's where you get to show those java skills you learned! There are three behavior models that you need to program to get your simulation running:

You program them by extending "BaseAgentModel", "BaseWorldModel" and "BaseContextModel" from the packege "de.nec.nle.siafu.behaviormodels.BaseAgentModel".

There are always two methods to override: createX and doIteration. The create method is called when the world is created, and allows you to create your Agents, Places or Overlays. The doIteration is called (guess) at each iteration, and allows you to modify them.

For simplicity, we will not change the context or world model here, that is, we will just create a class that extends BaseWorldModel and BaseContextModel. Here you go: WorldModel.java and ContextModel.java

The Agent Behavior model

We're going to define three types of users for TestLand, each with different behaviors:

I honestly don't know how much detail you guys need here, so, contact me if this isn't enough.

Let's go through AgentModel.java (colorized).

AgentModel walkthrough - Creating the agents

We start with the create agents method. You are going to have to return an ArrayList full with all Agents you need in the simulation. Check this code:

public ArrayList<Agent> createAgents() {

	System.out.println("Creating " + POPULATION + " people.");
	ArrayList<Agent> people =
			AgentGenerator.createRandomPopulation(POPULATION, world);

	for (Agent a : people) {
		a.set(ACTIVITY, Activity.WALKING);
		a.setSpeed(1 + RAND.nextInt(TOP_SPEED));
		a.setVisible(true);
	}

We fill most of the population with automatically created agents, using a generator class which you can ignore for now. It's right here, AgentGenerator.java (colorized).

However, we need one extra field in the agents, ACTIVITY. Because the AgentGenerator doesn't include this, we do it manually here; because all agents need to have the same fields, we add the ACTIVITY field to each and everyone of them here. We are also doing some other stuff, like making the agents visible, but this is all covered by the API.

This has created all our normal agents, but we want to highlight three special ones: Teresa, Pietro and the Postman. We will also move one of them to the isolated part of the map. In the following snippet, we take those four agents aside, plus a couple of places that we will need later:

	Iterator<Agent> peopleIt = people.iterator();
	Agent teresa = peopleIt.next();
	Agent pietro = peopleIt.next();
	postman = peopleIt.next();
	Agent isolated = peopleIt.next();

	Iterator<Place> nowheres =
			world.getPlacesOfType("Nowhere").iterator();
	placeOne = nowheres.next();
	placeTwo = nowheres.next();

Fine, now we need to define the details for these agents. It's all similar really. For Teresa and Pietro, getControl() is important, to keep them from following the behavior of the "normal" agents. The rest is basic property setting, which we detail in the following code chunk. Note that in the case of the isolated user, we change only the position. Also, see how we return our agent list (peolpe) at the end:

	postman.setName("Postman");
	postman.setPos(placeTwo.getPos());
	postman.setImage("HumanGreen");
	postman.setVisible(true);
	postman.setSpeed(2);
	postman.getControl();
	postman.set("Language", new Text("Russian"));

	isolated.setPos(world.getPlacesOfType("Isolated").iterator()
	.next().getPos());
	return people;
}

AgentModel walkthrough - Handling the agents

Let's work on the doIteration method now. This will be called at each iteration of the simulation, and it's our chance to have our agents do whey they need to:

public void doIteration(final Collection<Agent> agents) {
	Calendar time = world.getTime();
	now =
			new EasyTime(time.get(Calendar.HOUR_OF_DAY), time
					.get(Calendar.MINUTE));
	handlePostman();
	for (Agent a : agents) {
		if (!a.isOnAuto()) {
			continue; // This guy's being managed by the user interface
		}
		if (a.equals(postman)) {
			continue;
		}
		handlePerson(a);
	}
}

First of all, we take the simulation time and keep it in a static variable. Then we handle the postman (see later) and then everyone else. Note that the method to handle everyone else is handlePerson, but we only call it on that agent if it is on auto (Teresa and Pietro aren't) and is not the postman. It is important that your agent model leaves the user's that are not on auto alone, or the GUI will steal the agents you are moving around!

Now, let's do the handle methods. Pietro and Teresa don't need any further instructions, they will just stay put. Now, the postman is a different issue:

private void handlePostman() {
	postman.setSpeed(POSTMAN_PEAK
			- Math.abs(POSTMAN_PEAK - now.getHour()));
	if (postman.isAtDestination()) {
		if (postman.getPos().equals(placeOne.getPos())) {
			postman.setDestination(placeTwo);
		} else {
			postman.setDestination(placeOne);
		}
	}
}

Two things to the postman: his speed and his destination. The speed incrases as he approaches the POSTMAN_PEAK hour. The destination oscilates between the squarish part of the map, and the circular one. While he is not atDestination, nothing happens, and Siafu moves him towards the current destination. As soon as the destination is reached, we sent him back to where he came from.

And finally, the rest of the agents:

private void handlePerson(final Agent a) {
		switch ((Activity) a.get(ACTIVITY)) {
		case WAITING:
			break;

		case WALKING:
			a.wander();
			break;
		default:
			throw new RuntimeException("Unable to handle activity "
					+ (Activity) a.get(ACTIVITY));
}

We've build a little switch block here, even if it's not really used. The normal agents are always walking, and so all they do is wander (move randomly around). However, it would be easy to make them stop at a certain time of the day, by switching the ACTIVITY field to WAITING. The swith module is left in the tutorial as a canonical example of the state maching that usually governs agents. Check out other simulations for more advanced behaviors.

And that's that! Your agents are ready to rock!

Download

Latest code

Tutorial

Creating your own simulation