import util;
import game;
import output;

int g_wc = 0;

void act(Game g)
{
	Pos   ro = g.map.robot;
	Pos[] la = g.map.lambdas();
	Pos   li = g.map.lift;

	char c = 'W';
	if( la.empty ) {
		auto r = search(g, ro, li);
		c = r[0];
	} else {
		Tuple!(char,int)[] cand;
		foreach(lam; la)
			cand ~= search(g, ro, lam);
		sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){
			if(c1[1] != c2[1])
				return c1[1] < c2[1];
			return c1[0] < c2[0];
		})(cand);
		c = cand[0][0];
	}
	if(c=='W') {
		g_wc++;
		if(g_wc > 10)
			c = 'A';
	}
	else
		g_wc = 0;
	g.command(c);
}

Tuple!(char,int) search(Game g, Pos s, Pos o)
{
	Pos[] q = [o];
	bool[][] v = new bool[][](g.map.H+2, g.map.W+2);
	for(int step=1; q.length; ++step) {
		Pos[] q2;
		foreach(p; q) {
			int[] dy=[-1,+1,0,0];
			int[] dx=[0,0,-1,+1];
			for(int i=0; i<4; ++i) {
				int y = p.y+dy[i];
				int x = p.x+dx[i];
				if(v[y][x]) continue;
				if(y==s.y && x==s.x) {
					if(i==0) return tuple('U',step);
					if(i==1) return tuple('D',step);
					if(i==2) return tuple('R',step);
					if(i==3) return tuple('L',step);
				} else if(g.map[y,x]==' '||g.map[y,x]=='\\') {
					q2 ~= new Pos(y,x);
					v[y][x]=true;
				} else if(g.map[y,x]=='.' && g.map[y-1,x]!='*') {
					q2 ~= new Pos(y,x);
					v[y][x]=true;
				}
			}
		}
		q = q2;
	}
	q = [o];
	v = new bool[][](g.map.H+2, g.map.W+2);
	for(int step=1000; q.length; ++step) {
		Pos[] q2;
		foreach(p; q) {
			int[] dy=[-1,+1,0,0];
			int[] dx=[0,0,-1,+1];
			for(int i=0; i<4; ++i) {
				int y = p.y+dy[i];
				int x = p.x+dx[i];
				if(v[y][x]) continue;
				if(y==s.y && x==s.x) {
					if(i==0) return tuple('U',step);
					if(i==1) return tuple('D',step);
					if(i==2) return tuple('R',step);
					if(i==3) return tuple('L',step);
				} else if(g.map[y,x]==' '||g.map[y,x]=='\\') {
					q2 ~= new Pos(y,x);
					v[y][x]=true;
				} else if(g.map[y,x]=='.'/* && g[y-1,x]!='*'*/) {
					q2 ~= new Pos(y,x);
					v[y][x]=true;
				}
			}
		}
		q = q2;
	}
	return tuple('W', int.max);
}

void main(string[] args)
{
	auto g = Game.load(File(args[1]));
	g.set_output(new GuardedOutput(g));

	while(!g.dead && !g.cleared)
		act(g);
}
