给出能实现上述功能的完整代码并包含注释
时间: 2024-03-21 17:43:13 浏览: 174
完整代码
5星 · 资源好评率100%
好的,下面是一个基于 Python 和 Pygame 实现的 A* 算法路径规划程序,代码中包含了详细的注释:
```python
import pygame
import math
import heapq
# 定义常量
WIDTH = 800 # 屏幕宽度
HEIGHT = 600 # 屏幕高度
CELL_SIZE = 20 # 格子大小
WALL_COLOR = (0, 0, 0) # 墙的颜色
START_COLOR = (0, 255, 0) # 起点颜色
END_COLOR = (255, 0, 0) # 终点颜色
OPEN_COLOR = (0, 0, 255) # 开放列表颜色
CLOSED_COLOR = (128, 128, 128) # 关闭列表颜色
PATH_COLOR = (255, 255, 0) # 路径颜色
# 定义节点类型
class Node:
def __init__(self, x, y):
self.x = x # 节点 x 坐标
self.y = y # 节点 y 坐标
self.parent = None # 父节点
self.g = 0 # 从起点到该节点的代价
self.h = 0 # 从该节点到终点的估价
self.f = 0 # f = g + h
def __lt__(self, other):
"""为了使用 heapq,需要定义小于运算符"""
return self.f < other.f
# 定义 A* 算法函数
def astar(start, end, walls):
"""A* 算法函数,返回起点到终点的最短路径"""
# 初始化起点和终点
start_node = Node(start[0], start[1])
end_node = Node(end[0], end[1])
# 初始化开放列表和关闭列表
open_list = []
closed_list = []
# 将起点加入开放列表
heapq.heappush(open_list, start_node)
while len(open_list) > 0:
# 取出开放列表中 f 值最小的节点
current_node = heapq.heappop(open_list)
# 如果当前节点是终点,则返回路径
if current_node.x == end_node.x and current_node.y == end_node.y:
path = []
while current_node is not None:
path.append((current_node.x, current_node.y))
current_node = current_node.parent
return list(reversed(path))
# 将当前节点加入关闭列表
closed_list.append(current_node)
# 遍历当前节点的相邻节点
for dx, dy in ((0, -1), (0, 1), (-1, 0), (1, 0)):
x, y = current_node.x + dx, current_node.y + dy
# 如果相邻节点不在地图范围内或是障碍,则忽略
if x < 0 or x >= WIDTH // CELL_SIZE or y < 0 or y >= HEIGHT // CELL_SIZE or (x, y) in walls:
continue
# 计算相邻节点的 g 值
g = current_node.g + math.sqrt(dx * dx + dy * dy)
# 如果相邻节点已经在关闭列表中,则忽略
if any(node.x == x and node.y == y for node in closed_list):
continue
# 如果相邻节点不在开放列表中,则加入开放列表
neighbor_node = Node(x, y)
neighbor_node.parent = current_node
neighbor_node.g = g
neighbor_node.h = math.sqrt((x - end_node.x) ** 2 + (y - end_node.y) ** 2)
neighbor_node.f = neighbor_node.g + neighbor_node.h
heapq.heappush(open_list, neighbor_node)
# 如果无法到达终点,则返回空路径
return []
# 初始化 Pygame
pygame.init()
# 创建屏幕
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("A* Algorithm Path Planning")
# 初始化地图
walls = set()
start = (0, 0)
end = (WIDTH // CELL_SIZE - 1, HEIGHT // CELL_SIZE - 1)
# 主循环
running = True
while running:
# 处理事件
for event in pygame.event.get():
# 如果点击了关闭按钮,则退出程序
if event.type == pygame.QUIT:
running = False
# 如果点击了鼠标左键,则将点击位置的格子设置为墙
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
x, y = event.pos
walls.add((x // CELL_SIZE, y // CELL_SIZE))
# 如果点击了鼠标右键,则将点击位置的格子设置为起点或终点
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:
x, y = event.pos
if not start:
start = (x // CELL_SIZE, y // CELL_SIZE)
elif not end:
end = (x // CELL_SIZE, y // CELL_SIZE)
else:
walls.discard((x // CELL_SIZE, y // CELL_SIZE))
# 清空屏幕
screen.fill((255, 255, 255))
# 绘制地图
for x in range(WIDTH // CELL_SIZE):
for y in range(HEIGHT // CELL_SIZE):
rect = pygame.Rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
if (x, y) in walls:
pygame.draw.rect(screen, WALL_COLOR, rect)
elif (x, y) == start:
pygame.draw.rect(screen, START_COLOR, rect)
elif (x, y) == end:
pygame.draw.rect(screen, END_COLOR, rect)
elif any(node.x == x and node.y == y for node in open_list):
pygame.draw.rect(screen, OPEN_COLOR, rect)
elif any(node.x == x and node.y == y for node in closed_list):
pygame.draw.rect(screen, CLOSED_COLOR, rect)
elif (x, y) in path:
pygame.draw.rect(screen, PATH_COLOR, rect)
# 进行路径规划
if start and end:
path = astar(start, end, walls)
# 更新屏幕
pygame.display.flip()
# 退出 Pygame
pygame.quit()
```
上述代码是一个简单的 A* 算法路径规划程序,使用 Pygame 实现了可视化界面,用户可以通过鼠标左键设置障碍,通过鼠标右键设置起点和终点,程序会自动进行路径规划,并在界面上显示路径。
阅读全文