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)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小基基o_O

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

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

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

打赏作者

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

抵扣说明:

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

余额充值