A*寻路算法lua实现
前言:并在相当长的时间没有写blog该,我觉得有点“颓废”该,最近认识到各种同行,也刚刚大学毕业,我认为他们是优秀的。认识到与自己的间隙,有点自愧不如。我没有写blog当然,部分原因是由于工作。最初体验上有点欠缺,,原本国庆回去就要把这个寻路的功能改进一下,结果第一次去女朋友家了就没碰电脑,回上海来的第一个夜晚满脑子全是心事。早上凌晨四点就在床上辗转睡不着了,这个月随着项目的进行感觉压力也越来越大,上班时期天天六点多就醒了睡不着,希望挺过这段适应期。
关于寻路问题。在几个月之前一次面试就碰到。面试官叫我上机写出这个算法。由于之前没看过A*,仅仅是有这个概念,所以仅仅能凭着自己的思路来暂时编写。最后憋出了一段后来主动跟面试官说名能够用A*算法来实现,最后还是我的坚持打动了面试官。今天又碰到相同的问题,也让我纠结了一两天,再次写下寻路的学习心得。
一、问题概述
让我选择就纠结了一天,不敢轻易选择,假设稍有考虑不慎。说不定就要做几天白用工,但最后我还是坚持自己的想法用A*来实现。
二、关于A*
三、寻路思想
四、找回路径

五、数据结构
- module('Point', package.seeall)
- -- require("script/battle/BattleCommon")
- --计算F值
- function CalcF( point )
- point.F = point.G + point.H
- end
- function create( posId )
- local point = {}
- point.parentPoint = {}
- point.step = 1 --用于计算h值
- local x,y = BattleCommon.convertPosIdToCoord(posId)
- point.F = 0
- point.G = 0
- point.H = 0
- point.X = y --point.X范围[1,5]
- point.Y = x --point.Y范围[1,8]
- point.posId = posId
- point.CalcF = CalcF
- return point
- end
- return Point
地形(Maze)结构
- --依据一个table创建一个地形
- function create( tb )
- local maze = {}
- maze.step = 1 --格子与格子的基本距离,用于计算H值
- maze.mazeArray = tb
- maze.openList = TabledArray.create() --开启列表
- maze.closeList = TabledArray.create() --关闭列表
- maze.findPath = findPath
- return maze
- end
六、主要代码
- module('Maze', package.seeall)
- require("script/battle/TabledArray")
- require("script/battle/BattleCommon")
- require ("script/battle/Point")
- -- --获取列表中F值最小的点
- function getMinPoint( pointsList )
- local minPoint = pointsList.tbl[1]
- for i = 1,pointsList:getSize() do
- if minPoint.F > pointsList.tbl[i].F then
- minPoint = pointsList.tbl[i]
- end
- end
- return minPoint
- end
- -- --检測是否有阻挡,没有阻挡为true
- function checkBlock( maze,x,y,roleFlag) --x范围[1,5] y范围[1,8]
- if roleFlag == BattleCommon.BATTLE_GROUP_ALLIES then --我方阵营
- if maze.mazeArray[x][y][1] == 0 or maze.mazeArray[x][y][1] == 1 then
- return true --没有阻挡
- else
- return false
- end
- elseif roleFlag == BattleCommon.BATTLE_GROUP_ENEMY then
- if maze.mazeArray[x][y][1] == 0 or maze.mazeArray[x][y][1] == 2 then
- return true --没有阻挡
- else
- return false
- end
- end
- end
- -- --列表中是否包括x,y的点
- function existsXY( list,x,y )
- if list:getSize()>0 then
- for i,point in pairs(list.tbl) do
- if point.X == x and point.Y == y then
- return true
- end
- end
- end
- return false
- end
- --列表中是否包括某个点
- function existsPoint( list,point )
- for i, p in pairs(list.tbl) do
- if (p.X == point.X) and (p.Y == point.Y) then
- return true
- end
- end
- return false
- end
- -- --检測能达到的点
- function canReach( maze,startPoint,x,y,roleFlag)
- if (not checkBlock(maze,x,y,roleFlag)) or existsXY(maze.closeList,x,y) then --关闭列表中包括这个点或者有阻挡
- return false
- else
- if (math.abs(x-startPoint.X)+math.abs(y-startPoint.Y) == 1 ) then
- return true
- end
- end
- end
- -- --获取相邻的点
- function getSurroundPoints( maze,point,roleFlag )
- local surroundPoints = TabledArray.create()
- for i = point.X - 1 ,point.X + 1 do
- for j=point.Y - 1,point.Y + 1 do
- if i>0 and i<6 and j > 0 and j < 9 then --排除超过表姐
- if BattleCommon.distanceFromTo(point.posId,BattleCommon.convertToPositionId(j-1,i-1)) < 2 then
- if canReach(maze,point,i,j,roleFlag) then
- surroundPoints:append(maze.mazeArray[i][j][2])
- end
- end
- end
- end
- end
- return surroundPoints --返回point点的集合
- end
- -- --计算G值
- function CalcG( point )
- local G = point.G
- local parentG = 0
- if point.parentPoint then
- parentG = point.parentPoint.G
- end
- return G + parentG
- end
- function foundPoint( tempStart,point )
- local G = CalcG(point)
- if G < point.G then
- point.parentPoint = tempStart
- point.G = G
- point:CalcF()
- end
- end
- function notFoundPoint( maze,tempStart,point )
- point.parentPoint = tempStart
- point.G = CalcG(point)
- point:CalcF()
- maze.openList:append(point)
- end
- function getPoint( list,data )
- for i,point in pairs(list.tbl) do
- if point.posId == data.posId then
- return point
- end
- end
- return nil
- end
- -- --寻找路径(起始路径)
- local function findPath( maze,startPoint,endPoint,roleFlag)
- maze.openList:append(startPoint)
- while maze.openList:getSize() ~= 0 do
- --找出F的最小值
- local tempStart = getMinPoint(maze.openList)
- maze.openList:removeById(1)
- maze.closeList:append(tempStart)
- --找出它相邻的点
- local surroundPoints = getSurroundPoints(maze,tempStart,roleFlag)
- for i,point in pairs(surroundPoints.tbl) do
- if existsPoint(maze.openList,point) then
- --计算G值,假设比原来大,就什么都不做,否则设置他的父节点为当前节点,并更新G和F
- foundPoint(tempStart,point)
- else
- --假设他们不再開始列表里面,就加入,并设置父节点,并计算GHF
- notFoundPoint(maze,tempStart,point)
- end
- end
- --假设最后一个存在则返回
- if getPoint(maze.openList,endPoint) then
- return getPoint(maze.openList,endPoint)
- end
- end
- return getPoint(maze.openList,endPoint)
- end
- --依据一个table创建一个地形
- function create( tb )
- local maze = {}
- maze.step = 1 --格子与格子的基本距离,用于计算H值
- maze.mazeArray = tb
- maze.openList = TabledArray.create() --开启列表
- maze.closeList = TabledArray.create() --关闭列表
- maze.findPath = findPath
- return maze
- end
- return Maze
调用方法
- function printPath( presentPoint )
- local pathArray = TabledArray.create()
- while presentPoint do
- pathArray:preppend(presentPoint.posId)
- presentPoint = presentPoint.parentPoint
- end
- local startPoint = pathArray:get(2)
- local endPoint = pathArray:getLast()
- cclog(startPoint)
- cclog(endPoint)
- cclog("从"..startPoint.."到"..endPoint.."的路径是:")
- for i,p in pairs(pathArray.tbl) do
- cclog(p)
- end
- end
- local array = battleBoard:createBoxPoints(cRole:getFlag(),40)
- local maze = Maze.create(array)
- local startPoint = Point.create(cRole:getPositionId())
- local endPoint = Point.create(40)
- local presentPoint = maze:findPath(startPoint,endPoint,cRole:getFlag())
- printPath(presentPoint)
七、执行效果
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGluZ3hpYW93ZWkyMDEz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" style="font-size:14px;" alt="" />
假设需要交流请联系。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
A*寻路算法lua实现的更多相关文章
- A*寻路算法详细解读
文章目录 A*算法描述 简化搜索区域 概述算法步骤 进一步解释 具体寻路过程 模拟需要更新F值的情况 Lua代码实现 在学习A*算法之前,很好奇的是A*为什么叫做A*.在知乎上找到一个回答,大致意思是 ...
- A星寻路算法介绍
你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...
- A*寻路算法探究
A*寻路算法探究 A*算法常用在游戏的寻路,是一种静态网路中求解最短路径的搜索方法,也是解决很多搜索问题的算法.相对于Dijkstra,BFS这些算法在复杂的搜索更有效率.本文在U3D中进行代码的测试 ...
- A*寻路算法
对于初学者而言,A*寻路已经是个比较复杂的算法了,为了便于理解,本文降低了A*算法的难度,规定只能横竖(四方向)寻路,而无法直接走对角线,使得整个算法更好理解. 简而言之,A*寻路就是计算从起点经过该 ...
- 算法:Astar寻路算法改进,双向A*寻路算法
早前写了一篇关于A*算法的文章:<算法:Astar寻路算法改进> 最近在写个js的UI框架,顺便实现了一个js版本的A*算法,与之前不同的是,该A*算法是个双向A*. 双向A*有什么好处呢 ...
- 算法:Astar寻路算法改进
早前写了一篇<RCP:gef智能寻路算法(A star)> 出现了一点问题. 在AStar算法中,默认寻路起点和终点都是N x N的方格,但如果用在路由上,就会出现问题. 如果,需要连线的 ...
- js实现A*寻路算法
这两天在做百度前端技术学院的题目,其中有涉及到寻路相关的,于是就找来相关博客进行阅读. 看了Create Chen写的理解A*寻路算法具体过程之后,我很快就理解A*算法的原理.不得不说作者写的很好,通 ...
- 用简单直白的方式讲解A星寻路算法原理
很多游戏特别是rts,rpg类游戏,都需要用到寻路.寻路算法有深度优先搜索(DFS),广度优先搜索(BFS),A星算法等,而A星算法是一种具备启发性策略的算法,效率是几种算法中最高的,因此也成为游戏中 ...
- A星寻路算法
A星寻路算法 1.准备一个close关闭列表(存放已被检索的点),一个open开启列表(存放未被检索的点),一个当前点的对象cur 2.将cur设成开始点 3.从cur起,将cur点放入close表中 ...
随机推荐
- arcgis jsapi 调用google地区服务
做地理信息系统(GIS)项目,除了实现功能用户体验度要好之外,最重要的是地图渲染效果更要好.很多时候苦于数据的完整性和对于配图的审美观,程序猿们都很难配出好看的地图效果.基于上述一般直接调用googl ...
- friend keyword 对于模板 并不只不过友元!!!
friend是C++中封装的漏网之鱼. C++中的friend同意其它的类或者是函数訪问本类的不论什么成员.甚至是private成员,仅仅要该类声明其为友元. 但是,在有些情况下,并非同意外界訪问类的 ...
- hadoop namenode -format Couldn'tload main class "-Djava.library.path=.home.hadoop.hadoop-2.5.2.lib"
<pre name="code" class="sql">[hadoop@MasterHadoop50 ~]$ hadoop namenode -f ...
- Spring官方网站的改版后下载
Spring官方网站改版很长一段时间后还没有找到直接下载Jar链接包,下面总结了一些方法,可在网上,亲測可用. 1.直接输入地址,改对应版本号就可以:http://repo.springsource. ...
- ZOJ Problem Set - 3829Known Notation(贪心)
ZOJ Problem Set - 3829Known Notation(贪心) 题目链接 题目大意:给你一个后缀表达式(仅仅有数字和符号),可是这个后缀表达式的空格不幸丢失,如今给你一个这种后缀表达 ...
- 开源Math.NET基础数学类库使用(15)C#计算矩阵行列式
原文:[原创]开源Math.NET基础数学类库使用(15)C#计算矩阵行列式 本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p ...
- Ising模型(伊辛模型)
Ising模型(伊辛模型)是一个最简单且能够提供非常丰富的物理内容的模型.可用于描写叙述非常多物理现象,如:合金中的有序-无序转变.液氦到超流态的转变.液体的冻结与蒸发.玻璃物质的性质.森林火灾.城市 ...
- lua5.1 和 5.2 关于 sequence 的定义变化,对#table取值的影响
引子 环境 lua 5.2 a = {} for i=1,2 do a[i] = i*3 end a[4] = 11; print(a[#a]) ---print 11 ------- ...
- SharePoint 2013 创建web应用程序报错"This page can’t be displayed"
错误描写叙述 This page can't be displayed •Make sure the web address http://centeradmin is correct. •Look ...
- UVa 11879 - Multiple of 17
称号:计算一个数字是不17倍数. 说明:串,睑板. 简单的问题,直接推论可以是. 设定 n = 10a + d:(0 ≤ d ≤ 9) a - 5d = 51a - 5n,假设n被17整除,这个数必定 ...