Index: src/solver.d ================================================================== --- src/solver.d +++ src/solver.d @@ -76,12 +76,14 @@ return c; } Tuple!(char,int) search(in Game g, in Pos s, in Pos o, string death) { + // avoid directly below '*' const(Pos)[] q = [o]; bool[][] v = new bool[][](g.map.H+2, g.map.W+2); + v[o.y][o.x]=true; for(int step=1; q.length; ++step) { Pos[] q2; foreach(p; q) { int[] dy=[-1,+1,0,0]; int[] dx=[0,0,-1,+1]; @@ -102,12 +104,15 @@ } } } q = q2; } + + // any empty space is my ground q = [o]; v = new bool[][](g.map.H+2, g.map.W+2); + v[o.y][o.x]=true; for(int step=1000; q.length; ++step) { Pos[] q2; foreach(p; q) { int[] dy=[-1,+1,0,0]; int[] dx=[0,0,-1,+1]; @@ -125,11 +130,43 @@ } else if(g.map[y,x]=='.'/* && g[y-1,x]!='*'*/) { q2 ~= new Pos(y,x); v[y][x]=true; } } + } + q = q2; + } + + // push rocks! + q = [o]; + v = new bool[][](g.map.H+2, g.map.W+2); + v[o.y][o.x]=true; + for(int step=2000; q.length; ++step) { + Pos[] q2; + foreach(p; q) { + int[] dy=[-1,+1,0,0]; + int[] dx=[0,0,-1,+1]; + for(int i=0; i<4; ++i) { + int y = p.y+dy[i]; + int x = p.x+dx[i]; + if(v[y][x]) continue; + if(y==s.y && x==s.x) { + char c = "UDRL"[i]; + if( death.count(c) == 0 ) + return tuple(c,step); + } else if(g.map[y,x]==' '||g.map[y,x]=='\\') { + q2 ~= new Pos(y,x); + v[y][x]=true; + } else if(g.map[y,x]=='.'/* && g[y-1,x]!='*'*/) { + q2 ~= new Pos(y,x); + v[y][x]=true; + } else if(dy[i]==0 && g.map[y,x]=='*' && (g.map[y+dy[i],x+dx[i]]==' '||g.map[y+dy[i],x+dx[i]]=='R')) { + q2 ~= new Pos(y,x); + v[y][x]=true; + } + } } q = q2; } return tuple('W', int.max); } }