示例#1
0
文件: AscSokoban.py 项目: TAEB/roomba
 def invalidate(self):
     """
     A boulder has been moved so the traceback must be recalculated.
     """
     # calling this function means something has caused the old traceback to become invalid
     self.traceback = None
     # see where the boulders are
     boulder_locations = [loc for loc, c in self.level.items() if c == '0']
     # create solvers associated with boulder locations
     pq = []
     distance_solver_location_triples = []
     for boulder_location in boulder_locations:
         self.level[boulder_location] = '.'
         boulder_transition = BoulderTransition(self, self.level, self.floor_neighbors, self.location_to_back_front_pairs)
         boulder_heuristic = BoulderTransitionHeuristic(self, self.level, self.location_to_back_front_pairs)
         initial_state = (boulder_location, self.player_location)
         solver = AscDP.MeasureInformedTraceback([initial_state], boulder_transition, boulder_heuristic)
         solver.step()
         self.level[boulder_location] = '0'
         distance = solver.get_distance()
         if distance is not None:
             heappush(pq, (distance, solver, boulder_location))
     # Keep going until a solver has finished or until they have all failed to find a solution.
     best_path = None
     while pq:
         distance, solver, boulder_location = heappop(pq)
         solution = solver.get_solution()
         if solution:
             best_path = AscDP.traceback_to_path(*solution)
             break
         self.level[boulder_location] = '.'
         solver.step()
         self.level[boulder_location] = '0'
         distance = solver.get_distance()
         if distance is not None:
             heappush(pq, (distance, solver, boulder_location))
     # Set the path if one was found.
     if best_path:
         # Convert the path to boulder pushes.
         assert len(best_path) > 1
         self.traceback = []
         for (new_boulder, new_player), (old_boulder, old_player) in zip(best_path[0:-1], best_path[1:]):
             if new_boulder != old_boulder:
                 self.traceback.append((new_player, old_player))