import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.util.ArrayList; import java.util.StringTokenizer; import java.util.TreeMap; public class Lahing2011DemoStraightOn { BufferedReader in; PrintWriter out; class Planet { public int id; public int x, y, r; public boolean isFlag; public int owner, maxControl, control; public Planet(int id, int x, int y, int r, String isFlagStr) { this.id = id; this.x = x; this.y = y; this.r = r; this.isFlag = "t".equals(isFlagStr); } } ArrayList planets = new ArrayList(); class Unit { public int id, faction, type; public int x, y; public Unit() {} } TreeMap units = new TreeMap(); public Lahing2011DemoStraightOn(BufferedReader in, PrintWriter out) { init(in, out); } private void init(BufferedReader in, PrintWriter out) { this.in = in; this.out = out; } public void send(String cmd) { this.out.println(cmd); this.out.flush(); } public StringTokenizer receive() throws IOException { return new StringTokenizer(this.in.readLine()); } public void play() throws IOException { // handshake System.err.println("err test"); send("lahing2011 DemoStraightOn"); // first response line - faction StringTokenizer response = receive(); response.nextToken(); // "ok" int faction = getInt(response); // second response line - map parseMap(receive()); System.err.println("err test map done"); // third response line - state boolean gameOver = parseState(receive()); while (!gameOver) { // send commands ai(faction); // ask from new information send("notify"); gameOver = parseState(receive()); } } private void ai(int faction) { for (Unit unit : units.values()) { // not our guy if (unit.faction != faction) continue; // find closest planet to capture/defend Planet bestPlanet = null; for (Planet planet : planets) { if (!planet.isFlag) continue; if (planet.owner == faction && planet.maxControl == planet.control) continue; // found planet to capture/defend if (dist2(unit, planet) < dist2(unit, bestPlanet)) bestPlanet = planet; } // if found planet if (null != bestPlanet) { send("move " + unit.id + " " + bestPlanet.x + " " + bestPlanet.y + ""); } } } private long dist2(Unit u, Planet p) { if (u == null || p == null) return Integer.MAX_VALUE; long dx = u.x - p.x; long dy = u.y - p.y; return dx*dx + dy*dy; } private void parseMap(StringTokenizer result) { // Example "map 12800 9600 20 planet 0 4073 3788 930 f planet 1 8726 5811 930 ..." check("map", result); // map result.nextToken(); // map width result.nextToken(); // map height int planetCnt = getInt(result); for (int i = 0; i < planetCnt; ++i) { check("planet", result); // planet int id = getInt(result); // id (equals i) int x = getInt(result); // x int y = getInt(result); // y int r = getInt(result); // r String isFlagStr = result.nextToken(); // isFlag planets.add(new Planet(id, x, y, r, isFlagStr)); } } private boolean parseState(StringTokenizer result) { // example "game_state f -1 0 factions 2 200 200 // units 20 unit 0 0 . 0 500 500 500 500 0 -1 unit ... // destroyed_units 0 // shots 0 // flags 8 flag 8 -1 -1 1000 0 flag ..." check("game_state", result); boolean gameOver = "t".equals(result.nextToken()); result.nextToken(); // winner String time = result.nextToken(); // time check("factions", result); result.nextToken(); // 2 result.nextToken(); // faction 0 HP result.nextToken(); // faction 1 HP check("units", result); units.clear(); int unitCnt = getInt(result); for (int i = 0; i < unitCnt; ++i) { Unit unit = parseUnit(result); units.put(unit.id, unit); } check("destroyed_units", result); int destoyedUnitCnt = getInt(result); for (int i = 0; i < destoyedUnitCnt; ++i) { parseUnit(result); } check("shots", result); int shotsCnt = getInt(result); for (int i = 0; i < shotsCnt; ++i) { check("shot", result); result.nextToken(); result.nextToken(); result.nextToken(); } check("flags", result); //flags 8 flag 8 -1 -1 1000 0 int flagsCnt = getInt(result); for (int i = 0; i < flagsCnt; ++i) { check("flag", result); int planetId = getInt(result); // id Planet planet = planets.get(planetId); planet.owner = getInt(result); // faction result.nextToken(); // capturing faction planet.maxControl = getInt(result); // max control planet.control = getInt(result); // control } return gameOver; } private Unit parseUnit(StringTokenizer result) { check("unit", result); Unit unit = new Unit(); unit.id = getInt(result); unit.faction = getInt(result); result.nextToken(); // subfaction unit.type = getInt(result); result.nextToken(); // max HP result.nextToken(); // HP unit.x = getInt(result); unit.y = getInt(result); result.nextToken(); // time to reload result.nextToken(); return unit; } private void check(String a, StringTokenizer st) { if (!st.hasMoreTokens()) throw new IllegalStateException("Result processed, expected '" + a + "'"); String b = st.nextToken(); if (!a.equals(b)) throw new IllegalStateException("Expected '" + a + "', got '" + b + "'"); } private int getInt(StringTokenizer st) { return Integer.parseInt(st.nextToken()); } public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out), false); Lahing2011DemoStraightOn demo = new Lahing2011DemoStraightOn(in, out); demo.play(); } }