Index: src/driver.d
==================================================================
--- src/driver.d
+++ src/driver.d
@@ -8,11 +8,11 @@
 }
 
 class Driver
 {
 	this(Game g) { this.game = g; }
-	this(File game_data) { this(Game.load(game_data)); }
+	this(File game_data) { this(new Game(game_data)); }
 
 	void command(char c)
 	{
 		if( finished )
 			return;

Index: src/game.d
==================================================================
--- src/game.d
+++ src/game.d
@@ -8,11 +8,11 @@
 	mixin DeriveCreate;
 	mixin DeriveCompare;
 	mixin DeriveShow;
 	Pos clone() const { return cast(Pos) this; }
 
-@property:
+const @property:
 	Pos wait()  { return this.clone(); }
 	Pos up()    { return new Pos(y+1, x); }
 	Pos down()  { return new Pos(y-1, x); }
 	Pos left()  { return new Pos(y, x-1); }
 	Pos right() { return new Pos(y, x+1); }
@@ -43,26 +43,26 @@
 {
 	public immutable int base, pace;
 	mixin DeriveCreate;
 	mixin DeriveCompare;
 	mixin DeriveShow;
-	Water clone() const { return cast(Water)this; }
+	Water clone() const { return cast(Water) this; }
 
 	static load(string[string] params)
 	{
 		return new Water(params.get("Water",    "0").to!int(),
 		                 params.get("Flooding", "0").to!int());
 	}
 
-	int level(int number_of_update) const
+	int level(int turn) const
 	{
-		return pace ? base+(number_of_update/pace) : base;
+		return pace ? base+(turn/pace) : base;
 	}
 
-	int until_rise(int number_of_update) const
+	int until_rise(int turn) const
 	{
-		return pace ? pace-number_of_update%pace : int.max;
+		return pace ? pace-turn%pace : int.max;
 	}
 }
 
 unittest
 {
@@ -114,16 +114,10 @@
 
 class Map
 {
 	mixin DeriveShow;
 
-	static Map load(string[] raw_data, string[string] params, char[char] trampo)
-	{
-		// TODO: choose optimal representation.
-		return new Map(raw_data, params, trampo);
-	}
-
 	char[][] data;
 	Pos robot;
 	Pos lift;
 	int waterproof;
 	Pos[char] tr_target;
@@ -130,10 +124,12 @@
 	Pos[][char] tr_source;
 	const(Hige) hige;
 	int razor;
 	int collected_lambda;
 	int total_lambda;
+	bool cleared;
+	Pos[] may_update;
 
 	Map clone() const { return new Map(this); }
 	this(in Map m) {
 		foreach(s; m.data)
 			this.data ~= s.dup;
@@ -145,10 +141,11 @@
 		this.hige = m.hige.clone();
 		this.razor = m.razor;
 		this.collected_lambda = m.collected_lambda;
 		this.total_lambda = m.total_lambda;
 		this.may_update = (cast(Map)m).may_update.dup;
+		this.cleared = m.cleared;
 	}
 
 	this(string[] raw_data, string[string] params, char[char] trampo)
 	{
 		int width = 0;
@@ -236,53 +233,46 @@
 	}
 
 	Pos[] razors() const { return objects('!'); }
 	Pos[] lambdas() const { return objects('\\'); }
 
-	bool cleared() const
-	{
-		for(int y=1; y<=H; ++y)
-		for(int x=1; x<=W; ++x)
-			if(this[y,x] == 'L' || this[y,x] == 'O')
-				return false;
-		return true;
-	}
-	
-	bool command(char c, int turn)
+	bool command(char c, int turn, bool hige_day)
 	{
 		assert( this[robot] == 'R' );
-		if(c=='R') return move( 0, +1, turn);
-		if(c=='L') return move( 0, -1, turn);
-		if(c=='U') return move(+1,  0, turn);
-		if(c=='D') return move(-1,  0, turn);
-		if(c=='W') return move( 0,  0, turn);
-		if(c=='S') return use_razor(turn);
+		if(c=='R') return move( 0, +1, turn, hige_day);
+		if(c=='L') return move( 0, -1, turn, hige_day);
+		if(c=='U') return move(+1,  0, turn, hige_day);
+		if(c=='D') return move(-1,  0, turn, hige_day);
+		if(c=='W') return move( 0,  0, turn, hige_day);
+		if(c=='S') return use_razor(turn, hige_day);
 		assert(false);
 	}
 
-	bool use_razor(int turn)
+	bool use_razor(int turn, bool hige_day)
 	{
 		if(razor) {
 			razor--;
 			for(int dy=-1; dy<=+1; ++dy)
 			for(int dx=-1; dx<=+1; ++dx)
-				if(this[robot.y+dy,robot.x+dx] == 'W')
+				if(this[robot.y+dy,robot.x+dx] == 'W') {
+					emptified(new Pos(robot.y+dy,robot.x+dx));
 					this[robot.y+dy,robot.x+dx] = ' ';
+				}
 		}
 
-		return update(turn);
+		return update(turn, hige_day);
 	}
 
 	bool rocky(char c) { return c=='*' || c=='@'; }
-	Pos[] may_update;
+
 		void emptified(Pos p) {
 			for(int dy=0; dy<=+1; ++dy)
 			for(int dx=-1; dx<=+1; ++dx)
 				may_update ~= new Pos(p.y+dy, p.x+dx);
 		}
 
-	bool move(int dy, int dx, int turn)
+	bool move(int dy, int dx, int turn, bool hige_day)
 	{
 
 		emptified(robot);
 
 		int y = robot.y;
@@ -289,10 +279,12 @@
 		int x = robot.x;
 		if( '\\' == this[y+dy,x+dx] )
 			collected_lambda++;
 		if( '!' == this[y+dy,x+dx] )
 			razor++;
+		if( 'O' == this[y+dy,x+dx] )
+			cleared = true;
 		if( " \\!.O".count(this[y+dy,x+dx])==1 ) {
 			this[y,x]=' ';
 			this[y+dy,x+dx]='R';
 			robot = new Pos(y+dy,x+dx);
 		} else if(dy==0 && rocky(this[y+dy,x+dx]) && ' '==this[y+dy*2,x+dx*2]) {
@@ -309,14 +301,14 @@
 				this[p] = ' ';
 			}
 			this[tp] = 'R';
 			robot = tp;
 		}
-		return update(turn);
+		return update(turn, hige_day);
 	}
 
-	bool update(int turn)
+	bool update(int turn, bool hige_day)
 	{
 		// Write after all the updates are processed.
 		Tuple!(int,int,char)[] write_buffer;
 		void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c); }
 		void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c); }
@@ -358,18 +350,24 @@
 					writep(p.L.D, (rock=='@'&&this[p.L.D.D]!=' ' ? '\\' : rock));
 					if(robot == p.L.D.D)
 						dead=true;
 				}
 			}
-			else if(this[p]=='W') {
-				if( hige.is_growing_turn(turn) )
+		}
+
+		if( hige_day )
+		for(int y=1; y<=H; ++y)
+		for(int x=1; x<=W; ++x) {
+			Pos p = new Pos(y,x);
+			if(this[p]=='W') {
 					for(int dy=-1; dy<=+1; ++dy)
 					for(int dx=-1; dx<=+1; ++dx)
 						if(this[p.y+dy,p.x+dx] == ' ')
 							write(p.y+dy,p.x+dx,'W');
 			}
 		}
+
 		return dead;
 	}
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -376,11 +374,11 @@
 
 class Game
 {
 	mixin DeriveShow;
 
-	static Game load(File input)
+	this(File input)
 	{
 		string[]       raw_data;
 		string[string] params;
 
 		// Raw map data; read until empty line.
@@ -395,31 +393,20 @@
 				params[ss[0]] = ss[1];
 			if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="targets" )
 				trampo[ss[1][0]] = ss[3][0];
 		}
 
-		return load(raw_data, params, trampo);
-	}
-
-	static Game load(string[] raw_data, string[string] params, char[char] trampo = null)
-	{
-		return new Game(raw_data, params, trampo);
-	}
-
-	this(string[] raw_data, string[string] params, char[char] trampo)
-	{
-		this.map = Map.load(raw_data, params, trampo);
+		this.map   = new Map(raw_data, params, trampo);
 		this.water = Water.load(params);
 	}
 
 	Game clone() const { return new Game(this); }
 	this(in Game g) {
-		map = g.map.clone();
+		map   = g.map.clone();
 		water = g.water.clone();
-		turn = g.turn;
-		dead = g.dead;
-		cleared = g.cleared;
+		turn  = g.turn;
+		dead  = g.dead;
 		under_water = g.under_water;
 	}
 
 	void command(char c)
 	{
@@ -426,19 +413,14 @@
 		assert(c != 'A');
 		if(dead || cleared)
 			return;
 
 		// TODO: clarify the event order
-		bool dead_now = map.command(c, turn);
-		if( map.cleared() ) {
-			cleared = true;
-		}
-		else {
-			if( dead_now )
-				dead = true;
-		}
-		if(!cleared) {
+		bool dead_now = map.command(c, turn, map.hige.is_growing_turn(turn));
+		if( dead_now )
+			dead = true;
+		if(!map.cleared) {
 			if( map.robot.y <= water_level )
 				++under_water;
 			else
 				under_water = 0;
 			if( under_water > map.waterproof )
@@ -450,17 +432,16 @@
 	Map map;
 	Water water;
 	int  turn = 0;
 	bool dead = false;
 	int  under_water = 0;
-	bool cleared = false;
 	// TODO: when adding members, take care of clone().
 	// TODO: fix this poor design.
 
-	@property const {
-		long score() { return map.collected_lambda*(dead ? 25L : cleared ? 75L : 50L) - turn; }
-		int water_level() { return water.level(turn); }
-		int water_until_rise() { return water.until_rise(turn); }
-		int hige_until_rise() { return map.hige.until_rise(turn); }
-		int hp() { return map.waterproof - under_water; }
-	}
+@property const:
+	long score()           { return map.collected_lambda*(dead?25L:cleared?75L:50L)-turn; }
+	int water_level()      { return water.level(turn); }
+	int water_until_rise() { return water.until_rise(turn); }
+	int hige_until_rise()  { return map.hige.until_rise(turn); }
+	int hp()               { return map.waterproof - under_water; }
+	bool cleared()         { return map.cleared; }
 }