Differences From Artifact [403db28cbc4609b7]:
- File        
src/game.d
- 2012-07-15 12:32:33 - part of checkin [de416b884b] on branch trunk - horock game. (user: kinaba) [annotate]
 
 
To Artifact [074b8ae4c20c37c4]:
- File        
src/game.d
- 2012-07-15 14:36:04 - part of checkin [b83558c1a5] on branch trunk - Speed up update(). (user: kinaba) [annotate]
 
 
   142    142     this.waterproof = m.waterproof;
   143    143     this.tr_target = cast(Pos[char])m.tr_target;
   144    144     this.tr_source = cast(Pos[][char])m.tr_source;
   145    145     this.hige = m.hige.clone();
   146    146     this.razor = m.razor;
   147    147     this.collected_lambda = m.collected_lambda;
   148    148     this.total_lambda = m.total_lambda;
          149  +  this.may_update = (cast(Map)m).may_update.dup;
   149    150    }
   150    151   
   151    152    this(string[] raw_data, string[string] params, char[char] trampo)
   152    153    {
   153    154     int width = 0;
   154    155     foreach(r; raw_data)
   155    156      width = max(width, r.length);
................................................................................
   163    164     for(int x=1; x<=W; ++x) {
   164    165      if(this[y,x] == 'R')
   165    166       this.robot = new Pos(y,x);
   166    167      if(this[y,x] == 'L' || this[y,x] == 'O')
   167    168       this.lift = new Pos(y,x);
   168    169      if(this[y,x] == '\\' || this[y,x] == '@')
   169    170       total_lambda++;
          171  +   if(this[y,x] == '*' || this[y,x] == '@')
          172  +    may_update ~= new Pos(y,x);
   170    173     }
   171    174   
   172    175     Pos[char] tr_pos;
   173    176     for(int y=1; y<=H; ++y)
   174    177     for(int x=1; x<=W; ++x) {
   175    178      char c = this[y,x];
   176    179      if('1'<=c && c<='9' || 'A'<=c&&c<='I')
................................................................................
   266    269        this[robot.y+dy,robot.x+dx] = ' ';
   267    270     }
   268    271   
   269    272     return update(turn);
   270    273    }
   271    274   
   272    275    bool rocky(char c) { return c=='*' || c=='@'; }
          276  + Pos[] may_update;
          277  +  void emptified(Pos p) {
          278  +   for(int dy=0; dy<=+1; ++dy)
          279  +   for(int dx=-1; dx<=+1; ++dx)
          280  +    may_update ~= new Pos(p.y+dy, p.x+dx);
          281  +  }
   273    282   
   274    283    bool move(int dy, int dx, int turn)
   275    284    {
          285  +
          286  +  emptified(robot);
          287  +
   276    288     int y = robot.y;
   277    289     int x = robot.x;
   278    290     if( '\\' == this[y+dy,x+dx] )
   279    291      collected_lambda++;
   280    292     if( '!' == this[y+dy,x+dx] )
   281    293      razor++;
   282    294     if( " \\!.O".count(this[y+dy,x+dx])==1 ) {
................................................................................
   288    300      this[y,x]=' ';
   289    301      this[y+dy,x+dx]='R';
   290    302      this[y+dy*2,x+dx*2]=rock;
   291    303      robot = new Pos(y+dy,x+dx);
   292    304     } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') {
   293    305      this[y,x]=' ';
   294    306      Pos tp = tr_target[this[y+dy,x+dx]];
   295         -   foreach(p; tr_source[this[tp]])
          307  +   foreach(p; tr_source[this[tp]]) {
          308  +    emptified(p);
   296    309       this[p] = ' ';
          310  +   }
   297    311      this[tp] = 'R';
   298    312      robot = tp;
   299    313     }
   300    314     return update(turn);
   301    315    }
   302    316   
   303    317    bool update(int turn)
   304    318    {
          319  +  // Write after all the updates are processed.
          320  +  Tuple!(int,int,char)[] write_buffer;
          321  +  void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c); }
          322  +  void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c); }
          323  +  scope(exit) {
          324  +   may_update.length = 0;
          325  +   foreach(wr; write_buffer) {
          326  +    this[wr[0],wr[1]] = wr[2];
          327  +    if(rocky(wr[2]))
          328  +     may_update ~= new Pos(wr[0],wr[1]);
          329  +    if(wr[2]==' ')
          330  +     emptified(new Pos(wr[0], wr[1]));
          331  +   }
          332  +  }
          333  +
          334  +  if(collected_lambda == total_lambda)
          335  +   if(this[lift]=='L')
          336  +    this[lift] = 'O';
          337  +
   305    338     bool dead = false;
   306         -
   307         -  char[][] next;
   308         -  foreach(y,s; data)
   309         -   next ~= s.dup;
   310         -
   311         -  ref char access(Pos p) { return next[H-p.y][p.x-1]; }
   312         -
   313         -  for(int y=1; y<=H; ++y)
   314         -  for(int x=1; x<=W; ++x) {
   315         -   Pos p = new Pos(y,x);
          339  +  sort(may_update);
          340  +  foreach(p; may_update) {
          341  +   int y = p.y, x = p.x;
   316    342      char rock = this[p];
   317    343      if(rocky(this[p])) {
   318    344       if(this[p.D]==' ') {
   319         -     access(p)  =' ';
   320         -     access(p.D)=(rock=='@'&&this[p.D.D]!=' ' ? '\\' : rock);
          345  +     writep(p, ' ');
          346  +     writep(p.D, (rock=='@'&&this[p.D.D]!=' ' ? '\\' : rock));
   321    347        if(robot == p.D.D)
   322    348         dead=true;
   323    349       }
   324    350       else if((rocky(this[p.D]) || this[p.D]=='\\') && this[p.R]==' ' && this[p.R.D]==' ') {
   325         -     access(p)=' ';
   326         -     access(p.R.D)=(rock=='@'&&this[p.R.D.D]!=' ' ? '\\' : rock);
          351  +     writep(p, ' ');
          352  +     writep(p.R.D,(rock=='@'&&this[p.R.D.D]!=' ' ? '\\' : rock));
   327    353        if(robot == p.R.D.D)
   328    354         dead=true;
   329    355       }
   330    356       else if(rocky(this[p.D]) && this[p.L]==' ' && this[p.L.D]==' ') {
   331         -     access(p)=' ';
   332         -     access(p.L.D)=(rock=='@'&&this[p.L.D.D]!=' ' ? '\\' : rock);
          357  +     writep(p, ' ');
          358  +     writep(p.L.D, (rock=='@'&&this[p.L.D.D]!=' ' ? '\\' : rock));
   333    359        if(robot == p.L.D.D)
   334    360         dead=true;
   335    361       }
   336    362      }
   337         -   else if(this[p]=='L') {
   338         -    if(collected_lambda == total_lambda)
   339         -     access(p) = 'O';
   340         -   }
   341    363      else if(this[p]=='W') {
   342    364       if( hige.is_growing_turn(turn) )
   343    365        for(int dy=-1; dy<=+1; ++dy)
   344    366        for(int dx=-1; dx<=+1; ++dx)
   345    367         if(this[p.y+dy,p.x+dx] == ' ')
   346         -       access(new Pos(p.y+dy,p.x+dx)) = 'W';
          368  +       write(p.y+dy,p.x+dx,'W');
   347    369      }
   348    370     }
   349         -  data = next;
   350    371     return dead;
   351    372    }
   352    373   }
   353    374   
   354    375   ////////////////////////////////////////////////////////////////////////////////
   355    376   
   356    377   class Game