Differences From Artifact [7c15481493257083]:
- File        
game.d
- 2012-07-14 08:55:55 - part of checkin [69105bf94a] on branch trunk - Stand alone solver. (user: kinaba) [annotate]
 
 - File        
src/game.d
- 2012-07-14 09:16:47 - part of checkin [6293256fec] on branch trunk - Preparing for submission... (user: kinaba) [annotate]
 
 
To Artifact [cde4121762ca0c01]:
- File        
src/game.d
- 2012-07-14 11:24:30 - part of checkin [bee0596f0f] on branch trunk - Refactoring. (user: kinaba) [annotate]
 
 
    1  import util;                                                                           1  import util;
    2  import output;                                                                   <
    3                                                                                         2  
    4  ////////////////////////////////////////////////////////////////////////////////       3  ////////////////////////////////////////////////////////////////////////////////
    5                                                                                         4  
    6  class Pos                                                                              5  class Pos
    7  {                                                                                      6  {
    8          public immutable int y, x;                                                     7          public immutable int y, x;
    9          mixin DeriveCreate;                                                            8          mixin DeriveCreate;
   10          mixin DeriveCompare;                                                           9          mixin DeriveCompare;
   11          mixin DeriveShow;                                                             10          mixin DeriveShow;
   12          Pos clone() { return this; }                                             |    11          Pos clone() const { return new Pos(y, x); }
   13                                                                                        12  
   14  @property:                                                                            13  @property:
   15          Pos wait()  { return this; }                                             |    14          Pos wait()  { return this.clone(); }
   16          Pos up()    { return new Pos(y+1, x); }                                       15          Pos up()    { return new Pos(y+1, x); }
   17          Pos down()  { return new Pos(y-1, x); }                                       16          Pos down()  { return new Pos(y-1, x); }
   18          Pos left()  { return new Pos(y, x-1); }                                       17          Pos left()  { return new Pos(y, x-1); }
   19          Pos right() { return new Pos(y, x+1); }                                       18          Pos right() { return new Pos(y, x+1); }
   20          alias wait  W,w;                                                              19          alias wait  W,w;
   21          alias up    U,u;                                                              20          alias up    U,u;
   22          alias down  D,d;                                                              21          alias down  D,d;
................................................................................................................................................................................
   42                                                                                        41  
   43  class Water                                                                           42  class Water
   44  {                                                                                     43  {
   45          public immutable int base, pace;                                              44          public immutable int base, pace;
   46          mixin DeriveCreate;                                                           45          mixin DeriveCreate;
   47          mixin DeriveCompare;                                                          46          mixin DeriveCompare;
   48          mixin DeriveShow;                                                             47          mixin DeriveShow;
   49          Water clone() { return this; }                                           |    48          Water clone() const { return new Water(base, pace); }
   50                                                                                        49  
   51          static load(string[string] params)                                            50          static load(string[string] params)
   52          {                                                                             51          {
   53                  return new Water(                                                     52                  return new Water(
   54                          params.get("Water",    "0").to!int(),                         53                          params.get("Water",    "0").to!int(),
   55                          params.get("Flooding", "0").to!int()                          54                          params.get("Flooding", "0").to!int()
   56                  );                                                                    55                  );
   57          }                                                                             56          }
   58                                                                                        57  
   59          int level(int number_of_update)                                          |    58          int level(int number_of_update) const
   60          {                                                                             59          {
   61                  return pace ? base+(number_of_update/pace) : base;                    60                  return pace ? base+(number_of_update/pace) : base;
   62          }                                                                             61          }
   63                                                                                        62  
   64          int until_rise(int number_of_update)                                     |    63          int until_rise(int number_of_update) const
   65          {                                                                             64          {
   66                  return pace ? pace-number_of_update%pace : int.max;                   65                  return pace ? pace-number_of_update%pace : int.max;
   67          }                                                                             66          }
   68  }                                                                                     67  }
   69                                                                                        68  
   70  unittest                                                                              69  unittest
   71  {                                                                                     70  {
................................................................................................................................................................................
  100          }                                                                             99          }
  101                                                                                       100  
  102          char[][] data;                                                               101          char[][] data;
  103          Pos robot;                                                                   102          Pos robot;
  104          Pos lift;                                                                    103          Pos lift;
  105          int waterproof;                                                              104          int waterproof;
  106                                                                                       105  
  107          Map clone() { return new Map(this); }                                    |   106          Map clone() const { return new Map(this); }
  108          this(Map m) {                                                            |   107          this(const(Map) m) {
  109                  foreach(s; m.data)                                                   108                  foreach(s; m.data)
  110                          this.data ~= s.dup;                                          109                          this.data ~= s.dup;
  111                  this.robot = m.robot.clone();                                        110                  this.robot = m.robot.clone();
  112                  this.lift = m.lift.clone();                                          111                  this.lift = m.lift.clone();
  113                  this.waterproof = m.waterproof;                                      112                  this.waterproof = m.waterproof;
  114          }                                                                            113          }
  115                                                                                       114  
................................................................................................................................................................................
  136          }                                                                            135          }
  137                                                                                       136  
  138          const @property {                                                            137          const @property {
  139                  int H() { return data.length; }                                      138                  int H() { return data.length; }
  140                  int W() { return data[0].length; }                                   139                  int W() { return data[0].length; }
  141          }                                                                            140          }
  142                                                                                       141  
                                                                                        >   142          const {
  143          char opIndex(int y, int x)                                               |   143                  char opIndex(int y, int x)
  144          {                                                                        |   144                  {
  145                  // Adjust coordinate to the spec. bottom-left is (1,1).          |   145                          // Adjust coordinate to the spec. bottom-left is (1,1).
  146                  --y, --x;                                                        |   146                          --y, --x;
  147                  if(y<0||H<=y||x<0||W<=x)                                         |   147                          if(y<0||H<=y||x<0||W<=x)
  148                          return '#';                                              |   148                                  return '#';
  149                  return data[H-1-y][x];                                           |   149                          return data[H-1-y][x];
  150          }                                                                        |   150                  }
  151                                                                                       151  
  152          char opIndex(Pos p)                                                      |   152                  char opIndex(Pos p)
  153          {                                                                        |   153                  {
  154                  return this[p.y, p.x];                                           |   154                          return this[p.y, p.x];
                                                                                        >   155                  }
  155          }                                                                            156          }
  156                                                                                       157  
  157          void opIndexAssign(char c, int y, int x)                                     158          void opIndexAssign(char c, int y, int x)
  158          {                                                                            159          {
  159                  // Adjust coordinate to the spec. bottom-left is (1,1).              160                  // Adjust coordinate to the spec. bottom-left is (1,1).
  160                  --y, --x;                                                            161                  --y, --x;
  161                  if(y<0||H<=y||x<0||W<=x)                                             162                  if(y<0||H<=y||x<0||W<=x)
................................................................................................................................................................................
  298                  return new Game(raw_data, params);                                   299                  return new Game(raw_data, params);
  299          }                                                                            300          }
  300                                                                                       301  
  301          this(string[] raw_data, string[string] params)                               302          this(string[] raw_data, string[string] params)
  302          {                                                                            303          {
  303                  this.map = Map.load(raw_data, params);                               304                  this.map = Map.load(raw_data, params);
  304                  this.water = Water.load(params);                                     305                  this.water = Water.load(params);
  305                  this.output = new NilOutput;                                     <
  306          }                                                                            306          }
  307                                                                                       307  
  308          Game clone() { return new Game(this); }                                  |   308          Game clone() const { return new Game(this); }
  309          this(Game g) {                                                           |   309          this(const(Game) g) {
  310                  map = g.map.clone();                                                 310                  map = g.map.clone();
  311                  water = g.water.clone();                                             311                  water = g.water.clone();
  312                  output = new NilOutput;                                          <
  313                  turn = g.turn;                                                       312                  turn = g.turn;
  314                  dead = g.dead;                                                       313                  dead = g.dead;
  315                  lambda = g.lambda;                                                   314                  lambda = g.lambda;
  316                  exit_bonus = g.exit_bonus;                                           315                  exit_bonus = g.exit_bonus;
  317                  under_water = g.under_water;                                         316                  under_water = g.under_water;
  318          }                                                                            317          }
  319                                                                                       318  
  320          void set_output(Output o) { this.output = (o is null ? new NilOutput : o <
  321                                                                                   <
  322          void command(char c)                                                         319          void command(char c)
  323          {                                                                            320          {
  324                  if(dead || cleared)                                                  321                  if(dead || cleared)
  325                          return;                                                      322                          return;
  326                  scope(exit) {                                                    <
  327                          if(dead || cleared)                                      <
  328                                  output.flush();                                  <
  329                  }                                                                <
  330                  this.output.command(c);                                          <
  331                                                                                       323  
  332                  if(c == 'A')                                                         324                  if(c == 'A')
  333                  {                                                                    325                  {
  334                          exit_bonus = 1;                                              326                          exit_bonus = 1;
  335                          return;                                                      327                          return;
  336                  }                                                                    328                  }
  337                                                                                       329  
................................................................................................................................................................................
  353                  if( under_water > map.waterproof )                                   345                  if( under_water > map.waterproof )
  354                          dead = true;                                                 346                          dead = true;
  355                  turn += 1;                                                           347                  turn += 1;
  356          }                                                                            348          }
  357                                                                                       349  
  358          Map map;                                                                     350          Map map;
  359          Water water;                                                                 351          Water water;
  360          Output output;                                                           <
  361          int  turn = 0;                                                               352          int  turn = 0;
  362          bool dead = false;                                                           353          bool dead = false;
  363          int  lambda = 0;                                                             354          int  lambda = 0;
  364          int  exit_bonus = 0;                                                         355          int  exit_bonus = 0;
  365          int  under_water = 0;                                                        356          int  under_water = 0;
  366          // TODO: when adding members, take care of clone().                          357          // TODO: when adding members, take care of clone().
  367          // TODO: fix this poor design.                                               358          // TODO: fix this poor design.
  368                                                                                       359  
  369          @property {                                                              |   360          @property const {
  370                  long score() { return lambda*25L*(1+exit_bonus) - turn; }            361                  long score() { return lambda*25L*(1+exit_bonus) - turn; }
  371                  int water_level() { return water.level(turn); }                      362                  int water_level() { return water.level(turn); }
  372                  int water_until_rise() { return water.until_rise(turn); }            363                  int water_until_rise() { return water.until_rise(turn); }
  373                  bool cleared() { return exit_bonus>0; }                              364                  bool cleared() { return exit_bonus>0; }
  374                  int hp() { return map.waterproof - under_water; }                    365                  int hp() { return map.waterproof - under_water; }
  375                  long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus     366                  long score_if_abort_now() { return lambda*25*(1+max(1,exit_bonus
  376          }                                                                            367          }
  377  }                                                                                    368  }
  378                                                                                       369  
  379  unittest                                                                             370  unittest
  380  {                                                                                    371  {
  381          Game.load(["###","...","#RL"], ["xxx":"yyy"]);                               372          Game.load(["###","...","#RL"], ["xxx":"yyy"]);
  382  }                                                                                    373  }