Differences From Artifact [189f5a19c7160df3]:
- File
src/game.d
- 2012-07-15 14:55:18 - part of checkin [64f5c73b88] on branch trunk - hige moving tochu. (user: kinaba) [annotate]
To Artifact [7a4ec50fc295cb1f]:
- File
src/game.d
- 2012-07-15 15:13:15 - part of checkin [5491fa544d] on branch trunk - several fixes. (user: kinaba) [annotate]
118 118
119 char[][] data; 119 char[][] data;
120 Pos robot; 120 Pos robot;
121 Pos lift; 121 Pos lift;
122 int waterproof; 122 int waterproof;
123 Pos[char] tr_target; 123 Pos[char] tr_target;
124 Pos[][char] tr_source; 124 Pos[][char] tr_source;
125 const(Hige) hige; <
126 int razor; 125 int razor;
127 int collected_lambda; 126 int collected_lambda;
128 int total_lambda; 127 int total_lambda;
129 bool cleared; 128 bool cleared;
130 Pos[] may_update; 129 Pos[] may_update;
131 130
132 Map clone() const { return new Map(this); } 131 Map clone() const { return new Map(this); }
................................................................................................................................................................................
134 foreach(s; m.data) 133 foreach(s; m.data)
135 this.data ~= s.dup; 134 this.data ~= s.dup;
136 this.robot = m.robot.clone(); 135 this.robot = m.robot.clone();
137 this.lift = m.lift.clone(); 136 this.lift = m.lift.clone();
138 this.waterproof = m.waterproof; 137 this.waterproof = m.waterproof;
139 this.tr_target = cast(Pos[char])m.tr_target; 138 this.tr_target = cast(Pos[char])m.tr_target;
140 this.tr_source = cast(Pos[][char])m.tr_source; 139 this.tr_source = cast(Pos[][char])m.tr_source;
141 this.hige = m.hige.clone(); <
142 this.razor = m.razor; 140 this.razor = m.razor;
143 this.collected_lambda = m.collected_lambda; 141 this.collected_lambda = m.collected_lambda;
144 this.total_lambda = m.total_lambda; 142 this.total_lambda = m.total_lambda;
145 this.may_update = (cast(Map)m).may_update.dup; 143 this.may_update = (cast(Map)m).may_update.dup;
146 this.cleared = m.cleared; 144 this.cleared = m.cleared;
147 } 145 }
148 146
................................................................................................................................................................................
180 this.waterproof = params.get("Waterproof", "5").to!int(); 178 this.waterproof = params.get("Waterproof", "5").to!int();
181 foreach(fr,to; trampo) { 179 foreach(fr,to; trampo) {
182 tr_target[fr] = tr_pos[to]; 180 tr_target[fr] = tr_pos[to];
183 if(to !in tr_source) tr_source[to] = []; 181 if(to !in tr_source) tr_source[to] = [];
184 tr_source[to] ~= tr_pos[fr]; 182 tr_source[to] ~= tr_pos[fr];
185 } 183 }
186 184
187 this.hige = Hige.load(params); <
188 this.razor = params.get("Razors", "0").to!int(); 185 this.razor = params.get("Razors", "0").to!int();
189 } 186 }
190 187
191 const @property { 188 const @property {
192 int H() { return data.length; } 189 int H() { return data.length; }
193 int W() { return data[0].length; } 190 int W() { return data[0].length; }
194 } 191 }
................................................................................................................................................................................
234 231
235 Pos[] razors() const { return objects('!'); } 232 Pos[] razors() const { return objects('!'); }
236 Pos[] lambdas() const { return objects('\\'); } 233 Pos[] lambdas() const { return objects('\\'); }
237 234
238 bool command(char c, int turn, bool hige_day) 235 bool command(char c, int turn, bool hige_day)
239 { 236 {
240 assert( this[robot] == 'R' ); 237 assert( this[robot] == 'R' );
241 if(c=='R') return move( 0, +1, turn, hige_day); | 238 if(c=='R') return move( 0, +1, hige_day);
242 if(c=='L') return move( 0, -1, turn, hige_day); | 239 if(c=='L') return move( 0, -1, hige_day);
243 if(c=='U') return move(+1, 0, turn, hige_day); | 240 if(c=='U') return move(+1, 0, hige_day);
244 if(c=='D') return move(-1, 0, turn, hige_day); | 241 if(c=='D') return move(-1, 0, hige_day);
245 if(c=='W') return move( 0, 0, turn, hige_day); | 242 if(c=='W') return move( 0, 0, hige_day);
246 if(c=='S') return use_razor(turn, hige_day); | 243 if(c=='S') return use_razor(hige_day);
247 assert(false); 244 assert(false);
248 } 245 }
249 246
250 bool use_razor(int turn, bool hige_day) | 247 bool use_razor(bool hige_day)
251 { 248 {
252 if(razor) { 249 if(razor) {
253 razor--; 250 razor--;
254 for(int dy=-1; dy<=+1; ++dy) 251 for(int dy=-1; dy<=+1; ++dy)
255 for(int dx=-1; dx<=+1; ++dx) 252 for(int dx=-1; dx<=+1; ++dx)
256 if(this[robot.y+dy,robot.x+dx] == 'W') { 253 if(this[robot.y+dy,robot.x+dx] == 'W') {
257 emptified(new Pos(robot.y+dy,robot.x+dx) 254 emptified(new Pos(robot.y+dy,robot.x+dx)
258 this[robot.y+dy,robot.x+dx] = ' '; 255 this[robot.y+dy,robot.x+dx] = ' ';
259 } 256 }
260 } 257 }
261 258
262 return update(turn, hige_day); | 259 return update(hige_day);
263 } 260 }
264 261
265 bool rocky(char c) { return c=='*' || c=='@'; } 262 bool rocky(char c) { return c=='*' || c=='@'; }
266 263
267 void emptified(Pos p) { 264 void emptified(Pos p) {
268 for(int dy=0; dy<=+1; ++dy) 265 for(int dy=0; dy<=+1; ++dy)
269 for(int dx=-1; dx<=+1; ++dx) 266 for(int dx=-1; dx<=+1; ++dx)
270 may_update ~= new Pos(p.y+dy, p.x+dx); 267 may_update ~= new Pos(p.y+dy, p.x+dx);
271 } 268 }
272 269
273 bool move(int dy, int dx, int turn, bool hige_day) | 270 bool move(int dy, int dx, bool hige_day)
274 { 271 {
275 <
276 emptified(robot); 272 emptified(robot);
277 273
278 int y = robot.y; 274 int y = robot.y;
279 int x = robot.x; 275 int x = robot.x;
280 if( '\\' == this[y+dy,x+dx] ) 276 if( '\\' == this[y+dy,x+dx] )
281 collected_lambda++; 277 collected_lambda++;
282 if( '!' == this[y+dy,x+dx] ) 278 if( '!' == this[y+dy,x+dx] )
................................................................................................................................................................................
299 foreach(p; tr_source[this[tp]]) { 295 foreach(p; tr_source[this[tp]]) {
300 emptified(p); 296 emptified(p);
301 this[p] = ' '; 297 this[p] = ' ';
302 } 298 }
303 this[tp] = 'R'; 299 this[tp] = 'R';
304 robot = tp; 300 robot = tp;
305 } 301 }
306 return update(turn, hige_day); | 302 return update(hige_day);
307 } 303 }
308 304
309 bool update(int turn, bool hige_day) | 305 bool update(bool hige_day)
310 { 306 {
311 // Write after all the updates are processed. 307 // Write after all the updates are processed.
312 Tuple!(int,int,char)[] write_buffer; 308 Tuple!(int,int,char)[] write_buffer;
313 void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c); 309 void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c);
314 void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c 310 void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c
315 scope(exit) { 311 scope(exit) {
316 may_update.length = 0; 312 may_update.length = 0;
................................................................................................................................................................................
324 } 320 }
325 321
326 if(collected_lambda == total_lambda) 322 if(collected_lambda == total_lambda)
327 if(this[lift]=='L') 323 if(this[lift]=='L')
328 this[lift] = 'O'; 324 this[lift] = 'O';
329 325
330 bool dead = false; 326 bool dead = false;
> 327 if( hige_day ) {
> 328 for(int y=1; y<=H; ++y)
> 329 for(int x=1; x<=W; ++x)
> 330 if(this[y,x]=='W')
> 331 may_update ~= new Pos(y,x);
> 332 }
> 333
331 sort(may_update); 334 sort(may_update);
332 foreach(p; may_update) { 335 foreach(p; may_update) {
333 int y = p.y, x = p.x; 336 int y = p.y, x = p.x;
334 char rock = this[p]; 337 char rock = this[p];
335 if(rocky(this[p])) { 338 if(rocky(this[p])) {
336 if(this[p.D]==' ') { 339 if(this[p.D]==' ') {
337 writep(p, ' '); 340 writep(p, ' ');
................................................................................................................................................................................
348 else if(rocky(this[p.D]) && this[p.L]==' ' && th 351 else if(rocky(this[p.D]) && this[p.L]==' ' && th
349 writep(p, ' '); 352 writep(p, ' ');
350 writep(p.L.D, (rock=='@'&&this[p.L.D.D]! 353 writep(p.L.D, (rock=='@'&&this[p.L.D.D]!
351 if(robot == p.L.D.D) 354 if(robot == p.L.D.D)
352 dead=true; 355 dead=true;
353 } 356 }
354 } 357 }
355 } <
356 <
357 if( hige_day ) <
358 for(int y=1; y<=H; ++y) <
359 for(int x=1; x<=W; ++x) { <
360 Pos p = new Pos(y,x); <
361 if(this[p]=='W') { | 358 else if(this[p]=='W') {
> 359 if(hige_day) {
362 for(int dy=-1; dy<=+1; ++dy) 360 for(int dy=-1; dy<=+1; ++dy)
363 for(int dx=-1; dx<=+1; ++dx) 361 for(int dx=-1; dx<=+1; ++dx)
364 if(this[p.y+dy,p.x+dx] == ' ') 362 if(this[p.y+dy,p.x+dx] == ' ')
365 write(p.y+dy,p.x+dx,'W') 363 write(p.y+dy,p.x+dx,'W')
> 364 }
366 } 365 }
367 } 366 }
368 367
369 return dead; 368 return dead;
370 } 369 }
371 } 370 }
372 371
................................................................................................................................................................................
393 params[ss[0]] = ss[1]; 392 params[ss[0]] = ss[1];
394 if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar 393 if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar
395 trampo[ss[1][0]] = ss[3][0]; 394 trampo[ss[1][0]] = ss[3][0];
396 } 395 }
397 396
398 this.map = new Map(raw_data, params, trampo); 397 this.map = new Map(raw_data, params, trampo);
399 this.water = Water.load(params); 398 this.water = Water.load(params);
> 399 this.hige = Hige.load(params);
400 } 400 }
401 401
402 Game clone() const { return new Game(this); } 402 Game clone() const { return new Game(this); }
403 this(in Game g) { 403 this(in Game g) {
404 map = g.map.clone(); 404 map = g.map.clone();
405 water = g.water.clone(); 405 water = g.water.clone();
> 406 hige = g.hige.clone();
406 turn = g.turn; 407 turn = g.turn;
407 dead = g.dead; 408 dead = g.dead;
408 under_water = g.under_water; 409 under_water = g.under_water;
409 } 410 }
410 411
411 void command(char c) 412 void command(char c)
412 { 413 {
413 assert(c != 'A'); 414 assert(c != 'A');
414 if(dead || cleared) 415 if(dead || cleared)
415 return; 416 return;
416 417
417 // TODO: clarify the event order 418 // TODO: clarify the event order
418 bool dead_now = map.command(c, turn, map.hige.is_growing_turn(tu | 419 bool dead_now = map.command(c, turn, hige.is_growing_turn(turn))
419 if( dead_now ) 420 if( dead_now )
420 dead = true; 421 dead = true;
421 if(!map.cleared) { 422 if(!map.cleared) {
422 if( map.robot.y <= water_level ) 423 if( map.robot.y <= water_level )
423 ++under_water; 424 ++under_water;
424 else 425 else
425 under_water = 0; 426 under_water = 0;
................................................................................................................................................................................
427 dead = true; 428 dead = true;
428 } 429 }
429 turn += 1; 430 turn += 1;
430 } 431 }
431 432
432 Map map; 433 Map map;
433 Water water; 434 Water water;
> 435 Hige hige;
434 int turn = 0; 436 int turn = 0;
435 bool dead = false; 437 bool dead = false;
436 int under_water = 0; 438 int under_water = 0;
437 // TODO: when adding members, take care of clone(). 439 // TODO: when adding members, take care of clone().
438 // TODO: fix this poor design. 440 // TODO: fix this poor design.
439 441
440 @property const: 442 @property const:
441 long score() { return map.collected_lambda*(dead?25L:cleared?7 443 long score() { return map.collected_lambda*(dead?25L:cleared?7
442 int water_level() { return water.level(turn); } 444 int water_level() { return water.level(turn); }
443 int water_until_rise() { return water.until_rise(turn); } 445 int water_until_rise() { return water.until_rise(turn); }
444 int hige_until_rise() { return map.hige.until_rise(turn); } | 446 int hige_until_rise() { return hige.until_rise(turn); }
445 int hp() { return map.waterproof - under_water; } 447 int hp() { return map.waterproof - under_water; }
446 bool cleared() { return map.cleared; } 448 bool cleared() { return map.cleared; }
447 } 449 }