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