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表中 ...
随机推荐
- windows接口被占用
netsh winsock reset 重启winsock服务
- Windows phone 8 学习笔记(4) 应用的启动
原文:Windows phone 8 学习笔记(4) 应用的启动 Windows phone 8 的应用除了可以直接从开始菜单以及应用列表中打开外,还可以通过其他的方式打开.照片中心.音乐+视频中心提 ...
- iOS 多线程开发之OperationQueue(二)NSOperation VS GCD
原创Blog.转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...
- 内存泄露检測及cvClone造成的泄露
调了几个小时,到最后发现内存泄露的原因是opencv的cvClone函数,採用cvCopy函数后,问题解决. vs2010使用vld进行内存泄露检測 (1) 下载vld工具 (2) 将D:\Progr ...
- linux下使用vi操作
ESC : 进入命令模式 linux下使用vi后,怎样跳转到文件结尾 pagedown键连续按 虽然我也这么用,但还是太笨了.问了高手,方法是按shift+g,另外,到文件开头是gg. linux ...
- 【Cocos2d-x 粒子系统】火球用手指飞起来
程序: 创建球 sp1 = CCSprite::create("ball.png"); sp1->setPosition(ccp(10, visibleSize.height ...
- C#中使用gRPC
C#中使用gRPC 我的这几篇文章都是使用gRPC的example,不是直接编译example,而是新建一个项目,从添加依赖,编译example代码,执行example.这样做可以为我们创建自己的项目 ...
- Codeforces 432E Square Tiling(结构体+贪婪)
题目连接:Codeforces 432E Square Tiling 题目大意:给出一个n∗m的矩阵,要求对该矩阵进行上色,用大写字母,可是每次上色的区域必须是正方形,不求相邻的上色区域不能有同样的颜 ...
- SQL注入问题
斌斌 (给我写信) 原创博文(http://blog.csdn.net/binbinxyz),转载请注明出处! 背景:对于ibaits参数引用可以使用#和$两种写法,其中#写法会采用预编译方式,将转义 ...
- Linux如何用QQ?Linux下QQ使用的几种方案
在linux下如何使用QQ?在ubuntu11.10中如何使用QQ?或许有初涉linux的人这样问,我们可以看看ubuntusoft总结出来的几种在linux系统下用QQ的方法.前面的几种主要的方法都 ...