Differences From Artifact [15905b6766caaf1d]:
- File
src/solver.d
- 2012-07-16 01:23:58 - part of checkin [ff8066db42] on branch trunk - Replanning. (user: kinaba) [annotate]
To Artifact [3413d0e80fd69f87]:
- File
src/solver.d
- 2012-07-16 03:53:00 - part of checkin [971863e35a] on branch trunk - No-cloning death-move(). With several fixes to the simulator. (user: kinaba) [annotate]
339 plan_state = Tentative; 339 plan_state = Tentative;
340 if(g.map.W*g.map.H <= 400) { 340 if(g.map.W*g.map.H <= 400) {
341 RandomChoicePattern = ["UU","UD","UL","UR", 341 RandomChoicePattern = ["UU","UD","UL","UR",
342 "DU","DD","DL","DR", 342 "DU","DD","DL","DR",
343 "LU","LD","LL","LR", 343 "LU","LD","LL","LR",
344 "RU","RD","RL","RR","UUU","UUUU", 344 "RU","RD","RL","RR","UUU","UUUU",
345 PredictFuture = 20; 345 PredictFuture = 20;
346 clear_improvement = 3; | 346 clear_improvement = 1;
347 } 347 }
348 else if(g.map.W*g.map.H <= 4096) { 348 else if(g.map.W*g.map.H <= 4096) {
349 RandomChoicePattern = ["UUU","U","D","L","R","UD","DU"," 349 RandomChoicePattern = ["UUU","U","D","L","R","UD","DU","
350 PredictFuture = 10; 350 PredictFuture = 10;
351 clear_improvement = 0; 351 clear_improvement = 0;
352 } 352 }
353 else { 353 else {
................................................................................................................................................................................
371 // If the future is bad, correct. 371 // If the future is bad, correct.
372 if( plan_state==Tentative_Stuck && plan.length<replan_limit && ! 372 if( plan_state==Tentative_Stuck && plan.length<replan_limit && !
373 replan(); 373 replan();
374 374
375 // Follow the predicted plan. 375 // Follow the predicted plan.
376 if( plan.empty ) 376 if( plan.empty )
377 return 'A'; 377 return 'A';
378 stderr.writeln(plan, " ", plan_state); <
379 char c = plan[0]; 378 char c = plan[0];
380 plan = plan[1..$]; 379 plan = plan[1..$];
381 int b_lambda = current_game.map.collected_lambda; 380 int b_lambda = current_game.map.collected_lambda;
382 current_game.command(c); 381 current_game.command(c);
383 int a_lambda = current_game.map.collected_lambda; 382 int a_lambda = current_game.map.collected_lambda;
384 if(b_lambda < a_lambda) lambda_getter = false; 383 if(b_lambda < a_lambda) lambda_getter = false;
385 return c; 384 return c;
................................................................................................................................................................................
425 plan_state = (sub_solver.g.dead ? Tentative_Stuc 424 plan_state = (sub_solver.g.dead ? Tentative_Stuc
426 } 425 }
427 } 426 }
428 } 427 }
429 428
430 void replan() 429 void replan()
431 { 430 {
432 stderr.writeln("replan!"); <
433 // Try to replace every step of the plan by another move. 431 // Try to replace every step of the plan by another move.
434 Game g = current_game.clone(); 432 Game g = current_game.clone();
435 Tuple!(SubSolver, string, int) cand = tuple(sub_solver, plan, Te 433 Tuple!(SubSolver, string, int) cand = tuple(sub_solver, plan, Te
436 int insertion_point = plan.length; 434 int insertion_point = plan.length;
437 writeln(cand, " ", cand[0].g.map.collected_lambda); <
438 bool tiebreak_by_turn = false; 435 bool tiebreak_by_turn = false;
439 int consider_length = min(ReplanLength, g.map.W*g.map.H); 436 int consider_length = min(ReplanLength, g.map.W*g.map.H);
440 if(cand[0].g.cleared) consider_length = min(consider_length, can 437 if(cand[0].g.cleared) consider_length = min(consider_length, can
441 438
442 for(int i=0; i<plan.length; ++i) { 439 for(int i=0; i<plan.length; ++i) {
443 foreach(string prefix; RandomChoicePattern) 440 foreach(string prefix; RandomChoicePattern)
444 if(prefix[0] != plan[i]) { 441 if(prefix[0] != plan[i]) {
................................................................................................................................................................................
463 } 460 }
464 } 461 }
465 if(better) { 462 if(better) {
466 cand = r; 463 cand = r;
467 tiebreak_by_turn = true; 464 tiebreak_by_turn = true;
468 insertion_point = i+prefix.lengt 465 insertion_point = i+prefix.lengt
469 if(r[0].g.cleared) consider_leng 466 if(r[0].g.cleared) consider_leng
470 writeln(cand, " ", cand[0].g.map.collected_lambda); <
471 } 467 }
472 } 468 }
473 g.command(plan[i]); 469 g.command(plan[i]);
474 } 470 }
475 471
476 if(cand[2]==Fixed && insertion_point!=plan.length && clear_impro 472 if(cand[2]==Fixed && insertion_point!=plan.length && clear_impro
477 sub_solver = cand[0]; 473 sub_solver = cand[0];
................................................................................................................................................................................
507 } 503 }
508 if(s.g.cleared) state = Fixed; 504 if(s.g.cleared) state = Fixed;
509 else if(s.g.dead) state = Tentative_Stuck; 505 else if(s.g.dead) state = Tentative_Stuck;
510 return tuple(s, log, state); 506 return tuple(s, log, state);
511 } 507 }
512 } 508 }
513 509
> 510 class Queue(T)
> 511 {
> 512 alias Tuple!(T,int) t;
> 513
> 514 t[] cur, next;
> 515
> 516 void push(T v, int p) { (cur.empty ? cur : next) ~= tuple(v,p); }
> 517 bool empty() { return cur.empty; }
> 518 t pop() {
> 519 t v = cur[0]; cur = cur[1..$];
> 520 if(cur.empty) { cur = next; next = null; }
> 521 return v;
> 522 }
> 523 }
> 524
> 525 class Solver_3 : Solver
> 526 {
> 527 Game g;
> 528 this(in Game g)
> 529 {
> 530 this.g = g.clone();
> 531 }
> 532
> 533 char single_step()
> 534 {
> 535 char c = think(g);
> 536 if(c != 'A')
> 537 g.command(c);
> 538 return c;
> 539 }
> 540
> 541 void force(char c)
> 542 {
> 543 stderr.writeln(death_move(g));
> 544 if(c != 'A')
> 545 g.command(c);
> 546 }
> 547
> 548 bool is_spacy(char c) {
> 549 return c==' ' || c=='.' || c=='R' || c=='!' || c=='\\' || c=='O'
> 550 }
> 551 bool is_rocky(char c) {
> 552 return c=='*' || c=='@';
> 553 }
> 554 bool is_true_space(char c) {
> 555 return c==' ';
> 556 }
> 557 bool is_trampoline_source(char c) {
> 558 return 'A'<=c && c<='I';
> 559 }
> 560 bool is_rocklambda(char c) {
> 561 return is_rocky(c) || c=='\\';
> 562 }
> 563
> 564 string death_move(in Game g)
> 565 {
> 566 // TODO: S
> 567 string death;
> 568 int y = g.map.robot.y;
> 569 int x = g.map.robot.x;
> 570 int[5] dy_=[-1,+1,0,0,0];
> 571 int[5] dx_=[0,0,-1,+1,0];
> 572 char[] ds=['D','U','L','R','W'];
> 573 for(int i=0; i<5; ++i)
> 574 {
> 575 bool after_move_death(int y, int x, char tr_tgt)
> 576 {
> 577 bool is_spacy_t(char c) {
> 578 if(is_spacy(c) || c==tr_tgt)
> 579 return true;
> 580 return ('A'<=c && c<='I' && g.tr.target_
> 581 }
> 582
> 583 // check water
> 584 if( g.hp==0 && y<=g.water_level )
> 585 return true;
> 586
> 587 // check falling rock.
> 588 int yy=y+1, xx=x;
> 589 if( is_spacy_t(g.map[yy, xx]) )
> 590 {
> 591 if( is_rocky(g.map[yy+1,xx]) )
> 592 return true;
> 593 if( is_spacy_t(g.map[yy+1,xx]) && is_roc
> 594 if( is_spacy_t(g.map[yy+1,xx+2])
> 595 return false;
> 596 return true;
> 597 }
> 598 if( is_spacy_t(g.map[yy+1,xx]) && is_roc
> 599 if(g.hige_until_rise == 1 && g.m
> 600 return false;
> 601 return true;
> 602 }
> 603 }
> 604 return false;
> 605 }
> 606
> 607 int dy=dy_[i], dx=dx_[i];
> 608 if( is_spacy(g.map[y+dy,x+dx])
> 609 || dy==0 && is_rocky(g.map[y,x+dx]) && is_true_space(g.
> 610 {
> 611 if( after_move_death(y+dy, x+dx, char.init) )
> 612 death ~= ds[i];
> 613 }
> 614 else if( is_trampoline_source(g.map[y+dy,x+dx]) )
> 615 {
> 616 Pos p = g.tr.target_pos(g.map[y+dy,x+dx]);
> 617 if( after_move_death(p.y, p.x, g.tr.target_of(g.
> 618 death ~= ds[i];
> 619 }
> 620 else
> 621 {
> 622 death ~= ds[i];
> 623 }
> 624 }
> 625 return death;
> 626 }
> 627
> 628 char think(in Game g)
> 629 {
> 630 string s = death_move(g);
> 631 stderr.writeln(s);
> 632
> 633 auto Q = new Queue!(Tuple!(Pos,Pos));
> 634 Q.push(tuple(g.map.robot.clone(), g.map.robot.clone()), 0);
> 635 Pos[][] V = new Pos[][](g.map.H+2, g.map.W+2);
> 636 while(!Q.empty) {
> 637 auto tup = Q.pop();
> 638 Pos p = tup[0][0];
> 639 Pos prev = tup[0][1];
> 640 int dist = tup[1];
> 641 if(V[p.y][p.x])
> 642 continue;
> 643 V[p.y][p.x] = prev;
> 644 if(g.map[p]=='\\' || g.map[p]=='O')
> 645 {
> 646 Pos goback(Pos p) {
> 647 return V[p.y][p.x];
> 648 }
> 649 for(;;) {
> 650 Pos q = goback(p);
> 651 if(q == g.map.robot)
> 652 if(q.y==p.y)
> 653 return q.x<p.x ? 'R' : '
> 654 else
> 655 return q.y<p.y ? 'U' : '
> 656 p=q;
> 657 }
> 658 }
> 659
> 660 int[4] dy=[-1,+1,0,0];
> 661 int[4] dx=[0,0,-1,+1];
> 662 char[] ds=['D','U','L','R'];
> 663 for(int i=0; i<4; ++i)
> 664 {
> 665 int y=p.y+dy[i], x=p.x+dx[i];
> 666 if((g.map[y,x]==' '||g.map[y,x]=='\\'||g.map[y,x
> 667 Q.push(tuple(new Pos(y,x),p), dist+1);
> 668 }
> 669 }
> 670 }
> 671 return 'A';
> 672 }
> 673 }
> 674
> 675 alias Solver_3 MainSolver;
514 alias Solver_2!(Solver_1) MainSolver; | 676 //alias Solver_2!(Solver_1) MainSolver;
515 //alias Solver_1 MainSolver; 677 //alias Solver_1 MainSolver;
516 //alias Solver_0 MainSolver; 678 //alias Solver_0 MainSolver;