Diff
Not logged in

Differences From Artifact [7c15481493257083]:

To Artifact [cde4121762ca0c01]:


1 1 import util; 2 -import output; 3 2 4 3 //////////////////////////////////////////////////////////////////////////////// 5 4 6 5 class Pos 7 6 { 8 7 public immutable int y, x; 9 8 mixin DeriveCreate; 10 9 mixin DeriveCompare; 11 10 mixin DeriveShow; 12 - Pos clone() { return this; } 11 + Pos clone() const { return new Pos(y, x); } 13 12 14 13 @property: 15 - Pos wait() { return this; } 14 + Pos wait() { return this.clone(); } 16 15 Pos up() { return new Pos(y+1, x); } 17 16 Pos down() { return new Pos(y-1, x); } 18 17 Pos left() { return new Pos(y, x-1); } 19 18 Pos right() { return new Pos(y, x+1); } 20 19 alias wait W,w; 21 20 alias up U,u; 22 21 alias down D,d; ................................................................................ 42 41 43 42 class Water 44 43 { 45 44 public immutable int base, pace; 46 45 mixin DeriveCreate; 47 46 mixin DeriveCompare; 48 47 mixin DeriveShow; 49 - Water clone() { return this; } 48 + Water clone() const { return new Water(base, pace); } 50 49 51 50 static load(string[string] params) 52 51 { 53 52 return new Water( 54 53 params.get("Water", "0").to!int(), 55 54 params.get("Flooding", "0").to!int() 56 55 ); 57 56 } 58 57 59 - int level(int number_of_update) 58 + int level(int number_of_update) const 60 59 { 61 60 return pace ? base+(number_of_update/pace) : base; 62 61 } 63 62 64 - int until_rise(int number_of_update) 63 + int until_rise(int number_of_update) const 65 64 { 66 65 return pace ? pace-number_of_update%pace : int.max; 67 66 } 68 67 } 69 68 70 69 unittest 71 70 { ................................................................................ 100 99 } 101 100 102 101 char[][] data; 103 102 Pos robot; 104 103 Pos lift; 105 104 int waterproof; 106 105 107 - Map clone() { return new Map(this); } 108 - this(Map m) { 106 + Map clone() const { return new Map(this); } 107 + this(const(Map) m) { 109 108 foreach(s; m.data) 110 109 this.data ~= s.dup; 111 110 this.robot = m.robot.clone(); 112 111 this.lift = m.lift.clone(); 113 112 this.waterproof = m.waterproof; 114 113 } 115 114 ................................................................................ 136 135 } 137 136 138 137 const @property { 139 138 int H() { return data.length; } 140 139 int W() { return data[0].length; } 141 140 } 142 141 143 - char opIndex(int y, int x) 144 - { 145 - // Adjust coordinate to the spec. bottom-left is (1,1). 146 - --y, --x; 147 - if(y<0||H<=y||x<0||W<=x) 148 - return '#'; 149 - return data[H-1-y][x]; 150 - } 142 + const { 143 + char opIndex(int y, int x) 144 + { 145 + // Adjust coordinate to the spec. bottom-left is (1,1). 146 + --y, --x; 147 + if(y<0||H<=y||x<0||W<=x) 148 + return '#'; 149 + return data[H-1-y][x]; 150 + } 151 151 152 - char opIndex(Pos p) 153 - { 154 - return this[p.y, p.x]; 152 + char opIndex(Pos p) 153 + { 154 + return this[p.y, p.x]; 155 + } 155 156 } 156 157 157 158 void opIndexAssign(char c, int y, int x) 158 159 { 159 160 // Adjust coordinate to the spec. bottom-left is (1,1). 160 161 --y, --x; 161 162 if(y<0||H<=y||x<0||W<=x) ................................................................................ 298 299 return new Game(raw_data, params); 299 300 } 300 301 301 302 this(string[] raw_data, string[string] params) 302 303 { 303 304 this.map = Map.load(raw_data, params); 304 305 this.water = Water.load(params); 305 - this.output = new NilOutput; 306 306 } 307 307 308 - Game clone() { return new Game(this); } 309 - this(Game g) { 308 + Game clone() const { return new Game(this); } 309 + this(const(Game) g) { 310 310 map = g.map.clone(); 311 311 water = g.water.clone(); 312 - output = new NilOutput; 313 312 turn = g.turn; 314 313 dead = g.dead; 315 314 lambda = g.lambda; 316 315 exit_bonus = g.exit_bonus; 317 316 under_water = g.under_water; 318 317 } 319 318 320 - void set_output(Output o) { this.output = (o is null ? new NilOutput : o); } 321 - 322 319 void command(char c) 323 320 { 324 321 if(dead || cleared) 325 322 return; 326 - scope(exit) { 327 - if(dead || cleared) 328 - output.flush(); 329 - } 330 - this.output.command(c); 331 323 332 324 if(c == 'A') 333 325 { 334 326 exit_bonus = 1; 335 327 return; 336 328 } 337 329 ................................................................................ 353 345 if( under_water > map.waterproof ) 354 346 dead = true; 355 347 turn += 1; 356 348 } 357 349 358 350 Map map; 359 351 Water water; 360 - Output output; 361 352 int turn = 0; 362 353 bool dead = false; 363 354 int lambda = 0; 364 355 int exit_bonus = 0; 365 356 int under_water = 0; 366 357 // TODO: when adding members, take care of clone(). 367 358 // TODO: fix this poor design. 368 359 369 - @property { 360 + @property const { 370 361 long score() { return lambda*25L*(1+exit_bonus) - turn; } 371 362 int water_level() { return water.level(turn); } 372 363 int water_until_rise() { return water.until_rise(turn); } 373 364 bool cleared() { return exit_bonus>0; } 374 365 int hp() { return map.waterproof - under_water; } 375 366 long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus)) - turn; } 376 367 } 377 368 } 378 369 379 370 unittest 380 371 { 381 372 Game.load(["###","...","#RL"], ["xxx":"yyy"]); 382 373 }