Differences From Artifact [e25c75ea96d80507]:
- File        
src/game.d
- 2012-07-15 06:47:16 - part of checkin [6d497011d6] on branch trunk - Fixed judgement order of water-death and stage-clear. This makes flood2 solved. (user: kinaba) [annotate]
 - 2012-07-15 12:14:10 - part of checkin [e02668367d] on branch trunk - Revert redesign in the trunk. (user: kinaba) [annotate]
 
 
To Artifact [403db28cbc4609b7]:
- File        
src/game.d
- 2012-07-15 12:32:33 - part of checkin [de416b884b] on branch trunk - horock game. (user: kinaba) [annotate]
 
 
  126          Pos robot;                                                                   126          Pos robot;
  127          Pos lift;                                                                    127          Pos lift;
  128          int waterproof;                                                              128          int waterproof;
  129          Pos[char] tr_target;                                                         129          Pos[char] tr_target;
  130          Pos[][char] tr_source;                                                       130          Pos[][char] tr_source;
  131          const(Hige) hige;                                                            131          const(Hige) hige;
  132          int razor;                                                                   132          int razor;
                                                                                        >   133          int collected_lambda;
                                                                                        >   134          int total_lambda;
  133                                                                                       135  
  134          Map clone() const { return new Map(this); }                                  136          Map clone() const { return new Map(this); }
  135          this(in Map m) {                                                             137          this(in Map m) {
  136                  foreach(s; m.data)                                                   138                  foreach(s; m.data)
  137                          this.data ~= s.dup;                                          139                          this.data ~= s.dup;
  138                  this.robot = m.robot.clone();                                        140                  this.robot = m.robot.clone();
  139                  this.lift = m.lift.clone();                                          141                  this.lift = m.lift.clone();
  140                  this.waterproof = m.waterproof;                                      142                  this.waterproof = m.waterproof;
  141                  this.tr_target = cast(Pos[char])m.tr_target;                         143                  this.tr_target = cast(Pos[char])m.tr_target;
  142                  this.tr_source = cast(Pos[][char])m.tr_source;                       144                  this.tr_source = cast(Pos[][char])m.tr_source;
  143                  this.hige = m.hige.clone();                                          145                  this.hige = m.hige.clone();
  144                  this.razor = m.razor;                                                146                  this.razor = m.razor;
                                                                                        >   147                  this.collected_lambda = m.collected_lambda;
                                                                                        >   148                  this.total_lambda = m.total_lambda;
  145          }                                                                            149          }
  146                                                                                       150  
  147          this(string[] raw_data, string[string] params, char[char] trampo)            151          this(string[] raw_data, string[string] params, char[char] trampo)
  148          {                                                                            152          {
  149                  int width = 0;                                                       153                  int width = 0;
  150                  foreach(r; raw_data)                                                 154                  foreach(r; raw_data)
  151                          width = max(width, r.length);                                155                          width = max(width, r.length);
................................................................................................................................................................................
  157                                                                                       161  
  158                  for(int y=1; y<=H; ++y)                                              162                  for(int y=1; y<=H; ++y)
  159                  for(int x=1; x<=W; ++x) {                                            163                  for(int x=1; x<=W; ++x) {
  160                          if(this[y,x] == 'R')                                         164                          if(this[y,x] == 'R')
  161                                  this.robot = new Pos(y,x);                           165                                  this.robot = new Pos(y,x);
  162                          if(this[y,x] == 'L' || this[y,x] == 'O')                     166                          if(this[y,x] == 'L' || this[y,x] == 'O')
  163                                  this.lift = new Pos(y,x);                            167                                  this.lift = new Pos(y,x);
                                                                                        >   168                          if(this[y,x] == '\\' || this[y,x] == '@')
                                                                                        >   169                                  total_lambda++;
  164                  }                                                                    170                  }
  165                                                                                       171  
  166                  Pos[char] tr_pos;                                                    172                  Pos[char] tr_pos;
  167                  for(int y=1; y<=H; ++y)                                              173                  for(int y=1; y<=H; ++y)
  168                  for(int x=1; x<=W; ++x) {                                            174                  for(int x=1; x<=W; ++x) {
  169                          char c = this[y,x];                                          175                          char c = this[y,x];
  170                          if('1'<=c && c<='9' || 'A'<=c&&c<='I')                       176                          if('1'<=c && c<='9' || 'A'<=c&&c<='I')
................................................................................................................................................................................
  234                  for(int y=1; y<=H; ++y)                                              240                  for(int y=1; y<=H; ++y)
  235                  for(int x=1; x<=W; ++x)                                              241                  for(int x=1; x<=W; ++x)
  236                          if(this[y,x] == 'L' || this[y,x] == 'O')                     242                          if(this[y,x] == 'L' || this[y,x] == 'O')
  237                                  return false;                                        243                                  return false;
  238                  return true;                                                         244                  return true;
  239          }                                                                            245          }
  240                                                                                       246  
  241          Tuple!(int,bool) command(char c, int turn)                               |   247          bool command(char c, int turn)
  242          {                                                                            248          {
  243                  assert( this[robot] == 'R' );                                        249                  assert( this[robot] == 'R' );
  244                  if(c=='R') return move( 0, +1, turn);                                250                  if(c=='R') return move( 0, +1, turn);
  245                  if(c=='L') return move( 0, -1, turn);                                251                  if(c=='L') return move( 0, -1, turn);
  246                  if(c=='U') return move(+1,  0, turn);                                252                  if(c=='U') return move(+1,  0, turn);
  247                  if(c=='D') return move(-1,  0, turn);                                253                  if(c=='D') return move(-1,  0, turn);
  248                  if(c=='W') return move( 0,  0, turn);                                254                  if(c=='W') return move( 0,  0, turn);
  249                  if(c=='S') return use_razor(turn);                                   255                  if(c=='S') return use_razor(turn);
  250                  assert(false);                                                       256                  assert(false);
  251          }                                                                            257          }
  252                                                                                       258  
  253          Tuple!(int, bool) use_razor(int turn)                                    |   259          bool use_razor(int turn)
  254          {                                                                            260          {
  255                  if(razor) {                                                          261                  if(razor) {
  256                          razor--;                                                     262                          razor--;
  257                          for(int dy=-1; dy<=+1; ++dy)                                 263                          for(int dy=-1; dy<=+1; ++dy)
  258                          for(int dx=-1; dx<=+1; ++dx)                                 264                          for(int dx=-1; dx<=+1; ++dx)
  259                                  if(this[robot.y+dy,robot.x+dx] == 'W')               265                                  if(this[robot.y+dy,robot.x+dx] == 'W')
  260                                          this[robot.y+dy,robot.x+dx] = ' ';           266                                          this[robot.y+dy,robot.x+dx] = ' ';
  261                  }                                                                    267                  }
  262                                                                                       268  
  263                  bool dead = update(turn);                                        |   269                  return update(turn);
  264                  return tuple(0,dead);                                            <
  265          }                                                                            270          }
  266                                                                                       271  
                                                                                        >   272          bool rocky(char c) { return c=='*' || c=='@'; }
                                                                                        >   273  
  267          Tuple!(int, bool) move(int dy, int dx, int turn)                         |   274          bool move(int dy, int dx, int turn)
  268          {                                                                            275          {
  269                  int y = robot.y;                                                     276                  int y = robot.y;
  270                  int x = robot.x;                                                     277                  int x = robot.x;
  271                  int lambda = 0;                                                  <
  272                  if( '\\' == this[y+dy,x+dx] )                                        278                  if( '\\' == this[y+dy,x+dx] )
  273                          lambda++;                                                |   279                          collected_lambda++;
  274                  if( '!' == this[y+dy,x+dx] )                                         280                  if( '!' == this[y+dy,x+dx] )
  275                          razor++;                                                     281                          razor++;
  276                  if( " \\!.O".count(this[y+dy,x+dx])==1 ) {                           282                  if( " \\!.O".count(this[y+dy,x+dx])==1 ) {
  277                          this[y,x]=' ';                                               283                          this[y,x]=' ';
  278                          this[y+dy,x+dx]='R';                                         284                          this[y+dy,x+dx]='R';
  279                          robot = new Pos(y+dy,x+dx);                                  285                          robot = new Pos(y+dy,x+dx);
  280                  } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx |   286                  } else if(dy==0 && rocky(this[y+dy,x+dx]) && ' '==this[y+dy*2,x+
                                                                                        >   287                          char rock = this[y+dy,x+dx];
  281                          this[y,x]=' ';                                               288                          this[y,x]=' ';
  282                          this[y+dy,x+dx]='R';                                         289                          this[y+dy,x+dx]='R';
  283                          this[y+dy*2,x+dx*2]='*';                                 |   290                          this[y+dy*2,x+dx*2]=rock;
  284                          robot = new Pos(y+dy,x+dx);                                  291                          robot = new Pos(y+dy,x+dx);
  285                  } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') {            292                  } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') {
  286                          this[y,x]=' ';                                               293                          this[y,x]=' ';
  287                          Pos tp = tr_target[this[y+dy,x+dx]];                         294                          Pos tp = tr_target[this[y+dy,x+dx]];
  288                          foreach(p; tr_source[this[tp]])                              295                          foreach(p; tr_source[this[tp]])
  289                                  this[p] = ' ';                                       296                                  this[p] = ' ';
  290                          this[tp] = 'R';                                              297                          this[tp] = 'R';
  291                          robot = tp;                                                  298                          robot = tp;
  292                  }                                                                    299                  }
  293                  bool dead = update(turn);                                        |   300                  return update(turn);
  294                  return tuple(lambda,dead);                                       <
  295          }                                                                            301          }
  296                                                                                       302  
  297          bool update(int turn)                                                        303          bool update(int turn)
  298          {                                                                            304          {
  299                  bool dead = false;                                                   305                  bool dead = false;
  300                                                                                       306  
  301                  char[][] next;                                                       307                  char[][] next;
  302                  foreach(y,s; data)                                                   308                  foreach(y,s; data)
  303                          next ~= s.dup;                                               309                          next ~= s.dup;
  304                                                                                       310  
  305                  ref char access(Pos p) { return next[H-p.y][p.x-1]; }                311                  ref char access(Pos p) { return next[H-p.y][p.x-1]; }
  306                                                                                       312  
  307                  bool lambda = false;                                             <
  308                  for(int y=1; y<=H; ++y)                                          <
  309                  for(int x=1; x<=W; ++x)                                          <
  310                          lambda |= (this[y,x] == '\\');                           <
  311                                                                                   <
  312                  for(int y=1; y<=H; ++y)                                              313                  for(int y=1; y<=H; ++y)
  313                  for(int x=1; x<=W; ++x) {                                            314                  for(int x=1; x<=W; ++x) {
  314                          Pos p = new Pos(y,x);                                        315                          Pos p = new Pos(y,x);
                                                                                        >   316                          char rock = this[p];
  315                          if(this[p]=='*') {                                       |   317                          if(rocky(this[p])) {
  316                                  if(this[p.D]==' ') {                                 318                                  if(this[p.D]==' ') {
  317                                          access(p)  =' ';                             319                                          access(p)  =' ';
  318                                          access(p.D)='*';                         |   320                                          access(p.D)=(rock=='@'&&this[p.D.D]!=' '
  319                                          if(robot == p.D.D)                           321                                          if(robot == p.D.D)
  320                                                  dead=true;                           322                                                  dead=true;
  321                                  }                                                    323                                  }
  322                                  else if((this[p.D]=='*' || this[p.D]=='\\') && t |   324                                  else if((rocky(this[p.D]) || this[p.D]=='\\') &&
  323                                          access(p)=' ';                               325                                          access(p)=' ';
  324                                          access(p.R.D)='*';                       |   326                                          access(p.R.D)=(rock=='@'&&this[p.R.D.D]!
  325                                          if(robot == p.R.D.D)                         327                                          if(robot == p.R.D.D)
  326                                                  dead=true;                           328                                                  dead=true;
  327                                  }                                                    329                                  }
  328                                  else if(this[p.D]=='*' && this[p.L]==' ' && this |   330                                  else if(rocky(this[p.D]) && this[p.L]==' ' && th
  329                                          access(p)=' ';                               331                                          access(p)=' ';
  330                                          access(p.L.D)='*';                       |   332                                          access(p.L.D)=(rock=='@'&&this[p.L.D.D]!
  331                                          if(robot == p.L.D.D)                         333                                          if(robot == p.L.D.D)
  332                                                  dead=true;                           334                                                  dead=true;
  333                                  }                                                    335                                  }
  334                          }                                                            336                          }
  335                          else if(this[p]=='L') {                                      337                          else if(this[p]=='L') {
  336                                  if(!lambda)                                      |   338                                  if(collected_lambda == total_lambda)
  337                                          access(p) = 'O';                             339                                          access(p) = 'O';
  338                          }                                                            340                          }
  339                          else if(this[p]=='W') {                                      341                          else if(this[p]=='W') {
  340                                  if( hige.is_growing_turn(turn) )                     342                                  if( hige.is_growing_turn(turn) )
  341                                          for(int dy=-1; dy<=+1; ++dy)                 343                                          for(int dy=-1; dy<=+1; ++dy)
  342                                          for(int dx=-1; dx<=+1; ++dx)                 344                                          for(int dx=-1; dx<=+1; ++dx)
  343                                                  if(this[p.y+dy,p.x+dx] == ' ')       345                                                  if(this[p.y+dy,p.x+dx] == ' ')
................................................................................................................................................................................
  390                                                                                       392  
  391          Game clone() const { return new Game(this); }                                393          Game clone() const { return new Game(this); }
  392          this(in Game g) {                                                            394          this(in Game g) {
  393                  map = g.map.clone();                                                 395                  map = g.map.clone();
  394                  water = g.water.clone();                                             396                  water = g.water.clone();
  395                  turn = g.turn;                                                       397                  turn = g.turn;
  396                  dead = g.dead;                                                       398                  dead = g.dead;
  397                  lambda = g.lambda;                                               <
  398                  cleared = g.cleared;                                                 399                  cleared = g.cleared;
  399                  under_water = g.under_water;                                         400                  under_water = g.under_water;
  400          }                                                                            401          }
  401                                                                                       402  
  402          void command(char c)                                                         403          void command(char c)
  403          {                                                                            404          {
  404                  assert(c != 'A');                                                    405                  assert(c != 'A');
  405                  if(dead || cleared)                                                  406                  if(dead || cleared)
  406                          return;                                                      407                          return;
  407                                                                                       408  
  408                  // TODO: clarify the event order                                     409                  // TODO: clarify the event order
  409                  Tuple!(int,bool) ld = map.command(c, turn);                      |   410                  bool dead_now = map.command(c, turn);
  410                  if( map.cleared() ) {                                                411                  if( map.cleared() ) {
  411                          cleared = true;                                              412                          cleared = true;
  412                  }                                                                    413                  }
  413                  else {                                                               414                  else {
  414                          lambda += ld[0];                                         |   415                          if( dead_now )
  415                          if( ld[1] )                                              <
  416                                  dead = true;                                         416                                  dead = true;
  417                  }                                                                    417                  }
  418                  if(!cleared) {                                                       418                  if(!cleared) {
  419                          if( map.robot.y <= water_level )                             419                          if( map.robot.y <= water_level )
  420                                  ++under_water;                                       420                                  ++under_water;
  421                          else                                                         421                          else
  422                                  under_water = 0;                                     422                                  under_water = 0;
................................................................................................................................................................................
  426                  turn += 1;                                                           426                  turn += 1;
  427          }                                                                            427          }
  428                                                                                       428  
  429          Map map;                                                                     429          Map map;
  430          Water water;                                                                 430          Water water;
  431          int  turn = 0;                                                               431          int  turn = 0;
  432          bool dead = false;                                                           432          bool dead = false;
  433          int  lambda = 0;                                                         <
  434          int  under_water = 0;                                                        433          int  under_water = 0;
  435          bool cleared = false;                                                        434          bool cleared = false;
  436          // TODO: when adding members, take care of clone().                          435          // TODO: when adding members, take care of clone().
  437          // TODO: fix this poor design.                                               436          // TODO: fix this poor design.
  438                                                                                       437  
  439          @property const {                                                            438          @property const {
  440                  long score() { return lambda*(dead ? 25L : cleared ? 75L : 50L)  |   439                  long score() { return map.collected_lambda*(dead ? 25L : cleared
  441                  int water_level() { return water.level(turn); }                      440                  int water_level() { return water.level(turn); }
  442                  int water_until_rise() { return water.until_rise(turn); }            441                  int water_until_rise() { return water.until_rise(turn); }
  443                  int hige_until_rise() { return map.hige.until_rise(turn); }          442                  int hige_until_rise() { return map.hige.until_rise(turn); }
  444                  int hp() { return map.waterproof - under_water; }                    443                  int hp() { return map.waterproof - under_water; }
  445          }                                                                            444          }
  446  }                                                                                    445  }