@@ -336,23 +336,28 @@ { current_game = g.clone(); plan = ""; plan_state = Tentative; - replan_limit = PredictFuture; - if(g.map.W*g.map.H <= 400) + if(g.map.W*g.map.H <= 400) { RandomChoicePattern = ["UU","UD","UL","UR", "DU","DD","DL","DR", "LU","LD","LL","LR", "RU","RD","RL","RR","UUU","UUUU","UUUUU"]; - else if(g.map.W*g.map.H <= 4096) + PredictFuture = 20; + clear_improvement = 3; + } + else if(g.map.W*g.map.H <= 4096) { RandomChoicePattern = ["UUU","U","D","L","R","UD","DU","LR","RL"]; - else + PredictFuture = 10; + clear_improvement = 0; + } + else { RandomChoicePattern = ["U","D","L","R"]; - - if(g.map.W*g.map.H <= 400) - PredictFuture = 20; - else PredictFuture = 10; + clear_improvement = 0; + } + + replan_limit = PredictFuture; } char single_step() { @@ -408,10 +413,18 @@ if(c == 'A') plan_state = Tentative_Stuck; else { plan ~= c; - plan_state = (sub_solver.g.dead ? Tentative_Stuck : - sub_solver.g.cleared ? Fixed : Tentative); + if(sub_solver.g.cleared) { + if(clear_improvement-->0) { + plan_state = Tentative_Stuck; + replan_limit = min(plan.length-plan.length/(clear_improvement+1), PredictFuture); + } else { + plan_state = Fixed; + } + } else { + plan_state = (sub_solver.g.dead ? Tentative_Stuck : Tentative); + } } } void replan() @@ -422,12 +435,15 @@ Tuple!(SubSolver, string, int) cand = tuple(sub_solver, plan, Tentative_Stuck); int insertion_point = plan.length; writeln(cand, " ", cand[0].g.map.collected_lambda); bool tiebreak_by_turn = false; + int consider_length = min(ReplanLength, g.map.W*g.map.H); + if(cand[0].g.cleared) consider_length = min(consider_length, cand[1].length); + for(int i=0; i0) { sub_solver = cand[0]; plan = cand[1]; plan_state = Tentative_Stuck; - replan_limit = (plan.length - insertion_point); + replan_limit = min(plan.length - insertion_point, PredictFuture); lambda_getter = current_game.map.collected_lambda < cand[0].g.map.collected_lambda; } else { sub_solver = cand[0]; plan = cand[1]; plan_state = (plan.length < PredictFuture ? Fixed : cand[2]); - replan_limit = tiebreak_by_turn ? min(PredictFuture, plan.length/2) : PredictFuture; + replan_limit = tiebreak_by_turn ? min(PredictFuture, (plan.length+1)/2) : PredictFuture; lambda_getter = current_game.map.collected_lambda < cand[0].g.map.collected_lambda; } } - Tuple!(SubSolver, string, int) try_plan(in Game g, string prefix) + Tuple!(SubSolver, string, int) try_plan(in Game g, string prefix, int consider_length) { + if(consider_length<=0) consider_length = 2; + SubSolver s = new SubSolver(g); foreach(char c; prefix) s.force(c); string log; int state = Tentative; - while(!s.g.cleared && !s.g.dead && log.length<=ReplanLength && log.length<=g.map.W*g.map.H) { + while(!s.g.cleared && !s.g.dead && log.length<=consider_length) { char c = s.single_step(); if( c == 'A' ) { state = Tentative_Stuck; break;