Python 迷宫算法

步骤

1、创建迷宫

定义【0】为【墙】,【1】为【路】,先创建外墙,再创建内墙

# outer wall
maze=[[0,0,0,0,0,0],
      [0,1,1,1,1,0],
      [0,1,1,1,1,0],
      [0,1,1,1,1,0],
      [0,1,1,1,1,0],
      [0,0,0,0,0,0]]
# inner wall
maze[2][1]=maze[1][3]=maze[2][3]=maze[3][3]=0

这里写图片描述

2、寻路

  • 列表path记录路线
  • 列表footprint记录已经走过的路(以免重复)
  • steps表示上下左右4个可行方向
  • 起点:x=1 y=1
# the way out of maze
path=[(1,1)]
# never again
footprint=[]
# right down left up
steps=((0,1),(1,0),(0,-1),(-1,0))
# entrance
x=y=1
  • 终点:x=4 y=4
if 下一步(没有墙 & 没走过):
记录下一步 & 进入下一步
else:
返回上一步
  • path[-1]表示当前位置
while x!=4 or y!=4:
    # horizontal vertical
    for h,v in steps:
        if maze[x+h][y+v]==' ' and (x+h,y+v) not in footprint:
            path.append((x+h,y+v))
            footprint.append((x+h,y+v))
            break
    else:
        path.pop()
    # location
    x,y=path[-1]

3、绘制迷宫和路由

import random
# show the maze or the path
def show_maze(maze):
    for i in maze:
        for j in i:
            if j==0:
                print('\033[36m',j,sep='',end=' \033[0m')
            elif j=='+':
                print('\033[31m',j,sep='',end=' \033[0m')
            elif j=='O':
                print('\033[33m',j,sep='',end=' \033[0m')
            else:
                print(j,end=' ')
        print()
# build a maze which the size of maze is [n]
def build_maze(n):
    maze=[]
    # outer wall
    for i in range(n+2):
        if i==0:
            maze.append(['O']+[0]*(n+1))
        elif i==n+1:
            maze.append([0]*(n+1)+['O'])
        else:
            maze.append([0]+[' ']*n+[0])
    # random inner wall
    for i in range(1,n+1):
        if i==1:
            for j in range(n//4):
                maze[i][random.randint(2,n-1)]=0
        elif i==n:
            for j in range(n//4):
                maze[i][random.randint(1,n-2)]=0
        else:
            for j in range(n//4):
                maze[i][random.randint(1,n-1)]=0
    show_maze(maze)
    return maze
# find the exit of the maze
def route():
    maze=build_maze(9)
    # the way out of maze
    path=[(1,1)]
    # never again
    footprint=[]
    # right down left up
    steps=((0,1),(1,0),(0,-1),(-1,0))
    # entrance
    x=y=1
    while x!=9 or y!=9:
        # horizontal vertical
        for h,v in steps:
            if maze[x+h][y+v]==' ' and (x+h,y+v) not in footprint:
                path.append((x+h,y+v))
                footprint.append((x+h,y+v))
                break
        else:
            path.pop()
        # location
        x,y=path[-1]
    # show the maze and the path
    for x,y in path:
        maze[x][y]='+'
    show_maze(maze)
# play
route()

在这里插入图片描述

完整版

random迷宫,3种路由

# rectangle maze
import random,math,copy
# show the maze or the path
def show_maze(maze):
    for i in maze:
        for j in i:
            if j=='0':  # wall
                print('\033[36m',j,sep='',end='\033[0m')
            elif j=='O':  # [ entrance & exit ]& path
                print('\033[33m',j,sep='',end='\033[0m')
            elif j=='X':  # footprint
                print('\033[31m',j,sep='',end='\033[0m')
            else:
                print(j,end='')
        print()
# build a maze which the size of maze is [ n * 10n ]
def build_maze(n):
    maze = []
    # wall
    w='0'
    # entrance & exit
    e='O'
    # outer wall
    for i in range(n+2):
        if i==0:
            maze.append([e]+[w]*(n*10+1))
        elif i==n+1:
            maze.append([w]*(n*10+1)+[e])
        else:
            maze.append([w]+[' ']*n*10+[w])
    # random inner wall
    for i in range(1,n+1):
        atan=math.atan(n)
        balance=math.floor(atan**(atan**(atan+0.5)+0.5))*n
        if i==1:
            for j in range(balance):
                maze[i][random.randint(2,n*10-1)]=w
        elif i==n:
            for j in range(balance):
                maze[i][random.randint(1,n*10-2)]=w
        else:
            for j in range(balance):
                maze[i][random.randint(1,n*10-1)]=w
    show_maze(maze)
    return maze
# route optimization
def optimize(path):
    # anterior step, next step, posterior step
    anterior=0
    while anterior<len(path):
        x,y=path[anterior]
        next_step=[(x,y-1),(x-1,y),(x,y+1),(x+1,y)]
        for posterior in range(len(path)-1,anterior+1,-1):
            if path[posterior] in next_step:
                del path[anterior+1:posterior]
                break
        anterior+=1
# find the exit of the maze
def route(maze,n,option=0):
    if option==0:
        # right down up left
        steps=((0,1),(1,0),(-1,0),(0,-1))
    elif option==1:
        # right up down left
        steps=((0,1),(-1,0),(1,0),(0,-1))
    else:
        # left up down right
        steps=((0,-1),(-1,0),(1,0),(0,1))
    # the way out of maze
    path=[(1,1)]
    # never again
    footprint=[]
    # entrance
    x=y=1
    while x!=n or y!=n*10:
        # horizontal vertical
        for h,v in steps:
            if maze[x+h][y+v]==' ' and (x+h,y+v) not in footprint:
                path.append((x+h,y+v))
                footprint.append((x+h,y+v))
                break
        else:
            if path:
                path.pop()
            else:
                # There is no escape. show the maze and footprint
                for x,y in footprint:
                    maze[x][y]='X'
                show_maze(maze)
                break
        # location
        if path:
            x,y=path[-1]
    else:
        # show the maze, footprint and path
        for x,y in footprint:
            maze[x][y]='X'
        # optimize the path of maze
        optimize(path)
        for x,y in path:
            maze[x][y]='O'
        show_maze(maze)
# play
while True:
    n=input('the size of maze:').strip()
    if n.isdigit() and n!='0':
        n=int(n)
    else:
        n=19
    maze0=build_maze(n)
    maze1=copy.deepcopy(maze0)
    maze2=copy.deepcopy(maze0)
    input('Press any key to continue.')
    route(maze0,n)
    input('Press any key to continue.')
    route(maze1,n,1)
    input('Press any key to continue.')
    route(maze2,n,2)

在这里插入图片描述

  • 13
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
a*算法是一种启发式搜索算法,用于解决迷宫寻路问题。它通过估计每个节点到目标节点的距离来选择下一个节点,从而尽可能地减少搜索的次数。在Python中,可以使用以下步骤实现a*算法: 1. 定义迷宫地图和起点、终点坐标。 2. 定义一个open列表和一个closed列表,分别用于存储待搜索和已搜索的节点。 3. 将起点加入open列表,并设置其f值为。 4. 重复以下步骤直到找到终点或open列表为空: a. 从open列表中选取f值最小的节点作为当前节点。 b. 如果当前节点是终点,则返回路径。 c. 将当前节点从open列表中移除,并加入closed列表。 d. 遍历当前节点的相邻节点,如果相邻节点不在closed列表中,则计算其f值并加入open列表。 5. 如果open列表为空,则表示无法到达终点。 具体实现可以参考以下代码: ```python import heapq def a_star(maze, start, end): # 定义节点类 class Node: def __init__(self, x, y, g=, h=): self.x = x self.y = y self.g = g # 起点到当前节点的距离 self.h = h # 当前节点到终点的估计距离 self.f = g + h # f = g + h def __lt__(self, other): return self.f < other.f # 定义估价函数 def heuristic(node): return abs(node.x - end[]) + abs(node.y - end[1]) # 初始化起点和终点节点 start_node = Node(start[], start[1]) end_node = Node(end[], end[1]) # 初始化open列表和closed列表 open_list = [] closed_list = set() # 将起点加入open列表 heapq.heappush(open_list, start_node) # 开始搜索 while open_list: # 选取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: path.append((current_node.x, current_node.y)) current_node = current_node.parent return path[::-1] # 将当前节点加入closed列表 closed_list.add((current_node.x, current_node.y)) # 遍历当前节点的相邻节点 for dx, dy in [(, 1), (, -1), (1, ), (-1, )]: x, y = current_node.x + dx, current_node.y + dy if x < or x >= len(maze) or y < or y >= len(maze[]) or maze[x][y] == 1: continue if (x, y) in closed_list: continue # 计算相邻节点的f值 g = current_node.g + 1 h = heuristic(Node(x, y)) neighbor_node = Node(x, y, g, h) neighbor_node.parent = current_node # 如果相邻节点不在open列表中,则加入open列表 if neighbor_node not in open_list: heapq.heappush(open_list, neighbor_node) # 如果open列表为空,则表示无法到达终点 return None ``` 其中,maze是一个二维数组,表示迷宫地图;start和end是起点和终点的坐标。迷宫地图中,表示可以通过的路径,1表示障碍物。返回的路径是一个坐标列表,从起点到终点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小基基o_O

您的鼓励是我创作的巨大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值