Skip to content

Instantly share code, notes, and snippets.

@npruehs
Last active June 18, 2017 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save npruehs/e663c7be3efa27e93a8b557172475154 to your computer and use it in GitHub Desktop.
Save npruehs/e663c7be3efa27e93a8b557172475154 to your computer and use it in GitHub Desktop.
Animal AI that tries to stay alive and healthy.
public class NicksBrain extends Brain
{
// How far we're looking around for things like plants.
// Higher view range means better awareness of the environment, but also higher energy cost.
// Note that this is still capped by maxViewRange of the creature.
private static final int VIEW_RANGE = 2;
// Energy level that is considered healthy.
// If we're falling below this threshold, we'll run away and look for food.
private static final float HEALTHY_ENERGY_LEVEL = 0.8f;
// Die to roll, in order to move in random directions.
private java.util.Random random;
public void init() {
// Load image.
this.creature.setCreatureImage("kangaroo.png");
// Setup die.
this.random = new java.util.Random();
}
public String getName() {
return "Nick";
}
public void think() {
// Check current energy level.
int currentEnergy = this.creature.getEnergy();
int maxEnergy = this.creature.getMaxEnergy();
float energyLevel = (float)currentEnergy / maxEnergy;
// Examine environment.
Thing[] nearbyThings = this.creature.lookAround(VIEW_RANGE);
// Are we healty enough?
if (energyLevel > HEALTHY_ENERGY_LEVEL) {
// Yes. If there's a bear nearby and alive, attack it.
for (int i = 0; i < nearbyThings.length; ++i) {
Thing t = nearbyThings[i];
if (this.canAttack(t)) {
this.creature.attack(t);
this.creature.say("Attacked bear!");
return;
}
}
}
// If we're unhealthy, or no bear is nearby, look for food.
for (int i = 0; i < nearbyThings.length; ++i) {
Thing t = nearbyThings[i];
if (this.canEat(t)) {
// If we're at a plant, eat it.
this.creature.eat();
this.creature.say("Ate plant.");
return;
}
}
for (int i = 0; i < nearbyThings.length; ++i) {
Thing t = nearbyThings[i];
if (t.getType() == Thing.PLANT) {
// Move towards plant.
this.moveTowards(t);
this.creature.say("Moved towards nearby plant.");
return;
}
}
// There's no plant in sight, just move somewhere.
// Make a list of all nearby destinations.
java.util.ArrayList<Point> possibleDestinations = new java.util.ArrayList<Point>();
possibleDestinations.add(new Point(this.creature.getX() + 1, this.creature.getY()));
possibleDestinations.add(new Point(this.creature.getX() - 1, this.creature.getY()));
possibleDestinations.add(new Point(this.creature.getX(), this.creature.getY() + 1));
possibleDestinations.add(new Point(this.creature.getX(), this.creature.getY() - 1));
// Try each possible destination, one after another, in random order.
while (possibleDestinations.size() > 0) {
int randomDestinationIndex = random.nextInt(possibleDestinations.size());
Point randomDestination = possibleDestinations.get(randomDestinationIndex);
if (this.canMoveTowards(randomDestination.x, randomDestination.y, nearbyThings)) {
this.moveTowards(randomDestination.x, randomDestination.y);
this.creature.say("Moved in random direction.");
return;
}
possibleDestinations.remove(randomDestinationIndex);
}
// We're stuck. Pass the turn.
this.creature.say("Can't move anywhere!");
}
private boolean canEat(Thing t) {
return t.getType() == Thing.PLANT && getDistanceTo(t) == 0;
}
private boolean canAttack(Thing t) {
return t.getType() == Thing.BEAR && t.getEnergy() > 0 && getDistanceTo(t) == 1;
}
private int getDistanceTo(Thing t) {
return getDistanceTo(t.getX(), t.getY());
}
private int getDistanceTo(int otherX, int otherY) {
int thisX = this.creature.getX();
int thisY = this.creature.getY();
return Math.abs(thisX - otherX) + Math.abs(thisY - otherY);
}
private void moveTowards(Thing t) {
moveTowards(t.getX(), t.getY());
}
private void moveTowards(int destinationX, int destinationY) {
int currentX = this.creature.getX();
int currentY = this.creature.getY();
if (currentX < destinationX) {
this.creature.move(EAST);
} else if (currentX > destinationX) {
this.creature.move(WEST);
} else if (currentY < destinationY) {
this.creature.move(SOUTH);
} else if (currentY > destinationY) {
this.creature.move(NORTH);
}
}
private boolean canMoveTowards(int destinationX, int destinationY, Thing[] knownThings) {
// Check if we know any thing that might be blocking our way.
for (int i = 0; i < knownThings.length; ++i) {
Thing t = knownThings[i];
if (t.getX() == destinationX && t.getY() == destinationY && t.getType() != Thing.PLANT) {
// There's a thing at the destination, and it's not a plant. Won't move there.
return false;
}
}
return true;
}
private class Point
{
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment