@@ -1,62 +1,65 @@ import dfl.all; import util; import game; -import output; import driver; -//import solver; -pragma(lib, "dfl.lib"); -class GUI : Form, GameObserver +class GUI(Solver) : Form, GameObserver { - bool on_game_changed(char c, const(Game) g, bool finished) { - draw(gr, g); - invalidate(); - return false; + this(const(Game) g) + { + this.solver = new Solver(g); + setup_size(g.map.W, g.map.H); + setup_resources(); + setup_keyhandling(); + draw(g); + } + + private void delegate(char c) fn; + void set_fn(F)(F f) { this.fn = f; } + + void run() + { + Application.run(this); } - private { - int cell; - int turn = 0; - - Font font; - Color[char] colors; - string[char] render; - void delegate(char c) fn; + override void on_game_changed(char c, const(Game) g, bool finished) + { + draw(g); } - this(const(Game) g) - { - noMessageFilter(); - this.setStyle(ControlStyles.OPAQUE, true); - this.fn = fn; +private: + int cell; - this.paint ~= &my_paint; - this.keyDown ~= &my_keydown; - + void setup_size(int W, int H) + { this.formBorderStyle = FormBorderStyle.FIXED_DIALOG; this.maximizeBox = false; this.minimizeBox = false; - this.cell = min(1024/g.map.W, 640/g.map.H); - this.clientSize = Size(g.map.W*cell, g.map.H*cell); + this.cell = min(1024/W, 640/H); + this.clientSize = Size(W*cell, H*cell); + } - const scrH = this.clientSize.height; - const scrW = this.clientSize.width; - this.gr = new MemoryGraphics(scrW, scrH); + Font font; + Color[char] colors; + string[char] render; + Graphics graphicContext; - // Resources + void setup_resources() + { + this.graphicContext = new MemoryGraphics(this.clientSize.width, this.clientSize.height); + this.setStyle(ControlStyles.OPAQUE, true); this.font = new Font("MS Gothic", cell-2, GraphicsUnit.PIXEL); this.backColor = Color(255,255,255); this.colors['#'] = this.colors['.'] = Color(255,191,127); this.colors['*'] = Color(255,127,127); this.colors['R'] = Color(128,128,0); - this.colors['D'] = Color(255,0,0); // Dead + this.colors['D'] = Color(255,0,0); this.colors['\\'] = this.colors['L'] = this.colors['O'] = Color(127,255,127); - this.colors['W'] = Color(204,229,255); // water - + this.colors['W'] = Color(204,229,255); this.render['#'] = "■"; this.render['*'] = "✹"; this.render['.'] = "♒"; this.render['\\'] = "λ"; @@ -63,35 +66,24 @@ this.render['R'] = "☃"; this.render['D'] = "☠"; this.render['L'] = "☒"; this.render['O'] = "☐"; - draw(gr, g); - } - - void set_fn(F)(F f) { this.fn = f; } - - void run() { - Application.run(this); + this.paint ~= (Control c, PaintEventArgs ev) { + graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clientSize.height)); + }; } -private: - Graphics gr; - - void my_paint(Control, PaintEventArgs ev) - { - gr.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clientSize.height)); - } - - void draw(Graphics gr, const(Game) g) + void draw(const(Game) g) { int scrW = this.clientSize.width; int scrH = this.clientSize.height; + // Fill bg. - gr.fillRectangle(this.backColor, Rect(0,0,scrW,scrH)); + graphicContext.fillRectangle(this.backColor, Rect(0,0,scrW,scrH)); // Fill water. int w = g.water_level(); - gr.fillRectangle(this.colors['W'], Rect(0, scrH-cell*w-1, scrW, cell*w+1)); + graphicContext.fillRectangle(this.colors['W'], Rect(0, scrH-cell*w-1, scrW, cell*w+1)); // Paint map. for(int y=1; y<=g.map.H; ++y) for(int x=1; x<=g.map.W; ++x) { @@ -99,13 +91,22 @@ char c = g.map[y,x]; if( c != ' ' ) { if( c == 'R' && g.dead ) c = 'D'; - gr.drawText(this.render[c], font, this.colors[c], r); + graphicContext.drawText(this.render[c], font, this.colors[c], r); } } - set_text(g); + // Update textual info. + this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", g.water_until_rise); + invalidate(); + } + +private: + void setup_keyhandling() + { + noMessageFilter(); + this.keyDown ~= &my_keydown; } void my_keydown(Control c, KeyEventArgs ev) { @@ -116,21 +117,11 @@ case Keys.LEFT: fn('L'); break; case Keys.RIGHT: fn('R'); break; case Keys.W: fn('W'); break; case Keys.A: fn('A'); break; + case Keys.G: fn(solver.single_step()); break; default: break; } } - void set_text(const(Game) g) { - this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", g.water_until_rise); - } -} - -void main(string[] args) -{ - auto d = new Driver(File(args[1])); - d.addObserver!(GuardedOutput)(); - GUI g = d.addObserver!(GUI)(); - g.set_fn(&d.command); - g.run(); + Solver solver; }