A星寻路的lua实现

在项目中遇到了自动寻路的需求,于是决定开始学习一下A星,对于A星我也没有深究,只能说是勉强搞定了需求,在这和大家分享一下,相互进步,

A星有个公式 f(x) = g(x) + h(x) ,搞清楚这个公式就好办了,f(x)就是当前位置到下一个位置的总价值,g(x)表示实际价,这是说这一部分代价是确定的,h(x)表示估价值,就是说我从下一个位置到到终点的代价是未知的,所以叫估价值,如图中所示,黑色格子表示当前位置,绿色格子表示下一步可能到达的位置,即上、下、左、右这几个方向,红色格子表示终点,褐色表示障碍物,现在要从黑色格子到达红色格子,那么黑色格子的下一步肯定是绿色格子当中的一个,黑色格子到绿色格子之间是相挨着的,所以我们可以很明确的知道它的实际代价为1(移动一步的代价)即g(x),绿色格子到红色格子之间隔着很长的距离,中间还有障碍物,所以这个代价是未知的,即h(x),所以总的代价就为f(x)
= g(x) + h(x),我们看到周围有4个绿色的格子,到底走那一步比较好呢,所以我们要把这4个格子的f(x)值都求出来,然后进行排序,选择f(x)值最小的,即总代价最少的那个格子,以此方法继续下去,直到到达终点 或者 地图上没有绿色格子了

下面来看一下这个工具类,g(x)和h(x)要选的比较合适,一般就是采用的曼哈顿算法,即两点在x方向和y方向的距离之和,

-- Filename: PathUtil.lua
-- Author: bzx
-- Date: 2014-07-01
-- Purpose: 寻路

module("PathUtil", package.seeall)

local _map_data         -- 地图数据
local _open_list        -- 开放节点
local _open_map         -- 开放节点,为了提高性能而加
local _close_map        -- 关闭节点
local _deleget          -- 代理
local _dest_point       -- 目标点
local _start_point      -- 起点
local _path             -- 路径

-- 寻找路径
--[[
deleget = {
    g = function(point1, point2)
        -- add your code
        -- 返回点point1到点point2的实际代价
    end
    h = function(point1, point2)
        -- add your code
        -- 返回点point1到点point2的估算代价
    end
    getValue = function(j, i)
        -- 返回地图中第i行,第j列的数据 1为障碍物,0为非障碍物
    end
    width -- 地图宽度
    height -- 地图高度
}
--]]
function findPath(deleget, start_point, dest_point)
    _deleget = deleget
    _dest_point = dest_point
    _start_point = start_point
    init()
    while not table.isEmpty(_open_list) do
        local cur_point = _open_list[1]
        table.remove(_open_list, 1)
        _open_map[cur_point.key] = nil
        if isEqual(cur_point, dest_point) then
            return makePath(cur_point)
        else
            _close_map[cur_point.key] = cur_point
            local next_points = getNextPoints(cur_point)
            for i = 1, #next_points do
                local next_point = next_points[i]
                if _open_map[next_point.key] == nil and _close_map[next_point.key] == nil and isObstacle(next_point) == false then
                    _open_map[next_point.key] = next_point
                    table.insert(_open_list, next_point)
                end
            end
            table.sort(_open_list, compareF)
        end
    end
    return nil
end

function init()
    _open_list = {}
    _open_map = {}
    _close_map = {}
    _path = {}
    _map_data = {}
    for i = 1, _deleget.height do
        _map_data[i] = {}
        for j = 1, _deleget.width do
            local value = _deleget.getValue(j, i)
            _map_data[i][j] = value
        end
    end
    _open_map[getKey(_start_point)] = _start_point
    table.insert(_open_list, _start_point)
end

function createPoint(x, y)
    local point = {
        ["x"] = x,
        ["y"] = y,
        ["last"] = nil,
        ["g_value"] = 0,
        ["h_value"] = 0,
        ["f_value"] = 0
    }
    point["key"] = getKey(point)
    return point
end

-- 得到下一个可以移动的点
-- @param point 当前所在点
function getNextPoints(point)
    local next_points = {}
    for i = 1, #_deleget.directions do
        local offset = _deleget.directions[i]
        local next_point = createPoint(point.x + offset[1], point.y + offset[2])
        next_point["last"] = point
        if next_point.x >= 1 and next_point.x <= _deleget.width and next_point.y >= 1 and next_point.y <= _deleget.height then
            next_point["g_value"] = _deleget.g(point, next_point)
            next_point["h_value"] = _deleget.h(point, _dest_point)--math.abs(next_points.x - _dest_point.x) + math.abs(next_points.y - _dest_point.y)
            next_point["f_value"] = next_point.g_value + next_point.h_value
            table.insert(next_points, next_point)
        end
    end
    return next_points
end

-- 得到路径
-- @param end_point 目标点
function makePath(end_point)
    _path = {}
    local point = end_point
    while point.last ~= nil do
        table.insert(_path, createPoint(point.x, point.y))
        point = point.last
    end
    local start_point = point
    table.insert(_path, start_point)
    return _path
end

-- 两个点的代价比较器
function compareF(point1, point2)
    return point1.f_value < point2.f_value
end

-- 是否是障碍物
function isObstacle(point)
    local value = _map_data[point.y][point.x]
    if value == 1 then
        return true
    end
    return false
end

-- 两个点是否是同一个点
function isEqual(point1, point2)
    return point1.key == point2.key
end

-- 根据点得到点的key
function getKey(point)
    local key =  string.format("%d,%d", point.x, point.y)
    return key
end

下面是工具类PathUtil的用法

   local deleget = {}
        deleget.g = function(point1, point2)
            return math.abs(point1.x - point2.x) + math.abs(point1.y - point2.y)
        end
        deleget.h = deleget.g
        deleget.getValue = function(j, i)
            local index = FindTreasureUtil.getIndex(j, i)
            local map_info = _map_info.map[index]
            if map_info.display == 0 and map_info.eid ~= 1 then
                return 0
            end
            return 1
        end
        deleget.directions = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}} -- 左,上,下,右
        deleget.width = _cols
        deleget.height = _rows

        local dest_row, dest_col = FindTreasureUtil.getMapPosition(tag)
        local dest_point = PathUtil.createPoint(dest_col, dest_row)
        local start_row, start_col = FindTreasureUtil.getMapPosition(_player_index)
        local start_point = PathUtil.createPoint(start_col, start_row)
        _path = PathUtil.findPath(deleget, start_point, dest_point)

_path就是我们找到的路径,起点为最后一个元素,终点为第一个元素,由于项目中的地图比较简单,因此我也没有过于深究,关于A星的介绍网上的资料还有很多,我这一般就显得太简略了,初次接触自动寻路,希望大神们多多指教

另附广告一条:出售美容品的微店  如需详细了解可加我姐姐QQ:937893128    各路大神 给你的老婆,女朋友,小三,小四,小五......还有你的众多基友买点吧

A星寻路的lua实现,布布扣,bubuko.com

时间: 2024-10-07 23:12:16

A星寻路的lua实现的相关文章

关于各种编程语言调用C星寻路插件的例子

DLL的调用 1.VB Public Declare Function FindPath Lib "zd/LY_Cstar_VB.dll" (ByVal StarX As Integer, ByVal StarY As Integer, ByVal StopX As Integer, ByVal StopY As Integer, ByVal Space As Integer, ByVal MapSRC As String, ByVal ClickXY As Integer, ByVa

A星寻路算法以及C++实现

A星寻路算法真是我一生接触的第一个人工智能算法了... A星寻路算法显然是用来寻路的,应用也很普遍,比如梦幻西游...算法的思路很简单,就是在bfs的基础上加了估值函数. 它的核心是 F(x) = G(x) + H(x) 和open.close列表: G(x)表示从起点到X点的消耗(或者叫移动量什么的),H(X)表示X点到终点的消耗的估值,F(x)就是两者的和值.open列表记录了可能要走的区域,close列表记录了不会再考虑的区域.我们每次都选F值最小的区域搜索,就能搜到一条到终点的最短路径,

用简单直白的方式讲解A星寻路算法原理

很多游戏特别是rts,rpg类游戏,都需要用到寻路.寻路算法有深度优先搜索(DFS),广度优先搜索(BFS),A星算法等,而A星算法是一种具备启发性策略的算法,效率是几种算法中最高的,因此也成为游戏中最常用的寻路算法. 直入正题: 在游戏设计中,地图可以划分为若干大小相同的方块区域(方格),这些方格就是寻路的基本单元. 在确定了寻路的开始点,结束点的情况下,假定每个方块都有一个F值,该值代表了在当前路线下选择走该方块的代价.而A星寻路的思路很简单:从开始点,每走一步都选择代价最小的格子走,直到达

A星寻路算法-(入门级)

你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法的文章,但是大部分都是提供给已经了解基本原理的高级开发者的. 本篇教程将从最基本的原理讲起.我们会一步步讲解A星寻路算法,幷配有很多图解和例子. 不管你使用的是什么编程语言或者操作平台,你会发现本篇教程很有帮助,因为它在非编程语言的层面上解释了算法的原理. 现在找下到达一杯咖啡因饮料和美味的零食的最

关于智能寻路算法的研究,A-Star算法拓展,B星寻路算法

B星算法的原理图: 以下是C语言的一段源码 #ifndef __ASTARPATHFINDER_H__ #define __ASTARPATHFINDER_H__ #include "cocos2d.h" USING_NS_CC; /**  * 横向移动一格的路径评分  */ static const int COST_HORIZONTAL = 20; /**  * 竖向移动一格的路径评分  */ static const int COST_VERTICAL = 5; /**  * 斜

菜鸟福利 A星寻路算法 cocos2d-x实现

这篇blog是翻译自iOS Tutorial Team的成员 Johann Fradj,他目前是一位全职的资深iOS开发工程师.他是HotApps Factory的创始人,该公司开发了AppCooker 你是否在做一款游戏的时候想实现一种寻路算法,让一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用著名的A星寻路算法来实现它! 公式表示为: f(n)=g(n)+h(n), 其中 f(n)是从初始点经由节点n到目标点的估价函数, g(n

A星寻路算法-Mind&amp;Hand(C++)

//注1:Mind & Hand,MIT校训,这里指的理解与实现(动脑也动手) //注2:博文分为两部分:(1)理解部分,为参考其他优秀博文的摘要梳理:(2)代码部分,是C++代码实现的,源码来源GitHub开源代码. 一.理解部分 我一名2018级的Postgraduate新生,路径规划算法的初学者,这里的理解主要参照资深IT博主"莫水千流"的博客原文(链接附在本部分内容的结尾处),做一些梳理和笔记摘要,加深对于A星寻路算法的理解.学习从模仿开始. (1)建立模型,简化问题

[Unity算法]A星寻路(一):基础版本

参考链接: https://www.cnblogs.com/yangyxd/articles/5447889.html 一.原理 1.将场景简化,分割为一个个正方形格子,这些格子称之为节点(node),从一个节点到另一个节点的距离称之为代价(cost).一个节点与水平/垂直方向的相邻节点的代价是1,与对角节点的代价是1.4.这里引用公式f = g + h,f表示该节点的总代价,g表示该节点与上一路径节点的代价,h表示该节点与目标节点的代价. 2.需要两个列表,开启列表(openList)和关闭列

数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇

<数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇>一文让读者了解了 HT的 2D 拓扑图组件使用,本文将对 HT 的 3D 功能做个综合性的介绍,以便初学者可快速上手使用 HT 构建例如电信网管 3D 机房应用.水务燃气 SCADA 监控应用及智能楼宇等应用场景. HT for Web 的 3D 是完全基于 WebGL 技术实现的渲染引擎,但开发者几乎不需要了解 3D 图形数学或 Shader 渲染的底层技术,只需要掌握基本的 3D 坐标系和相机  Camera 的概念,剩下需要掌