6293256fec 2012-07-14 kinaba: import util; 6293256fec 2012-07-14 kinaba: import game; bee0596f0f 2012-07-14 kinaba: import driver; 6293256fec 2012-07-14 kinaba: import core.stdc.signal; 6293256fec 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: class NilOutput : GameObserver 6293256fec 2012-07-14 kinaba: { a0c3529225 2012-07-14 kinaba: this(in Game g) {} a0c3529225 2012-07-14 kinaba: override void on_game_changed(char c, in Game g, bool finished) {} 6293256fec 2012-07-14 kinaba: } 6293256fec 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: class StdOutput : GameObserver 6293256fec 2012-07-14 kinaba: { a0c3529225 2012-07-14 kinaba: this(in Game g) {} a0c3529225 2012-07-14 kinaba: override void on_game_changed(char c, in Game g, bool finished) 6293256fec 2012-07-14 kinaba: { bee0596f0f 2012-07-14 kinaba: stdout.write(c); 6293256fec 2012-07-14 kinaba: stdout.flush(); 6293256fec 2012-07-14 kinaba: } 6293256fec 2012-07-14 kinaba: } bd650eb3f9 2012-07-15 kinaba: bee0596f0f 2012-07-14 kinaba: class GuardedOutput : GameObserver 6293256fec 2012-07-14 kinaba: { a0c3529225 2012-07-14 kinaba: this(in Game g) bee0596f0f 2012-07-14 kinaba: { bee0596f0f 2012-07-14 kinaba: setup_sigint_handling(); 879099f815 2012-07-15 kinaba: score_log ~= g.score; 95915ac93f 2012-07-14 kinaba: flushed = false; bee0596f0f 2012-07-14 kinaba: } bee0596f0f 2012-07-14 kinaba: a0c3529225 2012-07-14 kinaba: override void on_game_changed(char c, in Game g, bool finished) 6293256fec 2012-07-14 kinaba: { 95915ac93f 2012-07-14 kinaba: if(flushed) 95915ac93f 2012-07-14 kinaba: return; 95915ac93f 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: log ~= c; bee0596f0f 2012-07-14 kinaba: score_log ~= g.score; e02668367d 2012-07-15 kinaba: if(finished || log.length+1==g.map.W*g.map.H) bee0596f0f 2012-07-14 kinaba: flush(); 6293256fec 2012-07-14 kinaba: } 6293256fec 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: private: 6293256fec 2012-07-14 kinaba: string log; 6293256fec 2012-07-14 kinaba: long[] score_log; 95915ac93f 2012-07-14 kinaba: bool flushed; 6293256fec 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: void flush() 6293256fec 2012-07-14 kinaba: { f6c126aeeb 2012-07-15 kinaba: if(flushed) f6c126aeeb 2012-07-15 kinaba: return; f6c126aeeb 2012-07-15 kinaba: 879099f815 2012-07-15 kinaba: Tuple!(long, int) cand; 6293256fec 2012-07-14 kinaba: cand[0] = long.min; bee0596f0f 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: for(int i=0; i<score_log.length; ++i) bee0596f0f 2012-07-14 kinaba: if(cand[0] < score_log[i]) 879099f815 2012-07-15 kinaba: cand = tuple(score_log[i],i); bee0596f0f 2012-07-14 kinaba: 879099f815 2012-07-15 kinaba: std.c.stdio.printf("%.*sA\n", cand[1], log.ptr); bee0596f0f 2012-07-14 kinaba: std.c.stdio.fflush(std.c.stdio.stdout); 95915ac93f 2012-07-14 kinaba: flushed = true; bee0596f0f 2012-07-14 kinaba: } bee0596f0f 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: private: bee0596f0f 2012-07-14 kinaba: static __gshared GuardedOutput g_output; bee0596f0f 2012-07-14 kinaba: bee0596f0f 2012-07-14 kinaba: void setup_sigint_handling() bee0596f0f 2012-07-14 kinaba: { bee0596f0f 2012-07-14 kinaba: assert(g_output is null); bee0596f0f 2012-07-14 kinaba: g_output = this; bee0596f0f 2012-07-14 kinaba: extern(C) static void catch_sigint(int) { g_output.flush(); application_exit(); } bee0596f0f 2012-07-14 kinaba: core.stdc.signal.signal(SIGINT, &catch_sigint); 6293256fec 2012-07-14 kinaba: } 6293256fec 2012-07-14 kinaba: }