Differences From Artifact [4dfcc976e17caad5]:
- File
src/solver.d
- 2012-07-15 15:42:31 - part of checkin [310a3c5d41] on branch trunk - speed testing... 100x100 no-op is fast enough... (user: kinaba) [annotate]
To Artifact [707b7344a0841f62]:
- File
src/solver.d
- 2012-07-15 16:06:29 - part of checkin [913d120d42] on branch trunk - size tuning solver (user: kinaba) [annotate]
1 import util; 1 import util;
2 import game; 2 import game;
3 3
4 bool rocky(char c){ return c=='*'||c=='@'; } 4 bool rocky(char c){ return c=='*'||c=='@'; }
5 5
> 6 interface Solver
> 7 {
> 8 // this(in Game g);
> 9 char single_step();
> 10 void force(char c);
> 11 }
> 12
6 class Solver_0 | 13 class Solver_0 : Solver
7 { 14 {
8 this(in Game g) {} 15 this(in Game g) {}
9 char single_step() { return 'W'; } 16 char single_step() { return 'W'; }
10 void force(char c) {} 17 void force(char c) {}
11 } 18 }
12 19
13 class Solver_1 | 20 class Solver_1 : Solver
14 { 21 {
15 int wait_count = 0; 22 int wait_count = 0;
16 int choke_count = 0; 23 int choke_count = 0;
17 24
18 Game g; 25 Game g;
19 this(in Game g) 26 this(in Game g)
20 { 27 {
................................................................................................................................................................................
163 { 170 {
164 bool danger(int y, int x) 171 bool danger(int y, int x)
165 { 172 {
166 if(g.map[y,x] == ' ' || g.map[y,x] == 'R') 173 if(g.map[y,x] == ' ' || g.map[y,x] == 'R')
167 return false; 174 return false;
168 if(rocky(g.map[y+1,x])) 175 if(rocky(g.map[y+1,x]))
169 return true; 176 return true;
170 if(rocky(g.map[y+1,x-1]) && (g.map[y,x-1]=='\\'||rocky(g | 177 if(rocky(g.map[y+1,x-1]) && (g.map[y,x-1]=='\\'||rocky(g
> 178 && (g.map[y+1,x]==' '||g.map[y+1,x]=='R'))
171 return true; 179 return true;
172 if(rocky(g.map[y+1,x+1]) && rocky(g.map[y,x+1]) && (g.ma 180 if(rocky(g.map[y+1,x+1]) && rocky(g.map[y,x+1]) && (g.ma
173 return true; 181 return true;
174 if(rocky(g.map[y,x-1]) && (g.map[y-1,x-1]=='\\'||rocky(g | 182 if(rocky(g.map[y,x-1]) && (g.map[y-1,x-1]=='\\'||rocky(g
> 183 && (g.map[y-1,x]==' '||g.map[y-1,x]=='R'))
175 return true; 184 return true;
176 if(rocky(g.map[y,x+1]) && rocky(g.map[y-1,x+1]) && (g.ma 185 if(rocky(g.map[y,x+1]) && rocky(g.map[y-1,x+1]) && (g.ma
177 return true; 186 return true;
178 return false; 187 return false;
179 } 188 }
180 189
181 // avoid directly below '*' 190 // avoid directly below '*'
................................................................................................................................................................................
300 } 309 }
301 return []; 310 return [];
302 } 311 }
303 return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC(); 312 return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC();
304 } 313 }
305 } 314 }
306 315
307 class Solver_2(Solver) | 316 class Solver_2(SubSolver) : Solver
308 { 317 {
309 string plan; 318 string plan;
310 bool plan_broken = true; 319 bool plan_broken = true;
311 320
312 Game g; 321 Game g;
313 this(in Game g) 322 this(in Game g)
314 { 323 {
315 this.g = g.clone(); 324 this.g = g.clone();
316 make_plan(g); 325 make_plan(g);
317 } 326 }
318 327
319 Tuple!(Solver,string) run_sub_solver(in Game g) | 328 Tuple!(SubSolver,string) run_sub_solver(in Game g)
320 { 329 {
321 string log; 330 string log;
322 auto s = new Solver(g); | 331 auto s = new SubSolver(g);
323 while(!g.cleared && !g.dead && plan.length<=g.map.H*g.map.W) { 332 while(!g.cleared && !g.dead && plan.length<=g.map.H*g.map.W) {
324 char c = s.single_step(); 333 char c = s.single_step();
325 if( c == 'A' ) 334 if( c == 'A' )
326 break; 335 break;
327 log ~= c; 336 log ~= c;
328 } 337 }
329 while(log.length>0 && log[$-1]=='W') 338 while(log.length>0 && log[$-1]=='W')
330 log.length--; 339 log.length--;
331 return tuple(s, log); 340 return tuple(s, log);
332 } 341 }
333 342
334 void make_plan(in Game g) { 343 void make_plan(in Game g) {
335 plan_broken = false; 344 plan_broken = false;
336 Tuple!(Solver,string) x = run_sub_solver(g); | 345 Tuple!(SubSolver,string) x = run_sub_solver(g);
337 plan = x[1]; 346 plan = x[1];
338 if(x[0].g.cleared) 347 if(x[0].g.cleared)
339 return; 348 return;
340 modify_plan(g, x[0].g.score); 349 modify_plan(g, x[0].g.score);
341 } 350 }
342 351
343 void modify_plan(in Game ini, long unmod) 352 void modify_plan(in Game ini, long unmod)
................................................................................................................................................................................
359 plan = cand[0]; 368 plan = cand[0];
360 } 369 }
361 370
362 Tuple!(string,long) try_plan(string c, in Game g) 371 Tuple!(string,long) try_plan(string c, in Game g)
363 { 372 {
364 Game gg = g.clone(); 373 Game gg = g.clone();
365 foreach(cc;c)gg.command(cc); 374 foreach(cc;c)gg.command(cc);
366 Tuple!(Solver, string) x = run_sub_solver(gg); | 375 Tuple!(SubSolver, string) x = run_sub_solver(gg);
367 return tuple(x[1], x[0].g.score); 376 return tuple(x[1], x[0].g.score);
368 } 377 }
369 378
370 char single_step() { 379 char single_step() {
371 if(plan_broken) 380 if(plan_broken)
372 make_plan(g); 381 make_plan(g);
373 if(plan.empty) 382 if(plan.empty)
................................................................................................................................................................................
385 plan_broken = true; 394 plan_broken = true;
386 } 395 }
387 else 396 else
388 plan = plan[1..$]; 397 plan = plan[1..$];
389 } 398 }
390 } 399 }
391 400
> 401 class MasterSolver : Solver
> 402 {
> 403 this(in Game g)
> 404 {
> 405 int SIZE = g.map.H * g.map.W;
> 406 if( SIZE <= 32*32 )
> 407 sub = new Solver_2!(Solver_1)(g);
> 408 else if( SIZE <= 100*100 )
> 409 sub = new Solver_1(g);
> 410 else
> 411 sub = new Solver_1(g);
> 412 }
> 413
> 414 private Solver sub;
> 415 char single_step() { return sub.single_step(); }
> 416 void force(char c) { sub.force(c); }
> 417 }
> 418
> 419 alias MasterSolver MainSolver;
392 //alias Solver_2!(Solver_1) MainSolver; 420 //alias Solver_2!(Solver_1) MainSolver;
393 //alias Solver_1 MainSolver; 421 //alias Solver_1 MainSolver;
394 alias Solver_0 MainSolver; | 422 //alias Solver_0 MainSolver;