Artifact Content
Not logged in

Artifact ac9f211f019469de79f969d129feae5c68ea1c68


     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() nothrow
    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) nothrow @system static void catch_sigint(int) { g_output.flush(); application_exit(); }
    85  		core.stdc.signal.signal(SIGINT, &catch_sigint);
    86  	}
    87  }