数据结构小设计--(迷宫问题Python版本)

Posted HUTEROX

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构小设计--(迷宫问题Python版本)相关的知识,希望对你有一定的参考价值。

说明

本文为2021 12 14 所著,实现语言为python。设计需求:

1.设计迷宫
2.让人物自动寻找迷宫出口
3.动态显示该过程
4.保存迷宫路径(这里只是简单的stdout)

功能说明

模块说明

函数接口参数说明

项目结构

算法实现

这个是重点,但还是比较基础的。至于具体实现原理,自行百度。

import copy
class ALgorithm:

    @staticmethod
    def DFSAutoFindingWay(maze_list_r,start,end_row,end_col):

        def dfs(lst,maze_list_,row_,col_):
            while lst:
                now = lst[-1]
                row, col = now
                maze_list_[row][col] = 2

                if (row == row_ and col == col_):

                    return lst
                if (row + 1 < len(maze_list_) and maze_list_[row + 1][col] == 0):
                    lst.append((row + 1, col))
                    continue
                elif (col + 1 < len(maze_list_[0]) and maze_list_[row][col + 1] == 0):
                    lst.append((row, col + 1))
                    continue
                elif (row - 1 >= 0 and maze_list_[row - 1][col] == 0):
                    lst.append((row - 1, col))
                    continue
                elif (col - 1 >= 0 and maze_list_[row][col - 1] == 0):
                    lst.append((row, col - 1))
                    continue
                else:
                    lst.pop()

        start = start
        end_col = end_col
        end_row = end_row
        #一开始往下走


        ways = [] #存储多条路径
        has_way = len(end_row)
        lst = [start]
        for i in range(has_way):

            maze_list_ = copy.deepcopy(maze_list_r)
            zz = copy.deepcopy(lst)

            res = dfs(zz,maze_list_,end_row[i],end_col[i])
            ways.append(res)

        if ways:
            for i in range(has_way):
                print("DFS搜索路径为".format(i,ways[i]))
            return ways
        else:
            return []


    @staticmethod
    def BFSAutoFindingWay(maze_list,start,end_row,end_col):

        pre_route = list()  # 广度度搜索得到的节点
        q = list()  # 队列结构控制循环次数
        xx = [0, 1, 0, -1]  # 右移、下移、左移、上移
        yy = [1, 0, -1, 0]
        visited = list()  # 记录节点是否已遍历
        father = list()  # 每一个pre_route节点的父节点
        route = list()
        maze_list = copy.deepcopy(maze_list)
        def bfs(maze_list, x, y, m, n):
            visited = [[0 for i in range(len(maze_list[0]))] for j in range(len(maze_list))]
            visited[x][y] = 1  # 入口节点设置为已遍历
            q.append([x, y])
            while q:  # 队列为空则结束循环

                now = q.pop(0)  # 移除队列头结点
                maze_list[now[0]][now[1]] = 2
                for i in range(4):
                    point = [now[0] + xx[i], now[1] + yy[i]]  # 当前节点
                    if point[0] >= 0 and point[1] >= 0 and point[0] < len(maze_list) and point[1] < len(maze_list[0]) and visited[point[0]][point[1]] != 1 and maze_list[point[0]][point[1]]==0:
                        father.append(now)
                        visited[point[0]][point[1]] = 1
                        q.append(point)
                        pre_route.append(point)


                    if point[0] in m and point[1] in n:

                        return 1

            return 0

        def get_route(father, pre_route):  # 输出最短迷宫路径
            route = [pre_route[-1], father[-1]]
            for i in range(len(pre_route) - 1, -1, -1): # 从后往前拿
                if pre_route[i] == route[-1]:
                    route.append(father[i])
            route.reverse()

            return route


        if bfs(maze_list,start[0],start[1],end_row,end_col)==1:
                route=get_route(father,pre_route)
                print("BFS最佳路径:",route)
                return route
        else:
            return []


if __name__ == "__main__":
    maze_list = [
        [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1],
        [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
        [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
        [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1],
        [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
        [1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1],
        [1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1],
        [1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1],
        [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1],
        [1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1],
        [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1],
        [1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1]
    ]

    # result = algorithm.DFSAutoFindingWay((0,5),[12],[7,9])
    # print(result)
    res = ALgorithm.BFSAutoFindingWay(maze_list,(0,5),[12,12],[9,7])


控制代码

from turtle import Turtle
import turtle
import time
from ALgorithm import ALgorithm

class Controller(Turtle):
  def __init__(self,playper):
    # 父类初始化
    Turtle.__init__(self)
    # 初始值设置
    self.go_up = playper.go_up
    self.go_down = playper.go_down
    self.go_left = playper.go_left
    self.go_right = playper.go_right
    self.move = playper.move
    self.maze_list = playper.maze_list
    self.start = (playper.m,playper.n)
    self.end_row  = playper.end_m
    self.end_col = playper.end_n
    self.ALgorithm = ALgorithm

    # 绘制控制器
    self.hideturtle()
    self.speed(0)
    self.draw_btn('上', -15, 165)
    self.draw_btn('下', -15, -135)
    self.draw_btn('左', -165, 15)
    self.draw_btn('右', 135, 15)
    self.draw_btn("自动寻路DFS",-150,250)
    self.draw_btn("自动寻路BFS", 60, 250)
    self.draw_btn("重置",200,-220)

    # 绑定点击事件
    screen = self.getscreen()
    screen.onclick(self.handlescreenclick)


  def draw_btn(self, name, x, y):
    self.penup()
    self.goto(x, y)
    self.begin_fill()
    self.fillcolor('#ffffff')
    for i in range(4):
      self.forward(30)
      self.right(90)
    self.end_fill()
    self.color('#000000')
    self.goto(x + 7, y - 20)
    self.write(name, font = ('SimHei', 12, 'bold'))

  def autopathfindingB(self):
      #自动寻路功能,也就是走迷宫功能
      print("自动寻路BFS")

      res = self.ALgorithm.BFSAutoFindingWay(self.maze_list,self.start,self.end_row,self.end_col)
      for path in res:

          m,n=path
          time.sleep(0.5)
          self.move(m,n)
      pass
  def autopathfindingD(self):
      #自动寻路功能,也就是走迷宫功能
      print("自动寻路DFS")

      res2 = self.ALgorithm.DFSAutoFindingWay(self.maze_list,self.start,self.end_row,self.end_col)
      for paths in res2:
          for path in paths:
              m,n=path
              time.sleep(0.5)
              self.move(m,n)
      pass

  def RestPlayes(self):

        self.move(self.start[0],self.start[1])


  #当点击事件发生时利用abs函数进行比较判断
  def handlescreenclick(self, x, y):

    if ( 220 < abs(y) < 250  ):

        if(x>=-150 and x<-40 ):
            self.autopathfindingD()
        if(x>60 and x<160):
            self.autopathfindingB()
        if(x>200 and x<240):
            self.RestPlayes()


    else:
        if y > 0 and abs(x) < y:
            self.go_up()

        if y < 0 and abs(x) < -y:
            self.go_down()

        if x < 0 and abs(y) < -x:
            self.go_left()

        if x > 0 and abs(y) < x:
            self.go_right()

玩家代码

from turtle import Turtle
import turtle
import time

class Player(Turtle):
    def __init__(self, maze_list, start_m, start_n, end_m, end_n):
        # 父类初始化
        Turtle.__init__(self)
        # 初始的横纵坐标
        self.m = start_m
        self.n = start_n
        # 终点的横纵坐标
        self.end_m = end_m
        self.end_n = end_n
        # 迷宫地图
        self.maze_list = maze_list
        self.hideturtle()
        self.speed(0)
        self.penup()
        # 玩家移到对应的位置
        self.goto(self.n * 20 - 120, 120 - self.m * 20)
        # 生成玩家
        self.shape('turtle')
        self.color('yellow')
        # 玩家初始方向
        self.setheading(270)
        self.showturtle()

    # 当抵达时
    def reach_exit(self, m, n):
        if m in self.end_m and n in self.end_n:
            # 走出迷宫,显示'Pass it!'
            text = turtle.Turtle()
            text.hideturtle()
            text.penup()

以上是关于数据结构小设计--(迷宫问题Python版本)的主要内容,如果未能解决你的问题,请参考以下文章

我半夜爬起来,用python给失眠的隔壁小姐姐:写了一个迷宫小游戏~~~

今天大佬带你做一个Python 小项目制作一个迷宫游戏附带源码

迷宫生成与路径规划算法-Python3.8-附Github代码

迷宫生成与路径规划算法-Python3.8-附Github代码

数据结构与算法大作业:走迷宫程序(实验报告)

Python 解决一个简单的迷宫问题 在线等