• 2008-12-16

    基于哈希表数据源的A星寻路算法 - [as 3.0]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://wxsr.blogbus.com/logs/32550422.html

    在这贴的代码是为了有需要的人学习而不是 提供源码给别人用的所以大家见谅。

     package astart.interfaces
    {
        public interface IAstartSourceMode
        {
            /**
                 *对应数据源的方格的id
                 * @return
                 *
                 */            
                function get keyPoint():Point
                /**
                 *对应数据源的方格的id 的字符串形式(如 var keyPoint=new Point(x,y),则key应为 "x,y" )
                 * @return
                 *
                 */            
                function get key():String
                /**
                 * 对应数据源的方格的类型 0为非可走区域
                 * @return
                 *
                 */            
                function get type():int
            
        }
    }

     //////////////////////////////////////////////////////

    package astart.interfaces
    {
        import flash.geom.Point;
        public interface IAstarData
        {
            function get key():String
            function get keyPoint():Point
            function get G():int;
            function get F():int;
            function get parent():IAstarData
            function get type():int
            function set key(val:String):void
            function set keyPoint(val:Point):void
            function set G(val:int):void;
            function set F(val:int):void;
            function set parent(val:IAstarData):void
            function set type(val:int):void
        }
    }

    ////////////////////////////////////////////////////////////////////////

    package astart.interfaces
    {
        import flash.geom.Point;
       
        public interface IAstar
        {
             /**
              * 返回结果路径
              * @param source 以IAstartSourceMode接口所实现的vo类的实例为键值的数组对象 查询key必须为                     *IAstartSourceMode接口所实现的vo类的key属性对应
              * @param startPoint 开始点,如:new Point (1,2)队形数据源
              * @param endPoint  结束点  如:new Point(4,5)对应数据源
              * @return
              *
              */
            function getPath(source:Array,startPoint:Point,endPoint:Point):Array
        }
    }

     

    ///////////////// /////以上是接口文件////////////////////////////////


     

     


    收藏到:Del.icio.us




    评论

  • 值得学习
  • 晕倒
    看不懂哦
  • 支持
  • 可以写算法思想吗?
    感觉看100行代码不如看一句话描述~^_^
    zzz | 发表于2009-04-30 11:39:10


    re:我这个算法的基本思想还是遵循a星的思想的,你想了解下可以自己收索下,但我这个算法的特点在于它不关心数据的分布或形状,它只按实际大小计算,而且查询修改速度都比2维数组的处理要快,你可以这么理解,有1000个格子,它只关心这1000个格子的这个数目,而不像一边的对形状,跟分布都有要求~就是说1000个格子他可以是任意形状~
  • 可以写算法思想吗?
    感觉看100行代码不如看一句话描述~^_^
  • //////////////////////////////下边是具体实现//////////////////////////////////////////

    /**
    *实现数据源以对象形式的A星寻路
    * by 吾系衰人/wxsr
    *@2008
    */
    package astart.actualize
    {
    import flash.geom.Point;
    import astart.interfaces.IAstartSourceMode
    import astart.interfaces.IAstart

    public class Astar implements IAstar
    {
    private static const COST_STRAIGHT :int=10;
    private static const COST_DIAGONAL :int=14;
    private static const DIR_TC:String='tc';
    private static const DIR_CT:String='ct';
    private static const DIR_CR:String='cr';
    private static const DIR_BC:String='bc';
    private var nonce:AstarData;
    private var isFinish:Boolean;
    private var G:int;

    private var source:Array;
    private var startPoint:Point
    private var endPoint:Point

    private var colsePath:Array;
    private var colseArray:Array;
    private var openPath:Array;
    private var openArray:Array;
    private var pathArray:Array
    private var canTL:Boolean;
    private var canTR:Boolean;
    private var canBL:Boolean;
    private var canBR:Boolean;

    public function Astar()
    {

    }
    /**
    *寻路
    * @param source 数据源
    * @param startPoint 当前开始
    * @param endPoint
    * @param cell
    * @return
    *
    */

    public function getPath(source:Array,startPoint:Point,endPoint:Point):Array
    {
    reSet()
    this.startPoint=startPoint
    this.endPoint=endPoint
    this.source=source
    this.nonce==null?this.nonce=new AstarData(0,0,this.startPoint):'';
    this.nonce.parent=this.nonce;
    this.colseArray.push({F:this.nonce.F,data:this.nonce})
    this.colsePath[this.nonce.key]=this.colseArray[0]
    while(this.isFinish){
    getScale9Grid(source,this.nonce,this.endPoint)
    }

    return cleanArray()
    }
    //评分
    private function getDis(point:Point,endPoint:Point):int
    {
    var dix:int=Math.abs(endPoint.x-point.x)
    var diy:int=Math.abs(endPoint.y-point.y)
    return Math.abs(dix+diy)
    }
    //获取当前评分最优对象垂直线对象
    private function stratght(tar:IAstartSourceMode,endPoint:Point,type:String):void
    {
    if(tar!=null){
    if(tar.type>0){
    var costH:int=getDis(tar.keyPoint,endPoint)*10;
    var costG:int=COST_STRAIGHT+G
    var data:AstarData=new AstarData(costG,(costG+costH),tar.keyPoint);
    data.parent==null?data.parent=this.nonce:''
    if(openPath[tar.key]==null&&this.colsePath[tar.key]==null){

    openPath[tar.key]=data
    this.openArray.push({F:data.F,data:data})

    }else if(openPath[tar.key]!=null)
    {
    var old:AstarData=openPath[tar.key]
    data.F<old.F?openPath[tar.key]=data:''

    }

    }else {
    if(type==DIR_TC)
    {
    this.canTL=false;
    this.canTR=false;
    }else if(type==DIR_CT)
    {
    this.canTL=false;
    this.canBL=false;
    }else if(type==DIR_CR)
    {
    this.canTR=false;
    this.canBR=false;
    }else if(type==DIR_BC)
    {
    this.canBL=false;
    this.canBR=false;
    }
    }
    }

    }
    //获取当前评分最优对象对角线对象
    private function diagonal(tar:IAstartSourceMode,endPoint:Point,can:Boolean):void
    {
    if(can&&tar!=null)
    {
    if(tar.type>0)
    {
    var costH:int=getDis(tar.keyPoint,endPoint)*10;
    var costG:int=COST_DIAGONAL+G
    var data:AstarData=new AstarData(costG,costG+costH,tar.keyPoint);
    data.parent==null?data.parent=this.nonce:''
    if(openPath[tar.key]==null&&colsePath[tar.key]==null)
    {
    openPath[tar.key]=data
    this.openArray.push({F:data.F,data:data})
    }else if(openPath[tar.key]!=null){

    var old:AstarData=openPath[tar.key]
    data.F<old.F?openPath[tar.key]=data:''

    }
    }
    }

    }
    //获取当前评分最佳对象
    private function getScale9Grid(source:Array,data:AstarData,endPoint:Point):void
    {
    this.canBL=true;
    this.canBR=true;
    this.canTL=true;
    this.canTR=true;

    var x:int=data.keyPoint.x
    var y:int=data.keyPoint.y

    var tc:IAstartSourceMode=source[x+','+(y-1)];
    var ct:IAstartSourceMode=source[(x-1)+','+y]
    var cr:IAstartSourceMode=source[(x+1)+','+y]
    var bc:IAstartSourceMode=source[x+','+(y+1)]

    var tl:IAstartSourceMode=source[(x-1)+','+(y-1)];
    var tr:IAstartSourceMode=source[(x+1)+','+(y-1)];
    var bl:IAstartSourceMode=source[(x-1)+','+(y+1)]
    var br:IAstartSourceMode=source[(x+1)+','+(y+1)]



    stratght(tc,endPoint,DIR_TC)
    stratght(ct,endPoint,DIR_CT)
    stratght(cr,endPoint,DIR_CR)
    stratght(bc,endPoint,DIR_BC)

    diagonal(tl,endPoint,canTL)
    diagonal(tr,endPoint,canTR)
    diagonal(bl,endPoint,canBL)
    diagonal(br,endPoint,canBR)

    openArray.sortOn('F',Array.NUMERIC);

    if(this.openArray[0]==null)
    {
    this.isFinish=false ;
    return
    }else {
    this.nonce=this.openArray[0].data;
    delete this.openPath[this.openArray[0].key];
    this.openArray.shift()

    if(this.colsePath[this.nonce.key]==null)
    {
    this.colseArray.unshift({F:this.nonce.F,data:this.nonce})
    this.colsePath[this.nonce.key]=this.colseArray[0]
    }
    this.G=this.nonce.G
    }
    if(this.nonce.keyPoint.x==endPoint.x&&this.nonce.keyPoint.y==endPoint.y)
    {
    this.isFinish=false;
    }
    return
    }
    //返回最后路径
    private function cleanArray():Array
    {

    this.pathArray=new Array

    var key:String=String(this.endPoint.x+','+this.endPoint.y);

    if(this.colsePath[key]!=null){
    this.pathArray.push(this.colsePath[key].data.parent.keyPoint);
    this.pathArray.push(this.colsePath[key].data.keyPoint);

    while(true){
    key=String(this.colsePath[key].data.parent.key);

    if(key==String(this.startPoint.x+','+this.startPoint.y))break;

    var item:IAstartSourceMode=this.source[key]
    this.pathArray.unshift(this.colsePath[key].data.parent.keyPoint)
    }
    }
    return this.pathArray
    }

    // 初始化数组
    private function reSet() : void
    {
    this.pathArray=[]
    this.source = [];
    this.colsePath = [];
    this.colseArray=[]
    this.openPath = [];
    this.openArray=[]
    this.G=0
    this.nonce=null
    this.canTL=true
    this.canTR=true
    this.canBL=true
    this.canBR=true
    this.isFinish=true
    }
    }
    }



    ////////////////////////////////////////////////////////////////////////////////////////////

    /**
    *A星寻路的数据存储单位
    * by 吾系衰人/wxsr
    *@2008
    */
    package astart.AstarData
    {
    import astar.interfaces.IAstarData;

    public class AstarData implements IAstarData
    {
    private var _key:String
    private var _keyPoint:Point
    private var _G:int=0;
    private var _F:int=0;
    private var _parent:AstarData
    private var _type:int
    public function AstarData(g:int,f:int,keyPoint:Point)
    {
    this._G=g;
    this.F=f;
    this.keyPoint=keyPoint
    }

    public function get key():String
    {
    return this._key;
    }

    public function get keyPoint():Point
    {
    return this._keyPoint;
    }

    public function get G():int
    {
    return this._G;
    }

    public function get F():int
    {
    return this._F;
    }

    public function get parent():IAstarData
    {
    return this._parent;
    }

    public function get type():int
    {
    return this._type;
    }

    public function set key(val:String):void
    {
    this._key=val
    }

    public function set keyPoint(val:Point):void
    {
    this.keyPoint=val
    }

    public function set G(val:int):void
    {
    this._G=val
    }

    public function set F(val:int):void
    {
    this._F=val
    }

    public function set parent(val:IAstarData):void
    {
    this._parent=val
    }

    public function set type(val:int):void
    {
    this._type=val
    }

    }
    }

    /////////////////////////////////////////////////////////////////////////

    /**
    *A星寻路的哈希表数据源的查询key为该类属性的key值,键值为该对象实例
    *如:source:Array=[]
    *source["1,2"]=new AstartSourceMode (new keyPoint(1,2),1);
    *source["-1,-2"]=new AstartSourceMode (new keyPoint(-1,-2),1)
    *source["2,-3"]=new AstartSourceMode (new keyPoint(2,-3),0)
    *然后以此source为参数 传递给Astart
    * by 吾系衰人/wxsr
    *@2008
    */
    package astar.actualize
    {
    import flash.geom.Point;
    import astar.interfaces.IAstartSourceMode;
    public class AstartSourceMode implements IAstartSourceMode
    {
    private var _keyPoint:Point
    private var _key:String
    private var _type:int
    public function AstartSourceMode(keyPoint:Point,type:int)
    {
    this._keyPoint=keyPoint
    this._key=String(this._keyPoint.x+','+this._keyPoint.y)
    this._type=type
    }

    public function get keyPoint():Point
    {
    return _keyPoint;
    }

    public function get key():String
    {
    return this._key;
    }

    public function get type():int
    {
    return this._type;
    }

    }
    }