/**
* --Copyright notice--
*
* Copyright (c) School of Geography, University of Leeds.
* http://www.geog.leeds.ac.uk/
* This software is licensed under 'The Artistic License' which can be found at
* the Open Source Initiative website at...
* http://www.opensource.org/licenses/artistic-license.php
* Please note that the optional Clause 8 does not apply to this code.
*
* The Standard Version source code, and associated documentation can be found at...
* [online] http://mass.leeds.ac.uk/
*
*
* --End of Copyright notice--
*
*/
import java.util.*;
/**
* Nibbler agent demonstrates how to implement behaviour, check and alter an environment, and communicate with other agents using method calls.
* The nibbler will move around randomly, but checks that its percieved neighbourhood doesn't contain any other agents by running through all
* the agents asking where they are and checking if they fall in its percieved area. This is the root of a partial knowledge system (we only
* interact with those we have 'knowledge' of because they fall in our perceived area). Once the nibbler has found a safe spot, it checks
* whether there is any value in that location in the Environment, and nibbles it down if there is.
* Note that the spatial x, y, and neighbourhood details are inherited from 'Animal'.
* To do: Crowded nibblers with nowhere to move to will currently loop forever. Need a stopping condition adding. See "run()".
* @version 1.0
* @author Andy Evans
*/
public class Nibbler extends Animal {
/**
* Constructor. Sets a random x and y based on current world size, but
* otherwise defers to Animal.
* @param worldIn environment for the model
* @param agentsIn list of all the agents in the model
*/
public Nibbler (Environment worldIn, ArrayList agentsIn) {
super(worldIn, agentsIn);
x = (int)(Math.random() * world.getWidth());
y = (int)(Math.random() * world.getHeight());
}
/**
* Moves the nibbler from its current location to a random position one step away.
* The new location must be suitable. Then interacts with the environment.
*/
public void run () {
if (world.getDataValue(x, y) == 0) {
move();
}
interactWithEnvironment();
}
/**
* Moves the nibbler from its current location to a random position one step away.
* The new location must be in the range of the associated environment.
*/
private void move() {
do {
int x = 0;
do {
x = this.x;
double randomNumber = Math.random();
if (randomNumber < 0.33) x--;
if (randomNumber > 0.66) x++;
} while ((x < 0) || (x > world.getWidth() - 1));
this.x = x;
int y = 0;
do {
y = this.y;
double randomNumber = Math.random();
if (randomNumber < 0.33) y--;
if (randomNumber > 0.66) y++;
} while ((y < 0) || (y > world.getHeight() - 1));
this.y = y;
} while (locationSuitable(x,y) == false);
}
/**
* Checks a prospective location for suitability.
* In this case checks there are no agents within the potential percieved neighbourhood around the
* new location.
* @param x spatial x coordinate
* @param y spatial y coordinate
* @return whether the neighbourhood is suitable (i.e. doesn't contain another agent in its neighbourhood)
*/
private boolean locationSuitable(int x, int y) {
for (Agent agent: agents) {
if ((getNeighbourhood(x,y).contains(agent.getX(), agent.getY()) == true) && (agent != this)) {
return false;
}
}
return true;
}
/**
* Checks the value in the environment at the location, and 'nibbles' it down a bit
* if there is values to nibble.
*/
private void interactWithEnvironment () {
if (world.getDataValue(x, y) > 10) {
world.setDataValue(x, y, world.getDataValue(x, y) - 10);
} else {
world.setDataValue(x, y, 0);
}
}
}