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