Artifact Content
Not logged in

Artifact 53cab87f74c4871d195ed8142c9a5eb3f8354083


import std.algorithm;
import std.array;
import std.conv;
import std.stdio;
import std.string;

class Map
{
	private char[][] data;

	this(File input)
	{
		foreach(s; input.byLine())
			data ~= s.chomp.dup;

		int width = 0;
		foreach(s; data)
			width = max(width, s.length);

		// space padding and sentinels
		foreach(ref s; data) {
			int p = s.length;
			s.length = width;
			s[p..$] = ' ';
			s = '#' ~ s ~ '#';
		}

		// vertical sentinel
		char[] sen = new char[width+2];
		sen[] = '#';
		data = sen.dup ~ data ~ sen;
	}

	@property const
	{
		int W() { return data[0].length; }
		int H() { return data.length; }
		string toString() {
			string result;
			foreach(i,s; data) {
				if(i) result ~= '\n';
				result ~= s.idup;
			}
			return result;
		}
	}

	void command_R() { move(0, +1); }
	void command_L() { move(0, -1); }
	void command_U() { move(-1, 0); }
	void command_D() { move(+1, 0); }
	void wait() { update(); }

	void move(int dy, int dx) {
		foreach(y,s; data)
		foreach(x,c; s)
			if(c == 'R')
				return move(dy, dx, y, x);
	}

	void move(int dy, int dx, int y, int x) {
		if(data[y+dy][x+dx]==' ' || data[y+dy][x+dx]=='.'
		   || data[y+dy][x+dx]=='\\' || data[y+dy][x+dx]=='O') {
			data[y][x]=' ';
			data[y+dy][x+dx]='R';
		} else if(dy==0 && data[y+dy][x+dx]=='*' && data[y+2*dy][x+2*dx]==' ') {
			data[y][x]=' ';
			data[y+dy][x+dx]='R';
			data[y+2*dy][x+2*dx]='*';
		}
		update();
	}

	void update() {
		char[][] next;
		foreach(y,s; data)
			next ~= s.dup;

		bool lambda = false;
		for(int y=1; y+1<H; ++y)
		for(int x=1; x+1<W; ++x)
			lambda |= (data[y][x] == '\\');

		for(int y=1; y+1<H; ++y)
		for(int x=1; x+1<W; ++x) {
			if(data[y][x]=='*') {
				if(data[y+1][x]==' ') {
					next[y][x]=' ';
					next[y+1][x]='*';
				}
				else if(data[y+1][x]=='*' && data[y][x+1]==' ' && data[y+1][x+1]==' ') {
					next[y][x]=' ';
					next[y+1][x+1]='*';
				}
				else if(data[y+1][x]=='*' && data[y][x-1]==' ' && data[y+1][x-1]==' ') {
					next[y][x]=' ';
					next[y+1][x-1]='*';
				}
				else if(data[y+1][x]=='\\' && data[y][x+1]==' ' && data[y+1][x+1]==' ') {
					next[y][x]=' ';
					next[y+1][x+1]='*';
				}
			}
			else if(data[y][x]=='L') {
				if(!lambda)
					next[y][x] = 'O';
			}
		}
		data = next;
	}
}

void main(string[] args)
{
	Map m = new Map(File(args[1]));
	for(;;) {
		writeln(m);
		write("> ");
		string s = readln();
		if(s.length == 0)
			break;
		s = s.chomp().toUpper();
		if(s=="R")m.command_R();
		if(s=="L")m.command_L();
		if(s=="U")m.command_U();
		if(s=="D")m.command_D();
		if(s=="W")m.wait();
	}

}