Differences From Artifact [e8c7d41c69c50305]:
- File
game.d
- 2012-07-14 07:58:45 - part of checkin [3e342af26c] on branch trunk - long score. (user: kinaba) [annotate]
To Artifact [1928257cf62dcd18]:
- File
game.d
- 2012-07-14 08:31:35 - part of checkin [a5e6c99b3d] on branch trunk - Guarded. (user: kinaba) [annotate]
5 5
6 class Pos 6 class Pos
7 { 7 {
8 public immutable int y, x; 8 public immutable int y, x;
9 mixin DeriveCreate; 9 mixin DeriveCreate;
10 mixin DeriveCompare; 10 mixin DeriveCompare;
11 mixin DeriveShow; 11 mixin DeriveShow;
> 12 Pos clone() { return this; }
12 13
13 @property: 14 @property:
14 Pos wait() { return this; } 15 Pos wait() { return this; }
15 Pos up() { return new Pos(y+1, x); } 16 Pos up() { return new Pos(y+1, x); }
16 Pos down() { return new Pos(y-1, x); } 17 Pos down() { return new Pos(y-1, x); }
17 Pos left() { return new Pos(y, x-1); } 18 Pos left() { return new Pos(y, x-1); }
18 Pos right() { return new Pos(y, x+1); } 19 Pos right() { return new Pos(y, x+1); }
................................................................................................................................................................................
41 42
42 class Water 43 class Water
43 { 44 {
44 public immutable int base, pace; 45 public immutable int base, pace;
45 mixin DeriveCreate; 46 mixin DeriveCreate;
46 mixin DeriveCompare; 47 mixin DeriveCompare;
47 mixin DeriveShow; 48 mixin DeriveShow;
> 49 Water clone() { return this; }
48 50
49 static load(string[string] params) 51 static load(string[string] params)
50 { 52 {
51 return new Water( 53 return new Water(
52 params.get("Water", "0").to!int(), 54 params.get("Water", "0").to!int(),
53 params.get("Flooding", "0").to!int() 55 params.get("Flooding", "0").to!int()
54 ); 56 );
................................................................................................................................................................................
98 } 100 }
99 101
100 private { 102 private {
101 char[][] data; 103 char[][] data;
102 Pos robot; 104 Pos robot;
103 Pos lift; 105 Pos lift;
104 int waterproof; 106 int waterproof;
> 107 }
> 108 Map clone() { return new Map(this); }
> 109 this(Map m) {
> 110 foreach(s; m.data)
> 111 this.data ~= s.dup;
> 112 this.robot = m.robot.clone();
> 113 this.lift = m.lift.clone();
> 114 this.waterproof = m.waterproof;
105 } 115 }
106 116
107 this(string[] raw_data, string[string] params) 117 this(string[] raw_data, string[string] params)
108 { 118 {
109 int width = 0; 119 int width = 0;
110 foreach(r; raw_data) 120 foreach(r; raw_data)
111 width = max(width, r.length); 121 width = max(width, r.length);
................................................................................................................................................................................
282 292
283 this(string[] raw_data, string[string] params) 293 this(string[] raw_data, string[string] params)
284 { 294 {
285 this.map = Map.load(raw_data, params); 295 this.map = Map.load(raw_data, params);
286 this.water = Water.load(params); 296 this.water = Water.load(params);
287 this.output = new NilOutput; 297 this.output = new NilOutput;
288 } 298 }
> 299
> 300 Game clone() { return new Game(this); }
> 301 this(Game g) {
> 302 map = g.map.clone();
> 303 water = g.water.clone();
> 304 output = new NilOutput;
> 305 turn = g.turn;
> 306 dead = g.dead;
> 307 lambda = g.lambda;
> 308 exit_bonus = g.exit_bonus;
> 309 under_water = g.under_water;
> 310 }
289 311
290 void set_output(Output o) { this.output = (o is null ? new NilOutput : o 312 void set_output(Output o) { this.output = (o is null ? new NilOutput : o
291 313
292 void command(char c) 314 void command(char c)
293 { 315 {
294 if(dead || cleared) 316 if(dead || cleared)
295 return; 317 return;
> 318 scope(exit) {
> 319 if(dead || cleared)
> 320 output.flush();
> 321 }
296 this.output.command(c); 322 this.output.command(c);
297 323
298 if(c == 'A') 324 if(c == 'A')
299 { 325 {
300 exit_bonus = 1; 326 exit_bonus = 1;
301 return; 327 return;
302 } 328 }
................................................................................................................................................................................
309 else { 335 else {
310 lambda += ld[0]; 336 lambda += ld[0];
311 if( ld[1] ) { 337 if( ld[1] ) {
312 dead = true; 338 dead = true;
313 } 339 }
314 } 340 }
315 if( map.robot.y <= water_level ) 341 if( map.robot.y <= water_level )
316 ++under_warter; | 342 ++under_water;
317 else 343 else
318 under_warter = 0; | 344 under_water = 0;
319 if( under_warter > map.waterproof ) | 345 if( under_water > map.waterproof )
320 dead = true; 346 dead = true;
321 turn += 1; 347 turn += 1;
322 } 348 }
323 349
324 Map map; 350 Map map;
325 Water water; 351 Water water;
326 Output output; 352 Output output;
327 <
328 int turn = 0; 353 int turn = 0;
329 bool dead = false; 354 bool dead = false;
330 int lambda = 0; 355 int lambda = 0;
331 int exit_bonus = 0; 356 int exit_bonus = 0;
332 int under_warter = 0; | 357 int under_water = 0;
> 358 // TODO: when adding members, take care of clone().
> 359 // TODO: fix this poor design.
> 360
333 @property { 361 @property {
334 long score() { return lambda*25L*(1+exit_bonus) - turn; } 362 long score() { return lambda*25L*(1+exit_bonus) - turn; }
335 int water_level() { return water.level(turn); } 363 int water_level() { return water.level(turn); }
336 int water_until_rise() { return water.until_rise(turn); } 364 int water_until_rise() { return water.until_rise(turn); }
337 bool cleared() { return exit_bonus>0; } 365 bool cleared() { return exit_bonus>0; }
338 int hp() { return map.waterproof - under_warter; } | 366 int hp() { return map.waterproof - under_water; }
339 long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus 367 long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus
340 } 368 }
341 } 369 }
342 370
343 unittest 371 unittest
344 { 372 {
345 Game.load(["###","...","#RL"], ["xxx":"yyy"]); 373 Game.load(["###","...","#RL"], ["xxx":"yyy"]);
346 } 374 }