File Annotation
Not logged in
6293256fec 2012-07-14        kinaba: import util;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: ////////////////////////////////////////////////////////////////////////////////
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: class Pos
6293256fec 2012-07-14        kinaba: {
6293256fec 2012-07-14        kinaba: 	public immutable int y, x;
6293256fec 2012-07-14        kinaba: 	mixin DeriveCreate;
6293256fec 2012-07-14        kinaba: 	mixin DeriveCompare;
6293256fec 2012-07-14        kinaba: 	mixin DeriveShow;
bee0596f0f 2012-07-14        kinaba: 	Pos clone() const { return new Pos(y, x); }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: @property:
bee0596f0f 2012-07-14        kinaba: 	Pos wait()  { return this.clone(); }
6293256fec 2012-07-14        kinaba: 	Pos up()    { return new Pos(y+1, x); }
6293256fec 2012-07-14        kinaba: 	Pos down()  { return new Pos(y-1, x); }
6293256fec 2012-07-14        kinaba: 	Pos left()  { return new Pos(y, x-1); }
6293256fec 2012-07-14        kinaba: 	Pos right() { return new Pos(y, x+1); }
6293256fec 2012-07-14        kinaba: 	alias wait  W,w;
6293256fec 2012-07-14        kinaba: 	alias up    U,u;
6293256fec 2012-07-14        kinaba: 	alias down  D,d;
6293256fec 2012-07-14        kinaba: 	alias left  L,l;
6293256fec 2012-07-14        kinaba: 	alias right R,r;
6293256fec 2012-07-14        kinaba: }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: unittest
6293256fec 2012-07-14        kinaba: {
6293256fec 2012-07-14        kinaba: 	assert( (new Pos(2,1)).U == new Pos(3,1) );
6293256fec 2012-07-14        kinaba: 	assert( (new Pos(0,1)).D == new Pos(-1,1) );
6293256fec 2012-07-14        kinaba: 	assert( (new Pos(2,1)).L == new Pos(2,0) );
6293256fec 2012-07-14        kinaba: 	assert( (new Pos(2,1)).R == new Pos(2,2) );
6293256fec 2012-07-14        kinaba: 	int[Pos] aa;
6293256fec 2012-07-14        kinaba: 	aa[new Pos(1,2)] = 1;
6293256fec 2012-07-14        kinaba: 	aa[new Pos(1,2)] = 2;
6293256fec 2012-07-14        kinaba: 	aa[new Pos(2,1)] = 3;
6293256fec 2012-07-14        kinaba: 	assert( aa.length==2 );
6293256fec 2012-07-14        kinaba: 	assert( aa[new Pos(1,2)]==2 );
6293256fec 2012-07-14        kinaba: }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: ////////////////////////////////////////////////////////////////////////////////
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: class Water
6293256fec 2012-07-14        kinaba: {
6293256fec 2012-07-14        kinaba: 	public immutable int base, pace;
6293256fec 2012-07-14        kinaba: 	mixin DeriveCreate;
6293256fec 2012-07-14        kinaba: 	mixin DeriveCompare;
6293256fec 2012-07-14        kinaba: 	mixin DeriveShow;
bee0596f0f 2012-07-14        kinaba: 	Water clone() const { return new Water(base, pace); }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	static load(string[string] params)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		return new Water(
6293256fec 2012-07-14        kinaba: 			params.get("Water",    "0").to!int(),
6293256fec 2012-07-14        kinaba: 			params.get("Flooding", "0").to!int()
6293256fec 2012-07-14        kinaba: 		);
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
bee0596f0f 2012-07-14        kinaba: 	int level(int number_of_update) const
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		return pace ? base+(number_of_update/pace) : base;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
bee0596f0f 2012-07-14        kinaba: 	int until_rise(int number_of_update) const
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		return pace ? pace-number_of_update%pace : int.max;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: unittest
6293256fec 2012-07-14        kinaba: {
6293256fec 2012-07-14        kinaba: 	Water w = new Water(1, 3);
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(0) );
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(1) );
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(2) );
6293256fec 2012-07-14        kinaba: 	assert( 2 == w.level(3) );
6293256fec 2012-07-14        kinaba: 	assert( 2 == w.level(4) );
6293256fec 2012-07-14        kinaba: 	assert( 2 == w.level(5) );
6293256fec 2012-07-14        kinaba: 	assert( 3 == w.level(6) );
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	w = new Water(1, 0);
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(0) );
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(1) );
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(2) );
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(3) );
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(4) );
6293256fec 2012-07-14        kinaba: 	assert( 1 == w.level(5) );
6293256fec 2012-07-14        kinaba: }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: ////////////////////////////////////////////////////////////////////////////////
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: class Map
6293256fec 2012-07-14        kinaba: {
6293256fec 2012-07-14        kinaba: 	mixin DeriveShow;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	static Map load(string[] raw_data, string[string] params)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		// TODO: choose optimal representation.
6293256fec 2012-07-14        kinaba: 		return new Map(raw_data, params);
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	char[][] data;
6293256fec 2012-07-14        kinaba: 	Pos robot;
6293256fec 2012-07-14        kinaba: 	Pos lift;
6293256fec 2012-07-14        kinaba: 	int waterproof;
6293256fec 2012-07-14        kinaba: 
bee0596f0f 2012-07-14        kinaba: 	Map clone() const { return new Map(this); }
bee0596f0f 2012-07-14        kinaba: 	this(const(Map) m) {
6293256fec 2012-07-14        kinaba: 		foreach(s; m.data)
6293256fec 2012-07-14        kinaba: 			this.data ~= s.dup;
6293256fec 2012-07-14        kinaba: 		this.robot = m.robot.clone();
6293256fec 2012-07-14        kinaba: 		this.lift = m.lift.clone();
6293256fec 2012-07-14        kinaba: 		this.waterproof = m.waterproof;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	this(string[] raw_data, string[string] params)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		int width = 0;
6293256fec 2012-07-14        kinaba: 		foreach(r; raw_data)
6293256fec 2012-07-14        kinaba: 			width = max(width, r.length);
6293256fec 2012-07-14        kinaba: 		foreach(r; raw_data) {
6293256fec 2012-07-14        kinaba: 			this.data ~= r.dup;
6293256fec 2012-07-14        kinaba: 			this.data[$-1].length = width;
6293256fec 2012-07-14        kinaba: 			this.data[$-1][r.length..$] = ' ';
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		for(int y=1; y<=H; ++y)
6293256fec 2012-07-14        kinaba: 		for(int x=1; x<=W; ++x) {
6293256fec 2012-07-14        kinaba: 			if(this[y,x] == 'R')
6293256fec 2012-07-14        kinaba: 				this.robot = new Pos(y,x);
6293256fec 2012-07-14        kinaba: 			if(this[y,x] == 'L' || this[y,x] == 'O')
6293256fec 2012-07-14        kinaba: 				this.lift = new Pos(y,x);
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		this.waterproof = params.get("Waterproof", "5").to!int();
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	const @property {
6293256fec 2012-07-14        kinaba: 		int H() { return data.length; }
6293256fec 2012-07-14        kinaba: 		int W() { return data[0].length; }
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
bee0596f0f 2012-07-14        kinaba: 	const {
bee0596f0f 2012-07-14        kinaba: 		char opIndex(int y, int x)
bee0596f0f 2012-07-14        kinaba: 		{
bee0596f0f 2012-07-14        kinaba: 			// Adjust coordinate to the spec. bottom-left is (1,1).
bee0596f0f 2012-07-14        kinaba: 			--y, --x;
bee0596f0f 2012-07-14        kinaba: 			if(y<0||H<=y||x<0||W<=x)
bee0596f0f 2012-07-14        kinaba: 				return '#';
bee0596f0f 2012-07-14        kinaba: 			return data[H-1-y][x];
bee0596f0f 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 
bee0596f0f 2012-07-14        kinaba: 		char opIndex(Pos p)
bee0596f0f 2012-07-14        kinaba: 		{
bee0596f0f 2012-07-14        kinaba: 			return this[p.y, p.x];
bee0596f0f 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	void opIndexAssign(char c, int y, int x)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		// Adjust coordinate to the spec. bottom-left is (1,1).
6293256fec 2012-07-14        kinaba: 		--y, --x;
6293256fec 2012-07-14        kinaba: 		if(y<0||H<=y||x<0||W<=x)
6293256fec 2012-07-14        kinaba: 			return;
6293256fec 2012-07-14        kinaba: 		data[H-1-y][x] = c;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	void opIndexAssign(char c, Pos p)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		this[p.y, p.x] = c;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	Pos[] lambdas() {
6293256fec 2012-07-14        kinaba: 		Pos[] ans;
6293256fec 2012-07-14        kinaba: 		for(int y=1; y<=H; ++y)
6293256fec 2012-07-14        kinaba: 		for(int x=1; x<=W; ++x)
6293256fec 2012-07-14        kinaba: 			if(this[y,x] == '\\')
6293256fec 2012-07-14        kinaba: 				ans ~= new Pos(y,x);
6293256fec 2012-07-14        kinaba: 		return ans;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	bool cleared()
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		for(int y=1; y<=H; ++y)
6293256fec 2012-07-14        kinaba: 		for(int x=1; x<=W; ++x)
6293256fec 2012-07-14        kinaba: 			if(this[y,x] == 'L' || this[y,x] == 'O')
6293256fec 2012-07-14        kinaba: 				return false;
6293256fec 2012-07-14        kinaba: 		return true;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	Tuple!(int,bool) command(char c)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		if(c=='R') return move( 0, +1);
6293256fec 2012-07-14        kinaba: 		if(c=='L') return move( 0, -1);
6293256fec 2012-07-14        kinaba: 		if(c=='U') return move(+1,  0);
6293256fec 2012-07-14        kinaba: 		if(c=='D') return move(-1,  0);
6293256fec 2012-07-14        kinaba: 		if(c=='W') return move( 0,  0);
6293256fec 2012-07-14        kinaba: 		assert(false);
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	Tuple!(int, bool) move(int dy, int dx)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		int y = robot.y;
6293256fec 2012-07-14        kinaba: 		int x = robot.x;
6293256fec 2012-07-14        kinaba: 		assert( this[robot] == 'R' );
6293256fec 2012-07-14        kinaba: 		int lambda = 0;
6293256fec 2012-07-14        kinaba: 		bool dead = false;
6293256fec 2012-07-14        kinaba: 		if( '\\' == this[y+dy,x+dx] )
6293256fec 2012-07-14        kinaba: 			lambda++;
6293256fec 2012-07-14        kinaba: 		if( " \\.O".count(this[y+dy,x+dx])==1 ) {
6293256fec 2012-07-14        kinaba: 			this[y,x]=' ';
6293256fec 2012-07-14        kinaba: 			this[y+dy,x+dx]='R';
6293256fec 2012-07-14        kinaba: 			robot = new Pos(y+dy,x+dx);
6293256fec 2012-07-14        kinaba: 		} else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx*2]) {
6293256fec 2012-07-14        kinaba: 			this[y,x]=' ';
6293256fec 2012-07-14        kinaba: 			this[y+dy,x+dx]='R';
6293256fec 2012-07-14        kinaba: 			this[y+dy*2,x+dx*2]='*';
6293256fec 2012-07-14        kinaba: 			robot = new Pos(y+dy,x+dx);
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 		if( update() )
6293256fec 2012-07-14        kinaba: 			dead = true;
6293256fec 2012-07-14        kinaba: 		return tuple(lambda,dead);
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	bool update()
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		bool dead = false;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		char[][] next;
6293256fec 2012-07-14        kinaba: 		foreach(y,s; data)
6293256fec 2012-07-14        kinaba: 			next ~= s.dup;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		ref char access(Pos p) { return next[H-p.y][p.x-1]; }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		bool lambda = false;
6293256fec 2012-07-14        kinaba: 		for(int y=1; y<=H; ++y)
6293256fec 2012-07-14        kinaba: 		for(int x=1; x<=W; ++x)
6293256fec 2012-07-14        kinaba: 			lambda |= (this[y,x] == '\\');
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		for(int y=1; y<=H; ++y)
6293256fec 2012-07-14        kinaba: 		for(int x=1; x<=W; ++x) {
6293256fec 2012-07-14        kinaba: 			Pos p = new Pos(y,x);
6293256fec 2012-07-14        kinaba: 			if(this[p]=='*') {
6293256fec 2012-07-14        kinaba: 				if(this[p.D]==' ') {
6293256fec 2012-07-14        kinaba: 					access(p)  =' ';
6293256fec 2012-07-14        kinaba: 					access(p.D)='*';
6293256fec 2012-07-14        kinaba: 					if(robot == p.D.D)
6293256fec 2012-07-14        kinaba: 						dead=true;
6293256fec 2012-07-14        kinaba: 				}
6293256fec 2012-07-14        kinaba: 				else if((this[p.D]=='*' || this[p.D]=='\\') && this[p.R]==' ' && this[p.R.D]==' ') {
6293256fec 2012-07-14        kinaba: 					access(p)=' ';
6293256fec 2012-07-14        kinaba: 					access(p.R.D)='*';
6293256fec 2012-07-14        kinaba: 					if(robot == p.R.D.D)
6293256fec 2012-07-14        kinaba: 						dead=true;
6293256fec 2012-07-14        kinaba: 				}
6293256fec 2012-07-14        kinaba: 				else if(this[p.D]=='*' && this[p.L]==' ' && this[p.L.D]==' ') {
6293256fec 2012-07-14        kinaba: 					access(p)=' ';
6293256fec 2012-07-14        kinaba: 					access(p.L.D)='*';
6293256fec 2012-07-14        kinaba: 					if(robot == p.L.D.D)
6293256fec 2012-07-14        kinaba: 						dead=true;
6293256fec 2012-07-14        kinaba: 				}
6293256fec 2012-07-14        kinaba: 			}
6293256fec 2012-07-14        kinaba: 			else if(this[p]=='L') {
6293256fec 2012-07-14        kinaba: 				if(!lambda)
6293256fec 2012-07-14        kinaba: 					access(p) = 'O';
6293256fec 2012-07-14        kinaba: 			}
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 		data = next;
6293256fec 2012-07-14        kinaba: 		return dead;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: ////////////////////////////////////////////////////////////////////////////////
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: class Game
6293256fec 2012-07-14        kinaba: {
6293256fec 2012-07-14        kinaba: 	mixin DeriveShow;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	static Game load(File input)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		string[]       raw_data;
6293256fec 2012-07-14        kinaba: 		string[string] params;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		// Raw map data; read until empty line.
6293256fec 2012-07-14        kinaba: 		for(string line; !(line=input.readln().chomp()).empty; )
6293256fec 2012-07-14        kinaba: 			raw_data ~= line;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		// Additional commands; read until EOF.
6293256fec 2012-07-14        kinaba: 		for(string line; !(line=input.readln()).empty; ) {
6293256fec 2012-07-14        kinaba: 			string[] ss = line.split();
6293256fec 2012-07-14        kinaba: 			if( ss.length == 2 )
6293256fec 2012-07-14        kinaba: 				params[ss[0]] = ss[1];
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		return load(raw_data, params);
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	static Game load(string[] raw_data, string[string] params)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		return new Game(raw_data, params);
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	this(string[] raw_data, string[string] params)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		this.map = Map.load(raw_data, params);
6293256fec 2012-07-14        kinaba: 		this.water = Water.load(params);
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
bee0596f0f 2012-07-14        kinaba: 	Game clone() const { return new Game(this); }
bee0596f0f 2012-07-14        kinaba: 	this(const(Game) g) {
6293256fec 2012-07-14        kinaba: 		map = g.map.clone();
6293256fec 2012-07-14        kinaba: 		water = g.water.clone();
6293256fec 2012-07-14        kinaba: 		turn = g.turn;
6293256fec 2012-07-14        kinaba: 		dead = g.dead;
6293256fec 2012-07-14        kinaba: 		lambda = g.lambda;
6293256fec 2012-07-14        kinaba: 		exit_bonus = g.exit_bonus;
6293256fec 2012-07-14        kinaba: 		under_water = g.under_water;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	void command(char c)
6293256fec 2012-07-14        kinaba: 	{
6293256fec 2012-07-14        kinaba: 		if(dead || cleared)
6293256fec 2012-07-14        kinaba: 			return;
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		if(c == 'A')
6293256fec 2012-07-14        kinaba: 		{
6293256fec 2012-07-14        kinaba: 			exit_bonus = 1;
6293256fec 2012-07-14        kinaba: 			return;
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 		// TODO: clarify the event order
6293256fec 2012-07-14        kinaba: 		Tuple!(int,bool) ld = map.command(c);
6293256fec 2012-07-14        kinaba: 		if( map.cleared() ) {
6293256fec 2012-07-14        kinaba: 			exit_bonus = 2;
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 		else {
6293256fec 2012-07-14        kinaba: 			lambda += ld[0];
6293256fec 2012-07-14        kinaba: 			if( ld[1] ) {
6293256fec 2012-07-14        kinaba: 				dead = true;
6293256fec 2012-07-14        kinaba: 			}
6293256fec 2012-07-14        kinaba: 		}
6293256fec 2012-07-14        kinaba: 		if( map.robot.y <= water_level )
6293256fec 2012-07-14        kinaba: 			++under_water;
6293256fec 2012-07-14        kinaba: 		else
6293256fec 2012-07-14        kinaba: 			under_water = 0;
6293256fec 2012-07-14        kinaba: 		if( under_water > map.waterproof )
6293256fec 2012-07-14        kinaba: 			dead = true;
6293256fec 2012-07-14        kinaba: 		turn += 1;
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: 	Map map;
6293256fec 2012-07-14        kinaba: 	Water water;
6293256fec 2012-07-14        kinaba: 	int  turn = 0;
6293256fec 2012-07-14        kinaba: 	bool dead = false;
6293256fec 2012-07-14        kinaba: 	int  lambda = 0;
6293256fec 2012-07-14        kinaba: 	int  exit_bonus = 0;
6293256fec 2012-07-14        kinaba: 	int  under_water = 0;
6293256fec 2012-07-14        kinaba: 	// TODO: when adding members, take care of clone().
6293256fec 2012-07-14        kinaba: 	// TODO: fix this poor design.
6293256fec 2012-07-14        kinaba: 
bee0596f0f 2012-07-14        kinaba: 	@property const {
6293256fec 2012-07-14        kinaba: 		long score() { return lambda*25L*(1+exit_bonus) - turn; }
6293256fec 2012-07-14        kinaba: 		int water_level() { return water.level(turn); }
6293256fec 2012-07-14        kinaba: 		int water_until_rise() { return water.until_rise(turn); }
6293256fec 2012-07-14        kinaba: 		bool cleared() { return exit_bonus>0; }
6293256fec 2012-07-14        kinaba: 		int hp() { return map.waterproof - under_water; }
6293256fec 2012-07-14        kinaba: 		long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus)) - turn; }
6293256fec 2012-07-14        kinaba: 	}
6293256fec 2012-07-14        kinaba: }
6293256fec 2012-07-14        kinaba: 
6293256fec 2012-07-14        kinaba: unittest
6293256fec 2012-07-14        kinaba: {
6293256fec 2012-07-14        kinaba: 	Game.load(["###","...","#RL"], ["xxx":"yyy"]);
6293256fec 2012-07-14        kinaba: }