import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.Point;
/*****/
class Player
{
public int m_pid;
public Point m_pos;
public int m_bombs;
public int m_str;
public int m_speed;
public boolean m_infict;
public char m_bonuses;
public Player(int _pid, Point _pos, int _bombs, int _bombsStrength, int _speed, boolean _isInfected) {
m_pid = _pid; m_pos = _pos; m_bombs = _bombs; m_str = _bombsStrength; m_speed = _speed; m_infict = _isInfected;
}
public Player()
{}
}
/*****/
class Bomb
{
public Point m_pos;
public int m_radius;
public int m_timer;
public Bomb (Point _pos, int _damage, int _time) {
m_pos = _pos;
m_radius = _damage;
m_timer = _time;
}
}
/*****/
public class BotEnv
{
private SocketMaster m_SM;
private AlgoBrain m_AB;
private Parser m_P;
// connection parameters
private String m_host;
private int m_port;
// World's state
public char[][] m_map;
public Player[] m_enemies;
public Bomb[] m_bombs;
public int m_scale;
public int m_tick;
// Bot's state
Player m_bot;
public BotEnv(String[] _args) {
//m_host = _args[0];
//m_port = Integer.parseInt(_args[1]);
m_SM = new SocketMaster(this, "localhost", 20016);
m_P = new Parser(this);
m_AB = new AlgoBrain(this);
m_bot = new Player(-1, new Point(), 0, 0, 0, false);
}
// This function can be killed maybe if someone don't like it
public AlgoBrain getAlgoBrainInterface()
{
return m_AB;
}
public String proccessComand (String _cmd) {
m_P.parse(_cmd);
return m_AB.processTactics();
}
public static void main(String[] _args) {
new BotEnv(_args).m_SM.run();
}
}
/*****/
class SocketMaster
{
private BotEnv m_BE;
private Socket m_sock;
private Scanner m_in;
private PrintWriter m_out;
public SocketMaster (BotEnv _bptr, String _host, int _port) {
m_BE = _bptr;
try {
m_sock = new Socket(_host, _port);
m_in = new Scanner(m_sock.getInputStream());
m_out = new PrintWriter(m_sock.getOutputStream());
} catch (Exception _e) {
_e.printStackTrace();
}
}
public void run() {
m_out.println(INIT_STRING);
m_out.flush();
int idx;
boolean started = false;
String startLex = "PID";
// Here we going to get all fucking shit, from task details to input stream...
String get, cmd = "", put;
while (m_in.hasNext()) {
get = m_in.next();
if (!started) {
idx = get.indexOf(startLex);
if (idx != -1) {
cmd = get.substring(idx);
started = true;
}
}
else {
idx = get.indexOf(';');
if (idx != -1) {
cmd += get.substring(0, idx);
System.out.println(cmd);
// IMPORTANT! Here we will instantly give out solution response!!!
m_out.print(m_BE.proccessComand(cmd)+";");
m_out.flush();
cmd = get.substring(idx+1) + " ";
}
else cmd += get + " ";
}
}
}
public boolean isAvailable()
{
try {
if(m_sock.getInputStream().available()>0)
return true;
} catch (Exception _e) {
_e.printStackTrace();
}
return false;
}
final String INIT_STRING = "launch heratorz CFGSrUPQPKgtmDcKuOhgCSy#CFGwjQJiWQQUViJiymrQoGY#CFGUfimkSUQhcMgGMqlWQYs#CFGWYiZmCiYpYaYWZuBspkg#CFGAEeaubIIRkDOlIxGmyPM#CFGYLEQYicsFWmjwKmXaOmC#CFGufAMuyIOhKxKaSOxoxUN#CFGowmRWjWSWxcZiqlGeYkF#CFGUpogIViMtiOkulA@IYoZ#CFGQOwAkDwyVAZCoKTqFuyJ#CFGMSYfClQgVEaUuinytily#CFGyNQRgQmanQxKmUAXEepm;";
}
/*****/
class AlgoBrain
{
private BotEnv m_BE;
private Point m_way[];
private int m_pos = 0;//just for test
private boolean m_init = false; //just for test
public AlgoBrain(BotEnv _bptr) {
m_BE = _bptr;
m_way = new Point[20];
}
public void reInit()
{
m_init = false;
m_pos = 0;
}
public void init()
{
if (!m_init)
{
m_init = true;
m_way[0] = (Point) m_BE.m_bot.m_pos.clone();
int i = 1;
Random rand = new Random();
while(i<m_way.length)
{
// There is a dumb code here, cause we have not much time
int a = 3*Math.abs((rand.nextInt()%2));
m_way[i] =(Point) m_way[i-1].clone();
m_way[i].x = a;
m_way[i].y =Math.abs(a);
++i;
}
}
}
public String proccessWay()
{
String cmd = null;
if (m_pos < m_way.length-1)
{
++m_pos;
}
else
{
cmd = "s;";
return cmd;
}
if ((m_way[m_pos].x - m_way[m_pos-1].x)>0)
{
cmd = "r;";
}
else if ((m_way[m_pos].x - m_way[m_pos-1].x)<0)
{
cmd = "l;";
}
else if ((m_way[m_pos].y - m_way[m_pos-1].y)>0)
{
cmd = "d;";
}
else
{
cmd = "u;";
}
return cmd;
}
public String processTactics() {
/*
//Socket empty testing
SocketMaster s = m_BE.getSocketMasterInterface();
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
if(s.isAvailable())
System.out.println("Stream isn't empty");
else
System.out.println("Stream is empty");
*/
/*
switch (new Random().nextInt() % 4) {
case 0 : return "l";
case 1 : return "r";
case 2 : return "u";
case 3 : return "d";
}*/
if (!m_init) //just for test
{
return "";
}
else
{
return proccessWay();
}
}
}
/*****/
class Parser
{
private BotEnv m_BE;
public Parser(BotEnv _bptr) {
m_BE = _bptr;
}
public void parse (String _cmd) {
switch(_cmd.charAt(0)) {
case 'P': playerIdComand(_cmd); break;
case 'S': startComand(_cmd); break;
case 'T': timerTick(_cmd); break;
case 'R': roundEnd(_cmd); break;
case 'G': gameEnd(_cmd); break;
}
}
private void playerIdComand (String _cmd) {
// At this stage map is ignored
int pid = 0, idx = 3;
while (_cmd.charAt(idx) >= '0' && _cmd.charAt(idx) <= '9')
pid = pid * 10 + _cmd.charAt(idx++) - '0';
m_BE.m_bot.m_pid = pid;
}
private void startComand (String _cmd) {
int idx = _cmd.indexOf('&') + 1;
int scale = 0;
while (_cmd.charAt(idx) >= '0' && _cmd.charAt(idx) <= '9')
scale = scale * 10 + _cmd.charAt(idx++) - '0';
String[] map = _cmd.substring(idx).trim().split(" ");
int h = map.length, w = map[0].length();
m_BE.m_map = new char[h][w];
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
m_BE.m_map[i][j] = map[i].charAt(j);
m_BE.m_scale = scale;
}
private void timerTick (String _cmd) {
String[] parts = _cmd.trim().split("&");
for (int p = 0; p < parts.length; p++)
if (p == 0) parseTickTimePart(parts[p]);
else if (p == 1) parseTickSapkaPart(parts[p]);
else if (p == 2) parseTickChangesPart(parts[p]);
}
private void parseTickTimePart (String _cmd) {
m_BE.m_tick = Integer.parseInt(_cmd.substring(1));
}
private void parseTickSapkaPart (String _cmd) {
int pid;//, x = -1, y = -1, bombs = -1, strength = -1, speed = -1;
boolean inficted = false;
Player link;
String[] pl = _cmd.trim().split(",");
String[] cur;
if (m_BE.m_enemies == null) {
m_BE.m_enemies = new Player[pl.length-1];
for (int i = 0; i < pl.length-1; i++)
m_BE.m_enemies[i] = new Player();
}
int k = 0;
for (int i = 0; i < pl.length; i++) {
cur = pl[i].trim().split(" ");
pid = Integer.parseInt(cur[0].substring(1));
link = (pid == m_BE.m_bot.m_pid) ? m_BE.m_bot : m_BE.m_enemies[k++];
if (cur.length == 2) link.m_pos = null;
else {
link.m_pos = new Point(Integer.parseInt(cur[1]), Integer.parseInt(cur[2]));
link.m_bombs = Integer.parseInt(cur[3]);
link.m_str = Integer.parseInt(cur[4]);
link.m_speed = Integer.parseInt(cur[5]);
link.m_infict = cur.length == 7;
}
}
m_BE.getAlgoBrainInterface().init(); // just for tests
}
private void parseTickChangesPart (String _cmd) {
if (_cmd.length() == 0) return;
String[] chp = _cmd.split(",");
String[] cur;
boolean add = false;
char type;
for (int i = 0; i < chp.length; i++) {
cur = chp[i].trim().split(" ");
for (int j = 0; j < cur.length; j++) {
add = cur[0].charAt(0) == '+';
type = cur[0].charAt(1);
switch (type) {
// Bomb
case '*':
{
} break;
// Explode
case '#':
{
} break;
// Destructable wall
case 'w':
{
} break;
// Indestructable wall
case 'X':
{
} break;
// Bonuses
default:
{
} break;
}
}
}
}
private void roundEnd(String _cmd) {
m_BE.m_enemies = null;
m_BE.m_bombs = null;
m_BE.m_tick = -1;
m_BE.getAlgoBrainInterface().reInit();
}
private void gameEnd(String _cmd) {
// Nothing to do...
}
}