Skip to content

Instantly share code, notes, and snippets.

@apsillers
Last active August 29, 2015 14:03
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 apsillers/bbe1a22ba62fd059400f to your computer and use it in GitHub Desktop.
Save apsillers/bbe1a22ba62fd059400f to your computer and use it in GitHub Desktop.
Java BftPD sample cell
/*
Sample code for a "Battle for the Petri Dish" cell
Released under the terms of the WTF Public License
No warranty express or implied is granted, etc, etc.
I just hacked this together very quickly; improvements are welcome, so please fork the Gist if you like.
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
public class CellTemplate {
public static final int MAX_HP = 5;
public static final int MAX_ENERGY = 5;
public static final int ACIDITY = 2;
// given arena state and cell stats, return an action string (e.g., "ATTACK NW 2", "DIVIDE S")
public static String decide(Arena arena, Point cell, int hp, int energy) {
// empty and corpses are free for movement and division
ArrayList<Point> nearbyEmpty = arena.getAdjacentMatches(cell, ".");
nearbyEmpty.addAll(arena.getAdjacentMatches(cell, "c"));
ArrayList<Point> nearbyEnemies = arena.getAdjacentMatches(cell, "x");
ArrayList<Point> nearbyCorpses = arena.getAdjacentMatches(cell, "c");
ArrayList<Point> nearbyFriends = arena.getAdjacentMatches(cell, "o");
// if you have energy and space to divide, divide into a random space
if(energy >= 5 && nearbyEmpty.size() > 0) {
Point randomEmpty = nearbyEmpty.get((int)Math.floor(nearbyEmpty.size()*Math.random()));
return "DIVIDE " + arena.getDirection(cell, randomEmpty);
}
// if you have two or more nearby enemies, explode if possible
if(nearbyEnemies.size() > 1 && energy > hp && hp <= 3) {
return "EXPLODE";
}
// if at least one adjacent enemy, attack if possible
if(energy > 0 && nearbyEnemies.size() > 0) {
int attackStrength = Math.min(energy, 3);
Point enemy = nearbyEnemies.get((int)Math.floor(nearbyEnemies.size()*Math.random()));
return "ATTACK " + arena.getDirection(cell, enemy) + " " + attackStrength;
}
// if there's a nearby corpse, eat it if your energy is below max
if(nearbyCorpses.size() > 0) {
Point corpse = nearbyCorpses.get((int)Math.floor(nearbyCorpses.size()*Math.random()));
return "EAT " + arena.getDirection(cell, corpse);
}
return "REST";
}
public static void main(String[] args) throws IOException {
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String firstLine;
firstLine = br.readLine();
if(firstLine.equals("BEGIN")) {
System.out.println(MAX_HP + " " + MAX_ENERGY + " " + ACIDITY);
} else {
String[] dimensions = firstLine.split(" ");
int width = Integer.parseInt(dimensions[0]);
int height = Integer.parseInt(dimensions[1]);
Point[][] arena = new Point[height][];
String input;
int lineno = 0;
while(!(input=br.readLine()).equals("")) {
String[] charList = input.substring(1).split("");
arena[lineno] = new Point[width];
for(int i=0; i<charList.length; ++i) {
arena[lineno][i] = new Point(i, lineno, charList[i]);
}
lineno++;
}
String[] stats = br.readLine().split(" ");
int x = Integer.parseInt(stats[0]);
int y = Integer.parseInt(stats[1]);
int hp = Integer.parseInt(stats[2]);
int energy = Integer.parseInt(stats[3]);
Arena arenaObj = new Arena(arena, width, height);
System.out.print(decide(arenaObj, arenaObj.get(x,y), hp, energy));
}
}
public static class Arena {
public Point[][] array;
public HashMap<String, String> c2d;
public int height;
public int width;
public Arena(Point[][] array, int width, int height) {
this.array = array;
this.width = width;
this.height = height;
this.c2d = new HashMap<String, String>();
this.c2d.put("0,0", "-");
this.c2d.put("0,-1", "N");
this.c2d.put("0,1", "S");
this.c2d.put("1,0", "E");
this.c2d.put("-1,0", "W");
this.c2d.put("-1,-1", "NW");
this.c2d.put("1,-1", "NE");
this.c2d.put("-1,1", "SW");
this.c2d.put("1,1", "SE");
}
// get the character at x,y
// or return empty string if out of bounds
public Point get(int x, int y) {
if(y < 0 || y >= this.array.length){
return null;
}
Point[] row = this.array[y];
if(x < 0 || x >= row.length) {
return null;
}
return row[x];
}
// get arraylist of Points for each adjacent space that matches the target string
public ArrayList<Point> getAdjacentMatches(Point p, String match) {
ArrayList<Point> result = new ArrayList<Point>();
for(int i=-1; i<=1; ++i) {
for(int j=-1; j<=1; ++j) {
Point found = this.get(p.x+i, p.y+j);
if((i!=0 || j!=0) && found != null && found.symbol.equals(match)) {
result.add(found);
}
}
}
return result;
}
// get the direction string from point 1 to point 2
public String getDirection(Point p1, Point p2) {
int dx = p2.x - p1.x;
int dy = p2.y - p1.y;
dx = Math.abs(dx) / (dx==0?1:dx);
dy = Math.abs(dy) / (dy==0?1:dy);
return this.c2d.get(dx + "," + dy);
}
}
public static class Point {
int x, y;
String symbol;
public Point(int x, int y, String sym) {
this.x=x;
this.y=y;
this.symbol=sym;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment