Index: src/game.d ================================================================== --- src/game.d +++ src/game.d @@ -144,10 +144,11 @@ this.tr_source = cast(Pos[][char])m.tr_source; this.hige = m.hige.clone(); this.razor = m.razor; this.collected_lambda = m.collected_lambda; this.total_lambda = m.total_lambda; + this.may_update = (cast(Map)m).may_update.dup; } this(string[] raw_data, string[string] params, char[char] trampo) { int width = 0; @@ -165,10 +166,12 @@ this.robot = new Pos(y,x); if(this[y,x] == 'L' || this[y,x] == 'O') this.lift = new Pos(y,x); if(this[y,x] == '\\' || this[y,x] == '@') total_lambda++; + if(this[y,x] == '*' || this[y,x] == '@') + may_update ~= new Pos(y,x); } Pos[char] tr_pos; for(int y=1; y<=H; ++y) for(int x=1; x<=W; ++x) { @@ -268,13 +271,22 @@ return update(turn); } bool rocky(char c) { return c=='*' || c=='@'; } + Pos[] may_update; + void emptified(Pos p) { + for(int dy=0; dy<=+1; ++dy) + for(int dx=-1; dx<=+1; ++dx) + may_update ~= new Pos(p.y+dy, p.x+dx); + } bool move(int dy, int dx, int turn) { + + emptified(robot); + int y = robot.y; int x = robot.x; if( '\\' == this[y+dy,x+dx] ) collected_lambda++; if( '!' == this[y+dy,x+dx] ) @@ -290,65 +302,74 @@ this[y+dy*2,x+dx*2]=rock; robot = new Pos(y+dy,x+dx); } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') { this[y,x]=' '; Pos tp = tr_target[this[y+dy,x+dx]]; - foreach(p; tr_source[this[tp]]) + foreach(p; tr_source[this[tp]]) { + emptified(p); this[p] = ' '; + } this[tp] = 'R'; robot = tp; } return update(turn); } bool update(int turn) { + // Write after all the updates are processed. + Tuple!(int,int,char)[] write_buffer; + void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c); } + void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c); } + scope(exit) { + may_update.length = 0; + foreach(wr; write_buffer) { + this[wr[0],wr[1]] = wr[2]; + if(rocky(wr[2])) + may_update ~= new Pos(wr[0],wr[1]); + if(wr[2]==' ') + emptified(new Pos(wr[0], wr[1])); + } + } + + if(collected_lambda == total_lambda) + if(this[lift]=='L') + this[lift] = 'O'; + bool dead = false; - - char[][] next; - foreach(y,s; data) - next ~= s.dup; - - ref char access(Pos p) { return next[H-p.y][p.x-1]; } - - for(int y=1; y<=H; ++y) - for(int x=1; x<=W; ++x) { - Pos p = new Pos(y,x); + sort(may_update); + foreach(p; may_update) { + int y = p.y, x = p.x; char rock = this[p]; if(rocky(this[p])) { if(this[p.D]==' ') { - access(p) =' '; - access(p.D)=(rock=='@'&&this[p.D.D]!=' ' ? '\\' : rock); + writep(p, ' '); + writep(p.D, (rock=='@'&&this[p.D.D]!=' ' ? '\\' : rock)); if(robot == p.D.D) dead=true; } else if((rocky(this[p.D]) || this[p.D]=='\\') && this[p.R]==' ' && this[p.R.D]==' ') { - access(p)=' '; - access(p.R.D)=(rock=='@'&&this[p.R.D.D]!=' ' ? '\\' : rock); + writep(p, ' '); + writep(p.R.D,(rock=='@'&&this[p.R.D.D]!=' ' ? '\\' : rock)); if(robot == p.R.D.D) dead=true; } else if(rocky(this[p.D]) && this[p.L]==' ' && this[p.L.D]==' ') { - access(p)=' '; - access(p.L.D)=(rock=='@'&&this[p.L.D.D]!=' ' ? '\\' : rock); + writep(p, ' '); + writep(p.L.D, (rock=='@'&&this[p.L.D.D]!=' ' ? '\\' : rock)); if(robot == p.L.D.D) dead=true; } } - else if(this[p]=='L') { - if(collected_lambda == total_lambda) - access(p) = 'O'; - } else if(this[p]=='W') { if( hige.is_growing_turn(turn) ) for(int dy=-1; dy<=+1; ++dy) for(int dx=-1; dx<=+1; ++dx) if(this[p.y+dy,p.x+dx] == ' ') - access(new Pos(p.y+dy,p.x+dx)) = 'W'; + write(p.y+dy,p.x+dx,'W'); } } - data = next; return dead; } } //////////////////////////////////////////////////////////////////////////////// Index: src/solver.d ================================================================== --- src/solver.d +++ src/solver.d @@ -387,8 +387,8 @@ else plan = plan[1..$]; } } -//alias Solver_2!(Solver_1) MainSolver; +alias Solver_2!(Solver_1) MainSolver; //alias Solver_1 MainSolver; -alias Solver_0 MainSolver; +//alias Solver_0 MainSolver;