ADDED maps/beard1.map Index: maps/beard1.map ================================================================== --- maps/beard1.map +++ maps/beard1.map @@ -0,0 +1,13 @@ +########## +#** \\\\# +#.R.. # +# \ ..*\# +#! ..*!# +#### # # +#\\... # L +#\\.W... # +#\\. # +########## + +Growth 15 +Razors 0 ADDED maps/beard2.map Index: maps/beard2.map ================================================================== --- maps/beard2.map +++ maps/beard2.map @@ -0,0 +1,19 @@ +############################## +#R...........................# +#.........................W..# +#..\\\\\\\\\\\\\\\\\\\\\\\\..# +#............................# +#..*****.*\...*...*...*****..# +#..*\....*\....*\*..*.\\*\\..# +#..*\....****..!*!......*....# +#..*\....*\....*\*..*...*....# +#..*\....*\...*...*.....*....# +#............................# +#..\\\\\\\\\\\\\\\\\\\\\\\\..# +#................ ..... .....# +#................ W....L# +############################## + +Growth 25 +Razors 10 +Flooding 20 ADDED maps/beard3.map Index: maps/beard3.map ================================================================== --- maps/beard3.map +++ maps/beard3.map @@ -0,0 +1,16 @@ + ################ + #*****#!! 1 # + #..\..# # +#########\\\\ # .\\\. # +#.............# * # +#.. .\\\#..!..#\** # +#.. LW\\#W ..##### #### +#..R\\\\#.. ..*\*\*W...# +#.......A.. ...\.\...\\# +#.......... ** # +############....\.###### + #.....!# + ######## + +Growth 10 +Trampoline A targets 1 ADDED maps/beard4.map Index: maps/beard4.map ================================================================== --- maps/beard4.map +++ maps/beard4.map @@ -0,0 +1,16 @@ +#################### +#W\\!#\\\**.\#W\\\W# +##*######..###..\\\# +#.......\.R ###...\# +#####.###.#.......## +#.......#.#\####.### +#\\##\###\#\\#...#.L +#\##\.###.####.#.#.# +#\W#####.....###.W.# +####\\...\\\...#.#.# +#W*######.######.#.# +#\\\\\\\\\.........# +############\###\### +#\\.. *..........\\# +#W... #.........##W# +#################### Index: src/game.d ================================================================== --- src/game.d +++ src/game.d @@ -86,10 +86,36 @@ assert( 1 == w.level(5) ); } //////////////////////////////////////////////////////////////////////////////// +class Hige +{ + public immutable int pace; + mixin DeriveCreate; + mixin DeriveCompare; + mixin DeriveShow; + Hige clone() const { return cast(Hige)this; } + + static load(string[string] params) + { + return new Hige(params.get("Growth", "25").to!int()); + } + + bool is_growing_turn(int turn) const + { + return pace ? turn%pace == pace-1 : false; + } + + int until_rise(int turn) const + { + return pace ? pace-turn%pace : int.max; + } +} + +//////////////////////////////////////////////////////////////////////////////// + class Map { mixin DeriveShow; static Map load(string[] raw_data, string[string] params, char[char] trampo) @@ -103,10 +129,12 @@ Pos lift; int waterproof; // TODO: immutable Pos[char] tr_target; Pos[][char] tr_source; + const(Hige) hige; + int razor; Map clone() const { return new Map(this); } this(in Map m) { foreach(s; m.data) this.data ~= s.dup; @@ -113,10 +141,12 @@ this.robot = m.robot.clone(); this.lift = m.lift.clone(); this.waterproof = m.waterproof; this.tr_target = cast(Pos[char])m.tr_target; this.tr_source = cast(Pos[][char])m.tr_source; + this.hige = m.hige.clone(); + this.razor = m.razor; } this(string[] raw_data, string[string] params, char[char] trampo) { int width = 0; @@ -148,10 +178,13 @@ foreach(fr,to; trampo) { tr_target[fr] = tr_pos[to]; if(to !in tr_source) tr_source[to] = []; tr_source[to] ~= tr_pos[fr]; } + + this.hige = Hige.load(params); + this.razor = params.get("Razors", "0").to!int(); } const @property { int H() { return data.length; } int W() { return data[0].length; } @@ -387,15 +420,11 @@ @property const { long score() { return lambda*25L*(1+exit_bonus) - turn; } int water_level() { return water.level(turn); } int water_until_rise() { return water.until_rise(turn); } + int hige_until_rise() { return map.hige.until_rise(turn); } bool cleared() { return exit_bonus>0; } int hp() { return map.waterproof - under_water; } long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus)) - turn; } } } - -unittest -{ - Game.load(["###","...","#RL"], ["xxx":"yyy"]); -} Index: src/gui.d ================================================================== --- src/gui.d +++ src/gui.d @@ -66,11 +66,13 @@ this.colors['R'] = Color(128,128,0); 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); + this.colors['w'] = Color(204,229,255); + this.colors['W'] = + this.colors['!'] = Color(159,159,159); 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['.'] = "♒"; @@ -77,13 +79,15 @@ this.render['\\'] = "λ"; this.render['R'] = "☃"; this.render['d'] = "☠"; this.render['L'] = "☒"; this.render['O'] = "☐"; + this.render['W'] = "ꔣ"; + this.render['!'] = "✄"; foreach(c,tp; g.map.tr_target) { char d = g.map[tp]; - this.render[c] = [cast(dchar)('☢'+d-'1')].to!string();/*㋀㏠*/ + 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)); }; @@ -97,11 +101,11 @@ // Fill bg. graphicContext.fillRectangle(this.backColor, Rect(0,0,scrW,scrH)); // Fill water. int w = g.water_level(); - graphicContext.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) { Rect r = Rect(cell*(x-1), scrH-cell*y, cell, cell); @@ -112,11 +116,16 @@ graphicContext.drawText(this.render[c], font, this.colors[c], r); } } // Update textual info. - this.text = .text("Score: ", g.score, " Air: ", g.hp, " Tide: ", g.water_until_rise); + this.text = .text( + "Score: ", g.score, + " Air: ", g.hp, + " Tide: ", g.water_until_rise, + " Wadler: ", g.hige_until_rise, + " Razor: ", g.map.razor); invalidate(); } private: void setup_keyhandling() Index: src/util.d ================================================================== --- src/util.d +++ src/util.d @@ -21,21 +21,21 @@ } template DeriveCompare() { override: - bool opEquals(Object rhs) + bool opEquals(Object rhs) const { return tuple(this.tupleof) == tuple((cast(typeof(this))rhs).tupleof); } - int opCmp(Object rhs) + int opCmp(Object rhs) const { return tuple(this.tupleof).opCmp(tuple((cast(typeof(this))rhs).tupleof)); } - hash_t toHash() + hash_t toHash() const { hash_t v = 0; foreach(mem; this.tupleof) { v *= 11; static if(__traits(compiles, v^=mem)) @@ -48,15 +48,15 @@ } template DeriveShow() { override: - string toString() + string toString() const { string str = text(typeof(this).stringof, "("); foreach(i,mem; this.tupleof) { if(i) str ~= ", "; str = text(str, this.tupleof[i].stringof[5..$], ":", mem); } return str ~ ")"; } }