/** * --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); } } }