Artifact Content
Not logged in

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);
	}
}