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