Differences From Artifact [3413d0e80fd69f87]:
- File        
src/solver.d
- 2012-07-16 03:53:00 - part of checkin [971863e35a] on branch trunk - No-cloning death-move(). With several fixes to the simulator. (user: kinaba) [annotate]
 
To Artifact [7de11f2564488051]:
- File        
src/solver.d
- 2012-07-16 04:17:22 - part of checkin [1110e2f932] on branch trunk - Migrated to no-clone deathmove (user: kinaba) [annotate]
 
    1  import util;                                                                           1  import util;
    2  import game;                                                                           2  import game;
    3                                                                                         3  
                                                                                        >     4  bool is_spacy(char c)
                                                                                        >     5  {
                                                                                        >     6          return c==' ' || c=='.' || c=='R' || c=='!' || c=='\\' || c=='O';
                                                                                        >     7  }
                                                                                        >     8  
    4  bool rocky(char c){ return c=='*'||c=='@'; }                                     |     9  bool is_rocky(char c)
                                                                                        >    10  {
                                                                                        >    11          return c=='*' || c=='@';
                                                                                        >    12  }
                                                                                        >    13  
                                                                                        >    14  bool is_true_space(char c)
                                                                                        >    15  {
                                                                                        >    16          return c==' ';
                                                                                        >    17  }
                                                                                        >    18  
                                                                                        >    19  bool is_trampoline_source(char c)
                                                                                        >    20  {
                                                                                        >    21          return 'A'<=c && c<='I';
                                                                                        >    22  }
                                                                                        >    23  
                                                                                        >    24  bool is_rocklambda(char c)
                                                                                        >    25  {
                                                                                        >    26          return is_rocky(c) || c=='\\';
                                                                                        >    27  }
                                                                                        >    28  
                                                                                        >    29  Tuple!(string,int) death_move(in Game g)
                                                                                        >    30  {
                                                                                        >    31          // TODO: S
                                                                                        >    32  
                                                                                        >    33          string death;
                                                                                        >    34          int breath;
                                                                                        >    35          int y = g.map.robot.y;
                                                                                        >    36          int x = g.map.robot.x;
                                                                                        >    37          int[5] dy_=[+1,-1,0,0,0];
                                                                                        >    38          int[5] dx_=[0,0,-1,+1,0];
                                                                                        >    39          char[] ds=['U','D','L','R','W'];
                                                                                        >    40          for(int i=0; i<5; ++i)
                                                                                        >    41          {
                                                                                        >    42                  bool after_move_death(int y, int x, char tr_tgt)
                                                                                        >    43                  {
                                                                                        >    44                          bool is_spacy_t(char c) {
                                                                                        >    45                                  if(is_true_space(c) || c=='R' || c==tr_tgt)
                                                                                        >    46                                          return true;
                                                                                        >    47                                  return ('A'<=c && c<='I' && g.tr.target_of(c)==t
                                                                                        >    48                          }
                                                                                        >    49  
                                                                                        >    50                          // check water
                                                                                        >    51                          if( g.map[y,x]!='O' && g.hp==0 && y<=g.water_level )
                                                                                        >    52                                  return true;
                                                                                        >    53  
                                                                                        >    54                          // check falling rock.
                                                                                        >    55                          int yy=y+1, xx=x;
                                                                                        >    56                          if( is_spacy_t(g.map[yy, xx]) )
                                                                                        >    57                          {
                                                                                        >    58                                  if( is_rocky(g.map[yy+1,xx]) )
                                                                                        >    59                                          return true;
                                                                                        >    60                                  if( is_spacy_t(g.map[yy+1,xx]) && is_rocky(g.map
                                                                                        >    61                                          if( is_spacy_t(g.map[yy+1,xx+2]) && is_s
                                                                                        >    62                                                  return false;
                                                                                        >    63                                          return true;
                                                                                        >    64                                  }
                                                                                        >    65                                  if( is_spacy_t(g.map[yy+1,xx]) && is_rocky(g.map
                                                                                        >    66                                          if(g.hige_until_rise == 1 && g.map[yy+1,
                                                                                        >    67                                                  return false;
                                                                                        >    68                                          return true;
                                                                                        >    69                                  }
                                                                                        >    70                          }
                                                                                        >    71                          return false;
                                                                                        >    72                  }
                                                                                        >    73  
                                                                                        >    74                  int dy=dy_[i], dx=dx_[i];
                                                                                        >    75                  if( is_spacy(g.map[y+dy,x+dx]) || dy==0 && is_rocky(g.map[y,x+dx
                                                                                        >    76                  {
                                                                                        >    77                          if( after_move_death(y+dy, x+dx, char.init) )
                                                                                        >    78                                  death ~= ds[i];
                                                                                        >    79                          else if(ds[i] != 'W')
                                                                                        >    80                                  breath ++;
                                                                                        >    81                  }
                                                                                        >    82                  else if( is_trampoline_source(g.map[y+dy,x+dx]) )
                                                                                        >    83                  {
                                                                                        >    84                          Pos p = g.tr.target_pos(g.map[y+dy,x+dx]);
                                                                                        >    85                          if( after_move_death(p.y, p.x, g.tr.target_of(g.map[y+dy
                                                                                        >    86                                  death ~= ds[i];
                                                                                        >    87                          else
                                                                                        >    88                                  breath ++;
                                                                                        >    89                  }
                                                                                        >    90                  else
                                                                                        >    91                  {
                                                                                        >    92                          death ~= ds[i];
                                                                                        >    93                  }
                                                                                        >    94          }
                                                                                        >    95  
                                                                                        >    96          return tuple(death, breath);
                                                                                        >    97  }
    5                                                                                        98  
    6  interface Solver                                                                      99  interface Solver
    7  {                                                                                    100  {
    8          // this(in Game g);                                                          101          // this(in Game g);
    9          char single_step();                                                          102          char single_step();
   10          void force(char c);                                                          103          void force(char c);
   11  }                                                                                    104  }
................................................................................................................................................................................
   39                                                                                       132  
   40          void force(char c)                                                           133          void force(char c)
   41          {                                                                            134          {
   42                  if(c != 'A')                                                         135                  if(c != 'A')
   43                          g.command(c);                                                136                          g.command(c);
   44          }                                                                            137          }
   45                                                                                       138  
   46          Tuple!(string,int) death_move(const(Game) g)                             <
   47          {                                                                        <
   48                  string death;                                                    <
   49                  int choice = 0;                                                  <
   50                  foreach(char c; "UDLRW") {                                       <
   51                          Game gg = g.clone();                                     <
   52                          gg.command(c);                                           <
   53                          if( !gg.cleared && gg.dead )                             <
   54                                  death ~= c;                                      <
   55                          else if( gg.map.robot != g.map.robot )                   <
   56                                  choice++;                                        <
   57                          else if( c != 'W' ) // meaningless move                  <
   58                                  death ~= c;                                      <
   59                  }                                                                <
   60                  return tuple(death, choice);                                     <
   61          }                                                                        <
   62                                                                                   <
   63          Tuple!(Pos, int)[] log;                                                      139          Tuple!(Pos, int)[] log;
   64          bool[][] forbidden_cell;                                                     140          bool[][] forbidden_cell;
   65                                                                                       141  
   66          char act(const(Game) g, string death, int breath)                            142          char act(const(Game) g, string death, int breath)
   67          {                                                                            143          {
   68                  const Pos    ro = g.map.robot;                                       144                  const Pos    ro = g.map.robot;
   69                  const Pos    li = g.map.lift;                                        145                  const Pos    li = g.map.lift;
................................................................................................................................................................................
  113                                                                                       189  
  114                  // 'dig' mode                                                        190                  // 'dig' mode
  115                  if(cand.empty) {                                                     191                  if(cand.empty) {
  116                          const(Pos)[] tgt;                                            192                          const(Pos)[] tgt;
  117                          for(int y=1; y<=g.map.H; ++y)                                193                          for(int y=1; y<=g.map.H; ++y)
  118                          for(int x=1; x<=g.map.W; ++x)                                194                          for(int x=1; x<=g.map.W; ++x)
  119                                  if(g.map[y,x]=='.')                                  195                                  if(g.map[y,x]=='.')
  120                                          if(rocky(g.map[y+1,x])||rocky(g.map[y+1, |   196                                          if(is_rocky(g.map[y+1,x])||is_rocky(g.ma
  121                                           ||rocky(g.map[y,x+1])||rocky(g.map[y,x- |   197                                           ||is_rocky(g.map[y,x+1])||is_rocky(g.ma
  122                                                  tgt ~= new Pos(y,x);                 198                                                  tgt ~= new Pos(y,x);
  123                          cand ~= search(g, ro, tgt, death, true);                     199                          cand ~= search(g, ro, tgt, death, true);
  124                  }                                                                    200                  }
  125                                                                                       201  
  126                  if(cand.empty) {                                                     202                  if(cand.empty) {
  127                          choke_count++;                                               203                          choke_count++;
  128                          cand ~= tuple('W',int.max);                                  204                          cand ~= tuple('W',int.max);
................................................................................................................................................................................
  170                                                                                       246  
  171          Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death     247          Tuple!(char,int)[] search(in Game g, in Pos s, in Pos[] gs, string death
  172          {                                                                            248          {
  173                  bool danger(int y, int x)                                            249                  bool danger(int y, int x)
  174                  {                                                                    250                  {
  175                          if(g.map[y,x] == ' ' || g.map[y,x] == 'R')                   251                          if(g.map[y,x] == ' ' || g.map[y,x] == 'R')
  176                                  return false;                                        252                                  return false;
  177                          if(rocky(g.map[y+1,x]))                                  |   253                          if(is_rocky(g.map[y+1,x]))
  178                                  return true;                                         254                                  return true;
  179                          if(rocky(g.map[y+1,x-1]) && (g.map[y,x-1]=='\\'||rocky(g |   255                          if(is_rocky(g.map[y+1,x-1]) && (g.map[y,x-1]=='\\'||is_r
  180                            && (g.map[y+1,x]==' '||g.map[y+1,x]=='R'))                 256                            && (g.map[y+1,x]==' '||g.map[y+1,x]=='R'))
  181                                  return true;                                         257                                  return true;
  182                          if(rocky(g.map[y+1,x+1]) && rocky(g.map[y,x+1]) && (g.ma |   258                          if(is_rocky(g.map[y+1,x+1]) && is_rocky(g.map[y,x+1]) &&
  183                                  return true;                                         259                                  return true;
  184                          if(rocky(g.map[y,x-1]) && (g.map[y-1,x-1]=='\\'||rocky(g |   260                          if(is_rocky(g.map[y,x-1]) && (g.map[y-1,x-1]=='\\'||is_r
  185                            && (g.map[y-1,x]==' '||g.map[y-1,x]=='R'))                 261                            && (g.map[y-1,x]==' '||g.map[y-1,x]=='R'))
  186                                  return true;                                         262                                  return true;
  187                          if(rocky(g.map[y,x+1]) && rocky(g.map[y-1,x+1]) && (g.ma |   263                          if(is_rocky(g.map[y,x+1]) && is_rocky(g.map[y-1,x+1]) &&
  188                                  return true;                                         264                                  return true;
  189                          return false;                                                265                          return false;
  190                  }                                                                    266                  }
  191                                                                                       267  
  192                  // avoid directly below '*'                                          268                  // avoid directly below '*'
  193                  Tuple!(char,int)[] tryA() {                                          269                  Tuple!(char,int)[] tryA() {
  194                          const(Pos)[] q;                                              270                          const(Pos)[] q;
................................................................................................................................................................................
  279                                  Pos[] q2;                                            355                                  Pos[] q2;
  280                                  foreach(p; q) {                                      356                                  foreach(p; q) {
  281                                          int[] yyy=[p.y-1,p.y+1,p.y,p.y];             357                                          int[] yyy=[p.y-1,p.y+1,p.y,p.y];
  282                                          int[] xxx=[p.x,p.x,p.x-1,p.x+1];             358                                          int[] xxx=[p.x,p.x,p.x-1,p.x+1];
  283                                          for(int i=0; i<yyy.length; ++i) {            359                                          for(int i=0; i<yyy.length; ++i) {
  284                                                  int y = yyy[i];                      360                                                  int y = yyy[i];
  285                                                  int x = xxx[i];                      361                                                  int x = xxx[i];
  286                                                  if(rocky(g.map[p])) {            |   362                                                  if(is_rocky(g.map[p])) {
  287                                                          if(i>=4)continue;            363                                                          if(i>=4)continue;
  288                                                          if(y!=p.y)continue;          364                                                          if(y!=p.y)continue;
  289                                                          if(g.map[y,p.x+(p.x-x)]!     365                                                          if(g.map[y,p.x+(p.x-x)]!
  290                                                  }                                    366                                                  }
  291                                                  if('1'<=g.map[y,x]&&g.map[y,x]<=     367                                                  if('1'<=g.map[y,x]&&g.map[y,x]<=
  292                                                          foreach(ppp; g.tr.source     368                                                          foreach(ppp; g.tr.source
  293                                                                  yyy ~= ppp.y;        369                                                                  yyy ~= ppp.y;
................................................................................................................................................................................
  297                                                  }                                    373                                                  }
  298                                                  if(v[y][x]) continue;                374                                                  if(v[y][x]) continue;
  299                                                  if(y==s.y && x==s.x && i<4) {        375                                                  if(y==s.y && x==s.x && i<4) {
  300                                                          char c = "UDRL"[i];          376                                                          char c = "UDRL"[i];
  301                                                          if( death.count(c) == 0      377                                                          if( death.count(c) == 0 
  302                                                                  return [tuple(c,     378                                                                  return [tuple(c,
  303                                                  } else if(forbidden_cell[y][x]){     379                                                  } else if(forbidden_cell[y][x]){
  304                                                  } else if(g.map[y,x]==' '||g.map |   380                                                  } else if(g.map[y,x]==' '||g.map
  305                                                          q2 ~= new Pos(y,x);          381                                                          q2 ~= new Pos(y,x);
  306                                                          v[y][x]=true;                382                                                          v[y][x]=true;
  307                                                  }                                    383                                                  }
  308                                          }                                            384                                          }
  309                                  }                                                    385                                  }
  310                                  q = q2;                                              386                                  q = q2;
  311                          }                                                            387                          }
................................................................................................................................................................................
  536                  if(c != 'A')                                                         612                  if(c != 'A')
  537                          g.command(c);                                                613                          g.command(c);
  538                  return c;                                                            614                  return c;
  539          }                                                                            615          }
  540                                                                                       616  
  541          void force(char c)                                                           617          void force(char c)
  542          {                                                                            618          {
  543  stderr.writeln(death_move(g));                                                   <
  544                  if(c != 'A')                                                         619                  if(c != 'A')
  545                          g.command(c);                                                620                          g.command(c);
  546          }                                                                            621          }
  547                                                                                       622  
  548          bool is_spacy(char c) {                                                  <
  549                  return c==' ' || c=='.' || c=='R' || c=='!' || c=='\\' || c=='O' <
  550          }                                                                        <
  551          bool is_rocky(char c) {                                                  <
  552                  return c=='*' || c=='@';                                         <
  553          }                                                                        <
  554          bool is_true_space(char c) {                                             <
  555                  return c==' ';                                                   <
  556          }                                                                        <
  557          bool is_trampoline_source(char c) {                                      <
  558                  return 'A'<=c && c<='I';                                         <
  559          }                                                                        <
  560          bool is_rocklambda(char c) {                                             <
  561                  return is_rocky(c) || c=='\\';                                   <
  562          }                                                                        <
  563                                                                                   <
  564          string death_move(in Game g)                                             <
  565          {                                                                        <
  566                  // TODO: S                                                       <
  567                  string death;                                                    <
  568                  int y = g.map.robot.y;                                           <
  569                  int x = g.map.robot.x;                                           <
  570                  int[5] dy_=[-1,+1,0,0,0];                                        <
  571                  int[5] dx_=[0,0,-1,+1,0];                                        <
  572                  char[] ds=['D','U','L','R','W'];                                 <
  573                  for(int i=0; i<5; ++i)                                           <
  574                  {                                                                <
  575                          bool after_move_death(int y, int x, char tr_tgt)         <
  576                          {                                                        <
  577                                  bool is_spacy_t(char c) {                        <
  578                                          if(is_spacy(c) || c==tr_tgt)             <
  579                                                  return true;                     <
  580                                          return ('A'<=c && c<='I' && g.tr.target_ <
  581                                  }                                                <
  582                                                                                   <
  583                                  // check water                                   <
  584                                  if( g.hp==0 && y<=g.water_level )                <
  585                                          return true;                             <
  586                                                                                   <
  587                                  // check falling rock.                           <
  588                                  int yy=y+1, xx=x;                                <
  589                                  if( is_spacy_t(g.map[yy, xx]) )                  <
  590                                  {                                                <
  591                                          if( is_rocky(g.map[yy+1,xx]) )           <
  592                                                  return true;                     <
  593                                          if( is_spacy_t(g.map[yy+1,xx]) && is_roc <
  594                                                  if( is_spacy_t(g.map[yy+1,xx+2]) <
  595                                                          return false;            <
  596                                                  return true;                     <
  597                                          }                                        <
  598                                          if( is_spacy_t(g.map[yy+1,xx]) && is_roc <
  599                                                  if(g.hige_until_rise == 1 && g.m <
  600                                                          return false;            <
  601                                                  return true;                     <
  602                                          }                                        <
  603                                  }                                                <
  604                                  return false;                                    <
  605                          }                                                        <
  606                                                                                   <
  607                          int dy=dy_[i], dx=dx_[i];                                <
  608                          if( is_spacy(g.map[y+dy,x+dx])                           <
  609                           || dy==0 && is_rocky(g.map[y,x+dx]) && is_true_space(g. <
  610                          {                                                        <
  611                                  if( after_move_death(y+dy, x+dx, char.init) )    <
  612                                          death ~= ds[i];                          <
  613                          }                                                        <
  614                          else if( is_trampoline_source(g.map[y+dy,x+dx]) )        <
  615                          {                                                        <
  616                                  Pos p = g.tr.target_pos(g.map[y+dy,x+dx]);       <
  617                                  if( after_move_death(p.y, p.x, g.tr.target_of(g. <
  618                                          death ~= ds[i];                          <
  619                          }                                                        <
  620                          else                                                     <
  621                          {                                                        <
  622                                  death ~= ds[i];                                  <
  623                          }                                                        <
  624                  }                                                                <
  625                  return death;                                                    <
  626          }                                                                        <
  627                                                                                   <
  628          char think(in Game g)                                                        623          char think(in Game g)
  629          {                                                                            624          {
  630                  string s = death_move(g);                                        <
  631                  stderr.writeln(s);                                               <
  632                                                                                       625  
  633                  auto Q = new Queue!(Tuple!(Pos,Pos));                                626                  auto Q = new Queue!(Tuple!(Pos,Pos));
  634                  Q.push(tuple(g.map.robot.clone(), g.map.robot.clone()), 0);          627                  Q.push(tuple(g.map.robot.clone(), g.map.robot.clone()), 0);
  635                  Pos[][] V = new Pos[][](g.map.H+2, g.map.W+2);                       628                  Pos[][] V = new Pos[][](g.map.H+2, g.map.W+2);
  636                  while(!Q.empty) {                                                    629                  while(!Q.empty) {
  637                          auto tup = Q.pop();                                          630                          auto tup = Q.pop();
  638                          Pos  p    = tup[0][0];                                       631                          Pos  p    = tup[0][0];
................................................................................................................................................................................
  668                                  }                                                    661                                  }
  669                          }                                                            662                          }
  670                  }                                                                    663                  }
  671                  return 'A';                                                          664                  return 'A';
  672          }                                                                            665          }
  673  }                                                                                    666  }
  674                                                                                       667  
  675  alias Solver_3 MainSolver;                                                       |   668  //alias Solver_3 MainSolver;
  676  //alias Solver_2!(Solver_1) MainSolver;                                          |   669  alias Solver_2!(Solver_1) MainSolver;
  677  //alias Solver_1 MainSolver;                                                         670  //alias Solver_1 MainSolver;
  678  //alias Solver_0 MainSolver;                                                         671  //alias Solver_0 MainSolver;