2

我正在爲一個需要我將AI放在Flash AS3中的自上而下的戰術策略遊戲中的課程組建一個項目。AS3中的A *(A-star)實現

我決定使用基於節點的路徑查找方法,因爲遊戲基於循環移動方案。當一個玩家移動一個單位時,他基本上會畫出一系列連接玩家單位的連線。

我想通過創建一個節點列表來遍歷目標節點,嘗試在我們的遊戲中爲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; 
} 
} 

謝謝!

回答

2

你能不能解釋一下什麼是這些行的目的:

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

A *對於其中成本始終爲正,即路徑成本是單調遞增的問題。

另一件需要檢查的問題是關於最優性,distFunction()總是返回一個小於或等於達到目標的實際成本的值(即啓發式要求被允許,所以A *可以保證它將找到最佳解決方案)。

我對AS3一無所知 - 所以我不能評論優先級隊列的使用情況。