Artifact Content
Not logged in

Artifact 93d9f5f261f71d2ccd378244793b281c8fc4d8de


     1  import dfl.all;
     2  import util;
     3  import game;
     4  import driver;
     5  
     6  class GUI(Solver) : Form, GameObserver
     7  {
     8  	this(in Game g)
     9  	{
    10  		this.solver = new Solver(g);
    11  		setup_size(g.map.W, g.map.H);
    12  		setup_resources(g);
    13  		draw(g);
    14  	}
    15  
    16  	void run(void delegate(char c) command, bool automate = true)
    17  	{
    18  		if(automate) {
    19  			Timer t = new Timer;
    20  			t.interval = 50;
    21  			t.tick ~= (Timer s, EventArgs e){command(solver.single_step());};
    22  			t.start();
    23  			this.closing ~= (Form f,CancelEventArgs c){t.stop();};
    24  		} else {
    25  			setup_keyhandling(command);
    26  		}
    27  		Application.run(this);
    28  	}
    29  
    30  	override void on_game_changed(char c, in Game g, bool finished)
    31  	{
    32  		draw(g);
    33  	}
    34  
    35  private:
    36  	void setup_size(int W, int H)
    37  	{
    38  		this.formBorderStyle = FormBorderStyle.FIXED_DIALOG;
    39  		this.maximizeBox = false;
    40  		this.minimizeBox = false;
    41  		this.cell = min(1024/W, 640/H);
    42  		this.clientSize = Size(W*cell, H*cell);
    43  	}
    44  
    45  	int          cell;
    46  	Font         font;
    47  	Color[char]  colors;
    48  	string[char] render;
    49  	Graphics     graphicContext;
    50  
    51  	void setup_resources(in Game g)
    52  	{
    53  		this.graphicContext = new MemoryGraphics(this.clientSize.width, this.clientSize.height);
    54  		this.setStyle(ControlStyles.OPAQUE, true);
    55  		this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL);
    56  		this.backColor = Color(255,255,255);
    57  		this.colors['#'] =
    58  		this.colors['.'] = Color(255,191,127);
    59  		this.colors['*'] =
    60  		this.colors['@'] = Color(255,127,127);
    61  		this.colors['R'] = Color(128,128,0);
    62  		this.colors['r'] = Color(100,128,255);
    63  		this.colors['d'] = Color(255,0,0);
    64  		this.colors['\\'] =
    65  		this.colors['L'] =
    66  		this.colors['O'] = Color(127,255,127);
    67  		this.colors['w'] = Color(204,229,255);
    68  		this.colors['W'] =
    69  		this.colors['!'] = Color(159,159,159);
    70  		foreach(char c; 'A'..'J') this.colors[c] = Color(142,142,255);
    71  		foreach(char c; '1'..':') this.colors[c] = Color(255,142,255);
    72  		this.render['#'] = "■";
    73  		this.render['*'] = "✹";
    74  		this.render['@'] = "❁";
    75  		this.render['.'] = "♒";
    76  		this.render['\\'] = "λ";
    77  		this.render['R'] = "☃";
    78  		this.render['r'] = "☃";
    79  		this.render['d'] = "☠";
    80  		this.render['L'] = "☒";
    81  		this.render['O'] = "☐";
    82  		this.render['W'] = "ꔣ";
    83  		this.render['!'] = "✄";
    84  		foreach(char c; g.tr.source_list)
    85  			this.render[c] = [cast(dchar)('☢'+g.tr.target_of(c)-'1')].to!string();
    86  		foreach(char c; g.tr.target_list)
    87  			this.render[c] = [cast(dchar)('☢'+c-'1')].to!string();
    88  		this.paint ~= (Control c, PaintEventArgs ev) {
    89  			graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clientSize.height));
    90  		};
    91  	}
    92  
    93  	void draw(in Game g)
    94  	{
    95  		int scrW = this.clientSize.width;
    96  		int scrH = this.clientSize.height;
    97  
    98  		// Fill bg.
    99  		graphicContext.fillRectangle(this.backColor, Rect(0,0,scrW,scrH));
   100  
   101  		// Fill water.
   102  		int w = g.water_level();
   103  		graphicContext.fillRectangle(this.colors['w'], Rect(0, scrH-cell*w-1, scrW, cell*w+1));
   104  
   105  		// Paint map.
   106  		for(int y=1; y<=g.map.H; ++y)
   107  		for(int x=1; x<=g.map.W; ++x) {
   108  			Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell);
   109  			char c = g.map[y,x];
   110  			if( c != ' ' ) {
   111  				if( c == 'R' )
   112  					c = (g.dead ? 'd' : g.cleared ? 'r' : 'R');
   113  				graphicContext.drawText(this.render[c], font, this.colors[c], r);
   114  			}
   115  		}
   116  
   117  		// Update textual info.
   118  		this.text = .text(
   119  			"Score: ", g.score,
   120  			" Air: ", g.hp,
   121  			" Tide: ", g.water_until_rise,
   122  			" Wadler: ", g.hige_until_rise,
   123  			" Razor: ", g.map.razor);
   124  		invalidate();
   125  	}
   126  
   127  private:
   128  	void setup_keyhandling(void delegate(char c) command)
   129  	{
   130  		noMessageFilter();
   131  		this.keyDown ~= (Control c, KeyEventArgs ev) {
   132  			void do_manual_command(char c)
   133  			{
   134  				solver.force(c);
   135  				command(c);
   136  			}
   137  			switch(ev.keyCode)
   138  			{
   139  			case Keys.DOWN:  do_manual_command('D'); break;
   140  			case Keys.UP:    do_manual_command('U'); break;
   141  			case Keys.LEFT:  do_manual_command('L'); break;
   142  			case Keys.RIGHT: do_manual_command('R'); break;
   143  			case Keys.W:     do_manual_command('W'); break;
   144  			case Keys.S:     do_manual_command('S'); break;
   145  			case Keys.A:     do_manual_command('A'); break;
   146  			case Keys.G:     command(solver.single_step()); break;
   147  			default:         break;
   148  			}
   149  		};
   150  	}
   151  
   152  	Solver solver;
   153  }