Diff
Not logged in

Differences From Artifact [7a4ec50fc295cb1f]:

To Artifact [b141e39ade797d94]:


39 39 40 //////////////////////////////////////////////////////////////////////////////// 40 //////////////////////////////////////////////////////////////////////////////// 41 41 42 class Water 42 class Water 43 { 43 { 44 public immutable int base, pace; 44 public immutable int base, pace; 45 mixin DeriveCreate; 45 mixin DeriveCreate; 46 mixin DeriveCompare; < 47 mixin DeriveShow; 46 mixin DeriveShow; 48 Water clone() const { return cast(Water) this; } 47 Water clone() const { return cast(Water) this; } 49 48 50 static load(string[string] params) 49 static load(string[string] params) 51 { 50 { 52 return new Water(params.get("Water", "0").to!int(), 51 return new Water(params.get("Water", "0").to!int(), 53 params.get("Flooding", "0").to!int()); 52 params.get("Flooding", "0").to!int()); ................................................................................................................................................................................ 86 85 87 //////////////////////////////////////////////////////////////////////////////// 86 //////////////////////////////////////////////////////////////////////////////// 88 87 89 class Hige 88 class Hige 90 { 89 { 91 public immutable int pace; 90 public immutable int pace; 92 mixin DeriveCreate; 91 mixin DeriveCreate; 93 mixin DeriveCompare; < 94 mixin DeriveShow; 92 mixin DeriveShow; 95 Hige clone() const { return cast(Hige)this; } 93 Hige clone() const { return cast(Hige)this; } 96 94 97 static load(string[string] params) 95 static load(string[string] params) 98 { 96 { 99 return new Hige(params.get("Growth", "25").to!int()); 97 return new Hige(params.get("Growth", "25").to!int()); 100 } 98 } ................................................................................................................................................................................ 108 { 106 { 109 return pace ? pace-turn%pace : int.max; 107 return pace ? pace-turn%pace : int.max; 110 } 108 } 111 } 109 } 112 110 113 //////////////////////////////////////////////////////////////////////////////// 111 //////////////////////////////////////////////////////////////////////////////// 114 112 > 113 class Trampoline > 114 { > 115 private immutable char[] target_of_; > 116 private immutable char[][] source_of_; > 117 private immutable Pos[] position_of_; > 118 private immutable char[] source_list_; > 119 private immutable char[] target_list_; > 120 mixin DeriveShow; > 121 Trampoline clone() const { return cast(Trampoline) this; } > 122 this(Map m, char[char] tramparam) > 123 { > 124 auto ta = new char['I'+1]; > 125 auto sr = new char[]['9'+1]; > 126 auto po = new Pos[max('I','9')+1]; > 127 char[] sl, tl; > 128 foreach(fr,to; tramparam) { > 129 ta[fr] = to; > 130 sr[to] ~= fr; > 131 } > 132 for(int y=1; y<=m.H; ++y) > 133 for(int x=1; x<=m.W; ++x) { > 134 char c = m[y,x]; > 135 if('A'<=c && c<='I') { > 136 sl ~= c; > 137 po[c] = new Pos(y,x); > 138 } > 139 if('1'<=c && c<='9') { > 140 tl ~= c; > 141 po[c] = new Pos(y,x); > 142 } > 143 } > 144 target_of_ = cast(immutable) ta; > 145 source_of_ = cast(immutable) sr; > 146 position_of_ = cast(immutable) po; > 147 source_list_ = cast(immutable) sl; > 148 target_list_ = cast(immutable) tl; > 149 } > 150 > 151 @property const: > 152 const(char[]) source_list() { return source_list_; } > 153 const(char[]) target_list() { return target_list_; } > 154 const(char[]) source_of(char c) { return source_of_[c]; } > 155 char target_of(char c) { return target_of_[c]; } > 156 Pos[] source_pos(char c) { > 157 Pos[] ps; > 158 foreach(s; source_of(c)) > 159 ps ~= position_of_[s].clone(); > 160 return ps; > 161 } > 162 Pos target_pos(char c) { return position_of_[target_of_[c]].clone(); } > 163 } > 164 > 165 //////////////////////////////////////////////////////////////////////////////// > 166 115 class Map 167 class Map 116 { 168 { 117 mixin DeriveShow; 169 mixin DeriveShow; 118 170 119 char[][] data; 171 char[][] data; 120 Pos robot; 172 Pos robot; 121 Pos lift; 173 Pos lift; 122 int waterproof; 174 int waterproof; 123 Pos[char] tr_target; < 124 Pos[][char] tr_source; < 125 int razor; 175 int razor; 126 int collected_lambda; 176 int collected_lambda; 127 int total_lambda; 177 int total_lambda; 128 bool cleared; 178 bool cleared; 129 Pos[] may_update; 179 Pos[] may_update; 130 180 131 Map clone() const { return new Map(this); } 181 Map clone() const { return new Map(this); } 132 this(in Map m) { 182 this(in Map m) { 133 foreach(s; m.data) 183 foreach(s; m.data) 134 this.data ~= s.dup; 184 this.data ~= s.dup; 135 this.robot = m.robot.clone(); 185 this.robot = m.robot.clone(); 136 this.lift = m.lift.clone(); 186 this.lift = m.lift.clone(); 137 this.waterproof = m.waterproof; 187 this.waterproof = m.waterproof; 138 this.tr_target = cast(Pos[char])m.tr_target; < 139 this.tr_source = cast(Pos[][char])m.tr_source; < 140 this.razor = m.razor; 188 this.razor = m.razor; 141 this.collected_lambda = m.collected_lambda; 189 this.collected_lambda = m.collected_lambda; 142 this.total_lambda = m.total_lambda; 190 this.total_lambda = m.total_lambda; 143 this.may_update = (cast(Map)m).may_update.dup; 191 this.may_update = (cast(Map)m).may_update.dup; 144 this.cleared = m.cleared; 192 this.cleared = m.cleared; 145 } 193 } 146 194 ................................................................................................................................................................................ 163 this.lift = new Pos(y,x); 211 this.lift = new Pos(y,x); 164 if(this[y,x] == '\\' || this[y,x] == '@') 212 if(this[y,x] == '\\' || this[y,x] == '@') 165 total_lambda++; 213 total_lambda++; 166 if(this[y,x] == '*' || this[y,x] == '@') 214 if(this[y,x] == '*' || this[y,x] == '@') 167 may_update ~= new Pos(y,x); 215 may_update ~= new Pos(y,x); 168 } 216 } 169 217 170 Pos[char] tr_pos; < 171 for(int y=1; y<=H; ++y) < 172 for(int x=1; x<=W; ++x) { < 173 char c = this[y,x]; < 174 if('1'<=c && c<='9' || 'A'<=c&&c<='I') < 175 tr_pos[c] = new Pos(y,x); < 176 } < 177 < 178 this.waterproof = params.get("Waterproof", "5").to!int(); 218 this.waterproof = params.get("Waterproof", "5").to!int(); 179 foreach(fr,to; trampo) { < 180 tr_target[fr] = tr_pos[to]; < 181 if(to !in tr_source) tr_source[to] = []; < 182 tr_source[to] ~= tr_pos[fr]; < 183 } < 184 < 185 this.razor = params.get("Razors", "0").to!int(); 219 this.razor = params.get("Razors", "0").to!int(); 186 } 220 } 187 221 188 const @property { 222 const @property { 189 int H() { return data.length; } 223 int H() { return data.length; } 190 int W() { return data[0].length; } 224 int W() { return data[0].length; } 191 } 225 } ................................................................................................................................................................................ 228 ans ~= new Pos(y,x); 262 ans ~= new Pos(y,x); 229 return ans; 263 return ans; 230 } 264 } 231 265 232 Pos[] razors() const { return objects('!'); } 266 Pos[] razors() const { return objects('!'); } 233 Pos[] lambdas() const { return objects('\\'); } 267 Pos[] lambdas() const { return objects('\\'); } 234 268 235 bool command(char c, int turn, bool hige_day) | 269 bool command(char c, int turn, bool hige_day, in Trampoline tr) 236 { 270 { 237 assert( this[robot] == 'R' ); 271 assert( this[robot] == 'R' ); 238 if(c=='R') return move( 0, +1, hige_day); | 272 if(c=='R') return move( 0, +1, hige_day, tr); 239 if(c=='L') return move( 0, -1, hige_day); | 273 if(c=='L') return move( 0, -1, hige_day, tr); 240 if(c=='U') return move(+1, 0, hige_day); | 274 if(c=='U') return move(+1, 0, hige_day, tr); 241 if(c=='D') return move(-1, 0, hige_day); | 275 if(c=='D') return move(-1, 0, hige_day, tr); 242 if(c=='W') return move( 0, 0, hige_day); | 276 if(c=='W') return move( 0, 0, hige_day, tr); 243 if(c=='S') return use_razor(hige_day); 277 if(c=='S') return use_razor(hige_day); 244 assert(false); 278 assert(false); 245 } 279 } 246 280 247 bool use_razor(bool hige_day) 281 bool use_razor(bool hige_day) 248 { 282 { 249 if(razor) { 283 if(razor) { ................................................................................................................................................................................ 263 297 264 void emptified(Pos p) { 298 void emptified(Pos p) { 265 for(int dy=0; dy<=+1; ++dy) 299 for(int dy=0; dy<=+1; ++dy) 266 for(int dx=-1; dx<=+1; ++dx) 300 for(int dx=-1; dx<=+1; ++dx) 267 may_update ~= new Pos(p.y+dy, p.x+dx); 301 may_update ~= new Pos(p.y+dy, p.x+dx); 268 } 302 } 269 303 270 bool move(int dy, int dx, bool hige_day) | 304 bool move(int dy, int dx, bool hige_day, in Trampoline tr) 271 { 305 { 272 emptified(robot); 306 emptified(robot); 273 307 274 int y = robot.y; 308 int y = robot.y; 275 int x = robot.x; 309 int x = robot.x; 276 if( '\\' == this[y+dy,x+dx] ) 310 if( '\\' == this[y+dy,x+dx] ) 277 collected_lambda++; 311 collected_lambda++; ................................................................................................................................................................................ 287 char rock = this[y+dy,x+dx]; 321 char rock = this[y+dy,x+dx]; 288 this[y,x]=' '; 322 this[y,x]=' '; 289 this[y+dy,x+dx]='R'; 323 this[y+dy,x+dx]='R'; 290 this[y+dy*2,x+dx*2]=rock; 324 this[y+dy*2,x+dx*2]=rock; 291 robot = new Pos(y+dy,x+dx); 325 robot = new Pos(y+dy,x+dx); 292 } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') { 326 } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') { 293 this[y,x]=' '; 327 this[y,x]=' '; 294 Pos tp = tr_target[this[y+dy,x+dx]]; | 328 Pos tp = tr.target_pos(this[y+dy,x+dx]); 295 foreach(p; tr_source[this[tp]]) { | 329 foreach(p; tr.source_pos(this[tp])) { 296 emptified(p); 330 emptified(p); 297 this[p] = ' '; 331 this[p] = ' '; 298 } 332 } 299 this[tp] = 'R'; 333 this[tp] = 'R'; 300 robot = tp; 334 robot = tp; 301 } 335 } 302 return update(hige_day); 336 return update(hige_day); ................................................................................................................................................................................ 393 if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar 427 if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar 394 trampo[ss[1][0]] = ss[3][0]; 428 trampo[ss[1][0]] = ss[3][0]; 395 } 429 } 396 430 397 this.map = new Map(raw_data, params, trampo); 431 this.map = new Map(raw_data, params, trampo); 398 this.water = Water.load(params); 432 this.water = Water.load(params); 399 this.hige = Hige.load(params); 433 this.hige = Hige.load(params); > 434 this.tr = new Trampoline(this.map, trampo); 400 } 435 } 401 436 402 Game clone() const { return new Game(this); } 437 Game clone() const { return new Game(this); } 403 this(in Game g) { 438 this(in Game g) { 404 map = g.map.clone(); 439 map = g.map.clone(); 405 water = g.water.clone(); 440 water = g.water.clone(); 406 hige = g.hige.clone(); 441 hige = g.hige.clone(); > 442 tr = g.tr.clone(); 407 turn = g.turn; 443 turn = g.turn; 408 dead = g.dead; 444 dead = g.dead; 409 under_water = g.under_water; 445 under_water = g.under_water; 410 } 446 } 411 447 412 void command(char c) 448 void command(char c) 413 { 449 { 414 assert(c != 'A'); 450 assert(c != 'A'); 415 if(dead || cleared) 451 if(dead || cleared) 416 return; 452 return; 417 453 418 // TODO: clarify the event order 454 // TODO: clarify the event order 419 bool dead_now = map.command(c, turn, hige.is_growing_turn(turn)) | 455 bool dead_now = map.command(c, turn, hige.is_growing_turn(turn), 420 if( dead_now ) 456 if( dead_now ) 421 dead = true; 457 dead = true; 422 if(!map.cleared) { 458 if(!map.cleared) { 423 if( map.robot.y <= water_level ) 459 if( map.robot.y <= water_level ) 424 ++under_water; 460 ++under_water; 425 else 461 else 426 under_water = 0; 462 under_water = 0; ................................................................................................................................................................................ 429 } 465 } 430 turn += 1; 466 turn += 1; 431 } 467 } 432 468 433 Map map; 469 Map map; 434 Water water; 470 Water water; 435 Hige hige; 471 Hige hige; > 472 Trampoline tr; 436 int turn = 0; 473 int turn = 0; 437 bool dead = false; 474 bool dead = false; 438 int under_water = 0; 475 int under_water = 0; 439 // TODO: when adding members, take care of clone(). 476 // TODO: when adding members, take care of clone(). 440 // TODO: fix this poor design. 477 // TODO: fix this poor design. 441 478 442 @property const: 479 @property const: