Diff
Not logged in

Differences From Artifact [1b458d7cd25e92dc]:

To Artifact [2ca374354297c908]:


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