Check-in Differences
Not logged in

Difference From:

[fc9286dad1] uum (user: kinaba, tags: redesign, date: 2012-07-15 12:11:33)

To:

[bd650eb3f9] Output is now fully functional. (user: kinaba, tags: trunk, date: 2012-07-15 11:26:58)

Modified src/game.d from [fc05481901940844] to [9428bbab7d2bc9a8].

346 } 346 } 347 data = next; 347 data = next; 348 return dead; 348 return dead; 349 } 349 } 350 } 350 } 351 351 352 //////////////////////////////////////////////////////////////////////////////// 352 //////////////////////////////////////////////////////////////////////////////// > 353 /* > 354 class Game > 355 { > 356 mixin DeriveShow; > 357 > 358 static Game load(File input) > 359 { > 360 string[] raw_data; > 361 string[string] params; > 362 > 363 // Raw map data; read until empty line. > 364 for(string line; !(line=input.readln().chomp()).empty; ) > 365 raw_data ~= line; > 366 > 367 // Additional commands; read until EOF. > 368 char[char] trampo; > 369 for(string line; !(line=input.readln()).empty; ) { > 370 string[] ss = line.split(); > 371 if( ss.length == 2 ) > 372 params[ss[0]] = ss[1]; > 373 if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar > 374 trampo[ss[1][0]] = ss[3][0]; > 375 } > 376 > 377 return load(raw_data, params, trampo); > 378 } > 379 > 380 static Game load(string[] raw_data, string[string] params, char[char] tr > 381 { > 382 return new Game(raw_data, params, trampo); > 383 } > 384 > 385 this(string[] raw_data, string[string] params, char[char] trampo) > 386 { > 387 this.map = Map.load(raw_data, params, trampo); > 388 this.water = Water.load(params); > 389 } > 390 > 391 Game clone() const { return new Game(this); } > 392 this(in Game g) { > 393 map = g.map.clone(); > 394 water = g.water.clone(); > 395 turn = g.turn; > 396 dead = g.dead; > 397 lambda = g.lambda; > 398 cleared = g.cleared; > 399 under_water = g.under_water; > 400 } > 401 > 402 void command(char c) > 403 { > 404 assert(c != 'A'); > 405 if(dead || cleared) > 406 return; > 407 > 408 // TODO: clarify the event order > 409 Tuple!(int,bool) ld = map.command(c, turn); > 410 if( map.cleared() ) { > 411 cleared = true; > 412 } > 413 else { > 414 lambda += ld[0]; > 415 if( ld[1] ) > 416 dead = true; > 417 } > 418 if(!cleared) { > 419 if( map.robot.y <= water_level ) > 420 ++under_water; > 421 else > 422 under_water = 0; > 423 if( under_water > map.waterproof ) > 424 dead = true; > 425 } > 426 turn += 1; > 427 } > 428 > 429 Map map; > 430 Water water; > 431 int turn = 0; > 432 bool dead = false; > 433 int lambda = 0; > 434 int under_water = 0; > 435 bool cleared = false; > 436 // TODO: when adding members, take care of clone(). > 437 // TODO: fix this poor design. > 438 > 439 @property const { > 440 long score() { return lambda*(dead ? 25L : cleared ? 75L : 50L) > 441 int water_level() { return water.level(turn); } > 442 int water_until_rise() { return water.until_rise(turn); } > 443 int hige_until_rise() { return map.hige.until_rise(turn); } > 444 int hp() { return map.waterproof - under_water; } > 445 } > 446 } > 447 */ > 448 > 449 //////////////////////////////////////////////////////////////////////////////// 353 450 354 class Game 451 class Game 355 { 452 { 356 public: 453 public: 357 this(File input) 454 this(File input) 358 { 455 { 359 // Read map data 456 // Read map data ................................................................................................................................................................................ 445 air_left_ = max_air_; 542 air_left_ = max_air_; 446 } 543 } 447 544 448 @property const { 545 @property const { 449 int H() { return H_; } 546 int H() { return H_; } 450 int W() { return W_; } 547 int W() { return W_; } 451 char trampoline(char c) { return (c in trampoline_ ? trampoline_ 548 char trampoline(char c) { return (c in trampoline_ ? trampoline_ 452 const(Pos)[] trampoline_rev(char c) { < 453 const(Pos)[] pp; < 454 if(c in trampoline_rev_) { < 455 foreach(ch; trampoline_rev_[c]) < 456 pp ~= trampoline_pos_[ch]; < 457 } < 458 return pp; < 459 } < 460 int water_level() { 549 int water_level() { 461 return water_pace_ ? water_base_ + turn_/water_pace_ : w 550 return water_pace_ ? water_base_ + turn_/water_pace_ : w 462 } 551 } 463 int water_until_rise() { 552 int water_until_rise() { 464 return water_pace_ ? water_pace_ - turn_%water_pace_ : i 553 return water_pace_ ? water_pace_ - turn_%water_pace_ : i 465 } 554 } 466 int hige_until_rise() { 555 int hige_until_rise() { ................................................................................................................................................................................ 470 return hige_pace_ ? turn_%hige_pace_ == hige_pace_-1 : f 559 return hige_pace_ ? turn_%hige_pace_ == hige_pace_-1 : f 471 } 560 } 472 int hp() { return air_left_; } 561 int hp() { return air_left_; } 473 int num_razor() { return num_razor_; } 562 int num_razor() { return num_razor_; } 474 bool cleared() { return cleared_; } 563 bool cleared() { return cleared_; } 475 bool dead() { return dead_; } 564 bool dead() { return dead_; } 476 long score() { return num_lambda_*(dead_ ? 25L : cleared_ ? 75L 565 long score() { return num_lambda_*(dead_ ? 25L : cleared_ ? 75L 477 const(Pos) robot() { return robot_pos_; } < 478 const(Pos) lift() { return lift_pos_; } < 479 Pos[] lambdas() { < 480 Pos[] pp; < 481 foreach(p; lambda_pos_) < 482 pp ~= p.clone(); < 483 return pp; < 484 } < 485 Pos[] razors() { < 486 Pos[] pp; < 487 foreach(p; razor_pos_) < 488 pp ~= p.clone(); < 489 return pp; < 490 } < 491 const(Pos)[] higes() { < 492 const(Pos)[] pp; < 493 foreach(p,c; dynamic_objects_) < 494 if(c=='W') < 495 pp ~= p; < 496 return pp; < 497 } < 498 } 566 } 499 const { 567 const { 500 char opIndex(in Pos p) { return opIndex(p.y, p.x); } 568 char opIndex(in Pos p) { return opIndex(p.y, p.x); } 501 char opIndex(int y, int x) { return map_get(y, x); } 569 char opIndex(int y, int x) { return map_get(y, x); } 502 } 570 } 503 571 504 public: 572 public: ................................................................................................................................................................................ 510 if(c == 'U') command_move(+1, 0); 578 if(c == 'U') command_move(+1, 0); 511 if(c == 'D') command_move(-1, 0); 579 if(c == 'D') command_move(-1, 0); 512 if(c == 'L') command_move(0, -1); 580 if(c == 'L') command_move(0, -1); 513 if(c == 'R') command_move(0, +1); 581 if(c == 'R') command_move(0, +1); 514 if(c == 'S') use_razor(); 582 if(c == 'S') use_razor(); 515 if(c == 'W') {} 583 if(c == 'W') {} 516 584 517 if(!cleared) | 585 if(cleared) > 586 return; 518 { | 587 519 map_update(); | 588 map_update(); 520 water_update(); | 589 water_update(); 521 } < 522 turn_ ++; 590 turn_ ++; 523 } 591 } 524 592 525 void command_move(int dy, int dx) 593 void command_move(int dy, int dx) 526 { 594 { 527 int y = robot_pos_.y, x = robot_pos_.x; 595 int y = robot_pos_.y, x = robot_pos_.x; 528 char c = this[y+dy, x+dx]; 596 char c = this[y+dy, x+dx]; ................................................................................................................................................................................ 720 void map_set_empty(int y, int x) 788 void map_set_empty(int y, int x) 721 { 789 { 722 if( y<1 || H<y || x<1 || W<x ) return; 790 if( y<1 || H<y || x<1 || W<x ) return; 723 if( x<0 || raw_data_[y].length<=x ) return; 791 if( x<0 || raw_data_[y].length<=x ) return; 724 raw_data_[y][x] = ' '; 792 raw_data_[y][x] = ' '; 725 } 793 } 726 794 727 public: < 728 Game clone() const { return new Game(this); } < 729 this(in Game g) { < 730 H_ = g.H_; < 731 W_ = g.W_; < 732 raw_data_ = new char[][g.raw_data_.length]; < 733 foreach(i,d; g.raw_data_) raw_data_[i] = d.dup; < 734 trampoline_pos_ = cast(Pos[char]) g.trampoline_pos_; < 735 razor_pos_ = (cast(Game)g).razor_pos_.dup; < 736 lambda_pos_ = (cast(Game)g).lambda_pos_.dup; < 737 lift_pos_ = g.lift_pos_.clone(); < 738 robot_pos_ = g.robot_pos_.clone(); < 739 dynamic_objects_ = dup(g.dynamic_objects_); < 740 trampoline_ = (cast(Game)g).trampoline_; < 741 trampoline_rev_ = (cast(Game)g).trampoline_rev_; < 742 water_base_ = g.water_base_; < 743 water_pace_ = g.water_pace_; < 744 max_air_ = g.max_air_; < 745 hige_pace_ = g.hige_pace_; < 746 num_razor_ = g.num_razor_; < 747 num_lambda_ = g.num_lambda_; < 748 turn_ = g.turn_; < 749 air_left_ = g.air_left_; < 750 cleared_ = g.cleared_; < 751 dead_ = g.dead_; < 752 may_update_ = dup(g.may_update_); < 753 } < 754 < 755 V[K] dup(V,K)(in V[K] aa) { < 756 V[K] aa2; < 757 foreach(k,v; aa) aa2[k] = v; < 758 return aa2; < 759 } < 760 < 761 private: 795 private: 762 int H_; 796 int H_; 763 int W_; 797 int W_; 764 char[][] raw_data_; 798 char[][] raw_data_; 765 Pos[char] trampoline_pos_; 799 Pos[char] trampoline_pos_; 766 Pos[] razor_pos_; 800 Pos[] razor_pos_; 767 Pos[] lambda_pos_; 801 Pos[] lambda_pos_;

Modified src/gui_main.d from [05082d0f328d756c] to [372bc7cd7d19e082].

5 import std.stdio; 5 import std.stdio; 6 pragma(lib, "dfl.lib"); 6 pragma(lib, "dfl.lib"); 7 7 8 void main(string[] args) 8 void main(string[] args) 9 { 9 { 10 Driver d = new Driver(stdin); 10 Driver d = new Driver(stdin); 11 d.addObserver!(GuardedOutput)(); 11 d.addObserver!(GuardedOutput)(); 12 auto g = d.addObserver!(GUI!MainSolver)(); | 12 // auto g = d.addObserver!(GUI!MainSolver)(); > 13 auto g = d.addObserver!(GUI!Solver_0)(); 13 g.set_fn(&d.command); 14 g.set_fn(&d.command); 14 g.run(); 15 g.run(); 15 } 16 }

Modified src/solver.d from [22c356ff1975e92f] to [42b4ef037737dcd0].

3 3 4 class Solver_0 4 class Solver_0 5 { 5 { 6 this(in Game g) {} 6 this(in Game g) {} 7 char single_step() { return 'W'; } 7 char single_step() { return 'W'; } 8 void force(char c) {} 8 void force(char c) {} 9 } 9 } 10 < > 10 /* 11 class Solver_1 11 class Solver_1 12 { 12 { 13 int wait_count = 0; 13 int wait_count = 0; 14 int choke_count = 0; 14 int choke_count = 0; 15 15 16 Game g; 16 Game g; 17 this(in Game g) 17 this(in Game g) 18 { 18 { 19 this.g = g.clone(); 19 this.g = g.clone(); 20 forbidden_cell = new bool[][](g.H+2, g.W+2); | 20 forbidden_cell = new bool[][](g.map.H+2, g.map.W+2); 21 } 21 } 22 22 23 char single_step() 23 char single_step() 24 { 24 { 25 Tuple!(string,int) de = death_move(g); 25 Tuple!(string,int) de = death_move(g); 26 char c = act(g, de[0], de[1]); 26 char c = act(g, de[0], de[1]); 27 force(c); 27 force(c); ................................................................................................................................................................................ 39 string death; 39 string death; 40 int choice = 0; 40 int choice = 0; 41 foreach(char c; "UDLRW") { 41 foreach(char c; "UDLRW") { 42 Game gg = g.clone(); 42 Game gg = g.clone(); 43 gg.command(c); 43 gg.command(c); 44 if( !gg.cleared && gg.dead ) 44 if( !gg.cleared && gg.dead ) 45 death ~= c; 45 death ~= c; 46 else if( gg.robot != g.robot ) | 46 else if( gg.map.robot != g.map.robot ) 47 choice++; 47 choice++; 48 else if( c != 'W' ) // meaningless move 48 else if( c != 'W' ) // meaningless move 49 death ~= c; 49 death ~= c; 50 } 50 } 51 return tuple(death, choice); 51 return tuple(death, choice); 52 } 52 } 53 53 54 Tuple!(Pos, int)[] log; 54 Tuple!(Pos, int)[] log; 55 bool[][] forbidden_cell; 55 bool[][] forbidden_cell; 56 56 57 char act(const(Game) g, string death, int breath) 57 char act(const(Game) g, string death, int breath) 58 { 58 { 59 const Pos ro = g.robot; | 59 const Pos ro = g.map.robot; 60 const Pos li = g.lift; | 60 const Pos li = g.map.lift; 61 Pos[] la = g.lambdas(); | 61 Pos[] la = g.map.lambdas(); 62 sort!((Pos a,Pos b){ 62 sort!((Pos a,Pos b){ 63 int ad=abs(a.y-li.y)+abs(a.x-li.x); 63 int ad=abs(a.y-li.y)+abs(a.x-li.x); 64 int bd=abs(b.y-li.y)+abs(b.x-li.x); 64 int bd=abs(b.y-li.y)+abs(b.x-li.x); 65 return ad>bd;; 65 return ad>bd;; 66 })(la); 66 })(la); 67 Pos[] ra = g.razors(); | 67 Pos[] ra = g.map.razors(); 68 const(Pos)[] hi = g.higes(); | 68 const(Pos)[] hi = g.map.objects('W'); 69 69 70 Tuple!(char,int)[] cand; 70 Tuple!(char,int)[] cand; 71 char c = 'W'; 71 char c = 'W'; 72 if( la.empty ) { 72 if( la.empty ) { 73 cand = search(g, ro, [li], death); 73 cand = search(g, ro, [li], death); 74 } else { 74 } else { 75 cand ~= search(g, ro, la~ra, death); 75 cand ~= search(g, ro, la~ra, death); 76 } 76 } 77 77 78 // 'higesori' mode 78 // 'higesori' mode 79 if( !hi.empty && g.num_razor>0 ) { | 79 if( !hi.empty && g.map.razor>0 ) { 80 int his = 0; 80 int his = 0; 81 for(int dy=-1; dy<=+1; ++dy) 81 for(int dy=-1; dy<=+1; ++dy) 82 for(int dx=-1; dx<=+1; ++dx) 82 for(int dx=-1; dx<=+1; ++dx) 83 if(g[ro.y+dy,ro.x+dx] == 'W') | 83 if(g.map[ro.y+dy,ro.x+dx] == 'W') 84 his++; 84 his++; 85 85 86 if(his>=2 || his==hi.length) 86 if(his>=2 || his==hi.length) 87 cand = [tuple('S',int.max)]; 87 cand = [tuple('S',int.max)]; 88 if(cand.empty) { 88 if(cand.empty) { 89 const(Pos)[] tgt; 89 const(Pos)[] tgt; 90 for(int y=1; y<=g.H; ++y) | 90 for(int y=1; y<=g.map.H; ++y) 91 for(int x=1; x<=g.W; ++x) | 91 for(int x=1; x<=g.map.W; ++x) 92 if(g[y,x]=='.'||g[y,x]==' ') { | 92 if(g.map[y,x]=='.'||g.map[y,x]==' ') { 93 his = 0; 93 his = 0; 94 for(int dy=-1; dy<=+1; ++dy) 94 for(int dy=-1; dy<=+1; ++dy) 95 for(int dx=-1; dx<=+1; ++dx) 95 for(int dx=-1; dx<=+1; ++dx) 96 if(g[y+dy,x+dx] == 'W') | 96 if(g.map[y+dy,x+dx] == ' 97 his++; 97 his++; 98 if(his>=2) 98 if(his>=2) 99 tgt ~= new Pos(y,x); 99 tgt ~= new Pos(y,x); 100 } 100 } 101 cand ~= search(g, ro, tgt, death, true); 101 cand ~= search(g, ro, tgt, death, true); 102 } 102 } 103 } 103 } 104 104 105 // 'dig' mode 105 // 'dig' mode 106 if(cand.empty) { 106 if(cand.empty) { 107 const(Pos)[] tgt; 107 const(Pos)[] tgt; 108 for(int y=1; y<=g.H; ++y) | 108 for(int y=1; y<=g.map.H; ++y) 109 for(int x=1; x<=g.W; ++x) | 109 for(int x=1; x<=g.map.W; ++x) 110 if(g[y,x]=='.') | 110 if(g.map[y,x]=='.') 111 if(g[y+1,x]=='*'||g[y+1,x-1]=='*'||g[y+1 | 111 if(g.map[y+1,x]=='*'||g.map[y+1,x-1]=='* 112 ||g[y,x+1]=='*'||g[y,x-1]=='*') | 112 ||g.map[y,x+1]=='*'||g.map[y,x-1]=='*') 113 tgt ~= new Pos(y,x); 113 tgt ~= new Pos(y,x); 114 cand ~= search(g, ro, tgt, death, true); 114 cand ~= search(g, ro, tgt, death, true); 115 } 115 } 116 116 117 if(cand.empty) { 117 if(cand.empty) { 118 choke_count++; 118 choke_count++; 119 cand ~= tuple('W',int.max); 119 cand ~= tuple('W',int.max); ................................................................................................................................................................................ 133 } 133 } 134 } 134 } 135 135 136 if(c == 'W') 136 if(c == 'W') 137 wait_count++; 137 wait_count++; 138 else 138 else 139 wait_count = 0; 139 wait_count = 0; 140 if(choke_count >= g.H) | 140 if(choke_count >= g.map.H) 141 c = 'A'; 141 c = 'A'; 142 142 143 bool[char] choice; 143 bool[char] choice; 144 foreach(t; cand) 144 foreach(t; cand) 145 choice[t[0]] = true; 145 choice[t[0]] = true; 146 log ~= tuple(ro.clone(), cast(int)choice.length); 146 log ~= tuple(ro.clone(), cast(int)choice.length); 147 if(log.length > 5) 147 if(log.length > 5) ................................................................................................................................................................................ 157 return c; 157 return c; 158 } 158 } 159 159 160 Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death 160 Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death 161 { 161 { 162 bool danger(int y, int x) 162 bool danger(int y, int x) 163 { 163 { 164 if(g[y,x] == ' ' || g[y,x] == 'R') | 164 if(g.map[y,x] == ' ' || g.map[y,x] == 'R') 165 return false; 165 return false; 166 if(g[y+1,x] == '*') | 166 if(g.map[y+1,x] == '*') > 167 return true; > 168 if(g.map[y+1,x-1]=='*' && (g.map[y,x-1]=='\\'||g.map[y,x 167 return true; 169 return true; 168 if(g[y+1,x-1]=='*' && (g[y,x-1]=='\\'||g[y,x-1]=='*') && | 170 if(g.map[y+1,x+1]=='*' && (g.map[y,x+1]=='*') && (g.map[ 169 return true; 171 return true; 170 if(g[y+1,x+1]=='*' && (g[y,x+1]=='*') && (g[y+1,x]==' '| | 172 if(g.map[y,x-1]=='*' && (g.map[y-1,x-1]=='\\'||g.map[y-1 171 return true; 173 return true; 172 if(g[y,x-1]=='*' && (g[y-1,x-1]=='\\'||g[y-1,x-1]=='*') | 174 if(g.map[y,x+1]=='*' && (g.map[y-1,x+1]=='*') && (g.map[ 173 return true; < 174 if(g[y,x+1]=='*' && (g[y-1,x+1]=='*') && (g[y-1,x]==' '| < 175 return true; 175 return true; 176 return false; 176 return false; 177 } 177 } 178 178 179 // avoid directly below '*' 179 // avoid directly below '*' 180 Tuple!(char,int)[] tryA() { 180 Tuple!(char,int)[] tryA() { 181 const(Pos)[] q; 181 const(Pos)[] q; 182 foreach(p; gs) 182 foreach(p; gs) 183 if(!danger(p.y,p.x)) 183 if(!danger(p.y,p.x)) 184 q ~= p; 184 q ~= p; 185 bool[][] v = new bool[][](g.H+2, g.W+2); | 185 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); 186 foreach(p; q) v[p.y][p.x]=true; 186 foreach(p; q) v[p.y][p.x]=true; 187 for(int step=1; q.length; ++step) { 187 for(int step=1; q.length; ++step) { 188 Pos[] q2; 188 Pos[] q2; 189 foreach(p; q) { 189 foreach(p; q) { 190 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 190 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 191 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 191 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 192 for(int i=0; i<yyy.length; ++i) { 192 for(int i=0; i<yyy.length; ++i) { 193 int y = yyy[i]; 193 int y = yyy[i]; 194 int x = xxx[i]; 194 int x = xxx[i]; 195 if('1'<=g[y,x]&&g[y,x]<='9') { | 195 if('1'<=g.map[y,x]&&g.map[y,x]<= 196 foreach(ppp; g.trampolin | 196 foreach(ppp; g.map.tr_so 197 yyy ~= ppp.y; 197 yyy ~= ppp.y; 198 xxx ~= ppp.x; 198 xxx ~= ppp.x; 199 } 199 } 200 continue; 200 continue; 201 } 201 } 202 if(v[y][x]) continue; 202 if(v[y][x]) continue; 203 if(y==s.y && x==s.x && i<4) { 203 if(y==s.y && x==s.x && i<4) { 204 char c = "UDRL"[i]; 204 char c = "UDRL"[i]; 205 if( death.count(c) == 0 205 if( death.count(c) == 0 206 return [tuple(c, 206 return [tuple(c, 207 } else if(forbidden_cell[y][x]){ 207 } else if(forbidden_cell[y][x]){ 208 } else if(g[y,x]==' '||g[y,x]==' | 208 } else if(g.map[y,x]==' '||g.map 209 if(danger(y,x)) 209 if(danger(y,x)) 210 continue; 210 continue; 211 q2 ~= new Pos(y,x); 211 q2 ~= new Pos(y,x); 212 v[y][x]=true; 212 v[y][x]=true; 213 } 213 } 214 } 214 } 215 } 215 } ................................................................................................................................................................................ 218 return []; 218 return []; 219 } 219 } 220 220 221 // any empty space is my ground 221 // any empty space is my ground 222 Tuple!(char,int)[] tryB() { 222 Tuple!(char,int)[] tryB() { 223 const(Pos)[] q; 223 const(Pos)[] q; 224 foreach(p; gs) q ~= p; 224 foreach(p; gs) q ~= p; 225 bool[][] v = new bool[][](g.H+2, g.W+2); | 225 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); 226 foreach(p; q) v[p.y][p.x]=true; 226 foreach(p; q) v[p.y][p.x]=true; 227 for(int step=10; q.length; ++step) { 227 for(int step=10; q.length; ++step) { 228 Pos[] q2; 228 Pos[] q2; 229 foreach(p; q) { 229 foreach(p; q) { 230 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 230 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 231 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 231 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 232 for(int i=0; i<yyy.length; ++i) { 232 for(int i=0; i<yyy.length; ++i) { 233 int y = yyy[i]; 233 int y = yyy[i]; 234 int x = xxx[i]; 234 int x = xxx[i]; 235 if('1'<=g[y,x]&&g[y,x]<='9') { | 235 if('1'<=g.map[y,x]&&g.map[y,x]<= 236 foreach(ppp; g.trampolin | 236 foreach(ppp; g.map.tr_so 237 yyy ~= ppp.y; 237 yyy ~= ppp.y; 238 xxx ~= ppp.x; 238 xxx ~= ppp.x; 239 } 239 } 240 continue; 240 continue; 241 } 241 } 242 if(v[y][x]) continue; 242 if(v[y][x]) continue; 243 if(y==s.y && x==s.x && i<4) { 243 if(y==s.y && x==s.x && i<4) { 244 char c = "UDRL"[i]; 244 char c = "UDRL"[i]; 245 if( death.count(c) == 0 245 if( death.count(c) == 0 246 return [tuple(c, 246 return [tuple(c, 247 } else if(forbidden_cell[y][x]){ 247 } else if(forbidden_cell[y][x]){ 248 } else if(g[y,x]==' '||g[y,x]==' | 248 } else if(g.map[y,x]==' '||g.map 249 q2 ~= new Pos(y,x); 249 q2 ~= new Pos(y,x); 250 v[y][x]=true; 250 v[y][x]=true; 251 } 251 } 252 } 252 } 253 } 253 } 254 q = q2; 254 q = q2; 255 } 255 } ................................................................................................................................................................................ 256 return []; 256 return []; 257 } 257 } 258 258 259 // push rocks! 259 // push rocks! 260 Tuple!(char,int)[] tryC() { 260 Tuple!(char,int)[] tryC() { 261 const(Pos)[] q; 261 const(Pos)[] q; 262 foreach(p; gs) q ~= p; 262 foreach(p; gs) q ~= p; 263 bool[][] v = new bool[][](g.H+2, g.W+2); | 263 bool[][] v = new bool[][](g.map.H+2, g.map.W+2); 264 foreach(p; q) v[p.y][p.x]=true; 264 foreach(p; q) v[p.y][p.x]=true; 265 for(int step=20; q.length; ++step) { 265 for(int step=20; q.length; ++step) { 266 Pos[] q2; 266 Pos[] q2; 267 foreach(p; q) { 267 foreach(p; q) { 268 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 268 int[] yyy=[p.y-1,p.y+1,p.y,p.y]; 269 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 269 int[] xxx=[p.x,p.x,p.x-1,p.x+1]; 270 for(int i=0; i<yyy.length; ++i) { 270 for(int i=0; i<yyy.length; ++i) { 271 int y = yyy[i]; 271 int y = yyy[i]; 272 int x = xxx[i]; 272 int x = xxx[i]; 273 if(g[p] == '*') { | 273 if(g.map[p] == '*') { 274 if(i>=4)continue; 274 if(i>=4)continue; 275 if(y!=p.y)continue; 275 if(y!=p.y)continue; 276 if(g[y,p.x+(p.x-x)]!=' ' | 276 if(g.map[y,p.x+(p.x-x)]! 277 } 277 } 278 if('1'<=g[y,x]&&g[y,x]<='9') { | 278 if('1'<=g.map[y,x]&&g.map[y,x]<= 279 foreach(ppp; g.trampolin | 279 foreach(ppp; g.map.tr_so 280 yyy ~= ppp.y; 280 yyy ~= ppp.y; 281 xxx ~= ppp.x; 281 xxx ~= ppp.x; 282 } 282 } 283 continue; 283 continue; 284 } 284 } 285 if(v[y][x]) continue; 285 if(v[y][x]) continue; 286 if(y==s.y && x==s.x && i<4) { 286 if(y==s.y && x==s.x && i<4) { 287 char c = "UDRL"[i]; 287 char c = "UDRL"[i]; 288 if( death.count(c) == 0 288 if( death.count(c) == 0 289 return [tuple(c, 289 return [tuple(c, 290 } else if(forbidden_cell[y][x]){ 290 } else if(forbidden_cell[y][x]){ 291 } else if(g[y,x]==' '||g[y,x]==' | 291 } else if(g.map[y,x]==' '||g.map 292 q2 ~= new Pos(y,x); 292 q2 ~= new Pos(y,x); 293 v[y][x]=true; 293 v[y][x]=true; 294 } 294 } 295 } 295 } 296 } 296 } 297 q = q2; 297 q = q2; 298 } 298 } ................................................................................................................................................................................ 314 make_plan(g); 314 make_plan(g); 315 } 315 } 316 316 317 Tuple!(Solver,string) run_sub_solver(in Game g) 317 Tuple!(Solver,string) run_sub_solver(in Game g) 318 { 318 { 319 string log; 319 string log; 320 auto s = new Solver(g); 320 auto s = new Solver(g); 321 while(!g.cleared && !g.dead && plan.length<=g.H*g.W) { | 321 while(!g.cleared && !g.dead && plan.length<=g.map.H*g.map.W) { 322 char c = s.single_step(); 322 char c = s.single_step(); 323 if( c == 'A' ) 323 if( c == 'A' ) 324 break; 324 break; 325 log ~= c; 325 log ~= c; 326 } 326 } 327 while(log.length>0 && log[$-1]=='W') 327 while(log.length>0 && log[$-1]=='W') 328 log.length--; 328 log.length--; ................................................................................................................................................................................ 383 plan_broken = true; 383 plan_broken = true; 384 } 384 } 385 else 385 else 386 plan = plan[1..$]; 386 plan = plan[1..$]; 387 } 387 } 388 } 388 } 389 389 390 alias Solver_2!(Solver_1) MainSolver; | 390 //alias Solver_2!(Solver_1) MainSolver; 391 //alias Solver_1 MainSolver; | 391 alias Solver_1 MainSolver; > 392 */