@@ -23,30 +23,38 @@ Game g; this(const(Game) g) { this.g = g.clone(); + forbidden_cell = new bool[][](g.map.H+2, g.map.W+2); } char single_step() { - char c = act(g, death_move(g)); + Tuple!(string,int) de = death_move(g); + char c = act(g, de[0], de[1]); g.command(c); return c; } - string death_move(const(Game) g) + Tuple!(string,int) death_move(const(Game) g) { string death; + int choice = 0; foreach(char c; "UDLRW") { Game gg = g.clone(); gg.command(c); if( !gg.cleared && gg.dead ) death ~= c; + else if( gg.map.robot != g.map.robot ) + choice++; } - return death; + return tuple(death, choice); } - char act(const(Game) g, string death) + Tuple!(Pos, int)[] log; + bool[][] forbidden_cell; + + char act(const(Game) g, string death, int breath) { const Pos ro = g.map.robot; const Pos[] la = g.map.lambdas(); const Pos li = g.map.lift; @@ -58,8 +66,9 @@ } else { foreach(lam; la) cand ~= search(g, ro, lam, death); } + cand ~= tuple('W',int.max); sort!((Tuple!(char,int) c1, Tuple!(char,int) c2){ if(c1[1] != c2[1]) return c1[1] < c2[1]; return c1[0] < c2[0]; @@ -72,8 +81,22 @@ c = 'A'; } else g_wc = 0; + bool[char] choice; + foreach(t; cand) + choice[t[0]] = true; + log ~= tuple(ro.clone(), cast(int)choice.length); + if(log.length > 5) + log = log[$-5..$]; + int cnt = 0; + foreach(l; log) + if(l[0] == log[$-1][0]) + ++cnt; + if( cnt >= 3 && breath==1 ) { + forbidden_cell[ro.y][ro.x] = true; + } + return c; } Tuple!(char,int)[] search(in Game g, in Pos s, in Pos o, string death) @@ -111,8 +134,9 @@ if(y==s.y && x==s.x) { 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]=='.') { if(danger(y,x)) continue; q2 ~= new Pos(y,x); @@ -130,9 +154,9 @@ Tuple!(char,int)[] tryB() { 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=15; q.length; ++step) { + for(int step=10; q.length; ++step) { Pos[] q2; foreach(p; q) { int[] dy=[-1,+1,0,0]; int[] dx=[0,0,-1,+1]; @@ -143,8 +167,9 @@ if(y==s.y && x==s.x) { 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]=='.') { q2 ~= new Pos(y,x); v[y][x]=true; } @@ -159,9 +184,9 @@ Tuple!(char,int)[] tryC() { 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=30; q.length; ++step) { + for(int step=20; q.length; ++step) { Pos[] q2; foreach(p; q) { int[] dy=[-1,+1,0,0]; int[] dx=[0,0,-1,+1]; @@ -172,8 +197,9 @@ if(y==s.y && x==s.x) { 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]=='.') { q2 ~= new Pos(y,x); v[y][x]=true; } else if(dy[i]==0 && g.map[p]==' ' && g.map[y,x]=='*' && (g.map[y+dy[i],x+dx[i]]==' '||g.map[y+dy[i],x+dx[i]]=='R')) { @@ -185,7 +211,7 @@ q = q2; } return []; } - return tryA() ~ tryB() ~ tryC() ~ tuple('W', int.max); + return tryA() ~ tryB() ~ tryC(); } }