Skip to content
flugen edited this page Jun 30, 2012 · 2 revisions

Behaviors

In the ArtLife universe, a behavior is a Java class that extends the Behavior abstract class in the behaviors package. This means they have two constructors, and implement the following methods:

  • public int perform(Grid grid, Organism self)
  • public Behavior clone() and
  • public Behavior mutate().

A description of the different aspects follow. We use the GO_FORWARD behavior to demonstrate.

Constructors

NAME(int numBehs)

This is the regular constructor for this behavior and should initialize all the behavior parameters to some default value. It also needs to call the Behavior constructor using super(numBehs, #) where the second argument is the number of possible branches this behavior can take. For example, in GO_FOWARD we have

public GO_FOWARD(int numBehs) {
	super(numBehs, 2);
	dist = 1;
}

NAME(int numBehs, ArrayList n)

This constructor is used for the clone() method, to assist in creating an exact copy of this behavior. As such, you generally only need to call super(numBehs, #, n) and possibly to initialize any parameters that aren't initialized in the clone() method, e.g. a HashMap. Remember that the # must be the same as in the previous constructor! In GO_FOWARD we have

public GO_FOWARD(int numBehs, ArrayList<Integer> n) {
	super(numBehs, 2, n);
}

Methods

Perform

The perform(Grid grid, Organism self) method implements the actions of the behavior. It must return an index into the list of organism behaviors. This is specified using return next(n) notation, where n represents one of the possible branches the behavior can take. Importantly however, the behavior has no idea what behavior next(n) will be. This allows significant mutation of the total behavior, simply be changing which behavior corresponds to next(n). In the perform method, we are allowed access to all of the public methods in Grid and Organism. For example, the GO_FORWARD behavior checks if the coordinates in front of it are within bounds and empty, and if so, moves forward one space. If it succeeds, it returns next(1), otherwise it returns next(0). Note that next(0) could be GO_FORWARD again! As that would lead into an pointless loop, which behavior comes next offers a powerful discriminant between organisms. The full code is shown below.

public int perform(Grid grid, Organism self) {
	direction dir = self.getDir();
	int x=self.getX(),y=self.getY();
	int newx = x+dist*dir.dx;
	int newy = y+dist*dir.dy;
	if(grid.checkCoords(newx, newy) &&
			grid.thingAt(newx,newy)==null){
		grid.move(x,y,newx,newy);
		return next(1);
	}
	return next(0);
}

Clone

The clone() method is used to make an exact copy of this behavior, including the ordering of next, and any internal parameters. Thus, this method is usually pretty simple, and for some behaviors amy even be just a return statement. Note that this should be the only time you use the constructor, and is also the only instance of the NAME(int numBehs, ArrayList<Integer> n) constructor. GO_FORWARD's clone() method is as follows:

public Behavior clone() {
	GO_FORWARD temp = new GO_FORWARD(numBehs, next);
	temp.dist = dist;
	return temp;
}

Mutate

The mutate() method allows us to create an almost exact copy of this behavior. It is essentially clone, but with a little randomness that tweaks the behavior parameters slightly. For instance, in GO_FOWARD, we make a new GO_FOWARD behavior using clone(), and then modify its dist parameter slightly. Perhaps it's better to move 2 or 3 spaces? We can also use a different next by calling the static Behavior.mutate(Behavior b) method on our new behavior.

public Behavior mutate() {
	GO_FOWARD temp = clone();
	temp.dist = r.nextInt(3) + 1;
	return Behavior.mutate(temp);
}

Other Methods

The following helper methods can also be found in Behavior.java. You could override them, but you probably shouldn't.

double dist2(Gridy a, Gridy b)

This method just computes the square of the distance between two objects on the Grid.

int next(int i)

Shortcut method to next.get(i)

Fields

Behavior.java provides you with the following fields. You are unlikely to use anything but r.

  • Random r -> just a means of providing randomness
  • ArrayList next -> the different indices we have
  • int branches -> the number of branches in our behavior