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