Artifact bdd3d4d83c822b4b79fe52f622a7d217d81178cf
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.map.W*g.map.H)
39 flush();
40 if(log.length+1==g.map.W*g.map.H)
41 application_exit();
42 }
43
44 void safety_data(string s_log, long[] s_score_log) {
45 this.s_log = s_log;
46 this.s_score_log = s_score_log;
47 }
48
49 private:
50 string log;
51 long[] score_log;
52 bool flushed;
53
54 string s_log;
55 long[] s_score_log;
56
57 void flush()
58 {
59 if(flushed)
60 return;
61
62 Tuple!(long, int, immutable(char)*) cand;
63 cand[0] = long.min;
64
65 for(int i=0; i<score_log.length; ++i)
66 if(cand[0] < score_log[i])
67 cand = tuple(score_log[i],i,log.ptr);
68 for(int i=0; i<s_score_log.length; ++i)
69 if(cand[0] < s_score_log[i])
70 cand = tuple(s_score_log[i],i,s_log.ptr);
71
72 std.c.stdio.printf("%.*sA\n", cand[1], cand[2]);
73 std.c.stdio.fflush(std.c.stdio.stdout);
74 flushed = true;
75 }
76
77 private:
78 static __gshared GuardedOutput g_output;
79
80 void setup_sigint_handling()
81 {
82 assert(g_output is null);
83 g_output = this;
84 extern(C) static void catch_sigint(int) { g_output.flush(); application_exit(); }
85 core.stdc.signal.signal(SIGINT, &catch_sigint);
86 }
87 }