A星算法javascript实现

赶休息时间写的 , 回头重构加说明.....

/**
 *
 * @author liujian
 * @date 2014-7-3
 */
dn.OpenNode = cc.Class.extend({
    ctor:function(pos){
        // var openNode ={};
        // this.endPos=end;
        // this.starPos =start;
        //F=H+G;
        this.F=65536;// (this.endPos.x - this.starPos.x) + (this.endPos.y - this.starPos.y);
        this.G=65536;
        this.x=0;//this.starPos.x;
        this.y=0;//this.starPos.y;
        this.num =0;// this.starPos.x*11+this.starPos.y;
        this.father = undefined;
        if(pos)
            this.setPos(pos);
    },
    setPos:function( pos){
        this.x=pos.x;
        this.y=pos.y;
        this.num = pos.x*11+pos.y;
    },
    setF:function( end){

        this.F= this.G+(end.x - this.x) + (end.y - this.y);
    },
    setG:function(G){
        this.G=G;
    }
});

//找出最小并返回下标
Array.prototype.min = function(){
    var temp=65536;
    var tempI=0;
    if(this.length ==0)
    {
        return null;
    }
    for(var i=1 ; i<this.length ;i++)
    {
        if(this[i].F<temp)
        {
            temp = this[i].F;
            tempI = i;
        }
    }
    return tempI;
};
//找出是否存在num相同的元素
Array.prototype.findNumIsIN = function(num){
    for(var i=0; i<this.length ;i++)
    {
        dn.log(this.length+"findNumIsIN : " +JSON.stringify(this[i]));

        if(this[i].num ==num)
            return i;
    }
    return -1;
};
Array.prototype.findNumIsINclose = function(num){
    for(var i=0; i<this.length ;i++)
    {
        dn.log(this.length+"findNumIsINclose : " +JSON.stringify(this[i]));
        dn.log("关闭队列中 : "+num);
        if(this[i].num ==num)
            return i;
    }
    return -1;
};
//重置num相同的元素的F 和 G
Array.prototype.resetFGWithNum = function(temp){
    for(var i=0; i<this.length ;i++)
    {
        if(this[i].num ==temp.num)
        {
            this[i].G=temp.G;
            this.setF();
        }

    }


};
dn.TestCtrl = ty.BaseAnimController.extend({

//深拷贝对象
    cloneAll :function (Obj){//fromObj,toObj){

        var buf = {};  //创建一个空对象
        for (var k in Obj) {  //为这个对象添加新的属性
            if( typeof this[k] === "object" )
                buf[k] = this.cloneAll(Obj[k]);
            else
                buf[k] = Obj[k];
        }
        return buf;


//        for(var ii in fromObj){
//
//            if(typeof(ii) == "object"){
//                toObj={};
//                this.cloneAll(fromObj,toObj);
//                continue;
//            }
//            dn.log("cloneAllinsidebegin + " + JSON.stringify(fromObj));
//            toObj = fromObj;
//            dn.log("cloneAllinsideend + " + JSON.stringify(toObj));
//        }
    },
    ctor: function () {
        dn.log("construction start");
        this._super();

        this.map= [ [0,0,0,0,0,0,0,0,0,0,0],
            [0,1,1,0,1,1,1,1,1,1,0],
            [0,1,1,0,1,1,1,1,1,1,0],
            [0,1,1,0,1,1,1,1,1,1,0],
            [0,1,1,0,1,1,1,1,1,1,0],
            [0,1,1,0,1,1,1,1,1,1,0],
            [0,1,1,0,1,1,1,1,1,1,0],
            [0,1,1,1,1,1,1,1,1,1,0],
            [0,1,1,1,1,1,1,1,1,1,0],
            [0,0,0,0,0,0,0,0,0,0,0]//11 * 10
        ];
        this.open = [];


        this.close =[];
        this.starPos={};
        this.starPos.x =1;
        this.starPos.y =1;
        this.endPos={};
        this.endPos.x =8;
        this.endPos.y =6;

        var openNode =new dn.OpenNode(this.starPos);
        openNode.setG(0);
        openNode.setF(this.endPos);
        this.open.push(openNode);//open里加入第一个元素
    },

    init:function (ccbiFileName) {
        this._super(ccbiFileName);

    },

    onLoad: function () {
        this._super();
        //结算弹窗子控件
        this.gameWinCtrl = tm.controllerHelper.createUIWithFile(tm.DNGameWinCtrl, 'DnTableGameWin', this.view.ccbRootNode, 0);
        this.gameWinCtrl.setParentController(this);
        this.gameWinCtrl.showWin();
        tm.SPRITE_FRAME_CACHE.addSpriteFrames("games/douniu/img/common.plist");
        for(var i=0 ; i<this.map.length ; i++)//map 素材
        {
            for(var j=0 ; j<this.map[i].length ; j++)
            {
                this["mapNode" +this.map[i].length*i+j] =cc.Sprite.createWithSpriteFrame(tm.SPRITE_FRAME_CACHE.getSpriteFrame("br_guanbi.png"));
                this["mapNode" +this.map[i].length*i+j].setPosition(cc.p(  j*35+50,i*35+50));
                this.view.ccbRootNode.addChild(this["mapNode" +this.map[i].length*i+j]);
                if(this.map[i][j]==0)
                {
                    this["mapNode" +this.map[i].length*i+j].setOpacity(190);
                }
            }
        }
        this["mapNode" +this.map[0].length*this.starPos.x+this.starPos.y].setOpacity(10);//start 
        this["mapNode" +this.map[0].length*this.endPos.x+this.endPos.y].setOpacity(10);//end
        this.findRoad(this.starPos , this.endPos);
    },
    //搜索路径
    findRoad :function(start , end){
        dn.log("find road start");
        var current={};

        current.x = start.x;
        current.y = start.y;
//        this.open.push(current);
        var k=0;
        while(1)//搜索主循环
        {
            dn.log("循环一次 : " +k++);
            dn.log("this.open.length : " +this.open.length);
            var tempI = this.open.min();//取最小值 F
            if(this.open[tempI].x == this.endPos.x &&this.open[tempI].y == this.endPos.y)
            {
                this.father =this.open[tempI];
                while(this.father)
                {

                    this["mapNode" +this.map[0].length*this.father.x+this.father.y].setOpacity(10);
                    this.father=this.father.father;
                }
                dn.log("OK!!!!!!!!!!!!!!!!!!!");
                break;
            }
            dn.log("tempI : " + tempI);
            var temp =new dn.OpenNode();
            temp=this.cloneAll( this.open[tempI] );
            dn.log("cloneAllbegin : " +JSON.stringify(this.open[tempI]));
            dn.log("cloneAllend : " +JSON.stringify(temp));
            this.open.splice(tempI,1);
            if(temp ==null)
            {
                dn.log("open is null");
                break;
            }
            dn.log("放入关闭数组中 : " +JSON.stringify(temp));
            this.close.push(temp);//放入关闭数组中
            this.findLinJu(temp);//找当前节点的邻居们

        }
//        if(current.x==end.x && current.y==end.y)
//        {
//
//        }
    },
    //找邻居
    findLinJu:function( Otemp){
        var temp =new dn.OpenNode();
        currentTempNode=this.cloneAll(Otemp);
        var currentTempNode=new dn.OpenNode();
        currentTempNode=this.cloneAll(Otemp);
        dn.log("找邻居开始 : " +JSON.stringify(currentTempNode));
        for(var i=0 ;i<8 ;i++)//查找邻居们是否在open
        {
            switch (i){
                case 0:{
                    temp.x=currentTempNode.x-1;
                    temp.y=currentTempNode.y-1;
                    break;
                }
                case 1:{
                    temp.x=currentTempNode.x-1;
                    // temp.y-=1;
                    break;
                }
                case 2:{
                    temp.x=currentTempNode.x-1;
                    temp.y=currentTempNode.y+1;
                    break;
                }
                case 3:{
                    // temp.x-=1;
                    temp.y=currentTempNode.y+1;
                    break;
                }
                case 4:{
                    temp.x=currentTempNode.x+1;
                    temp.y=currentTempNode.y+1;
                    break;
                }
                case 5:{
                    temp.x=currentTempNode.x+1;
                    // temp.y-=1;
                    break;
                }
                case 6:{
                    temp.x=currentTempNode.x+1;
                    temp.y=currentTempNode.y-1;
                    break;
                }
                case 7:{
                    // temp.x+=1;
                    temp.y=currentTempNode.y-1;
                    break;
                }
            }
            temp.num=temp.x*11+temp.y;
            dn.log("linju + " +temp.x +"linju.y : "+temp.y);
            if(this.map[temp.x][temp.y] ==0)
            {
                dn.log("不可通行 " +"linju + " +temp.x +"linju.y : "+temp.y);
                continue;
            }//不可通行
            dn.log("检查关闭队列 : " );
            if(-1!=this.close.findNumIsINclose(temp.num)) {
                dn.log("加入关闭队列 " +"linju + " +temp.x +"linju.y : "+temp.y +"linju.num : " +temp.num);
                continue;
            }//
            var tempI = this.open.findNumIsIN(temp.num);
            if(tempI != -1) {
                dn.log("is in open : " +temp.num);
                if(currentTempNode.F+10 <temp.F)
                {
                    //temp.G+=10;
                    this.open[tempI].G= currentTempNode.G+10;//.resetFGWithNum(temp);
                    this.open[tempI].setF(this.endPos);
                    this.open[tempI].father=currentTempNode;
//                    this.cloneAll( currentTempNode,);

                }
                continue;
            }
            dn.log("加入一个新邻居" + JSON.stringify(temp));
            var newNode = new dn.OpenNode(temp);
            newNode.setG(temp.G+10);
            newNode.setF(this.endPos);
            this.open.push(newNode);

        }
    },
});



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值