pathfinding.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. from collections import deque
  2. from functools import lru_cache
  3. class PathFinding:
  4. def __init__(self, game):
  5. self.game = game
  6. self.map = game.map.mini_map
  7. self.ways = [-1, 0], [0, -1], [1, 0], [0, 1], [-1, -1], [1, -1], [1, 1], [-1, 1]
  8. self.graph = {}
  9. self.get_graph()
  10. @lru_cache
  11. def get_path(self, start, goal):
  12. self.visited = self.bfs(start, goal, self.graph)
  13. path = [goal]
  14. step = self.visited.get(goal, start)
  15. while step and step != start:
  16. path.append(step)
  17. step = self.visited[step]
  18. return path[-1]
  19. def bfs(self, start, goal, graph):
  20. queue = deque([start])
  21. visited = {start: None}
  22. while queue:
  23. cur_node = queue.popleft()
  24. if cur_node == goal:
  25. break
  26. next_nodes = graph[cur_node]
  27. for next_node in next_nodes:
  28. if next_node not in visited and next_node not in self.game.object_handler.npc_positions:
  29. queue.append(next_node)
  30. visited[next_node] = cur_node
  31. return visited
  32. def get_next_nodes(self, x, y):
  33. return [(x + dx, y + dy) for dx, dy in self.ways if (x + dx, y + dy) not in self.game.map.world_map]
  34. def get_graph(self):
  35. for y, row in enumerate(self.map):
  36. for x, col in enumerate(row):
  37. if not col:
  38. self.graph[(x, y)] = self.graph.get((x, y), []) + self.get_next_nodes(x, y)