flash - AS3 中的 A*(A 星)实现

标签 flash actionscript-3 artificial-intelligence path-finding

我正在为一门类(class)整理一个项目,要求我将 AI 放入 Flash AS3 中的自上而下的战术策略游戏中。

我决定使用基于节点的路径查找方法,因为游戏是基于圆形运动方案。当玩家移动一个单位时,他实际上会绘制一系列连接玩家单位将跟随的线段。

我试图通过创建一个节点列表来遍历目标节点,为我们游戏中的 AI 单元组合类似的操作。因此我使用了 Astar(生成的路径可用于创建此行)。

这是我的算法

function findShortestPath (startN:node, goalN:node)
{
 var openSet:Array = new Array();
 var closedSet:Array = new Array();
 var pathFound:Boolean = false;


 startN.g_score = 0;
 startN.h_score = distFunction(startN,goalN);
 startN.f_score = startN.h_score;
 startN.fromNode = null;
 openSet.push (startN);
 var i:int = 0


 for(i= 0; i< nodeArray.length; i++)
 {
  for(var j:int =0; j<nodeArray[0].length; j++)
  {
   if(!nodeArray[i][j].isPathable)
   {
    closedSet.push(nodeArray[i][j]);
   }
  }
 }

 while (openSet.length != 0)
 {
  var cNode:node = openSet.shift();
  if (cNode == goalN)
  {
   resolvePath (cNode);
   return true;
  }
  closedSet.push (cNode);

  for (i= 0; i < cNode.dirArray.length; i++)
  {
   var neighborNode:node = cNode.nodeArray[cNode.dirArray[i]];

   if (!(closedSet.indexOf(neighborNode) == -1))
   {
    continue;
   }

   neighborNode.fromNode = cNode;

   var tenativeg_score:Number = cNode.gscore + distFunction(neighborNode.fromNode,neighborNode);

   if (openSet.indexOf(neighborNode) == -1)
   {


    neighborNode.g_score = neighborNode.fromNode.g_score + distFunction(neighborNode,cNode);

    if (cNode.dirArray[i] >= 4)
    {
     neighborNode.g_score -= 4;
    }
    neighborNode.h_score=distFunction(neighborNode,goalN);
    neighborNode.f_score=neighborNode.g_score+neighborNode.h_score;

    insertIntoPQ (neighborNode, openSet);
     //trace(" F Score of neighbor: " + neighborNode.f_score + " H score of Neighbor: " + neighborNode.h_score + "  G_score or neighbor: " +neighborNode.g_score);
   }

   else if (tenativeg_score <= neighborNode.g_score)
   {
    neighborNode.fromNode=cNode;
    neighborNode.g_score=cNode.g_score+distFunction(neighborNode,cNode);
    if (cNode.dirArray[i]>=4)
    {
     neighborNode.g_score-=4;
    }
    neighborNode.f_score=neighborNode.g_score+neighborNode.h_score;
    openSet.splice (openSet.indexOf(neighborNode),1);
    //trace(" F Score of neighbor: " + neighborNode.f_score + " H score of Neighbor: " + neighborNode.h_score + "  G_score or neighbor: " +neighborNode.g_score);
    insertIntoPQ (neighborNode, openSet);
   }
  }
 }
 trace ("fail");
 return false;
}

现在,这个函数创建的路径通常不是最优的或完全不准确的给定目标,这通常发生在我有无法路径的节点时,并且我不太确定我现在做错了什么。

如果有人能帮助我纠正这个问题,我将不胜感激。

一些注释

我的 OpenSet 本质上是一个优先级队列,所以这就是我按成本对节点进行排序的方式。 这是该函数

function insertIntoPQ (iNode:node, pq:Array)
{
 var inserted:Boolean=true;
 var iterater:int=0;
 while (inserted)
 {
  if (iterater==pq.length)
  {
   pq.push (iNode);
   inserted=false;
  }
  else if (pq[iterater].f_score >= iNode.f_score)
  {
   pq.splice (iterater,0,iNode);
   inserted=false;
  }

  ++iterater;
 }
}

谢谢!

最佳答案

您能解释一下这些行的用途吗:

if (cNode.dirArray[i] >= 4)
{
 neighborNode.g_score -= 4;
}

A* 适用于成本始终为正的问题,即路径成本单调递增。

关于最优性,要检查的另一件事是 distFunction() 返回的值始终小于或等于达到目标的实际成本(即启发式方法必须是可接受的,因此 A* 可以保证它将找到最佳解决方案)。

我对 AS3 一无所知 - 所以我无法评论优先级队列的使用。

关于flash - AS3 中的 A*(A 星)实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2748602/

相关文章:

javascript - 在 Flash 模式下切换比特率后,VideoJS 分辨率切换器不会自动重新启动

flash - 柔性 socket 连接

javascript - POST 以打开 javascript 窗口并让 Flash 关闭窗口

machine-learning - Erlang 中的感知器在训练后不学习

actionscript-3 - AS3 麦克风隐私设置仅显示 3 个选项卡

flash - 在带有矢量的 Flash Player 10 中,为什么还要使用数组?

actionscript-3 - 将嵌套函数与事件监听器一起使用有什么问题吗?

java - AS3有类似Java的NumberFormat的类吗

Java微服务训练AI模型问题

Prolog - 运算符的优先级 - Bratko - 第 3 章