Check-in [b96971b0b6]
Not logged in
Overview
SHA1 Hash:b96971b0b690ff1d9131f55f360391b19472b3cb
Date: 2012-07-16 19:02:57
User: kinaba
Comment:refactoring.
Timelines: family | ancestors | descendants | both | trunk
Diffs: redesign
Downloads: Tarball | ZIP archive
Other Links: files | file ages | manifest
Tags And Properties
Changes

Modified maps/static.map from [c02e46733b9bb4b5] to [256615d4a896c7e1].

3 3 \ 4 4 \ 5 5 \ 6 6 \ 7 7 \ 8 8 \ 9 9 \ 10 -R \ 10 +R \

Modified src/game.d from [d9bf3ea129c7cbc5] to [6849c1cc0eb810a9].

1 1 import util; 2 2 3 3 //////////////////////////////////////////////////////////////////////////////// 4 4 5 +bool is_spacy(char c) 6 +{ 7 + return c==' ' || c=='.' || c=='R' || c=='!' || c=='\\' || c=='O'; 8 +} 9 + 10 +bool is_rocky(char c) 11 +{ 12 + return c=='*' || c=='@'; 13 +} 14 + 15 +bool is_true_space(char c) 16 +{ 17 + return c==' '; 18 +} 19 + 20 +bool is_trampoline_source(char c) 21 +{ 22 + return 'A'<=c && c<='I'; 23 +} 24 + 25 +bool is_rocklambda(char c) 26 +{ 27 + return is_rocky(c) || c=='\\'; 28 +} 29 + 30 +//////////////////////////////////////////////////////////////////////////////// 31 + 5 32 class Pos 6 33 { 7 34 public immutable int y, x; 8 35 mixin DeriveCreate; 9 36 mixin DeriveCompare; 10 37 mixin DeriveShow; 11 38 Pos clone() const { return cast(Pos) this; } ................................................................................ 37 64 assert( aa[new Pos(1,2)]==2 ); 38 65 } 39 66 40 67 //////////////////////////////////////////////////////////////////////////////// 41 68 42 69 class Water 43 70 { 44 - public immutable int base, pace; 45 - mixin DeriveCreate; 46 71 mixin DeriveShow; 72 + 73 +private: 74 + immutable int base, pace; 75 + mixin DeriveCreate; 47 76 Water clone() const { return cast(Water) this; } 48 77 49 78 static load(string[string] params) 50 79 { 51 80 return new Water(params.get("Water", "0").to!int(), 52 81 params.get("Flooding", "0").to!int()); 53 82 } ................................................................................ 83 112 assert( 1 == w.level(5) ); 84 113 } 85 114 86 115 //////////////////////////////////////////////////////////////////////////////// 87 116 88 117 class Hige 89 118 { 90 - public immutable int pace; 91 - mixin DeriveCreate; 92 119 mixin DeriveShow; 120 + 121 +private: 122 + immutable int pace; 123 + mixin DeriveCreate; 93 124 Hige clone() const { return cast(Hige)this; } 94 125 95 126 static load(string[string] params) 96 127 { 97 128 return new Hige(params.get("Growth", "25").to!int()); 98 129 } 99 130 ................................................................................ 108 139 } 109 140 } 110 141 111 142 //////////////////////////////////////////////////////////////////////////////// 112 143 113 144 class Trampoline 114 145 { 115 - private immutable char[] target_of_; 116 - private immutable char[][] source_of_; 117 - private immutable Pos[] position_of_; 118 - private immutable char[] source_list_; 119 - private immutable char[] target_list_; 120 146 mixin DeriveShow; 147 + 148 +private: 149 + immutable char[] target_of_; 150 + immutable char[][] source_of_; 151 + immutable Pos[] position_of_; 152 + immutable char[] source_list_; 153 + immutable char[] target_list_; 121 154 Trampoline clone() const { return cast(Trampoline) this; } 155 + 122 156 this(Map m, char[char] tramparam) 123 157 { 124 158 auto ta = new char['I'+1]; 125 159 auto sr = new char[]['9'+1]; 126 160 auto po = new Pos[max('I','9')+1]; 127 161 char[] sl, tl; 128 162 foreach(fr,to; tramparam) { ................................................................................ 144 178 target_of_ = cast(immutable) ta; 145 179 source_of_ = cast(immutable) sr; 146 180 position_of_ = cast(immutable) po; 147 181 source_list_ = cast(immutable) sl; 148 182 target_list_ = cast(immutable) tl; 149 183 } 150 184 151 -@property const: 185 +public @property const: 152 186 const(char[]) source_list() { return source_list_; } 153 187 const(char[]) target_list() { return target_list_; } 154 188 const(char[]) source_of(char c) { return source_of_[c]; } 155 189 char target_of(char c) { return target_of_[c]; } 156 190 Pos[] source_pos(char c) { 157 191 Pos[] ps; 158 192 foreach(s; source_of(c)) ................................................................................ 164 198 165 199 //////////////////////////////////////////////////////////////////////////////// 166 200 167 201 class Map 168 202 { 169 203 mixin DeriveShow; 170 204 171 - char[][] data; 205 + private char[][] data; 172 206 Pos robot; 173 207 Pos lift; 174 - int waterproof; 175 - int razor; 208 + private int waterproof; 209 + private int collected_razor; 176 210 int collected_lambda; 177 211 int total_lambda; 178 - bool cleared; 179 - Pos[] may_update; 212 + private bool cleared; 213 + private Pos[] may_update; 180 214 181 - Map clone() const { return new Map(this); } 182 - this(in Map m) { 215 + private Map clone() const { return new Map(this); } 216 + private this(in Map m) { 183 217 foreach(s; m.data) 184 218 this.data ~= s.dup; 185 - this.robot = m.robot.clone(); 186 - this.lift = m.lift.clone(); 219 + this.robot = m.robot.clone(); 220 + this.lift = m.lift.clone(); 187 221 this.waterproof = m.waterproof; 188 - this.razor = m.razor; 222 + this.collected_razor = m.collected_razor; 189 223 this.collected_lambda = m.collected_lambda; 190 - this.total_lambda = m.total_lambda; 224 + this.total_lambda = m.total_lambda; 225 + this.cleared = m.cleared; 191 226 this.may_update = (cast(Map)m).may_update.dup; 192 - this.cleared = m.cleared; 193 227 } 194 228 229 + const { 230 + @property { 231 + int H() { return data.length; } 232 + int W() { return data[0].length; } 233 + int num_razor() { return collected_razor; } 234 + 235 + Pos[] razors() { return objects('!'); } 236 + Pos[] lambdas() { return objects('\\'); } 237 + } 238 + 239 + Pos[] objects(char c) { 240 + Pos[] ans; 241 + for(int y=1; y<=H; ++y) 242 + for(int x=1; x<=W; ++x) 243 + if(this[y,x] == c) 244 + ans ~= new Pos(y,x); 245 + return ans; 246 + } 247 + 248 + char opIndex(int y, int x) { 249 + --y, --x; 250 + if(y<0||H<=y||x<0||W<=x) 251 + return '#'; 252 + return data[H-1-y][x]; 253 + } 254 + 255 + char opIndex(in Pos p) { 256 + return this[p.y, p.x]; 257 + } 258 + } 259 + 260 +private: 195 261 this(string[] raw_data, string[string] params, char[char] trampo) 196 262 { 197 263 int width = 0; 198 264 foreach(r; raw_data) 199 265 width = max(width, r.length); 200 266 foreach(r; raw_data) { 201 267 this.data ~= r.dup; ................................................................................ 207 273 for(int x=1; x<=W; ++x) { 208 274 if(this[y,x] == 'R') 209 275 this.robot = new Pos(y,x); 210 276 if(this[y,x] == 'L' || this[y,x] == 'O') 211 277 this.lift = new Pos(y,x); 212 278 if(this[y,x] == '\\' || this[y,x] == '@') 213 279 total_lambda++; 214 - if(this[y,x] == '*' || this[y,x] == '@') 280 + if(is_rocky(this[y,x])) 215 281 may_update ~= new Pos(y,x); 216 282 } 217 283 218 - this.waterproof = params.get("Waterproof", "5").to!int(); 219 - this.razor = params.get("Razors", "0").to!int(); 220 - } 221 - 222 - const @property { 223 - int H() { return data.length; } 224 - int W() { return data[0].length; } 225 - } 226 - 227 - const { 228 - char opIndex(int y, int x) 229 - { 230 - // Adjust coordinate to the spec. bottom-left is (1,1). 231 - --y, --x; 232 - if(y<0||H<=y||x<0||W<=x) 233 - return '#'; 234 - return data[H-1-y][x]; 235 - } 236 - 237 - char opIndex(in Pos p) 238 - { 239 - return this[p.y, p.x]; 240 - } 284 + this.waterproof = params.get("Waterproof", "5").to!int(); 285 + this.collected_razor = params.get("Razors", "0").to!int(); 241 286 } 242 287 243 288 void opIndexAssign(char c, int y, int x) 244 289 { 245 - // Adjust coordinate to the spec. bottom-left is (1,1). 246 290 --y, --x; 247 291 if(y<0||H<=y||x<0||W<=x) 248 292 return; 249 293 data[H-1-y][x] = c; 250 294 } 251 295 252 296 void opIndexAssign(char c, in Pos p) 253 297 { 254 298 this[p.y, p.x] = c; 255 299 } 256 300 257 - Pos[] objects(char c) const { 258 - Pos[] ans; 259 - for(int y=1; y<=H; ++y) 260 - for(int x=1; x<=W; ++x) 261 - if(this[y,x] == c) 262 - ans ~= new Pos(y,x); 263 - return ans; 264 - } 265 - 266 - Pos[] razors() const { return objects('!'); } 267 - Pos[] lambdas() const { return objects('\\'); } 268 - 269 301 bool command(char c, int turn, bool hige_day, in Trampoline tr) 270 302 { 271 - assert( this[robot] == 'R' ); 272 - if(c=='R') return move( 0, +1, hige_day, tr); 273 - if(c=='L') return move( 0, -1, hige_day, tr); 274 - if(c=='U') return move(+1, 0, hige_day, tr); 275 - if(c=='D') return move(-1, 0, hige_day, tr); 276 - if(c=='W') return move( 0, 0, hige_day, tr); 277 - if(c=='S') return use_razor(hige_day); 278 - assert(false); 303 + switch(c) 304 + { 305 + case 'R': return move( 0, +1, hige_day, tr); 306 + case 'L': return move( 0, -1, hige_day, tr); 307 + case 'U': return move(+1, 0, hige_day, tr); 308 + case 'D': return move(-1, 0, hige_day, tr); 309 + case 'W': return move( 0, 0, hige_day, tr); 310 + case 'S': return use_razor(hige_day); 311 + default: assert(false); 312 + } 279 313 } 280 314 281 315 bool use_razor(bool hige_day) 282 316 { 283 - if(razor) { 284 - razor--; 317 + if(collected_razor > 0) 318 + { 319 + collected_razor--; 285 320 for(int dy=-1; dy<=+1; ++dy) 286 321 for(int dx=-1; dx<=+1; ++dx) 287 322 if(this[robot.y+dy,robot.x+dx] == 'W') { 288 323 emptified(new Pos(robot.y+dy,robot.x+dx)); 289 324 this[robot.y+dy,robot.x+dx] = ' '; 290 325 } 291 326 } 292 - 293 327 return update(hige_day); 294 328 } 295 329 296 - bool rocky(char c) { return c=='*' || c=='@'; } 297 - 298 - void emptified(Pos p) { 299 - for(int dy=0; dy<=+1; ++dy) 300 - for(int dx=-1; dx<=+1; ++dx) 301 - may_update ~= new Pos(p.y+dy, p.x+dx); 302 - } 330 + // Register a position that may become empty in the last turn. 331 + void emptified(Pos p) 332 + { 333 + for(int dy=0; dy<=+1; ++dy) 334 + for(int dx=-1; dx<=+1; ++dx) 335 + may_update ~= new Pos(p.y+dy, p.x+dx); 336 + } 303 337 304 338 bool move(int dy, int dx, bool hige_day, in Trampoline tr) 305 339 { 306 - emptified(robot); 307 - 308 - int y = robot.y; 309 - int x = robot.x; 310 - if( '\\' == this[y+dy,x+dx] ) 311 - collected_lambda++; 312 - if( '!' == this[y+dy,x+dx] ) 313 - razor++; 314 - if( 'O' == this[y+dy,x+dx] ) 315 - cleared = true; 316 - if( " \\!.O".count(this[y+dy,x+dx])==1 ) { 317 - this[y,x]=' '; 318 - this[y+dy,x+dx]='R'; 319 - robot = new Pos(y+dy,x+dx); 320 - } else if(dy==0 && rocky(this[y+dy,x+dx]) && ' '==this[y+dy*2,x+dx*2]) { 321 - char rock = this[y+dy,x+dx]; 322 - this[y,x]=' '; 323 - this[y+dy,x+dx]='R'; 324 - this[y+dy*2,x+dx*2]=rock; 325 - robot = new Pos(y+dy,x+dx); 340 + Pos next = new Pos(robot.y+dy, robot.x+dx); 341 + int y=robot.y, x=robot.x; 342 + 343 + if( '\\' == this[next] ) collected_lambda++; 344 + if( '!' == this[next] ) collected_razor++; 345 + if( 'O' == this[next] ) cleared = true; 346 + 347 + if( is_spacy(this[next]) ) 348 + { 349 + emptified(robot); 350 + this[y,x] = ' '; 351 + this[next] = 'R'; 352 + robot = next; 353 + } 354 + else if(dy==0 && is_rocky(this[next]) && ' '==this[y+dy*2,x+dx*2]) 355 + { 356 + char rock = this[next]; 357 + emptified(robot); 358 + this[y,x] = ' '; 359 + this[next] = 'R'; 360 + this[y+dy*2,x+dx*2] = rock; 361 + robot = next; 326 362 may_update ~= new Pos(y+dy*2,x+dx*2); 327 - } else if('A'<=this[y+dy,x+dx] && this[y+dy,x+dx]<='I') { 328 - this[y,x]=' '; 329 - Pos tp = tr.target_pos(this[y+dy,x+dx]); 330 - foreach(p; tr.source_pos(this[tp])) { 363 + } 364 + else if(is_trampoline_source(this[next])) 365 + { 366 + emptified(robot); 367 + this[y,x] = ' '; 368 + Pos tp = tr.target_pos(this[next]); 369 + foreach(p; tr.source_pos(this[tp])) 370 + { 331 371 emptified(p); 332 372 this[p] = ' '; 333 373 } 334 374 this[tp] = 'R'; 335 - robot = tp; 375 + robot = tp; 336 376 } 337 377 return update(hige_day); 338 378 } 339 379 340 380 bool update(bool hige_day) 341 381 { 342 382 // Write after all the updates are processed. ................................................................................ 343 383 Tuple!(int,int,char)[] write_buffer; 344 384 void write(int y, int x, char c) { write_buffer ~= tuple(y,x,c); } 345 385 void writep(Pos p, char c) { write_buffer ~= tuple(0+p.y,0+p.x,c); } 346 386 scope(exit) { 347 387 may_update.length = 0; 348 388 foreach(wr; write_buffer) { 349 389 this[wr[0],wr[1]] = wr[2]; 350 - if(rocky(wr[2])) 390 + if(is_rocky(wr[2])) 351 391 may_update ~= new Pos(wr[0],wr[1]); 352 392 if(wr[2]==' ') 353 393 emptified(new Pos(wr[0], wr[1])); 354 394 } 355 395 } 356 396 357 397 if(collected_lambda == total_lambda) ................................................................................ 366 406 may_update ~= new Pos(y,x); 367 407 } 368 408 369 409 sort(may_update); 370 410 foreach(p; may_update) { 371 411 int y = p.y, x = p.x; 372 412 char rock = this[p]; 373 - if(rocky(this[p])) { 413 + if(is_rocky(this[p])) { 374 414 if(this[p.D]==' ') { 375 415 writep(p, ' '); 376 416 writep(p.D, (rock=='@'&&this[p.D.D]!=' ' ? '\\' : rock)); 377 417 if(robot == p.D.D) 378 418 dead=true; 379 419 } 380 - else if((rocky(this[p.D]) || this[p.D]=='\\') && this[p.R]==' ' && this[p.R.D]==' ') { 420 + else if((is_rocky(this[p.D]) || this[p.D]=='\\') && this[p.R]==' ' && this[p.R.D]==' ') { 381 421 writep(p, ' '); 382 422 writep(p.R.D,(rock=='@'&&this[p.R.D.D]!=' ' ? '\\' : rock)); 383 423 if(robot == p.R.D.D) 384 424 dead=true; 385 425 } 386 - else if(rocky(this[p.D]) && this[p.L]==' ' && this[p.L.D]==' ') { 426 + else if(is_rocky(this[p.D]) && this[p.L]==' ' && this[p.L.D]==' ') { 387 427 writep(p, ' '); 388 428 writep(p.L.D, (rock=='@'&&this[p.L.D.D]!=' ' ? '\\' : rock)); 389 429 if(robot == p.L.D.D) 390 430 dead=true; 391 431 } 392 432 } 393 433 else if(this[p]=='W') {

Modified src/gui.d from [2b6041f7525bfa95] to [91ff36ba7e144853].

117 117 118 118 // Update textual info. 119 119 this.text = .text( 120 120 "Score: ", g.score, 121 121 " Air: ", g.hp, 122 122 " Tide: ", g.water_until_rise, 123 123 " Wadler: ", g.hige_until_rise, 124 - " Razor: ", g.map.razor); 124 + " Razor: ", g.map.num_razor); 125 125 invalidate(); 126 126 } 127 127 128 128 private: 129 129 void setup_keyhandling(void delegate(char c) command) 130 130 { 131 131 noMessageFilter();

Modified src/solver.d from [da568e3b806540de] to [97e58dfa28df65c7].

7 7 interface Solver 8 8 { 9 9 // this(in Game g); 10 10 char single_step(); 11 11 void force(char c); 12 12 } 13 13 14 - 15 -bool is_spacy(char c) 16 -{ 17 - return c==' ' || c=='.' || c=='R' || c=='!' || c=='\\' || c=='O'; 18 -} 19 - 20 -bool is_rocky(char c) 21 -{ 22 - return c=='*' || c=='@'; 23 -} 24 - 25 -bool is_true_space(char c) 26 -{ 27 - return c==' '; 28 -} 29 - 30 -bool is_trampoline_source(char c) 31 -{ 32 - return 'A'<=c && c<='I'; 33 -} 34 - 35 -bool is_rocklambda(char c) 36 -{ 37 - return is_rocky(c) || c=='\\'; 38 -} 39 - 40 14 Tuple!(string,int) death_move(in Game g) 41 15 { 42 16 // TODO: S 43 17 44 18 string death; 45 19 int breath; 46 20 int y = g.map.robot.y; ................................................................................ 186 160 if( g.map.collected_lambda == g.map.total_lambda ) { 187 161 cand = search(g, ro, [li], death); 188 162 } else if( !la.empty ){ 189 163 cand ~= search(g, ro, la~ra, death); 190 164 } 191 165 192 166 // 'higesori' mode 193 - if( !hi.empty && g.map.razor>0 ) { 167 + if( !hi.empty && g.map.num_razor>0 ) { 194 168 int his = 0; 195 169 for(int dy=-1; dy<=+1; ++dy) 196 170 for(int dx=-1; dx<=+1; ++dx) 197 171 if(g.map[ro.y+dy,ro.x+dx] == 'W') 198 172 his++; 199 173 200 174 if(his>=2 || his==hi.length)