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

戴克斯特拉算法(英语:Dijkstra's algorithm),又称迪杰斯特拉算法、Dijkstra算法,是由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年发现的算法。

算法过程:

1.首先设置开始节点的成本值为0,并将开始节点放入检测列表中。

2.将检测列表中的所有点按到目标点所需的成本值排序,选择成本最小的节点作为当前节点,并将其移出检测列表。

3.将当前点周围的点中不包含在检测列表中的点加入到检测列表,将周围点加入到已检测列表中。

4.更新检测列表中的节点到当前节点的成本值。

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

代码实现:

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

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

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

        DataNode startNode = new DataNode(startPos, null);
        startNode.gCost = 0;
        frontier.Add(startNode);
        reached.Add(startPos);

        while (frontier.Count > 0)
        {
            DataNode currentNode = GetLowestgCostNode(frontier);
            frontier.Remove(currentNode);
            if (currentNode.pos == goalPos)
            {
                Debug.Log("完成!!!");
                return new DataNode(goalPos, currentNode.parent);
            }

            List<DataNode> neighbors = GetNeighbors(currentNode.pos, reached);
            foreach (DataNode neighbourNode in neighbors)
            {
                if (!frontier.Contains(neighbourNode))
                {
                    neighbourNode.parent = currentNode;
                    frontier.Add(neighbourNode);
                }
                reached.Add(neighbourNode.pos);
            }

            this.UpdateCost(frontier, currentNode);
        }

        return null;
    }

    //更新成本值
    void UpdateCost(List<DataNode> nodes, DataNode currentNode)
    {
        for (int i = 0; i < nodes.Count; i++)
        {
            int newCost = currentNode.gCost + CalculateDistanceCost(nodes[i].pos, currentNode.pos);
            if (nodes[i].gCost > newCost)
            {
                nodes[i].gCost = newCost;
            }
        }
    }

    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 < MapData.m_MapData.GetLength(1) && current.y < MapData.m_MapData.GetLength(0))
        {
            //如果是障碍物,则不能被Add
            if (MapData.m_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].gCost < lowestFCostNode.gCost)
            {
                lowestFCostNode = pathNodeList[i];
            }
        }
        return lowestFCostNode;
    }
}

结果:

参考链接:

Pathfinding in Unity - Part3: Dijkstra Algorithm Theory (youtube.com)

Pathfinding in Unity - Part4: Dijkstra Algorithm Implementation (youtube.com)

How Dijkstra's Algorithm Works (youtube.com)

戴克斯特拉算法 - 维基百科,自由的百科全书 (wikipedia.org)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/941855.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# OpenCV机器视觉:缺陷检测

在一个阳光明媚的早晨&#xff0c;阿强正准备享受他的一杯咖啡&#xff0c;突然接到了老板的电话。“阿强&#xff0c;我们的生产线出现了问题&#xff01;有几个产品的质量不合格&#xff0c;客户投诉不断&#xff01;你能不能想办法解决这个问题&#xff1f;” 阿强一听&…

模型 ADDIE(分析、设计、开发、实施、评估)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。分析、设计、开发、实施、评估教学法。 1 模型ADDIE(分析、设计、开发、实施、评估)的应用 1.1 个人IP私域运营体系构建 在个人IP私域运营领域&#xff0c;ADDIE模型被应用于构建一个系统的运营体系…

【微信小程序】3|首页搜索框 | 我的咖啡店-综合实训

首页-搜索框-跳转 引言 在微信小程序中&#xff0c;首页的搜索框是用户交互的重要入口。本文将通过“我的咖啡店”小程序的首页搜索框实现&#xff0c;详细介绍如何在微信小程序中创建和处理搜索框的交互。 1. 搜索函数实现 onClickInput函数在用户点击搜索框时触发&#x…

upload-labs-master第21关超详细教程

目录 环境配置解题思路利用漏洞 操作演示 环境配置 需要的东西 phpstudy-2018 链接&#xff1a; phpstudy-2018 提取码&#xff1a;0278 32 位 vc 9 和 11 运行库 链接&#xff1a; 运行库 提取码&#xff1a;0278 upload-labs-master 靶场 链接&#xff1a; upload-lasb-ma…

Elasticsearch:确保业务规则与语义搜索无缝协作

作者&#xff1a;来自 Elastic Kathleen DeRusso 利用查询规则与语义搜索和重新排序相结合的强大功能。 更多阅读&#xff1a; Elasticsearch 8.10 中引入查询规则 - query rules Elasticsearch 查询规则现已正式发布 - query rules 你是否知道查询规则&#xff08;query ru…

mysql联表查询

创建多个表&#xff0c;语句如下&#xff1a; CREATE DATABASE /*!32312 IF NOT EXISTS*/sg_security /*!40100 DEFAULT CHARACTER SET utf8mb4 */;USE sg_security;/*Table structure for table sys_menu */DROP TABLE IF EXISTS sys_menu;CREATE TABLE sys_menu (id bigint(2…

(Orin NX - Ubuntu 20.04)环境配置-Mid360雷达版

换源 换到阿里云的源&#xff08;不要清华的&#xff0c;有些东西会下载失败&#xff09; 如有需要&#xff0c;可以安装一下基础终端工具 sudo apt-get update sudo apt-get install terminator byobu net-tools openssh-server -y 如果有需要&#xff0c;下载deb并安装NoM…

在 Vue3 项目中安装和配置 Three.js

简介 Three.js 是一个轻量级的 WebGL 封装库&#xff0c;用于在浏览器中渲染复杂的 3D 图形。它提供了便捷的 API&#xff0c;可以快速构建 3D 场景、对象和动画。 Vue.js 是一个渐进式 JavaScript 框架&#xff0c;擅长构建用户界面。其响应式数据绑定和组件系统使得复杂的交…

【踩坑记录】C编程变量未初始化导致的程序异常

1、在编程的时候养成良好的习惯&#xff0c;定义变量以后记得给变量初始化&#xff0c;不然可能会产生一些意想不到的Bug。 2、比如下面的例子&#xff0c;如果定义的变量没有被初始化就有可能是一个随机值。如果代码少还好&#xff0c;很容易排查出来。但如果是一个比较大的项…

51c自动驾驶~合集42

我自己的原文哦~ https://blog.51cto.com/whaosoft/12888355 #DriveMM 六大数据集全部SOTA&#xff01;最新DriveMM&#xff1a;自动驾驶一体化多模态大模型&#xff08;美团&中山大学&#xff09; 近年来&#xff0c;视觉-语言数据和模型在自动驾驶领域引起了广泛关注…

CosyVoice安装过程详解

CosyVoice安装过程详解 安装过程参考官方文档 前情提要 环境&#xff1a;Windows子系统WSL下安装的Ubunt22.4python环境管理&#xff1a;MiniConda3git 1. Clone代码 $ git clone --recursive https://github.com/FunAudioLLM/CosyVoice.git # 若是submodule下载失败&…

逻辑的诗:类与对象(下)

一、初始化列表 初始化列表的使用方式是以一个冒号开始&#xff0c;接着是一个以逗号分隔的数据成员列表&#xff0c;每个“成员变量”后面跟一个放在括号中的初始化值或表达式&#xff1b; 每个成员变量在初始化列表中只能出现一次&#xff0c;语法理解上初始化列表可以认为…

什么是EMI测试,如何进行EMI测试?

什么是EMI测试&#xff1f; EMI&#xff08;Electromagnetic Interference&#xff0c;电磁干扰&#xff09;是指电子设备自身工作过程中产生的电磁波对外发射&#xff0c;从而对设备其它部分或外部其它设备造成干扰&#xff0c;属于电磁兼容的一种。实际测试中&#xff0c;主…

KingbaseES(金仓数据库)入门学习

前言 金仓是一种多进程架构&#xff0c;每一个连接到服务器的会话&#xff0c;在服务器上面都会为该会话分配进程 图形化界面管理 新建数据库名 然后新建一个模式 再创建一个表 新建一个表&#xff0c;然后设置列名 记得要保存 查询数据 也可以新建数据表&#xff0c;用命令…

Burp Suite的安装

1.安装Java 8环境: https://www.java.com/ 2.安装Burp Suite: 3.导出证书&#xff0c;安装证书&#xff1a; 不安装的话无法抓包https协议 4.设置浏览器的代理为Burp Suite: 将浏览器代理端口改为Burp Suite的默认端口 ###我个人在安装中遇到的一些问题&#xff1a; #浏览…

利用Spring Cloud Gateway Predicate优化微服务路由策略

利用Spring Cloud Gateway Predicate优化微服务路由策略 一、Predicate简介 Spring Cloud Gateway 是 Spring 生态系统中用于构建 API 网关的框架&#xff0c;它基于 Project Reactor 和 Netty 构建&#xff0c;旨在提供一种高效且灵活的方式来处理 HTTP 请求和响应。 Spring …

【Java基础面试题035】什么是Java泛型的上下界限定符?

回答重点 Java泛型的上下界限定符用于对泛型类型参数进行范围限制&#xff0c;主要有上界限定符和下届限定符。 1&#xff09;上界限定符 (? extends T)&#xff1a; 定义&#xff1a;通配符?的类型必须是T或者T的子类&#xff0c;保证集合元素一定是T或者T的子类作用&…

用套接字的UDP,TCP知道什么是HTTP吗?

文章目录 UDP和TCP七层网络架构Omnipeek抓包分析举例图片备注code参考code HTTP协议的构成 UDP和TCP UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09; 和 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09; 是…

Apache Log4j漏洞复现

所用环境 宝塔云服务器 log4j2 是Apache的⼀个java日志框架&#xff0c;我们借助它进行日志相关操作管理&#xff0c;然而在2021年末log4j2爆出了远程代码执行漏洞&#xff0c;属于严重等级的漏洞。 apache log4j通过定义每⼀条日志信息的级别能够更加细致地控制日志⽣成地过…

苍穹外卖-day05redis 缓存的学习

苍穹外卖-day05 课程内容 Redis入门Redis数据类型Redis常用命令在Java中操作Redis店铺营业状态设置 学习目标 了解Redis的作用和安装过程 掌握Redis常用的数据类型 掌握Redis常用命令的使用 能够使用Spring Data Redis相关API操作Redis 能够开发店铺营业状态功能代码 功能实…