Artifact Content
Not logged in

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  }