private var _closed:Array;
private var _endNode:Node;
private var _startNode:Node;
private var _straightCost:float = 1.0;
private var _diagCost:float = Mathf.Sqrt(2);
private var _heuristic:Function = manhattan; // マンハッタン法
// private var _heuristic:Function = euclidian; // ユークリッド法
// private var _heuristic:Function = diagonal; // 対角線法
private var _skewPathFlg:boolean; // 斜め移動許可
public function findPath(grid:Grid, skewFlg:boolean){
_startNode = _grid.startNode;
_endNode = _grid.endNode;
_startNode.h = _heuristic(_startNode);
_startNode.f = _startNode.g + _startNode.h;
public function search():boolean{
var node:Node = _startNode;
var startX:int = Mathf.Max(0, node.x -1);
var endX:int = Mathf.Min(_grid.numCols - 1, node.x + 1);
var startY:int = Mathf.Max(0, node.y - 1);
var endY:int = Mathf.Min(_grid.numRows - 1, node.y + 1);
for(var i:int = startX; i <= endX; i++){
for(var j:int = startY; j <= endY; j++){
var test:Node= _grid.getNode(i,j);
if(test == node || !test.walkable){
var dx:Number = node.x - test.x;
var dy:Number = node.y - test.y;
var num:float = Mathf.Sqrt(dx * dx + dy * dy) * _straightCost;
var cost:Number = _straightCost;
if(!((node.x == test.x) || (node.y == test.y))){
var g:float = node.g + cost;
var h:float = _heuristic(test);
if(isOpen(test) || isClosed(test)){
node = _open.shift() as Node;
private function BubbleSort(_nodeList:Array):Array{
for(var i:int = 0; i < _nodeList.length; i++){
for(var j:int = 0; j < _nodeList.length-1; j++) {
if(Sort(_nodeList[j], _nodeList[j+1])){
var tmp:Node = _nodeList[j+1];
_nodeList[j+1] = _nodeList[j];
private function Sort(node1:Node, node2:Node){
return node2.f - node1.f;
private function buildPath():void{
var node:Node = _endNode;
while(node != _startNode){
public function get path():Array{
private function isOpen(node:Node):boolean{
for(var i:int = 0; i < _open.length; i++){
private function isClosed(node:Node):boolean{
for(var i:int = 0; i < _closed.length; i++){
private function manhattan(node:Node):float{
return Mathf.Abs(node.x - _endNode.x) * _straightCost +
Mathf.Abs(node.y - _endNode.y) * _straightCost;
private function euclidian(node:Node):float{
var dx:Number = node.x - _endNode.x;
var dy:Number = node.y - _endNode.y;
return Mathf.Sqrt(dx * dx + dy * dy) * _straightCost;
private function diagonal(node:Node):Number{
var dx:int = Mathf.Abs(node.x - _endNode.x);
var dy:int = Mathf.Abs(node.y - _endNode.y);
var diag:int = Mathf.Min(dx, dy);
var straight:int = dx + dy;
return _diagCost * diag + _straightCost * (straight - 2 * diag);
public function get visited():Array{
return _closed.concat(_open);