Check-in [de416b884b]
Not logged in
Overview
SHA1 Hash:de416b884b871ae6e3a1cacc4c6fa4ef4fd21d34
Date: 2012-07-15 21:32:33
User: kinaba
Comment:horock game.
Timelines: family | ancestors | descendants | both | trunk
Diffs: redesign
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified src/game.d from [e25c75ea96d80507] to [403db28cbc4609b7].

126 126 Pos robot; 127 127 Pos lift; 128 128 int waterproof; 129 129 Pos[char] tr_target; 130 130 Pos[][char] tr_source; 131 131 const(Hige) hige; 132 132 int razor; 133 + int collected_lambda; 134 + int total_lambda; 133 135 134 136 Map clone() const { return new Map(this); } 135 137 this(in Map m) { 136 138 foreach(s; m.data) 137 139 this.data ~= s.dup; 138 140 this.robot = m.robot.clone(); 139 141 this.lift = m.lift.clone(); 140 142 this.waterproof = m.waterproof; 141 143 this.tr_target = cast(Pos[char])m.tr_target; 142 144 this.tr_source = cast(Pos[][char])m.tr_source; 143 145 this.hige = m.hige.clone(); 144 146 this.razor = m.razor; 147 + this.collected_lambda = m.collected_lambda; 148 + this.total_lambda = m.total_lambda; 145 149 } 146 150 147 151 this(string[] raw_data, string[string] params, char[char] trampo) 148 152 { 149 153 int width = 0; 150 154 foreach(r; raw_data) 151 155 width = max(width, r.length); ................................................................................ 157 161 158 162 for(int y=1; y<=H; ++y) 159 163 for(int x=1; x<=W; ++x) { 160 164 if(this[y,x] == 'R') 161 165 this.robot = new Pos(y,x); 162 166 if(this[y,x] == 'L' || this[y,x] == 'O') 163 167 this.lift = new Pos(y,x); 168 + if(this[y,x] == '\\' || this[y,x] == '@') 169 + total_lambda++; 164 170 } 165 171 166 172 Pos[char] tr_pos; 167 173 for(int y=1; y<=H; ++y) 168 174 for(int x=1; x<=W; ++x) { 169 175 char c = this[y,x]; 170 176 if('1'<=c && c<='9' || 'A'<=c&&c<='I') ................................................................................ 234 240 for(int y=1; y<=H; ++y) 235 241 for(int x=1; x<=W; ++x) 236 242 if(this[y,x] == 'L' || this[y,x] == 'O') 237 243 return false; 238 244 return true; 239 245 } 240 246 241 - Tuple!(int,bool) command(char c, int turn) 247 + bool command(char c, int turn) 242 248 { 243 249 assert( this[robot] == 'R' ); 244 250 if(c=='R') return move( 0, +1, turn); 245 251 if(c=='L') return move( 0, -1, turn); 246 252 if(c=='U') return move(+1, 0, turn); 247 253 if(c=='D') return move(-1, 0, turn); 248 254 if(c=='W') return move( 0, 0, turn); 249 255 if(c=='S') return use_razor(turn); 250 256 assert(false); 251 257 } 252 258 253 - Tuple!(int, bool) use_razor(int turn) 259 + bool use_razor(int turn) 254 260 { 255 261 if(razor) { 256 262 razor--; 257 263 for(int dy=-1; dy<=+1; ++dy) 258 264 for(int dx=-1; dx<=+1; ++dx) 259 265 if(this[robot.y+dy,robot.x+dx] == 'W') 260 266 this[robot.y+dy,robot.x+dx] = ' '; 261 267 } 262 268 263 - bool dead = update(turn); 264 - return tuple(0,dead); 269 + return update(turn); 265 270 } 266 271 267 - Tuple!(int, bool) move(int dy, int dx, int turn) 272 + bool rocky(char c) { return c=='*' || c=='@'; } 273 + 274 + bool move(int dy, int dx, int turn) 268 275 { 269 276 int y = robot.y; 270 277 int x = robot.x; 271 - int lambda = 0; 272 278 if( '\\' == this[y+dy,x+dx] ) 273 - lambda++; 279 + collected_lambda++; 274 280 if( '!' == this[y+dy,x+dx] ) 275 281 razor++; 276 282 if( " \\!.O".count(this[y+dy,x+dx])==1 ) { 277 283 this[y,x]=' '; 278 284 this[y+dy,x+dx]='R'; 279 285 robot = new Pos(y+dy,x+dx); 280 - } else if(dy==0 && '*'==this[y+dy,x+dx] && ' '==this[y+dy*2,x+dx*2]) { 286 + } else if(dy==0 && rocky(this[y+dy,x+dx]) && ' '==this[y+dy*2,x+dx*2]) { 287 + char rock = this[y+dy,x+dx]; 281 288 this[y,x]=' '; 282 289 this[y+dy,x+dx]='R'; 283 - this[y+dy*2,x+dx*2]='*'; 290 + this[y+dy*2,x+dx*2]=rock; 284 291 robot = new Pos(y+dy,x+dx); 285 292 } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') { 286 293 this[y,x]=' '; 287 294 Pos tp = tr_target[this[y+dy,x+dx]]; 288 295 foreach(p; tr_source[this[tp]]) 289 296 this[p] = ' '; 290 297 this[tp] = 'R'; 291 298 robot = tp; 292 299 } 293 - bool dead = update(turn); 294 - return tuple(lambda,dead); 300 + return update(turn); 295 301 } 296 302 297 303 bool update(int turn) 298 304 { 299 305 bool dead = false; 300 306 301 307 char[][] next; 302 308 foreach(y,s; data) 303 309 next ~= s.dup; 304 310 305 311 ref char access(Pos p) { return next[H-p.y][p.x-1]; } 306 312 307 - bool lambda = false; 308 - for(int y=1; y<=H; ++y) 309 - for(int x=1; x<=W; ++x) 310 - lambda |= (this[y,x] == '\\'); 311 - 312 313 for(int y=1; y<=H; ++y) 313 314 for(int x=1; x<=W; ++x) { 314 315 Pos p = new Pos(y,x); 315 - if(this[p]=='*') { 316 + char rock = this[p]; 317 + if(rocky(this[p])) { 316 318 if(this[p.D]==' ') { 317 319 access(p) =' '; 318 - access(p.D)='*'; 320 + access(p.D)=(rock=='@'&&this[p.D.D]!=' ' ? '\\' : rock); 319 321 if(robot == p.D.D) 320 322 dead=true; 321 323 } 322 - else if((this[p.D]=='*' || this[p.D]=='\\') && this[p.R]==' ' && this[p.R.D]==' ') { 324 + else if((rocky(this[p.D]) || this[p.D]=='\\') && this[p.R]==' ' && this[p.R.D]==' ') { 323 325 access(p)=' '; 324 - access(p.R.D)='*'; 326 + access(p.R.D)=(rock=='@'&&this[p.R.D.D]!=' ' ? '\\' : rock); 325 327 if(robot == p.R.D.D) 326 328 dead=true; 327 329 } 328 - else if(this[p.D]=='*' && this[p.L]==' ' && this[p.L.D]==' ') { 330 + else if(rocky(this[p.D]) && this[p.L]==' ' && this[p.L.D]==' ') { 329 331 access(p)=' '; 330 - access(p.L.D)='*'; 332 + access(p.L.D)=(rock=='@'&&this[p.L.D.D]!=' ' ? '\\' : rock); 331 333 if(robot == p.L.D.D) 332 334 dead=true; 333 335 } 334 336 } 335 337 else if(this[p]=='L') { 336 - if(!lambda) 338 + if(collected_lambda == total_lambda) 337 339 access(p) = 'O'; 338 340 } 339 341 else if(this[p]=='W') { 340 342 if( hige.is_growing_turn(turn) ) 341 343 for(int dy=-1; dy<=+1; ++dy) 342 344 for(int dx=-1; dx<=+1; ++dx) 343 345 if(this[p.y+dy,p.x+dx] == ' ') ................................................................................ 390 392 391 393 Game clone() const { return new Game(this); } 392 394 this(in Game g) { 393 395 map = g.map.clone(); 394 396 water = g.water.clone(); 395 397 turn = g.turn; 396 398 dead = g.dead; 397 - lambda = g.lambda; 398 399 cleared = g.cleared; 399 400 under_water = g.under_water; 400 401 } 401 402 402 403 void command(char c) 403 404 { 404 405 assert(c != 'A'); 405 406 if(dead || cleared) 406 407 return; 407 408 408 409 // TODO: clarify the event order 409 - Tuple!(int,bool) ld = map.command(c, turn); 410 + bool dead_now = map.command(c, turn); 410 411 if( map.cleared() ) { 411 412 cleared = true; 412 413 } 413 414 else { 414 - lambda += ld[0]; 415 - if( ld[1] ) 415 + if( dead_now ) 416 416 dead = true; 417 417 } 418 418 if(!cleared) { 419 419 if( map.robot.y <= water_level ) 420 420 ++under_water; 421 421 else 422 422 under_water = 0; ................................................................................ 426 426 turn += 1; 427 427 } 428 428 429 429 Map map; 430 430 Water water; 431 431 int turn = 0; 432 432 bool dead = false; 433 - int lambda = 0; 434 433 int under_water = 0; 435 434 bool cleared = false; 436 435 // TODO: when adding members, take care of clone(). 437 436 // TODO: fix this poor design. 438 437 439 438 @property const { 440 - long score() { return lambda*(dead ? 25L : cleared ? 75L : 50L) - turn; } 439 + long score() { return map.collected_lambda*(dead ? 25L : cleared ? 75L : 50L) - turn; } 441 440 int water_level() { return water.level(turn); } 442 441 int water_until_rise() { return water.until_rise(turn); } 443 442 int hige_until_rise() { return map.hige.until_rise(turn); } 444 443 int hp() { return map.waterproof - under_water; } 445 444 } 446 445 }