Diff
Not logged in

Differences From Artifact [189f5a19c7160df3]:

To Artifact [7a4ec50fc295cb1f]:


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 }