Diff
Not logged in

Differences From Artifact [e76b6b97ba56256b]:

To Artifact [508aa0ef899fe75c]:


1 1 import dfl.all; 2 2 import util; 3 3 import game; 4 -import output; 5 4 import driver; 6 -//import solver; 7 -pragma(lib, "dfl.lib"); 8 5 9 -class GUI : Form, GameObserver 6 +class GUI(Solver) : Form, GameObserver 10 7 { 11 - bool on_game_changed(char c, const(Game) g, bool finished) { 12 - draw(gr, g); 13 - invalidate(); 14 - return false; 8 + this(const(Game) g) 9 + { 10 + this.solver = new Solver(g); 11 + setup_size(g.map.W, g.map.H); 12 + setup_resources(); 13 + setup_keyhandling(); 14 + draw(g); 15 + } 16 + 17 + private void delegate(char c) fn; 18 + void set_fn(F)(F f) { this.fn = f; } 19 + 20 + void run() 21 + { 22 + Application.run(this); 15 23 } 16 24 17 - private { 18 - int cell; 19 - int turn = 0; 20 - 21 - Font font; 22 - Color[char] colors; 23 - string[char] render; 24 - void delegate(char c) fn; 25 + override void on_game_changed(char c, const(Game) g, bool finished) 26 + { 27 + draw(g); 25 28 } 26 29 27 - this(const(Game) g) 28 - { 29 - noMessageFilter(); 30 - this.setStyle(ControlStyles.OPAQUE, true); 31 - this.fn = fn; 30 +private: 31 + int cell; 32 32 33 - this.paint ~= &my_paint; 34 - this.keyDown ~= &my_keydown; 35 - 33 + void setup_size(int W, int H) 34 + { 36 35 this.formBorderStyle = FormBorderStyle.FIXED_DIALOG; 37 36 this.maximizeBox = false; 38 37 this.minimizeBox = false; 39 - this.cell = min(1024/g.map.W, 640/g.map.H); 40 - this.clientSize = Size(g.map.W*cell, g.map.H*cell); 38 + this.cell = min(1024/W, 640/H); 39 + this.clientSize = Size(W*cell, H*cell); 40 + } 41 41 42 - const scrH = this.clientSize.height; 43 - const scrW = this.clientSize.width; 44 - this.gr = new MemoryGraphics(scrW, scrH); 42 + Font font; 43 + Color[char] colors; 44 + string[char] render; 45 + Graphics graphicContext; 45 46 46 - // Resources 47 + void setup_resources() 48 + { 49 + this.graphicContext = new MemoryGraphics(this.clientSize.width, this.clientSize.height); 50 + this.setStyle(ControlStyles.OPAQUE, true); 47 51 this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL); 48 52 this.backColor = Color(255,255,255); 49 53 this.colors['#'] = 50 54 this.colors['.'] = Color(255,191,127); 51 55 this.colors['*'] = Color(255,127,127); 52 56 this.colors['R'] = Color(128,128,0); 53 - this.colors['D'] = Color(255,0,0); // Dead 57 + this.colors['D'] = Color(255,0,0); 54 58 this.colors['\\'] = 55 59 this.colors['L'] = 56 60 this.colors['O'] = Color(127,255,127); 57 - this.colors['W'] = Color(204,229,255); // water 58 - 61 + this.colors['W'] = Color(204,229,255); 59 62 this.render['#'] = "■"; 60 63 this.render['*'] = "✹"; 61 64 this.render['.'] = "♒"; 62 65 this.render['\\'] = "λ"; 63 66 this.render['R'] = "☃"; 64 67 this.render['D'] = "☠"; 65 68 this.render['L'] = "☒"; 66 69 this.render['O'] = "☐"; 67 - draw(gr, g); 68 - } 69 - 70 - void set_fn(F)(F f) { this.fn = f; } 71 - 72 - void run() { 73 - Application.run(this); 70 + this.paint ~= (Control c, PaintEventArgs ev) { 71 + graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clientSize.height)); 72 + }; 74 73 } 75 74 76 -private: 77 - Graphics gr; 78 - 79 - void my_paint(Control, PaintEventArgs ev) 80 - { 81 - gr.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clientSize.height)); 82 - } 83 - 84 - void draw(Graphics gr, const(Game) g) 75 + void draw(const(Game) g) 85 76 { 86 77 int scrW = this.clientSize.width; 87 78 int scrH = this.clientSize.height; 79 + 88 80 // Fill bg. 89 - gr.fillRectangle(this.backColor, Rect(0,0,scrW,scrH)); 81 + graphicContext.fillRectangle(this.backColor, Rect(0,0,scrW,scrH)); 90 82 91 83 // Fill water. 92 84 int w = g.water_level(); 93 - gr.fillRectangle(this.colors['W'], Rect(0, scrH-cell*w-1, scrW, cell*w+1)); 85 + graphicContext.fillRectangle(this.colors['W'], Rect(0, scrH-cell*w-1, scrW, cell*w+1)); 94 86 95 87 // Paint map. 96 88 for(int y=1; y<=g.map.H; ++y) 97 89 for(int x=1; x<=g.map.W; ++x) { 98 90 Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell); 99 91 char c = g.map[y,x]; 100 92 if( c != ' ' ) { 101 93 if( c == 'R' && g.dead ) 102 94 c = 'D'; 103 - gr.drawText(this.render[c], font, this.colors[c], r); 95 + graphicContext.drawText(this.render[c], font, this.colors[c], r); 104 96 } 105 97 } 106 98 107 - set_text(g); 99 + // Update textual info. 100 + this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", g.water_until_rise); 101 + invalidate(); 102 + } 103 + 104 +private: 105 + void setup_keyhandling() 106 + { 107 + noMessageFilter(); 108 + this.keyDown ~= &my_keydown; 108 109 } 109 110 110 111 void my_keydown(Control c, KeyEventArgs ev) 111 112 { 112 113 switch(ev.keyCode) 113 114 { 114 115 case Keys.DOWN: fn('D'); break; 115 116 case Keys.UP: fn('U'); break; 116 117 case Keys.LEFT: fn('L'); break; 117 118 case Keys.RIGHT: fn('R'); break; 118 119 case Keys.W: fn('W'); break; 119 120 case Keys.A: fn('A'); break; 121 + case Keys.G: fn(solver.single_step()); break; 120 122 default: break; 121 123 } 122 124 } 123 125 124 - void set_text(const(Game) g) { 125 - this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", g.water_until_rise); 126 - } 127 -} 128 - 129 -void main(string[] args) 130 -{ 131 - auto d = new Driver(File(args[1])); 132 - d.addObserver!(GuardedOutput)(); 133 - GUI g = d.addObserver!(GUI)(); 134 - g.set_fn(&d.command); 135 - g.run(); 126 + Solver solver; 136 127 }