Sunday, August 13, 2006

Block Talk: Recruiting agents with "ask agent"

StarLogo TNG is a great environment for studying emergence. Just lay out some blocks that describe simple rules for the behavior of an individual agent and watch what happens when you put a group of them together.

The sample project termites.sltng (found in the projects folder where you installed StarLogo TNG) demonstrates this notion of emergent phenomena. Without the help of a leader or architect termite, a group of termites interacting with their environment independently of each other produce, over time, a single tower of wood chips. Random interactions result in a predictable sense of order.

And, yet, often we wish that agents could exert control over other agents, especially when we are designing models that represent games or interactive environments. In a recent post, we showed you how to use the collidee block in collisions to get more information about colliding agents. The colliding agent can react to the color, size, shape, or any other property of the collidee. But sometimes it isn't enough to react; the agent wants to control the collidee.

With the "ask agent" block, you can. Found in both the "Logic" and "Other Agents" categories, the "ask agent" block takes a who number and a list of commands to "do."

Consider the sample project paintball.sltng, in which you control an agent that looks like Mario and can fire paintballs at enemy turtles, which change color to match the paintballs that hit them. Let's say, for example, that you want Mario to say "Gotcha!" every time he hits a turtle.

Note that you do not need to use the "ask agent" block to solve this problem. You could have a global Boolean variable called "turtle was hit" and set it to false during Setup. Then, in the collision block for paintballs and turtles, have either the paintball or the turtle set "turtle was hit" to true. In Mario's code, if "turtle was hit" is true, then say "Gotcha!" and set "turtle was hit" back to false. That way, whenever Mario gets to run his program, he will say "Gotcha!" if and only if at least one turtle got hit since the last time he ran his program.

Nevertheless, the "ask agent" block makes the code much simpler and eliminates the need to create an extra state variable. In the collision block for paintballs and turtles, instead of setting the global Boolean, have either the paintball or the turtle ask Mario to say "Gotcha!"
Note that we do not know ahead of time what the who number will be for Mario. However, we do know that Mario always gets the agent-eye camera, so we can use the "who of agent camera" block found in the Control category for the who number of Mario. Then, in the list of commands, all we need is Say: "Gotcha!"

The first solution requires about a dozen blocks scattered throughout three or four locations in the program. The "ask agent" solution only requires four blocks contained within the collision block, which is reasonable since you want the action to occur in response to the collision. It just so happens that, in this case, the agent acting is not directly involved in the collision.

Hopefully you will find as we have that the "ask agent" block is seldom needed. There is something about agents asking other agents to do things that takes some of the elegant simplicity out of modeling decentralized systems. In fact, as of this writing, I think only one of the many sample projects included with Preview 3 uses the "ask agent" block, and then only in setup code. But there are exceptions to every rule, and we hope that you will remember the "ask agent" block when you discover a need for one agent to control another agent directly.

Labels: ,