Differences From Artifact [189f5a19c7160df3]:
- File        
src/game.d
- 2012-07-15 14:55:18 - part of checkin [64f5c73b88] on branch trunk - hige moving tochu. (user: kinaba) [annotate]
 
 
To Artifact [7a4ec50fc295cb1f]:
- File        
src/game.d
- 2012-07-15 15:13:15 - part of checkin [5491fa544d] on branch trunk - several fixes. (user: kinaba) [annotate]
 
 
  118                                                                                       118  
  119          char[][] data;                                                               119          char[][] data;
  120          Pos robot;                                                                   120          Pos robot;
  121          Pos lift;                                                                    121          Pos lift;
  122          int waterproof;                                                              122          int waterproof;
  123          Pos[char] tr_target;                                                         123          Pos[char] tr_target;
  124          Pos[][char] tr_source;                                                       124          Pos[][char] tr_source;
  125          const(Hige) hige;                                                        <
  126          int razor;                                                                   125          int razor;
  127          int collected_lambda;                                                        126          int collected_lambda;
  128          int total_lambda;                                                            127          int total_lambda;
  129          bool cleared;                                                                128          bool cleared;
  130          Pos[] may_update;                                                            129          Pos[] may_update;
  131                                                                                       130  
  132          Map clone() const { return new Map(this); }                                  131          Map clone() const { return new Map(this); }
................................................................................................................................................................................
  134                  foreach(s; m.data)                                                   133                  foreach(s; m.data)
  135                          this.data ~= s.dup;                                          134                          this.data ~= s.dup;
  136                  this.robot = m.robot.clone();                                        135                  this.robot = m.robot.clone();
  137                  this.lift = m.lift.clone();                                          136                  this.lift = m.lift.clone();
  138                  this.waterproof = m.waterproof;                                      137                  this.waterproof = m.waterproof;
  139                  this.tr_target = cast(Pos[char])m.tr_target;                         138                  this.tr_target = cast(Pos[char])m.tr_target;
  140                  this.tr_source = cast(Pos[][char])m.tr_source;                       139                  this.tr_source = cast(Pos[][char])m.tr_source;
  141                  this.hige = m.hige.clone();                                      <
  142                  this.razor = m.razor;                                                140                  this.razor = m.razor;
  143                  this.collected_lambda = m.collected_lambda;                          141                  this.collected_lambda = m.collected_lambda;
  144                  this.total_lambda = m.total_lambda;                                  142                  this.total_lambda = m.total_lambda;
  145                  this.may_update = (cast(Map)m).may_update.dup;                       143                  this.may_update = (cast(Map)m).may_update.dup;
  146                  this.cleared = m.cleared;                                            144                  this.cleared = m.cleared;
  147          }                                                                            145          }
  148                                                                                       146  
................................................................................................................................................................................
  180                  this.waterproof = params.get("Waterproof", "5").to!int();            178                  this.waterproof = params.get("Waterproof", "5").to!int();
  181                  foreach(fr,to; trampo) {                                             179                  foreach(fr,to; trampo) {
  182                          tr_target[fr] = tr_pos[to];                                  180                          tr_target[fr] = tr_pos[to];
  183                          if(to !in tr_source) tr_source[to] = [];                     181                          if(to !in tr_source) tr_source[to] = [];
  184                          tr_source[to] ~= tr_pos[fr];                                 182                          tr_source[to] ~= tr_pos[fr];
  185                  }                                                                    183                  }
  186                                                                                       184  
  187                  this.hige = Hige.load(params);                                   <
  188                  this.razor = params.get("Razors", "0").to!int();                     185                  this.razor = params.get("Razors", "0").to!int();
  189          }                                                                            186          }
  190                                                                                       187  
  191          const @property {                                                            188          const @property {
  192                  int H() { return data.length; }                                      189                  int H() { return data.length; }
  193                  int W() { return data[0].length; }                                   190                  int W() { return data[0].length; }
  194          }                                                                            191          }
................................................................................................................................................................................
  234                                                                                       231  
  235          Pos[] razors() const { return objects('!'); }                                232          Pos[] razors() const { return objects('!'); }
  236          Pos[] lambdas() const { return objects('\\'); }                              233          Pos[] lambdas() const { return objects('\\'); }
  237                                                                                       234  
  238          bool command(char c, int turn, bool hige_day)                                235          bool command(char c, int turn, bool hige_day)
  239          {                                                                            236          {
  240                  assert( this[robot] == 'R' );                                        237                  assert( this[robot] == 'R' );
  241                  if(c=='R') return move( 0, +1, turn, hige_day);                  |   238                  if(c=='R') return move( 0, +1, hige_day);
  242                  if(c=='L') return move( 0, -1, turn, hige_day);                  |   239                  if(c=='L') return move( 0, -1, hige_day);
  243                  if(c=='U') return move(+1,  0, turn, hige_day);                  |   240                  if(c=='U') return move(+1,  0, hige_day);
  244                  if(c=='D') return move(-1,  0, turn, hige_day);                  |   241                  if(c=='D') return move(-1,  0, hige_day);
  245                  if(c=='W') return move( 0,  0, turn, hige_day);                  |   242                  if(c=='W') return move( 0,  0, hige_day);
  246                  if(c=='S') return use_razor(turn, hige_day);                     |   243                  if(c=='S') return use_razor(hige_day);
  247                  assert(false);                                                       244                  assert(false);
  248          }                                                                            245          }
  249                                                                                       246  
  250          bool use_razor(int turn, bool hige_day)                                  |   247          bool use_razor(bool hige_day)
  251          {                                                                            248          {
  252                  if(razor) {                                                          249                  if(razor) {
  253                          razor--;                                                     250                          razor--;
  254                          for(int dy=-1; dy<=+1; ++dy)                                 251                          for(int dy=-1; dy<=+1; ++dy)
  255                          for(int dx=-1; dx<=+1; ++dx)                                 252                          for(int dx=-1; dx<=+1; ++dx)
  256                                  if(this[robot.y+dy,robot.x+dx] == 'W') {             253                                  if(this[robot.y+dy,robot.x+dx] == 'W') {
  257                                          emptified(new Pos(robot.y+dy,robot.x+dx)     254                                          emptified(new Pos(robot.y+dy,robot.x+dx)
  258                                          this[robot.y+dy,robot.x+dx] = ' ';           255                                          this[robot.y+dy,robot.x+dx] = ' ';
  259                                  }                                                    256                                  }
  260                  }                                                                    257                  }
  261                                                                                       258  
  262                  return update(turn, hige_day);                                   |   259                  return update(hige_day);
  263          }                                                                            260          }
  264                                                                                       261  
  265          bool rocky(char c) { return c=='*' || c=='@'; }                              262          bool rocky(char c) { return c=='*' || c=='@'; }
  266                                                                                       263  
  267                  void emptified(Pos p) {                                              264                  void emptified(Pos p) {
  268                          for(int dy=0; dy<=+1; ++dy)                                  265                          for(int dy=0; dy<=+1; ++dy)
  269                          for(int dx=-1; dx<=+1; ++dx)                                 266                          for(int dx=-1; dx<=+1; ++dx)
  270                                  may_update ~= new Pos(p.y+dy, p.x+dx);               267                                  may_update ~= new Pos(p.y+dy, p.x+dx);
  271                  }                                                                    268                  }
  272                                                                                       269  
  273          bool move(int dy, int dx, int turn, bool hige_day)                       |   270          bool move(int dy, int dx, bool hige_day)
  274          {                                                                            271          {
  275                                                                                   <
  276                  emptified(robot);                                                    272                  emptified(robot);
  277                                                                                       273  
  278                  int y = robot.y;                                                     274                  int y = robot.y;
  279                  int x = robot.x;                                                     275                  int x = robot.x;
  280                  if( '\\' == this[y+dy,x+dx] )                                        276                  if( '\\' == this[y+dy,x+dx] )
  281                          collected_lambda++;                                          277                          collected_lambda++;
  282                  if( '!' == this[y+dy,x+dx] )                                         278                  if( '!' == this[y+dy,x+dx] )
................................................................................................................................................................................
  299                          foreach(p; tr_source[this[tp]]) {                            295                          foreach(p; tr_source[this[tp]]) {
  300                                  emptified(p);                                        296                                  emptified(p);
  301                                  this[p] = ' ';                                       297                                  this[p] = ' ';
  302                          }                                                            298                          }
  303                          this[tp] = 'R';                                              299                          this[tp] = 'R';
  304                          robot = tp;                                                  300                          robot = tp;
  305                  }                                                                    301                  }
  306                  return update(turn, hige_day);                                   |   302                  return update(hige_day);
  307          }                                                                            303          }
  308                                                                                       304  
  309          bool update(int turn, bool hige_day)                                     |   305          bool update(bool hige_day)
  310          {                                                                            306          {
  311                  // Write after all the updates are processed.                        307                  // Write after all the updates are processed.
  312                  Tuple!(int,int,char)[] write_buffer;                                 308                  Tuple!(int,int,char)[] write_buffer;
  313                  void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c);     309                  void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c);
  314                  void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c     310                  void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c
  315                  scope(exit) {                                                        311                  scope(exit) {
  316                          may_update.length = 0;                                       312                          may_update.length = 0;
................................................................................................................................................................................
  324                  }                                                                    320                  }
  325                                                                                       321  
  326                  if(collected_lambda == total_lambda)                                 322                  if(collected_lambda == total_lambda)
  327                          if(this[lift]=='L')                                          323                          if(this[lift]=='L')
  328                                  this[lift] = 'O';                                    324                                  this[lift] = 'O';
  329                                                                                       325  
  330                  bool dead = false;                                                   326                  bool dead = false;
                                                                                        >   327                  if( hige_day ) {
                                                                                        >   328                          for(int y=1; y<=H; ++y)
                                                                                        >   329                          for(int x=1; x<=W; ++x)
                                                                                        >   330                                  if(this[y,x]=='W')
                                                                                        >   331                                          may_update ~= new Pos(y,x);
                                                                                        >   332                  }
                                                                                        >   333  
  331                  sort(may_update);                                                    334                  sort(may_update);
  332                  foreach(p; may_update) {                                             335                  foreach(p; may_update) {
  333                          int y = p.y, x = p.x;                                        336                          int y = p.y, x = p.x;
  334                          char rock = this[p];                                         337                          char rock = this[p];
  335                          if(rocky(this[p])) {                                         338                          if(rocky(this[p])) {
  336                                  if(this[p.D]==' ') {                                 339                                  if(this[p.D]==' ') {
  337                                          writep(p, ' ');                              340                                          writep(p, ' ');
................................................................................................................................................................................
  348                                  else if(rocky(this[p.D]) && this[p.L]==' ' && th     351                                  else if(rocky(this[p.D]) && this[p.L]==' ' && th
  349                                          writep(p, ' ');                              352                                          writep(p, ' ');
  350                                          writep(p.L.D, (rock=='@'&&this[p.L.D.D]!     353                                          writep(p.L.D, (rock=='@'&&this[p.L.D.D]!
  351                                          if(robot == p.L.D.D)                         354                                          if(robot == p.L.D.D)
  352                                                  dead=true;                           355                                                  dead=true;
  353                                  }                                                    356                                  }
  354                          }                                                            357                          }
  355                  }                                                                <
  356                                                                                   <
  357                  if( hige_day )                                                   <
  358                  for(int y=1; y<=H; ++y)                                          <
  359                  for(int x=1; x<=W; ++x) {                                        <
  360                          Pos p = new Pos(y,x);                                    <
  361                          if(this[p]=='W') {                                       |   358                          else if(this[p]=='W') {
                                                                                        >   359                                  if(hige_day) {
  362                                          for(int dy=-1; dy<=+1; ++dy)                 360                                          for(int dy=-1; dy<=+1; ++dy)
  363                                          for(int dx=-1; dx<=+1; ++dx)                 361                                          for(int dx=-1; dx<=+1; ++dx)
  364                                                  if(this[p.y+dy,p.x+dx] == ' ')       362                                                  if(this[p.y+dy,p.x+dx] == ' ')
  365                                                          write(p.y+dy,p.x+dx,'W')     363                                                          write(p.y+dy,p.x+dx,'W')
                                                                                        >   364                                  }
  366                          }                                                            365                          }
  367                  }                                                                    366                  }
  368                                                                                       367  
  369                  return dead;                                                         368                  return dead;
  370          }                                                                            369          }
  371  }                                                                                    370  }
  372                                                                                       371  
................................................................................................................................................................................
  393                                  params[ss[0]] = ss[1];                               392                                  params[ss[0]] = ss[1];
  394                          if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar     393                          if( ss.length == 4 && ss[0]=="Trampoline" && ss[2]=="tar
  395                                  trampo[ss[1][0]] = ss[3][0];                         394                                  trampo[ss[1][0]] = ss[3][0];
  396                  }                                                                    395                  }
  397                                                                                       396  
  398                  this.map   = new Map(raw_data, params, trampo);                      397                  this.map   = new Map(raw_data, params, trampo);
  399                  this.water = Water.load(params);                                     398                  this.water = Water.load(params);
                                                                                        >   399                  this.hige  = Hige.load(params);
  400          }                                                                            400          }
  401                                                                                       401  
  402          Game clone() const { return new Game(this); }                                402          Game clone() const { return new Game(this); }
  403          this(in Game g) {                                                            403          this(in Game g) {
  404                  map   = g.map.clone();                                               404                  map   = g.map.clone();
  405                  water = g.water.clone();                                             405                  water = g.water.clone();
                                                                                        >   406                  hige  = g.hige.clone();
  406                  turn  = g.turn;                                                      407                  turn  = g.turn;
  407                  dead  = g.dead;                                                      408                  dead  = g.dead;
  408                  under_water = g.under_water;                                         409                  under_water = g.under_water;
  409          }                                                                            410          }
  410                                                                                       411  
  411          void command(char c)                                                         412          void command(char c)
  412          {                                                                            413          {
  413                  assert(c != 'A');                                                    414                  assert(c != 'A');
  414                  if(dead || cleared)                                                  415                  if(dead || cleared)
  415                          return;                                                      416                          return;
  416                                                                                       417  
  417                  // TODO: clarify the event order                                     418                  // TODO: clarify the event order
  418                  bool dead_now = map.command(c, turn, map.hige.is_growing_turn(tu |   419                  bool dead_now = map.command(c, turn, hige.is_growing_turn(turn))
  419                  if( dead_now )                                                       420                  if( dead_now )
  420                          dead = true;                                                 421                          dead = true;
  421                  if(!map.cleared) {                                                   422                  if(!map.cleared) {
  422                          if( map.robot.y <= water_level )                             423                          if( map.robot.y <= water_level )
  423                                  ++under_water;                                       424                                  ++under_water;
  424                          else                                                         425                          else
  425                                  under_water = 0;                                     426                                  under_water = 0;
................................................................................................................................................................................
  427                                  dead = true;                                         428                                  dead = true;
  428                  }                                                                    429                  }
  429                  turn += 1;                                                           430                  turn += 1;
  430          }                                                                            431          }
  431                                                                                       432  
  432          Map map;                                                                     433          Map map;
  433          Water water;                                                                 434          Water water;
                                                                                        >   435          Hige hige;
  434          int  turn = 0;                                                               436          int  turn = 0;
  435          bool dead = false;                                                           437          bool dead = false;
  436          int  under_water = 0;                                                        438          int  under_water = 0;
  437          // TODO: when adding members, take care of clone().                          439          // TODO: when adding members, take care of clone().
  438          // TODO: fix this poor design.                                               440          // TODO: fix this poor design.
  439                                                                                       441  
  440  @property const:                                                                     442  @property const:
  441          long score()           { return map.collected_lambda*(dead?25L:cleared?7     443          long score()           { return map.collected_lambda*(dead?25L:cleared?7
  442          int water_level()      { return water.level(turn); }                         444          int water_level()      { return water.level(turn); }
  443          int water_until_rise() { return water.until_rise(turn); }                    445          int water_until_rise() { return water.until_rise(turn); }
  444          int hige_until_rise()  { return map.hige.until_rise(turn); }             |   446          int hige_until_rise()  { return hige.until_rise(turn); }
  445          int hp()               { return map.waterproof - under_water; }              447          int hp()               { return map.waterproof - under_water; }
  446          bool cleared()         { return map.cleared; }                               448          bool cleared()         { return map.cleared; }
  447  }                                                                                    449  }