Check-in [879099f815]
Not logged in
Overview
SHA1 Hash:879099f815ae88e83e6eb88e0c16a6798e6afca8
Date: 2012-07-15 13:44:33
User: kinaba
Comment:Moved 'abort' behavior completely out of Game.
Timelines: family | ancestors | descendants | both | trunk
Diffs: redesign
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified src/game.d from [9d4255819d57ec36] to [0eb850e277f37179].

391 391 Game clone() const { return new Game(this); } 392 392 this(in Game g) { 393 393 map = g.map.clone(); 394 394 water = g.water.clone(); 395 395 turn = g.turn; 396 396 dead = g.dead; 397 397 lambda = g.lambda; 398 - exit_bonus = g.exit_bonus; 398 + cleared = g.cleared; 399 399 under_water = g.under_water; 400 400 } 401 401 402 402 void command(char c) 403 403 { 404 + assert(c != 'A'); 404 405 if(dead || cleared) 405 406 return; 406 407 407 - if(c == 'A') 408 - { 409 - exit_bonus = 1; 410 - return; 411 - } 412 - 413 408 // TODO: clarify the event order 414 409 Tuple!(int,bool) ld = map.command(c, turn); 415 410 if( map.cleared() ) { 416 - exit_bonus = 2; 411 + cleared = true; 417 412 } 418 413 else { 419 414 lambda += ld[0]; 420 - if( ld[1] ) { 415 + if( ld[1] ) 421 416 dead = true; 422 - } 423 417 } 424 418 if( map.robot.y <= water_level ) 425 419 ++under_water; 426 420 else 427 421 under_water = 0; 428 422 if( under_water > map.waterproof ) 429 423 dead = true; ................................................................................ 431 425 } 432 426 433 427 Map map; 434 428 Water water; 435 429 int turn = 0; 436 430 bool dead = false; 437 431 int lambda = 0; 438 - int exit_bonus = 0; 439 432 int under_water = 0; 433 + bool cleared = false; 440 434 // TODO: when adding members, take care of clone(). 441 435 // TODO: fix this poor design. 442 436 443 437 @property const { 444 - long score() { return lambda*25L*(1+exit_bonus) - turn; } 438 + long score() { return lambda*(dead ? 25L : cleared ? 75L : 50L) - turn; } 445 439 int water_level() { return water.level(turn); } 446 440 int water_until_rise() { return water.until_rise(turn); } 447 441 int hige_until_rise() { return map.hige.until_rise(turn); } 448 - bool cleared() { return exit_bonus>0; } 449 442 int hp() { return map.waterproof - under_water; } 450 - long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus)) - turn; } 451 443 } 452 444 }

Modified src/output.d from [62e6040714438eff] to [ef5cfcc2ac51c863].

20 20 } 21 21 22 22 class GuardedOutput : GameObserver 23 23 { 24 24 this(in Game g) 25 25 { 26 26 setup_sigint_handling(); 27 - ideal_log ~= g.score_if_abort_now; 27 + score_log ~= g.score; 28 28 flushed = false; 29 29 } 30 30 31 31 override void on_game_changed(char c, in Game g, bool finished) 32 32 { 33 33 if(flushed) 34 34 return; 35 35 36 36 log ~= c; 37 37 score_log ~= g.score; 38 - ideal_log ~= g.score_if_abort_now; 39 38 if(finished || log.length+1==g.map.W*g.map.H) 40 39 flush(); 41 40 } 42 41 43 42 private: 44 43 string log; 45 44 long[] score_log; 46 - long[] ideal_log; 47 45 bool flushed; 48 46 49 47 void flush() 50 48 { 51 - Tuple!(long, int, int) cand; 49 + Tuple!(long, int) cand; 52 50 cand[0] = long.min; 53 51 54 52 for(int i=0; i<score_log.length; ++i) 55 53 if(cand[0] < score_log[i]) 56 - cand = tuple(score_log[i],i,0); 57 - for(int i=0; i<ideal_log.length; ++i) 58 - if(cand[0] < ideal_log[i]) 59 - cand = tuple(ideal_log[i],i,1); 54 + cand = tuple(score_log[i],i); 60 55 61 - if(cand[2]==0) { 62 - string str = log[0..cand[1]+1]; 63 - std.c.stdio.printf("%.*s\n", str.length, str.ptr); 64 - } else { 65 - string str = log[0..cand[1]]; 66 - std.c.stdio.printf("%.*sA\n", str.length, str.ptr); 67 - } 56 + std.c.stdio.printf("%.*sA\n", cand[1], log.ptr); 68 57 std.c.stdio.fflush(std.c.stdio.stdout); 69 58 flushed = true; 70 59 } 71 60 72 61 private: 73 62 static __gshared GuardedOutput g_output; 74 63

Modified src/solver.d from [98744373e0968733] to [ede3d182d99f2de5].

1 1 import util; 2 2 import game; 3 3 4 4 class Solver_0 5 5 { 6 - this(const(Game) g) {} 6 + this(in Game g) {} 7 7 char single_step() { return 'W'; } 8 8 void force(char c) {} 9 9 } 10 10 11 11 class Solver_1 12 12 { 13 13 int wait_count = 0; 14 14 int choke_count = 0; 15 15 16 16 Game g; 17 - this(const(Game) g) 17 + this(in Game g) 18 18 { 19 19 this.g = g.clone(); 20 20 forbidden_cell = new bool[][](g.map.H+2, g.map.W+2); 21 21 } 22 22 23 23 char single_step() 24 24 { 25 25 Tuple!(string,int) de = death_move(g); 26 26 char c = act(g, de[0], de[1]); 27 - g.command(c); 27 + force(c); 28 28 return c; 29 29 } 30 30 31 31 void force(char c) 32 32 { 33 - g.command(c); 33 + if(c != 'A') 34 + g.command(c); 34 35 } 35 36 36 37 Tuple!(string,int) death_move(const(Game) g) 37 38 { 38 39 string death; 39 40 int choice = 0; 40 41 foreach(char c; "UDLRW") {