基于A*算法的迷宫小游戏


前言

本文采用A*算法的思想,借助pycharm下的python环境,求解迷宫的最优路径问题。


一、程序设计说明

1.功能描述

①根据用户界面的提示,可以自定义生成一个迷宫;

②本迷宫所采用的主要算法为启发式A*算法,通过其寻找到一条起点和终点间的最短距离,输出走迷宫的最优路径并显示。

2.算法思想

(1)A*算法介绍

A算法是一种启发式搜索算法。在A*算法中,从起点开始后,通过启发函数来检查相邻方格,找到代价最小的“节点”作为下一个“父节点”,不断地搜索直到找到最优解。

(2)open表和close表

A*算法的两个重要数据列表:

①open表:用来存储可能用来寻找最短路径的可到达或通过的方格

②close表:用来存储不再需要检查或无法通过的方格

(3)启发函数

启发函数是A*算法的核心,在选择路径的过程中发挥重要作用。其表达式如下:

  f(n)=g(n)+h(n)

g(n)表示的是从起点到当前位置所产生的实际移动代价;
h(n)表示的是从当前位置到终点的预估移动代价。

h(n)的选取保证了找到最短路径这一条件,计算h(n)的方法有许多种,本文主要采用的是曼哈顿方法,即计算从当前格到目的格之间水平和垂直的方格的数量总和。

此外,A算法的启发函数还要满足的条件是:h(n)≤h*(n) (h*(n)为实际距离的代价值)。

(4)算法流程

① 首先初始化open表和close表,将开始节点放入open表中,此时开始节点的g值和h值都为0。

② 将所有可到达的方格作为相邻节点加入open表中,通过启发函数计算这些节点的f值,找到值最小的节点。

③ 将open表中的父节点删除,放入close表中。

④ 将找到的f值最小的节点作为现在的父节点,不断地重复循环遍历,找到下一个当前节点和其相邻结点f值最小的节点作为父节点。
若相邻节点不可通过或者已经在close中,则不执行任何操作;
若相邻节点不在open表中,则将其加入open表中,当前节点为其父节点,计算出它们之间的f值;
若相邻节点已经在open表中,则判断此时的当前节点和该相邻节点间的f值是否更小,如果是,则更新此时的f值。

⑤ 当最终的目的节点被加入到open列表时,表明此时已经找到了最短路径;否则,直到open列表空时也没有找到目的节点,则表明找不到路径,结束遍历。

二、模块设计

1.流程设计

(1)游戏流程
在这里插入图片描述
(2)寻找最短路径流程
在这里插入图片描述

2.算法实现

重要代码:

(1)判断终点是否在open表中

    def endInOpenList(self):
        for i in self.openList:
            if self.endPoint[0] == i.x and self.endPoint[1] == i.y:
                return True
        return False

(2)将节点加进open表前需检查其是否已经在open表中

    def inOpenList(self, p1):
        for i in range(0, len(self.openList)):
            if p1.isEq(self.openList[i]):
                return i
        return -1

(3)A star算法寻路

    def AstarMap(self):
        self.openList.append(self.startPoint)  # 将起点放到open表中
        while (not self.isOK): # 先检查终点是否在open表中 ,有则结束
            if self.inOpenList(self.endPoint) != -1:  
                self.isOK = True  
                self.end = self.openList[self.inOpenList(self.endPoint)]
                self.route.append(self.end)
                self.te = self.end
                while (self.te.parentPoint != 0):
                    self.te = self.te.parentPoint
                    self.route.append(self.te)
            else:
                self.sortOpenList()  # 将估值最小的节点放在index = 0
                Minnode = self.openList[0]  # Minnode为估值最小节点
                self.openList.pop(0)
                self.closeList.append(Minnode)
                     

3.界面设计

(1)设计窗体布局,以及实现迷宫的画布

 self.root = Tk()
        self.root.title('A*算法实现迷宫')
        self.root.geometry("1050x600+200+50") #设置窗口大小
self.canvas = Canvas(self.root, width=500, height=500, bg="white")
        self.canvas.pack(side='left')
        for i in range(1, 10):
            self.canvas.create_line(50, 50 * i, 450, 50 * i)  # 横线
            self.canvas.create_line(50 * i, 50, 50 * i, 450)  # 竖线
        self.canvas.bind("<Button-1>", self.drawMapBlock)# 将画布绑定到迷宫区域
        self.root.mainloop()

(2)设计障碍物、起点、终点、所寻路径的颜色

self.blockcolor = ['black', 'green', 'red', 'purple']  # 设置障碍为黑色,起点为绿色 终点为红色,路径为紫色
        self.mapStatus = np.ones((8, 8), dtype=int)  # 地图状态数组(全0数组) 1无障碍 0障碍
#颜色设置
    def selectobstacle(self):
        self.blockcolorIndex = 0  #黑色
    def selectstart(self):
        if not self.selectedStart:
            self.blockcolorIndex = 1  # 绿色
        else:
            self.blockcolorIndex = 0  # 黑色
    def selectend(self):
        if not self.selectedEnd:
            self.blockcolorIndex = 2  # 红色
        else:
            self.blockcolorIndex = 0  # 黑色
    def selectaction(self):
        self.blockcolorIndex = 0  # 黑色
        self.AstarMap()
        self.route.pop(-1)
        self.route.pop(0)
        for i in self.route:
            self.canvas.create_rectangle((i.x + 1) * 50, (i.y + 1) * 50, (i.x + 2) * 50, (i.y + 2) * 50, fill='purple')

(3)设计五个功能,分别为选择障碍,选择起点,选择重点,开始寻路和重新开始。

self.btn_obstacle = Button(self.root, text="选择障碍", command=self.selectobstacle)
        self.btn_obstacle.pack(side='left',anchor='n')
        self.btn_start = Button(self.root, text="选择起点", command=self.selectstart)
        self.btn_start.pack(side='left',anchor='n')
        self.btn_end = Button(self.root, text="选择终点", command=self.selectend)
        self.btn_end.pack(side='left',anchor='n')
        self.btn_pathfinding = Button(self.root, text="开始寻路", command=self.selectaction)
        self.btn_pathfinding.pack(side='left',anchor='n')
        self.btn_restart = Button(self.root, text="重新游戏", command=self.selectrestart)
        self.btn_restart.pack(anchor='w')

三、功能演示

设置迷宫,寻路结果如下:
在这里插入图片描述

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本
基于A*算法迷宫小游戏开发,可以让玩家面对迷宫的挑战,通过智慧和策略找到迷宫的出口。 首先,我们需要设计一个迷宫地图。可以采用多种方式生成迷宫地图,如随机生成、手动设计或者使用迷宫生成算法迷宫地图由起点、终点以及迷宫墙壁组成。 接下来,我们使用A*算法来寻找最佳路径。A*算法是一种启发式搜索算法,通过估计每个节点到目标点的距离来决定搜索方向。在实现A*算法时,需要定义一个启发函数来评估节点的价值,以便选择最优的路径。在该游戏中,可以使用曼哈顿距离或欧几里得距离作为启发函数。 当玩家开始游戏后,可以使用方向键或鼠标来控制角色移动。同时,在游戏界面上显示迷宫地图和玩家的当前位置。 在实现A*算法时,需要考虑一些特殊情况。比如,如何处理墙壁、如何处理无法到达的位置等。可以采用合适的数据结构,如优先队列或堆栈,来实现算法的搜索和路径的存储。 最后,为了增加游戏的趣味性和挑战性,可以在迷宫中添加一些道具或陷阱,用来干扰玩家的寻路过程。比如,道具可以提供额外的移动能力,而陷阱则会减慢玩家的速度。 通过以上方法,基于A*算法迷宫小游戏可以提供给玩家一个有趣而挑战的寻路体验。同时,这个游戏也可以帮助玩家锻炼逻辑思维和空间认知能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值