Index: src/game.d ================================================================== --- src/game.d +++ src/game.d @@ -90,20 +90,22 @@ class Map { mixin DeriveShow; - static Map load(string[] raw_data, string[string] params) + static Map load(string[] raw_data, string[string] params, char[char] trampo) { // TODO: choose optimal representation. - return new Map(raw_data, params); + return new Map(raw_data, params, trampo); } char[][] data; Pos robot; Pos lift; int waterproof; + Pos[char] tr_target; + Pos[][char] tr_source; Map clone() const { return new Map(this); } this(in Map m) { foreach(s; m.data) this.data ~= s.dup; @@ -110,11 +112,11 @@ this.robot = m.robot.clone(); this.lift = m.lift.clone(); this.waterproof = m.waterproof; } - this(string[] raw_data, string[string] params) + this(string[] raw_data, string[string] params, char[char] trampo) { int width = 0; foreach(r; raw_data) width = max(width, r.length); foreach(r; raw_data) { @@ -128,12 +130,25 @@ if(this[y,x] == 'R') this.robot = new Pos(y,x); if(this[y,x] == 'L' || this[y,x] == 'O') this.lift = new Pos(y,x); } + + Pos[char] tr_pos; + for(int y=1; y<=H; ++y) + for(int x=1; x<=W; ++x) { + char c = this[y,x]; + if('1'<=c && c<='9' || 'A'<=c&&c<='I') + tr_pos[c] = new Pos(y,x); + } this.waterproof = params.get("Waterproof", "5").to!int(); + foreach(fr,to; trampo) { + tr_target[fr] = tr_pos[to]; + if(to !in tr_source) tr_source[to] = []; + tr_source[to] ~= tr_pos[to]; + } } const @property { int H() { return data.length; } int W() { return data[0].length; } @@ -283,27 +298,30 @@ // Raw map data; read until empty line. for(string line; !(line=input.readln().chomp()).empty; ) raw_data ~= line; // Additional commands; read until EOF. + char[char] trampo; for(string line; !(line=input.readln()).empty; ) { string[] ss = line.split(); if( ss.length == 2 ) params[ss[0]] = ss[1]; + if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="targets" ) + trampo[ss[1][0]] = ss[3][0]; } - return load(raw_data, params); + return load(raw_data, params, trampo); } - static Game load(string[] raw_data, string[string] params) + static Game load(string[] raw_data, string[string] params, char[char] trampo = null) { - return new Game(raw_data, params); + return new Game(raw_data, params, trampo); } - this(string[] raw_data, string[string] params) + this(string[] raw_data, string[string] params, char[char] trampo) { - this.map = Map.load(raw_data, params); + this.map = Map.load(raw_data, params, trampo); this.water = Water.load(params); } Game clone() const { return new Game(this); } this(in Game g) { Index: src/gui.d ================================================================== --- src/gui.d +++ src/gui.d @@ -7,11 +7,11 @@ { this(in Game g) { this.solver = new Solver(g); setup_size(g.map.W, g.map.H); - setup_resources(); + setup_resources(g); draw(g); } private void delegate(char c) fn; void set_fn(F)(F f) { this.fn = f; } @@ -52,11 +52,11 @@ Font font; Color[char] colors; string[char] render; Graphics graphicContext; - void setup_resources() + void setup_resources(in Game g) { 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); @@ -67,18 +67,24 @@ 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); + foreach(char c; 'A'..'J') this.colors[c] = Color(142,142,255); + foreach(char c; '1'..':') this.colors[c] = Color(255,142,255); this.render['#'] = "■"; this.render['*'] = "✹"; this.render['.'] = "♒"; this.render['\\'] = "λ"; this.render['R'] = "☃"; this.render['D'] = "☠"; this.render['L'] = "☒"; - this.render['O'] = "☐"; + foreach(c,tp; g.map.tr_target) { + char d = g.map[tp]; + this.render[c] = [cast(dchar)('㋀'+d-'1')].to!string(); + } + foreach(char c; '1'..':') this.render[c] = [cast(dchar)('㏠'+c-'1')].to!string(); this.paint ~= (Control c, PaintEventArgs ev) { graphicContext.copyTo(ev.graphics, Rect(0,0,this.clientSize.width,this.clientSize.height)); }; }