Artifact 1b458d7cd25e92dc9c3c0885da832e38a4cef7cf
1 import util;
2 import game;
3 import core.stdc.signal;
4 import std.c.stdlib;
5
6 abstract class Output
7 {
8 void command(char c);
9 void flush();
10 }
11
12 class NilOutput : Output
13 {
14 override void command(char c) {}
15 override void flush() {}
16 }
17
18 class StdOutput : Output
19 {
20 override void command(char c)
21 {
22 write(c);
23 stdout.flush();
24 }
25 override void flush() {}
26 }
27
28 // TODO: clean it up.
29 __gshared Output g_output;
30
31 class GuardedOutput : StdOutput
32 {
33 // Handle SIGINT: force abort and exit.
34 static this()
35 {
36 signal(SIGINT, &sigint);
37 }
38
39 extern(C) static void sigint(int)
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; g_output = this; }
52
53 string log;
54 long[] score_log;
55 long[] ideal_log;
56
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()
65 {
66 Tuple!(long, int, int) cand;
67 cand[0] = long.min;
68 foreach(int i, long s; score_log)
69 if(cand[0] < s)
70 cand = tuple(s,i,0);
71 foreach(int i, long s; ideal_log)
72 if(cand[0] < s)
73 cand = tuple(s,i,1);
74 if(cand[2]==0)
75 writeln(log[0..cand[1]+1]);
76 else
77 writeln(log[0..cand[1]]~"A");
78 stdout.flush();
79 }
80 }