| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import heapq
- grid.obstacles = [partner.pos]
-
- def is_passable(self, x, y):
- return self.at(x, y) in (FLOOR_CELL, "0", "1") and not (x, y) in self.obstacles
-
-
- class NoPathFound(Exception):
- pass
- class Node(tuple):
- def __new__(self, x, y, parent=None):
- n = tuple.__new__(self, (x, y))
- n.parent = parent
- n.cost = 0
- return n
- class NodesHeap():
- def __init__(self):
- self._lst = []
- def push(self, node, priority):
- heapq.heappush(self._lst, (priority, node))
- def pop(self):
- return heapq.heappop(self._lst)[1]
- class Pathfinder():
- @staticmethod
- def a_star(grid, origin, target):
- nodes = NodesHeap()
- origin = Node(*origin)
- nodes.push(origin, 0)
- while nodes:
- current = nodes.pop()
- if current == target:
- break
- for x, y in grid.neighbors(*current):
- node = Node(x, y, current)
- # get the moving cost to this node
- movingcost = grid.movingcost(*current, *node)
- if movingcost < 0:
- continue
- # cost of the node is the accumulated cost from origin
- node.cost = current.cost + movingcost
- # priority of the node is the sum of its cost and distance to target
- # (the lower the better)
- priority = node.cost + grid.geometry.manhattan(*node, *target)
- # (?) would it be necessary to check if there is already a
- # node with same coordinates and a lower priority?
- # append to the checked nodes list
- nodes.push(node, priority)
- else:
- # all the reachable nodes hve been checked, no way found to the target
- raise NoPathFound("no path were found to the targetted location {}".format(target))
- # build the result by going back up from target to origin
- result = [target]
- while current != origin:
- result.append(tuple(current))
- current = current.parent
- result.append(origin)
- result.reverse()
- return result
|