// Kestrel in a swarm // // Author Matthew Caryl // Created 14.12.96 // // Although under copywrite to the author (Matthew Caryl) this code can be copied and modified for non-commercial // purposes as long as any derivatives contain this condition. package Swarm; import java.awt.Rectangle; final class Kestrel extends Bot { // // Private interface // // global kestrel data polar coordinates private static final int radius = 10; private static final int collision_radius = radius + 1; private static final float forwardSpeed = 4; private static final float angularSpeed = PI / 320f; private static final float[] aBodyOutline = {0f, 2.36f, 3.93f, 0f}; private static final float[] rBodyOutline = {radius, radius, radius, radius}; // individual kestrel data private int wait = 0; private static final int DIGESTION_TIME = 50; // // public interface of kestrel to World object // // retrieve outlines of kestrel components public int[][][] outline() { outline[0][0][0] = (int) (x + radius * Math.sin(heading + 0f)); outline[0][1][0] = (int) (y - radius * Math.cos(heading + 0f)); outline[0][0][1] = (int) (x + radius * Math.sin(heading + 2.36f)); outline[0][1][1] = (int) (y - radius * Math.cos(heading + 2.36f)); outline[0][0][2] = (int) (x + radius * Math.sin(heading + 3.93f)); outline[0][1][2] = (int) (y - radius * Math.cos(heading + 3.93f)); outline[0][0][3] = outline[0][0][0]; outline[0][1][3] = outline[0][1][0]; return outline; } // retrieve bounding rectangle of kestrel components public Rectangle bounds() { bounds.reshape((int) (x - radius), (int) (y - radius), (int) (2 * radius), (int) (2 * radius)); return bounds; } // retrieve the maximum radius of the kestrel public int radius() { return collision_radius; } // initialise kestrel public Kestrel(World W, int X, int Y) { world = W; x = X; y = Y; heading = (float) world.random().range(360) / (float) 180 * PI; color = randomColor(); } // single move public void action() { remember(); // store current location in case of collision if (neighbours[0] instanceof Sparrow) { // eat sparrows if hungrey and close enough if (wait == 0 && separation(neighbours[0]) < sqr(collision_radius + neighbours[0].radius())) { ((Sparrow) neighbours[0]).kill(); wait = DIGESTION_TIME; } // otherwise fly towards closest else { float sp = angle(neighbours[0].x(), neighbours[0].y()); heading -= angularSpeed * sp / QUARTERPI; } } // appetite increases if (wait > 0) wait--; // move forward x += Math.sin(heading) * forwardSpeed; y -= Math.cos(heading) * forwardSpeed; normalise(); // restrict heading to [0, 360] } }