Check-in [9d4aca73fa]
Not logged in
Overview
SHA1 Hash:9d4aca73facc4e591f8be31b2522a4c6b5985819
Date: 2012-07-14 21:29:17
User: kinaba
Comment:GUI+Solver revived.
Timelines: family | ancestors | descendants | both | trunk
Diffs: redesign
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Added src/cui_auto_main.d version [25b34c42eebd93c9]

> 1 import util; > 2 import game; > 3 import output; > 4 import driver; > 5 import solver; > 6 > 7 void main(string[] args) > 8 { > 9 Driver d = new Driver(stdin); > 10 d.addObserver!(GuardedOutput)(); > 11 Solver s = d.addObserver!(Solver)(); > 12 s.run(&d.command); > 13 }

Modified src/game.d from [cde4121762ca0c01] to [545a22e98c8c86c7].

165 } 165 } 166 166 167 void opIndexAssign(char c, Pos p) 167 void opIndexAssign(char c, Pos p) 168 { 168 { 169 this[p.y, p.x] = c; 169 this[p.y, p.x] = c; 170 } 170 } 171 171 172 Pos[] lambdas() { | 172 Pos[] lambdas() const { 173 Pos[] ans; 173 Pos[] ans; 174 for(int y=1; y<=H; ++y) 174 for(int y=1; y<=H; ++y) 175 for(int x=1; x<=W; ++x) 175 for(int x=1; x<=W; ++x) 176 if(this[y,x] == '\\') 176 if(this[y,x] == '\\') 177 ans ~= new Pos(y,x); 177 ans ~= new Pos(y,x); 178 return ans; 178 return ans; 179 } 179 } 180 180 181 bool cleared() | 181 bool cleared() const 182 { 182 { 183 for(int y=1; y<=H; ++y) 183 for(int y=1; y<=H; ++y) 184 for(int x=1; x<=W; ++x) 184 for(int x=1; x<=W; ++x) 185 if(this[y,x] == 'L' || this[y,x] == 'O') 185 if(this[y,x] == 'L' || this[y,x] == 'O') 186 return false; 186 return false; 187 return true; 187 return true; 188 } 188 }

Modified src/gui.d from [e76b6b97ba56256b] to [508aa0ef899fe75c].

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

Added src/gui_main.d version [49f16753320613b8]

> 1 import gui; > 2 import output; > 3 import driver; > 4 import solver; > 5 import std.stdio; > 6 pragma(lib, "dfl.lib"); > 7 > 8 void main(string[] args) > 9 { > 10 Driver d = new Driver(stdin); > 11 d.addObserver!(GuardedOutput)(); > 12 auto g = d.addObserver!(GUI!Solver_1)(); > 13 g.set_fn(&d.command); > 14 g.run(); > 15 }

Modified src/output.d from [2ca374354297c908] to [7fa423ba9f8ebe92].

1 import util; 1 import util; 2 import game; 2 import game; 3 import driver; 3 import driver; 4 import std.c.stdlib; < 5 import core.stdc.signal; 4 import core.stdc.signal; 6 5 7 class NilOutput : GameObserver 6 class NilOutput : GameObserver 8 { 7 { 9 this(const(Game) g) {} 8 this(const(Game) g) {} 10 override bool on_game_changed(char c, const(Game) g, bool finished) {ret | 9 override void on_game_changed(char c, const(Game) g, bool finished) {} 11 } 10 } 12 11 13 class StdOutput : GameObserver 12 class StdOutput : GameObserver 14 { 13 { 15 this(const(Game) g) {} 14 this(const(Game) g) {} 16 override bool on_game_changed(char c, const(Game) g, bool finished) | 15 override void on_game_changed(char c, const(Game) g, bool finished) 17 { 16 { 18 stdout.write(c); 17 stdout.write(c); 19 stdout.flush(); 18 stdout.flush(); 20 return false; < 21 } 19 } 22 } 20 } 23 21 24 class GuardedOutput : GameObserver 22 class GuardedOutput : GameObserver 25 { 23 { 26 this(const(Game) g) 24 this(const(Game) g) 27 { 25 { 28 setup_sigint_handling(); 26 setup_sigint_handling(); 29 ideal_log ~= g.score_if_abort_now; 27 ideal_log ~= g.score_if_abort_now; 30 } 28 } 31 29 32 override bool on_game_changed(char c, const(Game) g, bool finished) | 30 override void on_game_changed(char c, const(Game) g, bool finished) 33 { 31 { 34 log ~= c; 32 log ~= c; 35 score_log ~= g.score; 33 score_log ~= g.score; 36 ideal_log ~= g.score_if_abort_now; 34 ideal_log ~= g.score_if_abort_now; 37 if(finished) 35 if(finished) 38 flush(); 36 flush(); 39 return false; < 40 } 37 } 41 38 42 private: 39 private: 43 string log; 40 string log; 44 long[] score_log; 41 long[] score_log; 45 long[] ideal_log; 42 long[] ideal_log; 46 43

Modified src/solver.d from [42db89cb5c63a7bd] to [0bb4050087a6fb3f].

1 import util; 1 import util; 2 import game; 2 import game; 3 import output; | 3 import driver; 4 4 5 int g_wc = 0; < 6 < 7 void act(Game g) < > 5 /* > 6 interface Solver 8 { 7 { 9 Pos ro = g.map.robot; | 8 this(const(Game) g); 10 Pos[] la = g.map.lambdas(); | 9 char single_step(); 11 Pos li = g.map.lift; < > 10 } > 11 */ 12 12 13 char c = 'W'; | 13 class Solver_0 14 if( la.empty ) { < > 14 { 15 auto r = search(g, ro, li); | 15 this(const(Game) g) {} 16 c = r[0]; | 16 char single_step() { return 'W'; } 17 } else { < 18 Tuple!(char,int)[] cand; < 19 foreach(lam; la) < 20 cand ~= search(g, ro, lam); < 21 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ < 22 if(c1[1] != c2[1]) < 23 return c1[1] < c2[1]; < 24 return c1[0] < c2[0]; < 25 })(cand); < 26 c = cand[0][0]; < 27 } < 28 if(c=='W') { < 29 g_wc++; < 30 if(g_wc > 10) < 31 c = 'A'; < 32 } < 33 else < 34 g_wc = 0; < 35 g.command(c); < 36 } 17 } 37 18 38 Tuple!(char,int) search(Game g, Pos s, Pos o) | 19 class Solver_1 39 { 20 { 40 Pos[] q = [o]; | 21 int g_wc = 0; 41 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); < > 22 42 for(int step=1; q.length; ++step) { | 23 Game g; 43 Pos[] q2; | 24 this(const(Game) g) 44 foreach(p; q) { < > 25 { 45 int[] dy=[-1,+1,0,0]; | 26 this.g = g.clone(); 46 int[] dx=[0,0,-1,+1]; < 47 for(int i=0; i<4; ++i) { < > 27 } > 28 48 int y = p.y+dy[i]; | 29 char single_step() 49 int x = p.x+dx[i]; < > 30 { 50 if(v[y][x]) continue; | 31 char c = act(g); 51 if(y==s.y && x==s.x) { | 32 g.command(c); 52 if(i==0) return tuple('U',step); | 33 return c; 53 if(i==1) return tuple('D',step); < 54 if(i==2) return tuple('R',step); < > 34 } > 35 55 if(i==3) return tuple('L',step); | 36 char act(const(Game) g) 56 } else if(g.map[y,x]==' '||g.map[y,x]=='\\') { < > 37 { 57 q2 ~= new Pos(y,x); | 38 const Pos ro = g.map.robot; 58 v[y][x]=true; | 39 const Pos[] la = g.map.lambdas(); 59 } else if(g.map[y,x]=='.' && g.map[y-1,x]!='*') | 40 const Pos li = g.map.lift; 60 q2 ~= new Pos(y,x); < 61 v[y][x]=true; < 62 } | 41 > 42 char c = 'W'; > 43 if( la.empty ) { > 44 auto r = search(g, ro, li); > 45 c = r[0]; > 46 } else { > 47 Tuple!(char,int)[] cand; > 48 foreach(lam; la) > 49 cand ~= search(g, ro, lam); > 50 sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ > 51 if(c1[1] != c2[1]) > 52 return c1[1] < c2[1]; > 53 return c1[0] < c2[0]; > 54 })(cand); > 55 c = cand[0][0]; 63 } | 56 } > 57 if(c=='W') { > 58 g_wc++; > 59 if(g_wc > 10) > 60 c = 'A'; 64 } 61 } > 62 else 65 q = q2; | 63 g_wc = 0; > 64 return c; 66 } 65 } > 66 > 67 Tuple!(char,int) search(in Game g, in Pos s, in Pos o) > 68 { > 69 const(Pos)[] q = [o]; > 70 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); > 71 for(int step=1; q.length; ++step) { > 72 Pos[] q2; > 73 foreach(p; q) { > 74 int[] dy=[-1,+1,0,0]; > 75 int[] dx=[0,0,-1,+1]; > 76 for(int i=0; i<4; ++i) { > 77 int y = p.y+dy[i]; > 78 int x = p.x+dx[i]; > 79 if(v[y][x]) continue; > 80 if(y==s.y && x==s.x) { > 81 if(i==0) return tuple('U',step); > 82 if(i==1) return tuple('D',step); > 83 if(i==2) return tuple('R',step); > 84 if(i==3) return tuple('L',step); > 85 } else if(g.map[y,x]==' '||g.map[y,x]==' > 86 q2 ~= new Pos(y,x); > 87 v[y][x]=true; > 88 } else if(g.map[y,x]=='.' && g.map[y-1,x > 89 q2 ~= new Pos(y,x); > 90 v[y][x]=true; > 91 } > 92 } > 93 } > 94 q = q2; > 95 } 67 q = [o]; | 96 q = [o]; 68 v = new bool[][](g.map.H+2, g.map.W+2); | 97 v = new bool[][](g.map.H+2, g.map.W+2); 69 for(int step=1000; q.length; ++step) { | 98 for(int step=1000; q.length; ++step) { 70 Pos[] q2; | 99 Pos[] q2; 71 foreach(p; q) { | 100 foreach(p; q) { 72 int[] dy=[-1,+1,0,0]; | 101 int[] dy=[-1,+1,0,0]; 73 int[] dx=[0,0,-1,+1]; | 102 int[] dx=[0,0,-1,+1]; 74 for(int i=0; i<4; ++i) { | 103 for(int i=0; i<4; ++i) { 75 int y = p.y+dy[i]; | 104 int y = p.y+dy[i]; 76 int x = p.x+dx[i]; | 105 int x = p.x+dx[i]; 77 if(v[y][x]) continue; | 106 if(v[y][x]) continue; 78 if(y==s.y && x==s.x) { | 107 if(y==s.y && x==s.x) { 79 if(i==0) return tuple('U',step); | 108 if(i==0) return tuple('U',step); 80 if(i==1) return tuple('D',step); | 109 if(i==1) return tuple('D',step); 81 if(i==2) return tuple('R',step); | 110 if(i==2) return tuple('R',step); 82 if(i==3) return tuple('L',step); | 111 if(i==3) return tuple('L',step); 83 } else if(g.map[y,x]==' '||g.map[y,x]=='\\') { | 112 } else if(g.map[y,x]==' '||g.map[y,x]==' 84 q2 ~= new Pos(y,x); | 113 q2 ~= new Pos(y,x); 85 v[y][x]=true; | 114 v[y][x]=true; 86 } else if(g.map[y,x]=='.'/* && g[y-1,x]!='*'*/) | 115 } else if(g.map[y,x]=='.'/* && g[y-1,x]! 87 q2 ~= new Pos(y,x); | 116 q2 ~= new Pos(y,x); 88 v[y][x]=true; | 117 v[y][x]=true; > 118 } 89 } 119 } 90 } 120 } > 121 q = q2; 91 } 122 } 92 q = q2; | 123 return tuple('W', int.max); 93 } 124 } 94 return tuple('W', int.max); < 95 } < 96 < 97 void main(string[] args) < 98 { < 99 auto g = Game.load(stdin); < 100 g.set_output(new GuardedOutput(g)); < 101 < 102 while(!g.dead && !g.cleared) < 103 act(g); < 104 } 125 }