Diff
Not logged in

Differences From Artifact [7a4ec50fc295cb1f]:

To Artifact [b141e39ade797d94]:


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