diff options
author | Livio Recchia <recchialivio@libero.it> | 2020-02-10 23:06:34 +0100 |
---|---|---|
committer | Livio Recchia <recchialivio@libero.it> | 2020-02-10 23:06:34 +0100 |
commit | 9a13903a2f7d3a65fdf15a65fb59cccd622e2066 (patch) | |
tree | 9403b7dff39eb5e5d7fa0f79efb69b496add4c4b /gui/pathfind.py | |
parent | 11cc316b74d5f3f283413a33e7693b314741aa4a (diff) | |
download | manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.gz manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.bz2 manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.xz manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.zip |
Initial commit
Diffstat (limited to 'gui/pathfind.py')
-rw-r--r-- | gui/pathfind.py | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/gui/pathfind.py b/gui/pathfind.py new file mode 100644 index 0000000..2c870e1 --- /dev/null +++ b/gui/pathfind.py @@ -0,0 +1,91 @@ +import collections + + +class Queue: + def __init__(self): + self.elements = collections.deque() + + def empty(self): + return len(self.elements) == 0 + + def put(self, x): + self.elements.append(x) + + def get(self): + return self.elements.popleft() + + +class Graph: + def __init__(self, collisions): + self.collisions = collisions + self.width = len(collisions[0]) + self.height = len(collisions) + + def walkable(self, coor): + x, y = coor + if x < 0 or x > self.width - 1: + return False + if y < 0 or y > self.height - 1: + return False + if self.collisions[self.height - y - 1][x] > 0: + return False + return True + + def neighbors(self, coor): + n = [] + x, y = coor + + for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)): + nx = x + dx + ny = y + dy + if self.walkable((nx, ny)): + n.append((nx, ny)) + + for dx, dy in ((-1, -1), (-1, 1), (1, -1), (1, 1)): + nx = x + dx + ny = y + dy + if (self.walkable((nx, ny)) and + self.walkable((nx, y)) and + self.walkable((x, ny))): + n.append((nx, ny)) + + return n + + +def breadth_first_search(collisions, start, goal): + graph = Graph(collisions) + frontier = Queue() + frontier.put(start) + came_from = {} + came_from[start] = None + + while not frontier.empty(): + current = frontier.get() + + if current == goal: + break + + for next in graph.neighbors(current): + if next not in came_from: + frontier.put(next) + came_from[next] = current + + current = goal + path = [current] + while current != start: + current = came_from[current] + path.append(current) + path.reverse() + + # simplify path + spath = path[:1] + for i in range(1, len(path) - 1): + px, py = path[i - 1] + cx, cy = path[i] + nx, ny = path[i + 1] + if nx - cx == cx - px and ny - cy == cy - py: + continue + spath.append(path[i]) + spath.append(path[-1]) + + return spath |