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 6 class Pos 7 7 { 8 8 public immutable int y, x; 9 9 mixin DeriveCreate; 10 10 mixin DeriveCompare; 11 11 mixin DeriveShow; 12 + Pos clone() { return this; } 12 13 13 14 @property: 14 15 Pos wait() { return this; } 15 16 Pos up() { return new Pos(y+1, x); } 16 17 Pos down() { return new Pos(y-1, x); } 17 18 Pos left() { return new Pos(y, x-1); } 18 19 Pos right() { return new Pos(y, x+1); } ................................................................................ 41 42 42 43 class Water 43 44 { 44 45 public immutable int base, pace; 45 46 mixin DeriveCreate; 46 47 mixin DeriveCompare; 47 48 mixin DeriveShow; 49 + Water clone() { return this; } 48 50 49 51 static load(string[string] params) 50 52 { 51 53 return new Water( 52 54 params.get("Water", "0").to!int(), 53 55 params.get("Flooding", "0").to!int() 54 56 ); ................................................................................ 98 100 } 99 101 100 102 private { 101 103 char[][] data; 102 104 Pos robot; 103 105 Pos lift; 104 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 117 this(string[] raw_data, string[string] params) 108 118 { 109 119 int width = 0; 110 120 foreach(r; raw_data) 111 121 width = max(width, r.length); ................................................................................ 282 292 283 293 this(string[] raw_data, string[string] params) 284 294 { 285 295 this.map = Map.load(raw_data, params); 286 296 this.water = Water.load(params); 287 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 312 void set_output(Output o) { this.output = (o is null ? new NilOutput : o); } 291 313 292 314 void command(char c) 293 315 { 294 316 if(dead || cleared) 295 317 return; 318 + scope(exit) { 319 + if(dead || cleared) 320 + output.flush(); 321 + } 296 322 this.output.command(c); 297 323 298 324 if(c == 'A') 299 325 { 300 326 exit_bonus = 1; 301 327 return; 302 328 } ................................................................................ 309 335 else { 310 336 lambda += ld[0]; 311 337 if( ld[1] ) { 312 338 dead = true; 313 339 } 314 340 } 315 341 if( map.robot.y <= water_level ) 316 - ++under_warter; 342 + ++under_water; 317 343 else 318 - under_warter = 0; 319 - if( under_warter > map.waterproof ) 344 + under_water = 0; 345 + if( under_water > map.waterproof ) 320 346 dead = true; 321 347 turn += 1; 322 348 } 323 349 324 350 Map map; 325 351 Water water; 326 352 Output output; 327 - 328 353 int turn = 0; 329 354 bool dead = false; 330 355 int lambda = 0; 331 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 361 @property { 334 362 long score() { return lambda*25L*(1+exit_bonus) - turn; } 335 363 int water_level() { return water.level(turn); } 336 364 int water_until_rise() { return water.until_rise(turn); } 337 365 bool cleared() { return exit_bonus>0; } 338 - int hp() { return map.waterproof - under_warter; } 366 + int hp() { return map.waterproof - under_water; } 339 367 long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus)) - turn; } 340 368 } 341 369 } 342 370 343 371 unittest 344 372 { 345 373 Game.load(["###","...","#RL"], ["xxx":"yyy"]); 346 374 }

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

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

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

2 2 import game; 3 3 import core.stdc.signal; 4 4 import std.c.stdlib; 5 5 6 6 abstract class Output 7 7 { 8 8 void command(char c); 9 + void flush(); 9 10 } 10 11 11 12 class NilOutput : Output 12 13 { 13 14 override void command(char c) {} 15 + override void flush() {} 14 16 } 15 17 16 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 33 // Handle SIGINT: force abort and exit. 19 34 static this() 20 35 { 21 36 signal(SIGINT, &sigint); 22 37 } 23 - extern(C) static void sigint(int) { 24 - write("A"); 25 - stdout.flush(); 38 + 39 + extern(C) static void sigint(int) 40 + { 41 + if(g_output !is null) 42 + g_output.flush(); 43 + else { 44 + write("A"); 45 + stdout.flush(); 46 + } 26 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; g_output = this; } 52 + 53 + string log; 54 + long[] score_log; 55 + long[] ideal_log; 56 + 29 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 78 stdout.flush(); 34 79 } 35 80 }