Differences From 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]
To Artifact [4176698dd9ba368b]:
- File
src/solver.d
- 2012-07-15 22:56:00 - part of checkin [9a93aeb664] on branch trunk - Adoptive replanning. (user: kinaba) [annotate]
142 } 142 }
143 } 143 }
144 144
145 if(c == 'W') 145 if(c == 'W')
146 wait_count++; 146 wait_count++;
147 else 147 else
148 wait_count = 0; 148 wait_count = 0;
> 149 if(wait_count==2)
> 150 c = 'A';
149 if(choke_count >= g.map.H) 151 if(choke_count >= g.map.H)
150 c = 'A'; 152 c = 'A';
151 153
152 bool[char] choice; 154 bool[char] choice;
153 foreach(t; cand) 155 foreach(t; cand)
154 choice[t[0]] = true; 156 choice[t[0]] = true;
155 log ~= tuple(ro.clone(), cast(int)choice.length); 157 log ~= tuple(ro.clone(), cast(int)choice.length);
................................................................................................................................................................................
311 } 313 }
312 return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC(); 314 return (danger_ok ? [] : tryA()) ~ tryB() ~ tryC();
313 } 315 }
314 } 316 }
315 317
316 class Solver_2(SubSolver) : Solver 318 class Solver_2(SubSolver) : Solver
317 { 319 {
> 320 static const PredictFuture = 10;
> 321
> 322 Game current_game;
> 323 SubSolver sub_solver;
> 324
> 325 enum {Tentative, Tentative_Stuck, Fixed};
318 string plan; 326 string plan;
319 bool plan_broken = true; | 327 int plan_state;
320 328
321 Game g; <
322 this(in Game g) 329 this(in Game g)
323 { 330 {
324 this.g = g.clone(); | 331 current_game = g.clone();
> 332 plan = "";
> 333 plan_state = Tentative;
> 334 }
> 335
> 336 char single_step()
> 337 {
> 338 if(current_game.dead || current_game.cleared)
> 339 return 'A';
> 340
> 341 // Make enough prediction.
> 342 while( plan_state==Tentative && plan.length<PredictFuture )
> 343 single_step_predict();
> 344
> 345 // If the future is bad, correct.
> 346 if( plan_state==Tentative_Stuck && plan.length<PredictFuture )
325 make_plan(g); | 347 replan();
> 348
> 349 // Follow the predicted plan.
> 350 if( plan.empty )
> 351 return 'A';
> 352 writeln(plan, " ", plan_state);
> 353 char c = plan[0];
> 354 plan = plan[1..$];
> 355 current_game.command(c);
> 356 return c;
326 } 357 }
327 358
328 Tuple!(SubSolver,string) run_sub_solver(in Game g) | 359 void force(char c)
329 { 360 {
330 string log; | 361 if(plan.length>0 && plan[0]==c)
331 auto s = new SubSolver(g); <
> 362 {
332 while(!g.cleared && !g.dead && plan.length<=g.map.H*g.map.W) { | 363 // If matching the plan, just go forward.
333 char c = s.single_step(); | 364 plan = plan[1..$];
334 if( c == 'A' ) <
> 365 }
335 break; | 366 else
336 log ~= c; <
> 367 {
> 368 // Discard the plan, otherwise.
> 369 plan_state = Tentative;
> 370 plan = "";
> 371 sub_solver = null;
337 } 372 }
338 while(log.length>0 && log[$-1]=='W') | 373 current_game.command(c);
339 log.length--; <
340 return tuple(s, log); <
341 } 374 }
342 375
343 void make_plan(in Game g) { | 376 void single_step_predict()
344 plan_broken = false; <
> 377 {
345 Tuple!(SubSolver,string) x = run_sub_solver(g); | 378 if(sub_solver is null) {
> 379 sub_solver = new SubSolver(current_game);
> 380 plan = "";
> 381 }
> 382
> 383 char c = sub_solver.single_step();
> 384 if(c == 'A')
> 385 plan_state = Tentative_Stuck;
> 386 else {
346 plan = x[1]; | 387 plan ~= c;
347 if(x[0].g.cleared) <
348 return; <
349 modify_plan(g, x[0].g.score); <
> 388 plan_state = (sub_solver.g.dead ? Tentative_Stuck :
> 389 sub_solver.g.cleared ? Fixed : Tentative);
> 390 }
350 } 391 }
351 392
352 void modify_plan(in Game ini, long unmod) | 393 void replan()
353 { 394 {
354 int bp = max(0, (cast(int)plan.length)-10); | 395 writeln("replan!");
> 396 // Try to replace every step of the plan by another move.
355 Game g = ini.clone(); | 397 Game g = current_game.clone();
356 for(int i=0; i<bp; ++i) g.command(plan[i]); <
357 <
> 398 Tuple!(long, SubSolver, string, int) cand =
358 Tuple!(string,long) cand = tuple(plan, unmod); | 399 tuple(sub_solver.g.score, sub_solver, plan, Tentative_St
359 for(int i=bp; i<plan.length; ++i) { | 400 for(int i=0; i<plan.length; ++i) {
360 foreach(string c; ["U","D","L","R","UD","DU","LR","RL"]) | 401 foreach(string prefix; ["U","D","L","R","UD","DU","LR","
361 if(c[0] != plan[i]) { | 402 if(prefix[0] != plan[i]) {
362 Tuple!(string,long) zz = try_plan(c, g); | 403 Tuple!(long, SubSolver, string, int) r =
363 if(cand[1]<zz[1]) | 404 if(cand[0] < r[0]) {
364 cand = tuple(plan[0..i]~c~zz[0], | 405 r[2] = plan[0..i] ~ prefix ~ r[2
> 406 cand = r;
> 407 }
365 } 408 }
366 g.command(plan[i]); 409 g.command(plan[i]);
367 } 410 }
368 plan = cand[0]; <
369 } <
370 411
371 Tuple!(string,long) try_plan(string c, in Game g) | 412 sub_solver = cand[1];
372 { <
> 413 plan = cand[2];
373 Game gg = g.clone(); | 414 plan_state = (plan.length < PredictFuture ? Fixed : cand[3]);
374 foreach(cc;c)gg.command(cc); <
375 Tuple!(SubSolver, string) x = run_sub_solver(gg); <
376 return tuple(x[1], x[0].g.score); <
377 } 415 }
378 416
379 char single_step() { | 417 Tuple!(long, SubSolver, string, int) try_plan(in Game g, string prefix)
380 if(plan_broken) <
> 418 {
381 make_plan(g); | 419 SubSolver s = new SubSolver(g);
382 if(plan.empty) | 420 foreach(char c; prefix)
383 return 'A'; | 421 s.force(c);
> 422 string log;
> 423 int state = Tentative;
> 424 while(!s.g.cleared && !s.g.dead && log.length<=g.map.H*g.map.W)
384 char c = plan[0]; | 425 char c = s.single_step();
385 plan = plan[1..$]; <
386 g.command(c); <
387 return c; <
> 426 if( c == 'A' ) {
> 427 state = Tentative_Stuck;
> 428 break;
388 } | 429 }
389 <
390 void force(char c) { <
391 g.command(c); <
392 if(plan.length==0 || plan[0]!=c) { | 430 log ~= c;
393 plan = ""; <
394 plan_broken = true; <
395 } 431 }
396 else | 432 if(s.g.cleared) state = Fixed;
397 plan = plan[1..$]; | 433 else if(s.g.dead) state = Tentative_Stuck;
> 434 return tuple(s.g.score, s, log, state);
398 } 435 }
399 } 436 }
400 437
401 class MasterSolver : Solver 438 class MasterSolver : Solver
402 { 439 {
403 this(in Game g) 440 this(in Game g)
404 { 441 {
................................................................................................................................................................................
412 } 449 }
413 450
414 private Solver sub; 451 private Solver sub;
415 char single_step() { return sub.single_step(); } 452 char single_step() { return sub.single_step(); }
416 void force(char c) { sub.force(c); } 453 void force(char c) { sub.force(c); }
417 } 454 }
418 455
419 alias MasterSolver MainSolver; | 456 //alias MasterSolver MainSolver;
420 //alias Solver_2!(Solver_1) MainSolver; | 457 alias Solver_2!(Solver_1) MainSolver;
421 //alias Solver_1 MainSolver; 458 //alias Solver_1 MainSolver;
422 //alias Solver_0 MainSolver; 459 //alias Solver_0 MainSolver;