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 }