@@ -1,6 +1,5 @@ import util; -import output; //////////////////////////////////////////////////////////////////////////////// class Pos @@ -8,12 +7,12 @@ public immutable int y, x; mixin DeriveCreate; mixin DeriveCompare; mixin DeriveShow; - Pos clone() { return this; } + Pos clone() const { return new Pos(y, x); } @property: - Pos wait() { return this; } + 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); } @@ -45,9 +44,9 @@ public immutable int base, pace; mixin DeriveCreate; mixin DeriveCompare; mixin DeriveShow; - Water clone() { return this; } + Water clone() const { return new Water(base, pace); } static load(string[string] params) { return new Water( @@ -55,14 +54,14 @@ params.get("Flooding", "0").to!int() ); } - int level(int number_of_update) + int level(int number_of_update) const { return pace ? base+(number_of_update/pace) : base; } - int until_rise(int number_of_update) + int until_rise(int number_of_update) const { return pace ? pace-number_of_update%pace : int.max; } } @@ -103,10 +102,10 @@ Pos robot; Pos lift; int waterproof; - Map clone() { return new Map(this); } - this(Map m) { + Map clone() const { return new Map(this); } + this(const(Map) m) { foreach(s; m.data) this.data ~= s.dup; this.robot = m.robot.clone(); this.lift = m.lift.clone(); @@ -139,20 +138,22 @@ int H() { return data.length; } int W() { return data[0].length; } } - char opIndex(int y, int x) - { - // Adjust coordinate to the spec. bottom-left is (1,1). - --y, --x; - if(y<0||H<=y||x<0||W<=x) - return '#'; - return data[H-1-y][x]; - } + const { + char opIndex(int y, int x) + { + // Adjust coordinate to the spec. bottom-left is (1,1). + --y, --x; + if(y<0||H<=y||x<0||W<=x) + return '#'; + return data[H-1-y][x]; + } - char opIndex(Pos p) - { - return this[p.y, p.x]; + char opIndex(Pos p) + { + return this[p.y, p.x]; + } } void opIndexAssign(char c, int y, int x) { @@ -301,34 +302,25 @@ this(string[] raw_data, string[string] params) { this.map = Map.load(raw_data, params); this.water = Water.load(params); - this.output = new NilOutput; } - Game clone() { return new Game(this); } - this(Game g) { + Game clone() const { return new Game(this); } + this(const(Game) g) { map = g.map.clone(); water = g.water.clone(); - output = new NilOutput; turn = g.turn; dead = g.dead; lambda = g.lambda; exit_bonus = g.exit_bonus; under_water = g.under_water; } - void set_output(Output o) { this.output = (o is null ? new NilOutput : o); } - void command(char c) { if(dead || cleared) return; - scope(exit) { - if(dead || cleared) - output.flush(); - } - this.output.command(c); if(c == 'A') { exit_bonus = 1; @@ -356,9 +348,8 @@ } Map map; Water water; - Output output; int turn = 0; bool dead = false; int lambda = 0; int exit_bonus = 0; @@ -365,9 +356,9 @@ int under_water = 0; // TODO: when adding members, take care of clone(). // TODO: fix this poor design. - @property { + @property const { long score() { return lambda*25L*(1+exit_bonus) - turn; } int water_level() { return water.level(turn); } int water_until_rise() { return water.until_rise(turn); } bool cleared() { return exit_bonus>0; }