当前位置: 首页 > article >正文

游戏AI实现-寻路算法(GBFS)

贪婪最佳优先算法是宽度优先遍历和贪婪算法结合的产物,使用启发式函数选择当前最低代价的节点,改善了宽度优先遍历需要遍历地图的大量节点来找寻结果的缺点。

算法过程:

1.首先设置开始节点的启发函数值(h)为0,并将开始节点放入检测列表中。

2.将检测列表中的所有点按启发函数值(h)排序,选择h最小的节点作为当前节点,并将其检测列表清空。

3.计算当前点周围的八个点启发函数值(h),将不包含在检测列表中的点加入到检测列表。将已检测的点添加到已检测列表。

4.重复2,3直到找到目标点。

代码实现:

算法类:

public class GBFS : FindPathAlgorithm
{
    public GBFS(int[,] mapData, int xCount, int zCount) : base(mapData, xCount, zCount){}

    public override List<Vector2Int> FindPath(Vector2Int startPos, Vector2Int goalPos)
    {
        List<Vector2Int> nodes = this.GBFSFind(startPos, goalPos);
        if (nodes == null)
        {
            Debug.LogError("寻路有误,请检查参数是否正确");
            return null;
        }
        return nodes;
    }

    List<Vector2Int> GBFSFind(Vector2Int startPos, Vector2Int goalPos)
    {
        //存储要检测的点
        List<DataNode> frontier = new List<DataNode>();
        //存储已经检测的点
        List<Vector2Int> reached = new List<Vector2Int>();

        //存储路径点
        List<Vector2Int> path = new List<Vector2Int>();
        DataNode startNode = new DataNode(startPos, null);
        startNode.hCost = 0;
        frontier.Add(startNode);
        reached.Add(startPos);

        while (frontier.Count > 0)
        {
            DataNode currentNode = GetLowestgCostNode(frontier);
            path.Add(currentNode.pos);

            if (currentNode.pos == goalPos)
            {
                return path;
            }

            frontier.Clear();

            List<DataNode> neighbors = GetNeighbors(currentNode.pos, reached);
            foreach (DataNode neighbourNode in neighbors)
            {
                neighbourNode.parent = currentNode;
                neighbourNode.hCost = CalculateDistanceCost(goalPos, neighbourNode.pos);

                if (!frontier.Contains(neighbourNode))
                {
                    frontier.Add(neighbourNode);
                }
                reached.Add(neighbourNode.pos);
            }
        }
        return path;
    }

    

    List<DataNode> GetNeighbors(Vector2Int current, List<Vector2Int> reached)
    {
        List<DataNode> neighbors = new List<DataNode>();
        for (int i = 0; i < Utils.pointDir.Count; i++)
        {
            Vector2Int neighbor = current + Utils.pointDir[i];
            if (this.IsCanAdd(neighbor, reached))
            {
                neighbors.Add(new DataNode(neighbor, null));
            }
        }
        return neighbors;
    }

    bool IsCanAdd(Vector2Int current, List<Vector2Int> reached)
    {
        if (reached.Contains(current))
            return false;
        if (current.x >= 0 && current.y >= 0 && current.x < xCount && current.y < zCount)
        {
            //如果是障碍物,则不能被Add
            if (this.mapData[current.y, current.x] == 1)
            {
                return false;
            }
            return true;
        }
        return false;
    }

    private int CalculateDistanceCost(Vector2Int a, Vector2Int b)
    {
        return Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);
    }

    private DataNode GetLowestgCostNode(List<DataNode> pathNodeList)
    {
        DataNode lowestFCostNode = pathNodeList[0];
        for (int i = 1; i < pathNodeList.Count; i++)
        {
            if (pathNodeList[i].hCost < lowestFCostNode.hCost)
            {
                lowestFCostNode = pathNodeList[i];
            }
        }
        return lowestFCostNode;
    }
}

结果:


http://www.kler.cn/a/441912.html

相关文章:

  • C++实现Point2D类 有限元基础类
  • EasyControl:首个登陆AWS Marketplace的中国MDM先锋
  • Vue进阶之旅:核心技术与页面应用实战(路由进阶)
  • STM32 学习笔记【补充】(十)硬件I2C读写MPU6050
  • 深入浅出:Go语言os包中的API使用指南
  • (十五)WebGL中gl.texImage2D函数使用详解
  • ubuntu系统版本安装docker容器
  • Electron和C/C++开发桌面应用对比
  • 数据结构实验题目剖析·下篇(PTA平台原题)
  • springboot443旅游管理系统(论文+源码)_kaic
  • 点焊机器人维修-ABB-KUKA-FANUC-YASKAWA
  • 第四篇:HTTP 的铠甲——HTTPS 的故事
  • 家中常用的路由器密码如何更改详细教程
  • flask flask-socketio创建一个网页聊天应用
  • 编辑器kindeditor
  • 优化Lua-cURL:减少网络请求延迟的实用方法
  • git从入门到实践
  • DAOBase 推出 DAO POP:赋能创作者与社区,畅享链上未来
  • linux中docker命令大全
  • SpringAop-拦截参数带注解的方法
  • “人工智能+职业本科”:VR虚拟仿真实训室的发展前景
  • ElasticSearch09-并发控制
  • 【HarmonyOS之旅】HarmonyOS开发基础知识(一)
  • CCNP_SEC_ASA 第四天作业
  • SAP PP 死循环bom,递归BOM的问题 ,再bom保存时校验
  • python练习之“用 Python 的 Pygame 库创建五子棋游戏”