Differences From Artifact [4dfcc976e17caad5]:
- File        
src/solver.d
- 2012-07-15 15:42:31 - part of checkin [310a3c5d41] on branch trunk - speed testing... 100x100 no-op is fast enough... (user: kinaba) [annotate]
 
To Artifact [707b7344a0841f62]:
- File        
src/solver.d
- 2012-07-15 16:06:29 - part of checkin [913d120d42] on branch trunk - size tuning solver (user: kinaba) [annotate]
 
    1  import util;                                                                           1  import util;
    2  import game;                                                                           2  import game;
    3                                                                                         3  
    4  bool rocky(char c){ return c=='*'||c=='@'; }                                           4  bool rocky(char c){ return c=='*'||c=='@'; }
    5                                                                                         5  
                                                                                        >     6  interface Solver
                                                                                        >     7  {
                                                                                        >     8          // this(in Game g);
                                                                                        >     9          char single_step();
                                                                                        >    10          void force(char c);
                                                                                        >    11  }
                                                                                        >    12  
    6  class Solver_0                                                                   |    13  class Solver_0 : Solver
    7  {                                                                                     14  {
    8          this(in Game g) {}                                                            15          this(in Game g) {}
    9          char single_step() { return 'W'; }                                            16          char single_step() { return 'W'; }
   10          void force(char c) {}                                                         17          void force(char c) {}
   11  }                                                                                     18  }
   12                                                                                        19  
   13  class Solver_1                                                                   |    20  class Solver_1 : Solver
   14  {                                                                                     21  {
   15          int wait_count = 0;                                                           22          int wait_count = 0;
   16          int choke_count = 0;                                                          23          int choke_count = 0;
   17                                                                                        24  
   18          Game g;                                                                       25          Game g;
   19          this(in Game g)                                                               26          this(in Game g)
   20          {                                                                             27          {
................................................................................................................................................................................
  163          {                                                                            170          {
  164                  bool danger(int y, int x)                                            171                  bool danger(int y, int x)
  165                  {                                                                    172                  {
  166                          if(g.map[y,x] == ' ' || g.map[y,x] == 'R')                   173                          if(g.map[y,x] == ' ' || g.map[y,x] == 'R')
  167                                  return false;                                        174                                  return false;
  168                          if(rocky(g.map[y+1,x]))                                      175                          if(rocky(g.map[y+1,x]))
  169                                  return true;                                         176                                  return true;
  170                          if(rocky(g.map[y+1,x-1]) && (g.map[y,x-1]=='\\'||rocky(g |   177                          if(rocky(g.map[y+1,x-1]) && (g.map[y,x-1]=='\\'||rocky(g
                                                                                        >   178                            && (g.map[y+1,x]==' '||g.map[y+1,x]=='R'))
  171                                  return true;                                         179                                  return true;
  172                          if(rocky(g.map[y+1,x+1]) && rocky(g.map[y,x+1]) && (g.ma     180                          if(rocky(g.map[y+1,x+1]) && rocky(g.map[y,x+1]) && (g.ma
  173                                  return true;                                         181                                  return true;
  174                          if(rocky(g.map[y,x-1]) && (g.map[y-1,x-1]=='\\'||rocky(g |   182                          if(rocky(g.map[y,x-1]) && (g.map[y-1,x-1]=='\\'||rocky(g
                                                                                        >   183                            && (g.map[y-1,x]==' '||g.map[y-1,x]=='R'))
  175                                  return true;                                         184                                  return true;
  176                          if(rocky(g.map[y,x+1]) && rocky(g.map[y-1,x+1]) && (g.ma     185                          if(rocky(g.map[y,x+1]) && rocky(g.map[y-1,x+1]) && (g.ma
  177                                  return true;                                         186                                  return true;
  178                          return false;                                                187                          return false;
  179                  }                                                                    188                  }
  180                                                                                       189  
  181                  // avoid directly below '*'                                          190                  // avoid directly below '*'
................................................................................................................................................................................
  300                          }                                                            309                          }
  301                          return [];                                                   310                          return [];
  302                  }                                                                    311                  }
  303                  return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC();                  312                  return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC();
  304          }                                                                            313          }
  305  }                                                                                    314  }
  306                                                                                       315  
  307  class Solver_2(Solver)                                                           |   316  class Solver_2(SubSolver) : Solver
  308  {                                                                                    317  {
  309          string plan;                                                                 318          string plan;
  310          bool plan_broken = true;                                                     319          bool plan_broken = true;
  311                                                                                       320  
  312          Game g;                                                                      321          Game g;
  313          this(in Game g)                                                              322          this(in Game g)
  314          {                                                                            323          {
  315                  this.g = g.clone();                                                  324                  this.g = g.clone();
  316                  make_plan(g);                                                        325                  make_plan(g);
  317          }                                                                            326          }
  318                                                                                       327  
  319          Tuple!(Solver,string) run_sub_solver(in Game g)                          |   328          Tuple!(SubSolver,string) run_sub_solver(in Game g)
  320          {                                                                            329          {
  321                  string log;                                                          330                  string log;
  322                  auto s = new Solver(g);                                          |   331                  auto s = new SubSolver(g);
  323                  while(!g.cleared && !g.dead && plan.length<=g.map.H*g.map.W) {       332                  while(!g.cleared && !g.dead && plan.length<=g.map.H*g.map.W) {
  324                          char c = s.single_step();                                    333                          char c = s.single_step();
  325                          if( c == 'A' )                                               334                          if( c == 'A' )
  326                                  break;                                               335                                  break;
  327                          log ~= c;                                                    336                          log ~= c;
  328                  }                                                                    337                  }
  329                  while(log.length>0 && log[$-1]=='W')                                 338                  while(log.length>0 && log[$-1]=='W')
  330                          log.length--;                                                339                          log.length--;
  331                  return tuple(s, log);                                                340                  return tuple(s, log);
  332          }                                                                            341          }
  333                                                                                       342  
  334          void make_plan(in Game g) {                                                  343          void make_plan(in Game g) {
  335                  plan_broken = false;                                                 344                  plan_broken = false;
  336                  Tuple!(Solver,string) x = run_sub_solver(g);                     |   345                  Tuple!(SubSolver,string) x = run_sub_solver(g);
  337                  plan = x[1];                                                         346                  plan = x[1];
  338                  if(x[0].g.cleared)                                                   347                  if(x[0].g.cleared)
  339                          return;                                                      348                          return;
  340                  modify_plan(g, x[0].g.score);                                        349                  modify_plan(g, x[0].g.score);
  341          }                                                                            350          }
  342                                                                                       351  
  343          void modify_plan(in Game ini, long unmod)                                    352          void modify_plan(in Game ini, long unmod)
................................................................................................................................................................................
  359                  plan = cand[0];                                                      368                  plan = cand[0];
  360          }                                                                            369          }
  361                                                                                       370  
  362          Tuple!(string,long) try_plan(string c, in Game g)                            371          Tuple!(string,long) try_plan(string c, in Game g)
  363          {                                                                            372          {
  364                  Game gg = g.clone();                                                 373                  Game gg = g.clone();
  365                  foreach(cc;c)gg.command(cc);                                         374                  foreach(cc;c)gg.command(cc);
  366                  Tuple!(Solver, string) x = run_sub_solver(gg);                   |   375                  Tuple!(SubSolver, string) x = run_sub_solver(gg);
  367                  return tuple(x[1], x[0].g.score);                                    376                  return tuple(x[1], x[0].g.score);
  368          }                                                                            377          }
  369                                                                                       378  
  370          char single_step() {                                                         379          char single_step() {
  371                  if(plan_broken)                                                      380                  if(plan_broken)
  372                          make_plan(g);                                                381                          make_plan(g);
  373                  if(plan.empty)                                                       382                  if(plan.empty)
................................................................................................................................................................................
  385                          plan_broken = true;                                          394                          plan_broken = true;
  386                  }                                                                    395                  }
  387                  else                                                                 396                  else
  388                          plan = plan[1..$];                                           397                          plan = plan[1..$];
  389          }                                                                            398          }
  390  }                                                                                    399  }
  391                                                                                       400  
                                                                                        >   401  class MasterSolver : Solver
                                                                                        >   402  {
                                                                                        >   403          this(in Game g)
                                                                                        >   404          {
                                                                                        >   405                  int SIZE = g.map.H * g.map.W;
                                                                                        >   406                  if( SIZE <= 32*32 )
                                                                                        >   407                          sub = new Solver_2!(Solver_1)(g);
                                                                                        >   408                  else if( SIZE <= 100*100 )
                                                                                        >   409                          sub = new Solver_1(g);
                                                                                        >   410                  else
                                                                                        >   411                          sub = new Solver_1(g);
                                                                                        >   412          }
                                                                                        >   413  
                                                                                        >   414          private Solver sub;
                                                                                        >   415          char single_step() { return sub.single_step(); }
                                                                                        >   416          void force(char c) { sub.force(c); }
                                                                                        >   417  }
                                                                                        >   418  
                                                                                        >   419  alias MasterSolver MainSolver;
  392  //alias Solver_2!(Solver_1) MainSolver;                                              420  //alias Solver_2!(Solver_1) MainSolver;
  393  //alias Solver_1 MainSolver;                                                         421  //alias Solver_1 MainSolver;
  394  alias Solver_0 MainSolver;                                                       |   422  //alias Solver_0 MainSolver;