教你怎么用Python实现多路径迷宫


Posted in Python onApril 29, 2021

一、思路介绍

  • 在已有的单路径迷宫基础上打开一块合适的墙就可以构成2路径的迷宫。
  • 打开的墙不能和已有的路径过近。
  • 1。从开始和终点开始进行广度优先搜索,并为迷宫中的每个单元格记录单元格远离开始和终点的步数。
  • 2。通过将距离开头较近的所有单元格放入 start 集合,并将更接近目标的所有单元格放入end集合来将迷宫分成两个部分。
  • 3。 选择分开两个区域的任意一面墙拆开就可以形成2通路的迷宫。
  • 如想生成最短的通路可以选择相邻格子距离差值最大的那面墙拆开,一般情况下这两条路距离也比较远。

二、图示

教你怎么用Python实现多路径迷宫

三、分区域演示代码

#!/usr/bin/python3.7
# -*- coding: utf-8 -*-
import random
import pygame
#import depth_maze
import maze
#import aldous_broder_maze

pygame.init()  # 初始化pygame
size = width, height = 800, 600  # 设置窗口大小
screen = pygame.display.set_mode(size)  # 显示窗口
# 颜色
diamond_color_size = 8
COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_YELLOW, COLOR_BLACK, COLOR_GREY, COLOR_GOLDEN, COLOR_NO_DIAMOND = list(range(
    diamond_color_size))
COLOR = {
    COLOR_RED: (255, 0, 0),
    COLOR_BLUE: (0, 0, 255),
    COLOR_GREEN: (0, 255, 0),
    COLOR_YELLOW: (255, 255, 0),
    COLOR_BLACK: (0, 0, 0),
    COLOR_GREY: (250, 240, 230),
    COLOR_GOLDEN : (255,215,0),
    COLOR_NO_DIAMOND: (100, 100, 100),
}
# 格子大小
DIAMOND_LEN = 20
DIAMOND_SIZE = (DIAMOND_LEN, DIAMOND_LEN)
# 蓝格子
DIAMOND=pygame.surface.Surface(DIAMOND_SIZE).convert()
DIAMOND.fill(COLOR[COLOR_BLUE])
# 绿格子 
DIAMOND_GREEN=pygame.surface.Surface(DIAMOND_SIZE).convert()
DIAMOND_GREEN.fill(COLOR[COLOR_GREEN])
# 红格子 
DIAMOND_RED=pygame.surface.Surface(DIAMOND_SIZE).convert()
DIAMOND_RED.fill(COLOR[COLOR_RED])
# 黄格子 
DIAMOND_YELLOW=pygame.surface.Surface(DIAMOND_SIZE).convert()
DIAMOND_YELLOW.fill(COLOR[COLOR_YELLOW])
# 灰的格子 
DIAMOND_GREY=pygame.surface.Surface(DIAMOND_SIZE).convert()
DIAMOND_GREY.fill(COLOR[COLOR_GREY])
# 字体
use_font = pygame.font.Font("FONT.TTF", 16)
use_font12 = pygame.font.Font("FONT.TTF", 12)
# 背景
background=pygame.surface.Surface(size).convert()
background.fill(COLOR[COLOR_BLACK])
# 文字
score_surface = use_font.render("找到终点", True, COLOR[COLOR_BLACK], COLOR[COLOR_GREY])
# 时间
clock = pygame.time.Clock()

##############################################
#   格子访问标记x,y,0,右墙x,y,1,下墙x,y,2
##############################################
#标记 
NOWALL=maze.NOWALL # 无墙
WALL=maze.WALL  # 有墙
WALL2=maze.WALL2  # 有墙

VISIT=maze.VISIT # 到访过
NOVISIT=maze.NOVISIT # 没到过
VERTICAL = maze.VERTICAL # 垂直的
HORIZONTAL = maze.HORIZONTAL# 水平的
INFINITE = maze.INFINITE # 无穷远

INFINITE = maze.INFINITE # 无穷远

# 
def FindNext(pathList, walls, grids, rows, cols):
    nextList = [] # 下一步
    for node in pathList:
        r, c = node
        l = grids[r][c]
        nl=l+1
        # 可以到达的位置
        if r>0 and NOWALL == walls[r][c][1] and INFINITE == grids[r-1][c]:
            # move = 'u'
            nr=r-1
            nc=c
            if (nr,nc) not in nextList:
                nextList.append((nr,nc))
                grids[nr][nc] = l+1
        if c>0 and NOWALL == walls[r][c][0] and INFINITE == grids[r][c-1]:
            # move = 'l'
            nr=r
            nc=c-1
            if (nr,nc) not in nextList:
                nextList.append((nr,nc))
                grids[nr][nc] = l+1
        if c<cols-1 and NOWALL == walls[r][c+1][0] and INFINITE == grids[r][c+1] :
            # move='r'
            nr=r
            nc=c+1
            if (nr,nc) not in nextList:
                nextList.append((nr,nc))
                grids[nr][nc] = l+1
        if r<rows-1 and NOWALL == walls[r+1][c][1] and INFINITE == grids[r+1][c] :
            # move='d'
            nr=r+1
            nc=c
            if (nr,nc) not in nextList:
                nextList.append((nr,nc))
                grids[nr][nc] = l+1
    return nextList


def draw_diamond(r,c, screen, POSX, POSY, diamod):
    px,py=POSX + 1 + (c) * DIAMOND_SIZE[0], POSY + 1 + (r) * DIAMOND_SIZE[1]
    # 标记访问过的格子
    screen.blit(diamod, (px, py))
    return 

def draw_diamond_and_str(r,c, screen, POSX, POSY, diamod, use_font, string, color, color_back):
    px,py=POSX + 1 + (c) * DIAMOND_SIZE[0], POSY + 1 + (r) * DIAMOND_SIZE[1]
    # 标记访问过的格子
    screen.blit(diamod, (px, py))
    distance_surface = use_font.render(string, True, color, color_back)
    screen.blit(distance_surface, (px, py))
    return 


# Sample algorithm
def multipath_maze_demo(rows, cols):
    #walls = maze.aldous_broder_maze(rows, cols)
    #walls = maze.depth_maze(rows, cols)
    #walls = maze.kruskal_maze(rows, cols)
    #walls = maze.prim_maze(rows, cols)
    #walls = maze.wilson_maze(rows, cols)
    walls = maze.wilson_maze(rows, cols)
    POSX=40
    POSY=40
    # 初始化未访问
    grids=[[ INFINITE for i in range(cols)]for j in range(rows)]
    # 起点
    # 标记迷宫
    r=0
    c=0
    findEndPoint=False
    findPath=False
    # 起点
    startPoint=(r,c)
    # 终点
    stopPoint=(rows-1,cols-1)
    # 
    mainList=[] # 主路径

    beginList=[startPoint]
    endList=[stopPoint]
    grids[r][c]=0 # 标记已经到过格子距离
    grids[stopPoint[0]][stopPoint[1]]=0

    # 没有访问过的格子
    notUseGrids = [] 
    for tr in range(rows):
        for tc in range(cols):
            notUseGrids.append((tr,tc))

    beginMap=beginList
    endMap=endList

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
        if notUseGrids:        
            beginNextList = [] # 下一步
            for node in beginList:
                r, c = node
                l = grids[r][c]
                # 可以到达的位置
                if r>0 and NOWALL == walls[r][c][1] and INFINITE == grids[r-1][c]:
                    # move = 'u'
                    nr=r-1
                    nc=c
                    if (nr,nc) not in beginNextList:
                        beginNextList.append((nr,nc))
                        grids[nr][nc] = l+1
                if c>0 and NOWALL == walls[r][c][0] and INFINITE == grids[r][c-1]:
                    # move = 'l'
                    nr=r
                    nc=c-1
                    if (nr,nc) not in beginNextList:
                        beginNextList.append((nr,nc))
                        grids[nr][nc] = l+1
                if c<cols-1 and NOWALL == walls[r][c+1][0] and INFINITE == grids[r][c+1] :
                    # move='r'
                    nr=r
                    nc=c+1
                    if (nr,nc) not in beginNextList:
                        beginNextList.append((nr,nc))
                        grids[nr][nc] = l+1
                if r<rows-1 and NOWALL == walls[r+1][c][1] and INFINITE == grids[r+1][c] :
                    # move='d'
                    nr=r+1
                    nc=c
                    if (nr,nc) not in beginNextList:
                        beginNextList.append((nr,nc))
                        grids[nr][nc] = l+1
            # 下一圈
            beginList = beginNextList
            beginMap = beginMap + beginNextList
            # end
            endNextList = [] # 下一步
            for node in endList:
                r, c = node
                l = grids[r][c]
                # 可以到达的位置
                if r>0 and NOWALL == walls[r][c][1] and INFINITE == grids[r-1][c]:
                    # move = 'u'
                    nr=r-1
                    nc=c
                    if (nr,nc) not in endNextList:
                        endNextList.append((nr,nc))
                        grids[nr][nc] = l+1
                if c>0 and NOWALL == walls[r][c][0] and INFINITE == grids[r][c-1]:
                    # move = 'l'
                    nr=r
                    nc=c-1
                    if (nr,nc) not in endNextList:
                        endNextList.append((nr,nc))
                        grids[nr][nc] = l+1
                if c<cols-1 and NOWALL == walls[r][c+1][0] and INFINITE == grids[r][c+1] :
                    # move='r'
                    nr=r
                    nc=c+1
                    if (nr,nc) not in endNextList:
                        endNextList.append((nr,nc))
                        grids[nr][nc] = l+1
                if r<rows-1 and NOWALL == walls[r+1][c][1] and INFINITE == grids[r+1][c] :
                    # move='d'
                    nr=r+1
                    nc=c
                    if (nr,nc) not in endNextList:
                        endNextList.append((nr,nc))
                        grids[nr][nc] = l+1
            # 下一圈
            endList = endNextList
            endMap = endMap + endNextList

        elif findEndPoint and not findPath:
            mainList.append((r,c))
            l = grids[r][c]
            nl=l-1
            # 最近的
            if r>0 and NOWALL == walls[r][c][1] and nl == grids[r-1][c]:
                # move = 'u'
                nr=r-1
                nc=c
            if c>0 and NOWALL == walls[r][c][0] and nl == grids[r][c-1]:
                # move = 'l'
                nr=r
                nc=c-1
                beginNextList.append((nr,nc))
            if c<cols-1 and NOWALL == walls[r][c+1][0] and nl == grids[r][c+1] :
                # move='r'
                nr=r
                nc=c+1
            if r<rows-1 and NOWALL == walls[r+1][c][1] and nl == grids[r+1][c] :
                # move='d'
                nr=r+1
                nc=c
            # 找到起点
            if 0 == nl:
                mainList.append((nr,nc))
                findPath = True
            r,c=nr,nc

        screen.blit(background, (0, 0))
        # 格子
        for cx in range(cols):
            for ry in range(rows):
                px,py=POSX + 1 + (cx) * DIAMOND_SIZE[0], POSY + 1 + (ry) * DIAMOND_SIZE[1]
                # 标记访问过的格子
                if maze.INFINITE == grids[ry][cx]:
                    draw_diamond(ry, cx, screen, POSX, POSY, DIAMOND)
                else:
                    s = "{}".format(grids[ry][cx])
                    draw_diamond_and_str(ry, cx, screen, POSX,POSY, DIAMOND_GREY, use_font12, s, COLOR[COLOR_BLACK], COLOR[COLOR_GREY]) 
        # 圈地
        for pos in beginMap:
            s = "{}".format(grids[pos[0]][pos[1]])
            draw_diamond_and_str(pos[0], pos[1], screen, POSX,POSY, DIAMOND_GREEN, use_font12, s, COLOR[COLOR_BLACK], COLOR[COLOR_GREEN])
        for pos in endMap:
            s = "{}".format(grids[pos[0]][pos[1]])
            draw_diamond_and_str(pos[0], pos[1], screen, POSX,POSY, DIAMOND_YELLOW, use_font12, s, COLOR[COLOR_BLACK], COLOR[COLOR_YELLOW])
        # 循环外圈
        if beginList and not mainList:
            for pos in beginList:
                s = "{}".format(grids[pos[0]][pos[1]])
                draw_diamond_and_str(pos[0], pos[1], screen, POSX,POSY, DIAMOND_RED, use_font12, s, COLOR[COLOR_BLACK], COLOR[COLOR_RED])
            for pos in endList:
                s = "{}".format(grids[pos[0]][pos[1]])
                draw_diamond_and_str(pos[0], pos[1], screen, POSX,POSY, DIAMOND_RED, use_font12, s, COLOR[COLOR_BLACK], COLOR[COLOR_RED])
        # 路径
        if mainList:
            for pos in mainList:
                s = "{}".format(grids[pos[0]][pos[1]])
                draw_diamond_and_str(pos[0], pos[1], screen, POSX,POSY, DIAMOND_YELLOW, use_font12, s, COLOR[COLOR_BLACK], COLOR[COLOR_YELLOW])
            # r,c
            px,py=POSX + 1 + (c) * DIAMOND_SIZE[0], POSY + 1 + (r) * DIAMOND_SIZE[1]
            screen.blit(DIAMOND_GREEN, (px, py))
            s = "{}".format(grids[r][c])
            distance_surface = use_font12.render(s, True, COLOR[COLOR_BLACK], COLOR[COLOR_GREEN])
            screen.blit(distance_surface, (px, py))

        # 画外墙
        pygame.draw.rect(screen, COLOR[COLOR_RED], (POSX + 0, POSY + 0, DIAMOND_LEN*cols+1, DIAMOND_LEN*rows+1), 2)
        # 画没打通的墙
        for cx in range( cols):
            for ry in range(rows):
                px,py=POSX + 1 + (cx) * DIAMOND_SIZE[0], POSY + 1 + (ry) * DIAMOND_SIZE[1]
                color = COLOR[COLOR_BLACK]
                if maze.WALL == walls[ry][cx][0]:
                    pygame.draw.line(screen, color, (px, py), (px, py+DIAMOND_LEN), 2)
                if maze.WALL == walls[ry][cx][1]:
                    pygame.draw.line(screen, color, (px, py), (px+DIAMOND_LEN, py), 2)
        # 打印文字提示
        if findEndPoint:
            screen.blit(score_surface, (POSX+50, POSY+rows*22))
        # 帧率
        clock.tick(25)

        pygame.display.update()
    return 



# main
if __name__ == "__main__":
    '''main'''
    multipath_maze_demo(20, 30)

到此这篇关于教你怎么用Python实现多路径迷宫的文章就介绍到这了,更多相关Python实现多路径迷宫内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python利用beautifulSoup实现爬虫
Sep 29 Python
Python装饰器入门学习教程(九步学习)
Jan 28 Python
python检查URL是否正常访问的小技巧
Feb 25 Python
python实现图片文件批量重命名
Mar 23 Python
Python实现正则表达式匹配任意的邮箱方法
Dec 20 Python
django中使用事务及接入支付宝支付功能
Sep 15 Python
Django REST Framework之频率限制的使用
Sep 29 Python
Python生成六万个随机,唯一的8位数字和数字组成的随机字符串实例
Mar 03 Python
python GUI库图形界面开发之PyQt5布局控件QGridLayout详细使用方法与实例
Mar 06 Python
PyCharm中配置PySide2的图文教程
Jun 18 Python
tensorflow图像裁剪进行数据增强操作
Jun 30 Python
Python实现归一化算法详情
Mar 18 Python
python3.9之你应该知道的新特性详解
Apr 29 #Python
Python基础之tkinter图形化界面学习
Apr 29 #Python
Django cookie和session的应用场景及如何使用
Apr 29 #Python
Python使用random模块实现掷骰子游戏的示例代码
Apr 29 #Python
python中requests库+xpath+lxml简单使用
python实现进度条的多种实现
教你如何使用Python下载B站视频的详细教程
You might like
php+iframe实现隐藏无刷新上传文件
2012/02/10 PHP
php采集文章中的图片获取替换到本地(实现代码)
2013/07/08 PHP
thinkphp中memcache的用法实例
2014/11/29 PHP
php防止sql注入简单分析
2015/03/18 PHP
php连接mysql数据库
2017/03/21 PHP
php出租房数据管理及搜索页面
2017/05/23 PHP
一个对于js this关键字的问题
2007/01/09 Javascript
js判断浏览器的比较全的代码
2007/02/13 Javascript
TextArea 控件的最大长度问题(js json)
2009/12/16 Javascript
浅谈Javascript 执行顺序
2013/12/18 Javascript
js使用for循环及if语句判断多个一样的name
2014/09/09 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
深入浅析JS的数组遍历方法(推荐)
2016/06/15 Javascript
微信小程序 radio单选框组件详解及实例代码
2017/01/10 Javascript
React组件对子组件children进行加强的方法
2019/06/23 Javascript
零基础写python爬虫之爬虫框架Scrapy安装配置
2014/11/06 Python
Python中使用Tkinter模块创建GUI程序实例
2015/01/14 Python
python列表操作实例
2015/01/14 Python
在Python中操作文件之read()方法的使用教程
2015/05/24 Python
Linux 下 Python 实现按任意键退出的实现方法
2016/09/25 Python
教你用Python创建微信聊天机器人
2020/03/31 Python
python处理DICOM并计算三维模型体积
2019/02/26 Python
python argparser的具体使用
2019/11/10 Python
Pytorch基本变量类型FloatTensor与Variable用法
2020/01/08 Python
使用TensorFlow对图像进行随机旋转的实现示例
2020/01/20 Python
TensorFlow的环境配置与安装方法
2021/02/20 Python
HTML5里的placeholder属性使用实例和美化显示效果的方法
2014/04/23 HTML / CSS
美国羽绒床上用品第一品牌:Pacific Coast
2018/08/25 全球购物
世界上最大的皮肤科医生拥有和经营的美容网站:LovelySkin
2021/01/03 全球购物
Tomcat的缺省是多少,怎么修改
2014/04/09 面试题
英文自荐信
2013/12/19 职场文书
经理秘书求职自荐信范文
2014/03/23 职场文书
电子信息工程专业自荐书
2014/06/24 职场文书
接收函格式
2015/01/30 职场文书
python实现进度条的多种实现
2021/04/29 Python
Python中的 enumerate和zip详情
2022/05/30 Python