美文网首页
python 迷宫生成算法:递归回溯算法

python 迷宫生成算法:递归回溯算法

作者: rgbRed | 来源:发表于2020-03-04 20:30 被阅读0次
2102280160.png

步骤一:初始化地图

1.行宽和列高为奇数
2.边框设置为墙
3.所有偶数行和偶数列设置为墙

218512471.png
def __init_map(self):
        for i in range(self.height):
            row = []
            if(i % 2 == 0):
                for j in range(self.width):
                    row.append(1)
            else:
                for j in range(self.width):
                    if(j % 2 == 0):
                        row.append(1)
                    else:
                        row.append(0)
            self.__map.append(row)

步骤二:打通路线

1.选择坐标为(1,1)为起点,将起点坐标加入标记列表中
2.取标记列表中的第一个坐标,从其四周的空间中,随机取一个未被标记的空间,加入标记列表中,并打通和起点之间的墙
3.将上一个随机空间作为起点,重复第二步.(递归)直到最后一个空间四周不存在未被标记的空间.
4.将第一个起点移出标记列表,存放至已处理标记列表中.

2062210631.png 798394785.png
def __get_through(self, pos=""):
        if(pos == ""):
            pos = self.__signList[0]

        target_pos_list = self.__get_around_pos(pos)

        if(len(target_pos_list)):
            target_pos = self.__sign_pos(pos, target_pos_list)
            self.__break_wall(pos, target_pos)
            self.__get_through(target_pos)
        else:
            self.__unsignList.append(self.__signList[0])
            del self.__signList[0]

步骤三:重复打通路线

不断重复第二个步骤,直到标记列表中没有坐标为止

849776282.png

流程效果:


510248891.gif

完整代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from random import randint


class Map():
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.__map = []
        self.__signList = [(1, 1)]  # 起点
        self.__unsignList = []

    def show_data(self):
        self.__init_map()
        self.__create_map()

        return self.__map

    def show_map(self):
        self.__init_map()
        self.__create_map()

        for i in self.__map:
            for j in i:
                if(j == 1):
                    print("# ", end="")
                else:
                    print("  ", end="")
            print("")

    # 初始化地图
    def __init_map(self):
        for i in range(self.height):
            row = []
            if(i % 2 == 0):
                for j in range(self.width):
                    row.append(1)
            else:
                for j in range(self.width):
                    if(j % 2 == 0):
                        row.append(1)
                    else:
                        row.append(0)
            self.__map.append(row)

    def __create_map(self):
        while True:
            if(len(self.__signList)):
                self.__get_through()
            else:
                break

    # 从标记坐标列表中选取下标为0的元组作为起始点,
    # 一直往下打通墙,直到四周不存在未被标记的空间
    def __get_through(self, pos=""):
        # 若没有传入起始位置,取标记列表中的第一个坐标作为起始位置
        if(pos == ""):
            pos = self.__signList[0]

        # 获取起始坐标上下左右中未被标记的坐标作为目标位置列表
        target_pos_list = self.__get_around_pos(pos)

        # 如果目标位置列表不为空
        if(len(target_pos_list)):
            # 从目标位置列表中随机选取一个作为目标位置
            target_pos = self.__sign_pos(pos, target_pos_list)
            # 打通起始位置和目标位置之间的墙
            self.__break_wall(pos, target_pos)
            # 递归,将本次的目标位置作为下次的起始位置
            self.__get_through(target_pos)
        # 如果目标位置列表为空,说明路走到尽头
        # 将标记坐标列表的第一个坐标存放至已处理坐标列表
        # 结束本条路线
        else:
            self.__unsignList.append(self.__signList[0])
            del self.__signList[0]

    # 从坐标列表中随机取其中一个坐标,将该坐标存入标记列表中
    def __sign_pos(self, pos, target_pos_list):
        target_pos = target_pos_list[randint(0, len(target_pos_list) - 1)]
        self.__signList.append(target_pos)

        return target_pos

    # 将墙打通
    def __break_wall(self, pos, target_pos):
        if(target_pos[1] > pos[1]):
            x = pos[1] + 1
        elif(target_pos[1] < pos[1]):
            x = pos[1] - 1
        else:
            x = pos[1]

        if(target_pos[0] > pos[0]):
            y = pos[0] + 1
        elif(target_pos[0] < pos[0]):
            y = pos[0] - 1
        else:
            y = pos[0]

        self.__map[x][y] = 0

    # 获取指定位置四周未被标记空位
    def __get_around_pos(self, pos):
        around_pos = []
        data = []
        data.append(self.__get_top_pos(pos, 2))
        data.append(self.__get_right_pos(pos, 2))
        data.append(self.__get_below_pos(pos, 2))
        data.append(self.__get_left_pos(pos, 2))

        for item in data:
            if(item and item not in self.__signList and item not in self.__unsignList):
                around_pos.append(item)

        return around_pos

    # 获取指定坐标上方坐标
    def __get_top_pos(self, pos, step):
        if(pos[1] - step >= 0):
            return (pos[0], pos[1] - step)
        return False

    # 获取指定坐标右方坐标
    def __get_right_pos(self, pos, step):
        if(pos[0] + step < self.width):
            return (pos[0] + step, pos[1])
        return False

    # 获取指定坐标下方坐标
    def __get_below_pos(self, pos, step):
        if(pos[1] + step < self.height):
            return (pos[0], pos[1] + step)
        return False

    # 获取指定坐标左方坐标
    def __get_left_pos(self, pos, step):
        if(pos[0] - step >= 0):
            return (pos[0] - step, pos[1])
        return False


if __name__ == "__main__":
    m = Map(31, 31)
    m.show_map()

相关文章

  • python 迷宫生成算法:递归回溯算法

    步骤一:初始化地图 1.行宽和列高为奇数2.边框设置为墙3.所有偶数行和偶数列设置为墙 步骤二:打通路线 1.选择...

  • 走迷宫算法(C回溯递归)

    引言 迷宫算法在很多场景都非常实用,比如游戏中的机器人等。而且高级的迷宫算法与回溯、递归也是息息相关的。而且回溯的...

  • python迷宫游戏,迷宫生成,解决与可视化

    代码已上传github 使用prime算法生成迷宫使用递归算法走迷宫使用pygame做可视化展示 prime算法生...

  • 递归2-回溯与递归

    I. 回溯算法基础 回溯与递归的区别和联系  很多人不理解回溯与递归到底是什么关系。其实很简单,回溯算法是一种算法...

  • Python3 趣味系列题7(续) ------ A

    前文:Python3 趣味系列题7 ------ Prim算法生成完美迷宫 一、A*算法 寻找路径的算法有很多,例...

  • 8.30 leetcode刷题(2)

    递归和回溯:17 电话号码 思路:运用递归去实现回溯算法的思想。回溯算法本质上是一种暴力搜索,通过递归调用去实现,...

  • 算法入门教程-冒泡排序

    上节我们分别通过案例迷宫和八皇后亲自体验了递归回溯算法的思想,本节我们学习常见八大算法之一的冒泡排序算法,亲自感受...

  • 递归、迭代、回溯、广度和深度优先

    在学习算法的时候,经常碰到递归、迭代、回溯、广度优先和深度优先算法,可是回溯使用了递归,深度优先也使用了递归,广度...

  • 二叉树算法之0-计算二叉树的深度

    算法思想:使用递归 算法解析:分别递归左树和右树,递归到叶子节点时返回0,递归回溯时值+1,不断累积回溯的深度,每...

  • 回溯递归算法

    回溯大法严重依赖【递归】 1、求子集 78. 子集[https://leetcode-cn.com/problem...

网友评论

      本文标题:python 迷宫生成算法:递归回溯算法

      本文链接:https://www.haomeiwen.com/subject/ftpilhtx.html