问题描述
我正在尝试在我的算法上使用一个 yield 函数来实现一个寻路算法可视化工具,该函数在每次访问我的函数末尾的节点时产生访问节点的列表:
# Breadth First Search Algorithm
def bfs(graph,start,goal):
explored = []
# Queue for traversing the
# graph in the BFS
queue = [[start]]
# If the desired node is
# reached
if start == goal:
return
# Loop to traverse the graph
# with the help of the queue
while queue:
path = queue.pop(0)
node = path[-1]
y,x = node
# Codition to check if the
# current node is not visited
if node not in explored and nodes_rows[x][y].color is not BLACK:
neighbours = graph[node]
# Loop to iterate over the
# neighbours of the node
for neighbour in neighbours:
new_path = list(path)
new_path.append(neighbour)
queue.append(new_path)
# Condition to check if the
# neighbour node is the goal
if neighbour == goal:
new_path.remove(start)
new_path.remove(goal)
return new_path
explored.append(node)
yield explored
return None
nodes_rows[x][y].color is not BLACK
- 避免使用黑色的墙壁
if event.key == pygame.K_RETURN:
algorithm = bfs(neihgbours,(start[0]),(end[0]))
ticks = None
try:
while True:
if not ticks or pygame.time.get_ticks() - ticks >= 500:
ticks = pygame.time.get_ticks()
nodes = next(algorithm)
nodes_rows[nodes[-1][1]][nodes[-1][0]].color = LIGHT_BLUE
pygame.display.update()
except stopiteration:
pass
nodes_rows[nodes[-1][1]][nodes[-1][0]].color = LIGHT_BLUE
这个令人困惑的部分基本上是取列表nodes[-1][1]
中最后一个元素的行,然后是列表nodes[-1][0]
中最后一个元素的列,然后是{{ 1}} 矩阵它相应地更改节点颜色,列表由(行,列)元组组成,以便更好地说明。如果我打印 nodes_rows
以获得更好的表示,输出将如下所示:
nodes = next(algorithm)
我试图让算法每半秒在一个节点上为网格上的节点着色,如果我打印它,它确实适用于产量函数,它实际上每 0.5 个节点添加一个节点到访问节点列表,但是出于某种原因,当我尝试更新屏幕并为它们着色时,它只是一次等待所有刻度和颜色的总量,而不是更多的动画外观。如何更新显示,以便在算法函数结束时使用 yield 逐个节点而不是每个访问过的节点着色?
为了更好地理解这里是一次完成所有节点着色后网格的样子:
视频来表示过程中的算法:
解决方法
您的事件循环或主游戏循环中不应有 while
循环。改用标志来表示是否更新算法:
algorithm = None
update_timer = 0
clock = pygame.time.Clock()
while running:
dt = clock.tick()
for event in pygame.event.get():
# ... Other event handling
if event.key == pygame.K_RETURN:
algorithm = bfs(neihgbours,(start[0]),(end[0]))
update_timer = 500 # To make sure we update first time
update_timer += dt
if algorithm and update_timer > 500:
update_timer -= 500
try:
nodes = next(algorithm)
except StopIteration:
algorithm = None
else:
nodes_rows[nodes[-1][1]][nodes[-1][0]].color = LIGHT_BLUE
# The actual rendering should happen here.