Index: src/game.d ================================================================== --- src/game.d +++ src/game.d @@ -544,10 +544,18 @@ @property const { int H() { return H_; } int W() { return W_; } char trampoline(char c) { return (c in trampoline_ ? trampoline_[c] : 0); } + const(Pos)[] trampoline_rev(char c) { + const(Pos)[] pp; + if(c in trampoline_rev_) { + foreach(ch; trampoline_rev_[c]) + pp ~= trampoline_pos_[ch]; + } + return pp; + } int water_level() { return water_pace_ ? water_base_ + turn_/water_pace_ : water_base_; } int water_until_rise() { return water_pace_ ? water_pace_ - turn_%water_pace_ : int.max; @@ -561,10 +569,31 @@ int hp() { return air_left_; } int num_razor() { return num_razor_; } bool cleared() { return cleared_; } bool dead() { return dead_; } long score() { return num_lambda_*(dead_ ? 25L : cleared_ ? 75L : 50L) - turn_; } + const(Pos) robot() { return robot_pos_; } + const(Pos) lift() { return lift_pos_; } + Pos[] lambdas() { + Pos[] pp; + foreach(p; lambda_pos_) + pp ~= p.clone(); + return pp; + } + Pos[] razors() { + Pos[] pp; + foreach(p; razor_pos_) + pp ~= p.clone(); + return pp; + } + const(Pos)[] higes() { + const(Pos)[] pp; + foreach(p,c; dynamic_objects_) + if(c=='W') + pp ~= p; + return pp; + } } const { char opIndex(in Pos p) { return opIndex(p.y, p.x); } char opIndex(int y, int x) { return map_get(y, x); } } @@ -580,15 +609,15 @@ if(c == 'L') command_move(0, -1); if(c == 'R') command_move(0, +1); if(c == 'S') use_razor(); if(c == 'W') {} - if(cleared) - return; - - map_update(); - water_update(); + if(!cleared) + { + map_update(); + water_update(); + } turn_ ++; } void command_move(int dy, int dx) { @@ -789,10 +818,44 @@ { if( y<1 || Hbd;; })(la); - Pos[] ra = g.map.razors(); - const(Pos)[] hi = g.map.objects('W'); + Pos[] ra = g.razors(); + const(Pos)[] hi = g.higes(); Tuple!(char,int)[] cand; char c = 'W'; if( la.empty ) { cand = search(g, ro, [li], death); @@ -74,28 +74,28 @@ } else { cand ~= search(g, ro, la~ra, death); } // 'higesori' mode - if( !hi.empty && g.map.razor>0 ) { + if( !hi.empty && g.num_razor>0 ) { int his = 0; for(int dy=-1; dy<=+1; ++dy) for(int dx=-1; dx<=+1; ++dx) - if(g.map[ro.y+dy,ro.x+dx] == 'W') + if(g[ro.y+dy,ro.x+dx] == 'W') his++; if(his>=2 || his==hi.length) cand = [tuple('S',int.max)]; if(cand.empty) { const(Pos)[] tgt; - for(int y=1; y<=g.map.H; ++y) - for(int x=1; x<=g.map.W; ++x) - if(g.map[y,x]=='.'||g.map[y,x]==' ') { + for(int y=1; y<=g.H; ++y) + for(int x=1; x<=g.W; ++x) + if(g[y,x]=='.'||g[y,x]==' ') { his = 0; for(int dy=-1; dy<=+1; ++dy) for(int dx=-1; dx<=+1; ++dx) - if(g.map[y+dy,x+dx] == 'W') + if(g[y+dy,x+dx] == 'W') his++; if(his>=2) tgt ~= new Pos(y,x); } cand ~= search(g, ro, tgt, death, true); @@ -103,15 +103,15 @@ } // 'dig' mode if(cand.empty) { const(Pos)[] tgt; - for(int y=1; y<=g.map.H; ++y) - for(int x=1; x<=g.map.W; ++x) - if(g.map[y,x]=='.') - if(g.map[y+1,x]=='*'||g.map[y+1,x-1]=='*'||g.map[y+1,x+1]=='*' - ||g.map[y,x+1]=='*'||g.map[y,x-1]=='*') + for(int y=1; y<=g.H; ++y) + for(int x=1; x<=g.W; ++x) + if(g[y,x]=='.') + if(g[y+1,x]=='*'||g[y+1,x-1]=='*'||g[y+1,x+1]=='*' + ||g[y,x+1]=='*'||g[y,x-1]=='*') tgt ~= new Pos(y,x); cand ~= search(g, ro, tgt, death, true); } if(cand.empty) { @@ -135,11 +135,11 @@ if(c == 'W') wait_count++; else wait_count = 0; - if(choke_count >= g.map.H) + if(choke_count >= g.H) c = 'A'; bool[char] choice; foreach(t; cand) choice[t[0]] = true; @@ -159,21 +159,21 @@ Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death, bool danger_ok=false) { bool danger(int y, int x) { - if(g.map[y,x] == ' ' || g.map[y,x] == 'R') + if(g[y,x] == ' ' || g[y,x] == 'R') return false; - if(g.map[y+1,x] == '*') + if(g[y+1,x] == '*') + return true; + if(g[y+1,x-1]=='*' && (g[y,x-1]=='\\'||g[y,x-1]=='*') && (g[y+1,x]==' '||g[y+1,x]=='R')) return true; - if(g.map[y+1,x-1]=='*' && (g.map[y,x-1]=='\\'||g.map[y,x-1]=='*') && (g.map[y+1,x]==' '||g.map[y+1,x]=='R')) + if(g[y+1,x+1]=='*' && (g[y,x+1]=='*') && (g[y+1,x]==' '||g[y+1,x]=='R')) return true; - if(g.map[y+1,x+1]=='*' && (g.map[y,x+1]=='*') && (g.map[y+1,x]==' '||g.map[y+1,x]=='R')) + if(g[y,x-1]=='*' && (g[y-1,x-1]=='\\'||g[y-1,x-1]=='*') && (g[y-1,x]==' '||g[y-1,x]=='R')) return true; - if(g.map[y,x-1]=='*' && (g.map[y-1,x-1]=='\\'||g.map[y-1,x-1]=='*') && (g.map[y-1,x]==' '||g.map[y-1,x]=='R')) - return true; - if(g.map[y,x+1]=='*' && (g.map[y-1,x+1]=='*') && (g.map[y-1,x]==' '||g.map[y-1,x]=='R')) + if(g[y,x+1]=='*' && (g[y-1,x+1]=='*') && (g[y-1,x]==' '||g[y-1,x]=='R')) return true; return false; } // avoid directly below '*' @@ -180,22 +180,22 @@ Tuple!(char,int)[] tryA() { const(Pos)[] q; foreach(p; gs) if(!danger(p.y,p.x)) q ~= p; - bool[][] v = new bool[][](g.map.H+2, g.map.W+2); + bool[][] v = new bool[][](g.H+2, g.W+2); foreach(p; q) v[p.y][p.x]=true; for(int step=1; q.length; ++step) { Pos[] q2; foreach(p; q) { int[] yyy=[p.y-1,p.y+1,p.y,p.y]; int[] xxx=[p.x,p.x,p.x-1,p.x+1]; for(int i=0; i=4) { + } else if(g[y,x]==' '||g[y,x]=='\\'||g[y,x]=='.'||g[y,x]=='!'||i>=4) { if(danger(y,x)) continue; q2 ~= new Pos(y,x); v[y][x]=true; } @@ -220,22 +220,22 @@ // any empty space is my ground Tuple!(char,int)[] tryB() { const(Pos)[] q; foreach(p; gs) q ~= p; - bool[][] v = new bool[][](g.map.H+2, g.map.W+2); + bool[][] v = new bool[][](g.H+2, g.W+2); foreach(p; q) v[p.y][p.x]=true; for(int step=10; q.length; ++step) { Pos[] q2; foreach(p; q) { int[] yyy=[p.y-1,p.y+1,p.y,p.y]; int[] xxx=[p.x,p.x,p.x-1,p.x+1]; for(int i=0; i=4) { + } else if(g[y,x]==' '||g[y,x]=='\\'||g[y,x]=='.'||g[y,x]=='!'||i>=4) { q2 ~= new Pos(y,x); v[y][x]=true; } } } @@ -258,27 +258,27 @@ // push rocks! Tuple!(char,int)[] tryC() { const(Pos)[] q; foreach(p; gs) q ~= p; - bool[][] v = new bool[][](g.map.H+2, g.map.W+2); + bool[][] v = new bool[][](g.H+2, g.W+2); foreach(p; q) v[p.y][p.x]=true; for(int step=20; q.length; ++step) { Pos[] q2; foreach(p; q) { int[] yyy=[p.y-1,p.y+1,p.y,p.y]; int[] xxx=[p.x,p.x,p.x-1,p.x+1]; for(int i=0; i=4)continue; if(y!=p.y)continue; - if(g.map[y,p.x+(p.x-x)]!=' '&&g.map[y,p.x+(p.x-x)]!='R')continue; + if(g[y,p.x+(p.x-x)]!=' '&&g[y,p.x+(p.x-x)]!='R')continue; } - if('1'<=g.map[y,x]&&g.map[y,x]<='9') { - foreach(ppp; g.map.tr_source[g.map[y,x]]) { + if('1'<=g[y,x]&&g[y,x]<='9') { + foreach(ppp; g.trampoline_rev(g[y,x])) { yyy ~= ppp.y; xxx ~= ppp.x; } continue; } @@ -286,11 +286,11 @@ if(y==s.y && x==s.x && i<4) { char c = "UDRL"[i]; if( death.count(c) == 0 ) return [tuple(c,step)]; } else if(forbidden_cell[y][x]){ - } else if(g.map[y,x]==' '||g.map[y,x]=='\\'||g.map[y,x]=='.'||g.map[y,x]=='*'||g.map[y,x]=='!'||i>=4) { + } else if(g[y,x]==' '||g[y,x]=='\\'||g[y,x]=='.'||g[y,x]=='*'||g[y,x]=='!'||i>=4) { q2 ~= new Pos(y,x); v[y][x]=true; } } } @@ -316,11 +316,11 @@ Tuple!(Solver,string) run_sub_solver(in Game g) { string log; auto s = new Solver(g); - while(!g.cleared && !g.dead && plan.length<=g.map.H*g.map.W) { + while(!g.cleared && !g.dead && plan.length<=g.H*g.W) { char c = s.single_step(); if( c == 'A' ) break; log ~= c; } @@ -385,8 +385,7 @@ else plan = plan[1..$]; } } -//alias Solver_2!(Solver_1) MainSolver; -alias Solver_1 MainSolver; -*/ +alias Solver_2!(Solver_1) MainSolver; +//alias Solver_1 MainSolver;