//================================================================
//
// Copyright (C) 2017 Team Saluka
// All Rights Reserved
//
// Author:小妖精Balous
//
//================================================================

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Saruka
{
/// <summary>
/// A*算法
/// </summary>
public class AStar
{
private AStar() { }

/// <summary>
/// A*搜索算法
/// </summary>
/// <param name="navGrid">导航网格</param>
/// <param name="startPosition">起点坐标</param>
/// <param name="targetPosition">目标点坐标</param>
/// <param name="heuristics">启发因子</param>
/// <returns>路径</returns>
public static List<NavNode> SearchPath(NavGrid navGrid, Vector3 startPosition, Vector3 targetPosition, Heuristics heuristics)
{
if (navGrid == null)
{
Debug.LogError("你正在使用A*算法,但是没有提供导航网格!");
return null;
}

NavNode startNode = navGrid.NavNodeFromWorldPosition(startPosition);
NavNode targetNode = navGrid.NavNodeFromWorldPosition(targetPosition);

if (!targetNode.isWalkable) return null;

List<NavNode> queueNodes = new List<NavNode>();
HashSet<NavNode> evaluatedNodes = new HashSet<NavNode>();

queueNodes.Add(startNode);

while(queueNodes.Count > 0)
{
NavNode currentNode = queueNodes[0];
for (int i = 1; i < queueNodes.Count; i++)
if (queueNodes[i].fCost < currentNode.fCost || queueNodes[i].fCost == currentNode.fCost && queueNodes[i].hCost < currentNode.hCost)
currentNode = queueNodes[i];

queueNodes.Remove(currentNode);
evaluatedNodes.Add(currentNode);

//找到路径,返回路径
if (currentNode == targetNode)
{
List<NavNode> path = new List<NavNode>();
NavNode node = targetNode;
while(node != startNode)
{
path.Add(node);
node = node.parent;
}
path.Reverse();
return path;
}

foreach (NavNode neighborNode in navGrid.GetNeighborNodes(currentNode))
{
if (!neighborNode.isWalkable || evaluatedNodes.Contains(neighborNode)) continue;

float newGCostToNeighborNode = currentNode.gCost + heuristics.GetHeuristics(currentNode, neighborNode);
if (!queueNodes.Contains(neighborNode) || newGCostToNeighborNode < neighborNode.gCost)
{
if (!queueNodes.Contains(neighborNode)) queueNodes.Add(neighborNode);
neighborNode.gCost = newGCostToNeighborNode;
neighborNode.hCost = heuristics.GetHeuristics(neighborNode, targetNode);
neighborNode.parent = currentNode;
}
}
}
//找不到路径,返回null
return null;
}
}
}

小妖精的完美游戏教室——人工智能,A*算法,实现篇的更多相关文章

  1. 小妖精的完美游戏教室——人工智能,A*算法,引言

    今天也要直播魔法,求科学的! 欢迎来到小妖精Balous的完美游戏教室! 经过前两周的学习,相信米娜桑已经对状态机有所了解了呢~虽然状态机能够实现几乎所有的人工智能,但是,在实践中,你们有没有发现,自 ...

  2. 小妖精的完美游戏教室——人工智能,A*算法,启发因子篇

    //================================================================//// Copyright (C) 2017 Team Saluk ...

  3. 小妖精的完美游戏教室——人工智能,A*算法,导航网络篇

    //================================================================//// Copyright (C) 2017 Team Saluk ...

  4. 小妖精的完美游戏教室——人工智能,A*算法,结点篇

    //================================================================//// Copyright (C) 2017 Team Saluk ...

  5. 小妖精的完美游戏教室——buff系统

    作者:小妖精Balous,未经作者允许,任何个人与单位不得将此源代码用于商业化项目 #region buff /// <summary> /// 是否魔法免疫,魔法免疫的生物不会受到除自己 ...

  6. 小妖精的完美游戏教室——东方PROJECT,同人,墙

    //================================================================//// Copyright (C) 东方同人社// All Rig ...

  7. 小妖精的完美游戏教室——东方PROJECT,同人,符卡系统

    //================================================================//// Copyright (C) 东方同人社// All Rig ...

  8. 小妖精的完美游戏教室——东方PROJECT,同人,th12灵梦A

    ╮(╯▽╰)╭没办法,小妖精Balous也很讨厌学院化的教育呀,一点意义都没有. 这次就上传东方地灵殿灵梦A逻辑部分的核心代码吧,估计连老师都看不懂.动画部分的代码就不放上来了. //======== ...

  9. 小妖精的完美游戏教室——东方PROJECT,同人,子机

    //================================================================//// Copyright (C)// All Rights Re ...

随机推荐

  1. go报错unimplemented: 64-bit mode not compiled in与mingw 64位安装报错ERROR res已解决

    问题一:cc1.exe: sorry, unimplemented: 64-bit mode not compiled in 参考:https://www.cnblogs.com/lesroad/p/ ...

  2. 网络拓扑_华三H3C的路由器+交换机

    最近在弄公司网络,目前的拓扑图长这样:点击查看网络拓扑图 华三的路由器和交换机都可以通过Console口进行配置,如下: 用SecureCRT.或者putty.或者windows的超级终端,打开ser ...

  3. Django知识总结(一)

    壹 ● 有关http协议 一 ● 全称 超文本传输协议(HyperText Transfer Protocol) 二 ● 协议 双方遵循的规范 http协议是属于应用层的协议(还有ftp, smtp等 ...

  4. Java互联网应用和企业级应用的区别

    企业级应用是为了满足企业日常运营所产生的IT应用,其目的是满足企业自己,对交付厂家而言,俗称2B业务:互联网应用则是面向个人用户,俗称2C业务.就个人经验,企业应用主要关注业务服务的能力,针对该企业的 ...

  5. Java小目标

    看了智联.内推和拉勾这三个招聘网站,除了智联外,其它招聘网站对岗位要求的描述都比较专业.大部分公司都要求会一些HTML5.JS,SSH等前端技术,所有公司都要求会使用Oracle.MySQL等数据库, ...

  6. JavaScript js 引入CDN 不生效 注意事项

    [博客园cnblogs笔者m-yb原创,转载请加本文博客链接,笔者github: https://github.com/mayangbo666,公众号aandb7,QQ群927113708]https ...

  7. redis应用--位图

    在我们平时开发过程中,会有一些 bool 型数据需要存取,比如用户一年的签到记录,签了是 1,没签是 0,要记录 365 天.如果使用普通的 key/value,每个用户要记录 365 个,当用户上亿 ...

  8. 初识html与css

    ---恢复内容开始--- PS应用量尺寸w.h- 操作方式: 窗口,信息,右上角面板选项,标尺单位,像素切图- 操作方式: 切片工具, 文件 ,另存为web所有格式,jpeg,存储,切片:选中的切片, ...

  9. Win10调整MTU值

    VPN连接后出现可以ping通google.com但是网页打不开的情况,需要修改MTU值,方法如下:用管理员身份运行cmd列出当前各网络的mtu值C:\Windows\system32>nets ...

  10. node.js学习二---------------------同步API和异步API的区别

    /** * node.js大部分api都有同步的方法,同步方法名后面都会带有Sync,js编译的时候,同步代码会立即执行,异步代码会先存到异步池中,等同步代码执行完后它才会执行异步:不会阻塞线程,没有 ...