Check-in [a5e6c99b3d]
Not logged in
Overview
SHA1 Hash:a5e6c99b3d14f4384d3d870f9797ecac4954a046
Date: 2012-07-14 17:31:35
User: kinaba
Comment:Guarded.
Timelines: family | ancestors | descendants | both | trunk
Diffs: redesign
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified game.d from [e8c7d41c69c50305] to [1928257cf62dcd18].

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 }

Modified gui.d from [2332c804152f20b9] to [1dc5dff936083189].

108 this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", 108 this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", 109 } 109 } 110 } 110 } 111 111 112 void main(string[] args) 112 void main(string[] args) 113 { 113 { 114 auto g = Game.load(File(args[1])); 114 auto g = Game.load(File(args[1])); 115 g.set_output(new StdOutput); | 115 g.set_output(new GuardedOutput(g)); 116 auto myForm = new GUI(g); 116 auto myForm = new GUI(g); 117 Application.run(myForm); 117 Application.run(myForm); 118 } 118 }

Modified output.d from [29c4bbd4331091b4] to [1b458d7cd25e92dc].

2 import game; 2 import game; 3 import core.stdc.signal; 3 import core.stdc.signal; 4 import std.c.stdlib; 4 import std.c.stdlib; 5 5 6 abstract class Output 6 abstract class Output 7 { 7 { 8 void command(char c); 8 void command(char c); > 9 void flush(); 9 } 10 } 10 11 11 class NilOutput : Output 12 class NilOutput : Output 12 { 13 { 13 override void command(char c) {} 14 override void command(char c) {} > 15 override void flush() {} 14 } 16 } 15 17 16 class StdOutput : Output 18 class StdOutput : Output 17 { 19 { > 20 override void command(char c) > 21 { > 22 write(c); > 23 stdout.flush(); > 24 } > 25 override void flush() {} > 26 } > 27 > 28 // TODO: clean it up. > 29 __gshared Output g_output; > 30 > 31 class GuardedOutput : StdOutput > 32 { 18 // Handle SIGINT: force abort and exit. 33 // Handle SIGINT: force abort and exit. 19 static this() 34 static this() 20 { 35 { 21 signal(SIGINT, &sigint); 36 signal(SIGINT, &sigint); 22 } 37 } > 38 23 extern(C) static void sigint(int) { | 39 extern(C) static void sigint(int) > 40 { > 41 if(g_output !is null) > 42 g_output.flush(); > 43 else { 24 write("A"); | 44 write("A"); 25 stdout.flush(); | 45 stdout.flush(); > 46 } 26 exit(0); 47 exit(0); 27 } 48 } 28 49 > 50 Game g; > 51 this(Game ini) { this.g = ini.clone(); ideal_log ~= g.score_if_abort_now > 52 > 53 string log; > 54 long[] score_log; > 55 long[] ideal_log; > 56 29 override void command(char c) 57 override void command(char c) 30 { 58 { 31 // TODO: optimize redundancy. < 32 write(c); | 59 g.command(c); > 60 log ~= c; > 61 score_log ~= g.score; > 62 ideal_log ~= g.score_if_abort_now; > 63 } > 64 override void flush() > 65 { > 66 Tuple!(long, int, int) cand; > 67 cand[0] = long.min; > 68 foreach(int i, long s; score_log) > 69 if(cand[0] < s) > 70 cand = tuple(s,i,0); > 71 foreach(int i, long s; ideal_log) > 72 if(cand[0] < s) > 73 cand = tuple(s,i,1); > 74 if(cand[2]==0) > 75 writeln(log[0..cand[1]+1]); > 76 else > 77 writeln(log[0..cand[1]]~"A"); 33 stdout.flush(); 78 stdout.flush(); 34 } 79 } 35 } 80 }