Artifact e2d0d7db868c3a441b8c44729f6f0ac1eb9b6bbe
1 import util;
2 import game;
3 import driver;
4 import core.stdc.signal;
5
6 class NilOutput : GameObserver
7 {
8 this(in Game g) {}
9 override void on_game_changed(char c, in Game g, bool finished) {}
10 }
11
12 class StdOutput : GameObserver
13 {
14 this(in Game g) {}
15 override void on_game_changed(char c, in Game g, bool finished)
16 {
17 stdout.write(c);
18 stdout.flush();
19 }
20 }
21
22 class GuardedOutput : GameObserver
23 {
24 this(in Game g)
25 {
26 setup_sigint_handling();
27 score_log ~= g.score;
28 flushed = false;
29 }
30
31 override void on_game_changed(char c, in Game g, bool finished)
32 {
33 if(flushed)
34 return;
35
36 log ~= c;
37 score_log ~= g.score;
38 if(finished || log.length+1==g.W*g.H)
39 flush();
40 }
41
42 private:
43 string log;
44 long[] score_log;
45 bool flushed;
46
47 void flush()
48 {
49 if(flushed)
50 return;
51
52 Tuple!(long, int) cand;
53 cand[0] = long.min;
54
55 for(int i=0; i<score_log.length; ++i)
56 if(cand[0] < score_log[i])
57 cand = tuple(score_log[i],i);
58
59 std.c.stdio.printf("%.*sA\n", cand[1], log.ptr);
60 std.c.stdio.fflush(std.c.stdio.stdout);
61 flushed = true;
62 }
63
64 private:
65 static __gshared GuardedOutput g_output;
66
67 void setup_sigint_handling()
68 {
69 assert(g_output is null);
70 g_output = this;
71 extern(C) static void catch_sigint(int) { g_output.flush(); application_exit(); }
72 core.stdc.signal.signal(SIGINT, &catch_sigint);
73 }
74 }