Artifact 2ca374354297c9082c56e3be890db4ac5a1d3c0c
import util;
import game;
import driver;
import std.c.stdlib;
import core.stdc.signal;
class NilOutput : GameObserver
{
this(const(Game) g) {}
override bool on_game_changed(char c, const(Game) g, bool finished) {return false;}
}
class StdOutput : GameObserver
{
this(const(Game) g) {}
override bool on_game_changed(char c, const(Game) g, bool finished)
{
stdout.write(c);
stdout.flush();
return false;
}
}
class GuardedOutput : GameObserver
{
this(const(Game) g)
{
setup_sigint_handling();
ideal_log ~= g.score_if_abort_now;
}
override bool on_game_changed(char c, const(Game) g, bool finished)
{
log ~= c;
score_log ~= g.score;
ideal_log ~= g.score_if_abort_now;
if(finished)
flush();
return false;
}
private:
string log;
long[] score_log;
long[] ideal_log;
void flush()
{
Tuple!(long, int, int) cand;
cand[0] = long.min;
for(int i=0; i<score_log.length; ++i)
if(cand[0] < score_log[i])
cand = tuple(score_log[i],i,0);
for(int i=0; i<ideal_log.length; ++i)
if(cand[0] < ideal_log[i])
cand = tuple(ideal_log[i],i,1);
if(cand[2]==0) {
string str = log[0..cand[1]+1];
std.c.stdio.printf("%.*s\n", str.length, str.ptr);
} else {
string str = log[0..cand[1]];
std.c.stdio.printf("%.*sA\n", str.length, str.ptr);
}
std.c.stdio.fflush(std.c.stdio.stdout);
}
private:
static __gshared GuardedOutput g_output;
void setup_sigint_handling()
{
assert(g_output is null);
g_output = this;
extern(C) static void catch_sigint(int) { g_output.flush(); application_exit(); }
core.stdc.signal.signal(SIGINT, &catch_sigint);
}
}