javascript 回溯寻路算法

最近一直在手游 caveboy escape(安卓上,不知道IOS上有没有,可以下来玩玩)。

游戏规则是,在5x5的矩阵,从最下面的起点,每个颜色走三步,到达最上面的重点。

想写个js版本。碰到第一个问题就是,矩阵布局,寻路算法。

网上搜了下只有 PathFinding.js 带有的著名的 A*寻路法(自己百度)

源码:

https://github.com/qiao/PathFinding.js

DEMO:

http://qiao.github.io/PathFinding.js/visual/

 

但是,做个框架和我的业务不符。PathFinding框架里都是找出最捷径,而我要的是随机路线。

百度了一下,木有雷同或者写的不好,只好自己造轮子。

思前想后,只能用最基本的回溯寻路法,将在一个5x5的矩阵中,随机出不同起点,终点,随机找出不同路线,存储文件,做成不同关卡。

下面附上自己写的‘回溯寻路法’源码:

 

util.js

 

define(['node'], function(node) {

    var Util = {

        random: function (max){

            return Math.floor(Math.random() * ( max + 1));

        },

        logP: function (point,info){

            var t = ' x,y:  '+ point.x+' '+point.y;

            if(info){

                t= info + t;

            }

            console.log(t)

        }

    }

    

    return Util;

})

 

node.js

 

define([], function() {

    var node = function (x,y){

        this.x = x;

        this.y = y;

        this.walkable = true;

    }

    

    return node;

})

 

grid.js

 

define(['node','util'], function(node,util) {

    var grid = function (option){

        this.width = option.width;

        this.height = option.height;

        this.grid = [];

        this._init();

    }

    

    grid.prototype = {

        _init: function (){

            for(var i=0; i<this.width;i++){

                this.grid[i] = [];

                for(var j=0;j<this.height;j++){

                    this.grid[i][j] = new node(i,j);

                }

            }

        },

        getPointAt: function (x,y){

            return this.grid[x][y];

        },

        isInGrid: function (x,y){

            return (x >= 0 && x < this.width) && (y >= 0 && y < this.height);

        },

        isWorkAble: function (x,y){

            return this.isInGrid(x,y) && this.getPointAt(x,y).walkable

        },

        getRandomNeighbor: function (point){

            var neighbors = this.getNeighbors(point);

            var r = util.random(neighbors.length - 1);

            return neighbors[r];

        },

        getNeighbors: function (point){

            var p1,p2,p3,p4;

            var neighbors = [];

            

            if(this.isWorkAble(point.x-1,point.y)){

                p1 = this.getPointAt(point.x-1,point.y);

                neighbors.push(p1);

            }

            if(this.isWorkAble(point.x+1,point.y)){

                p2 = this.getPointAt(point.x+1,point.y);

                neighbors.push(p2);

            }

            if(this.isWorkAble(point.x,point.y+1)){

                p3 = this.getPointAt(point.x,point.y+1);

                neighbors.push(p3);

            }

            if(this.isWorkAble(point.x,point.y-1)){

                p4 = this.getPointAt(point.x,point.y-1);

                neighbors.push(p4);

            }

            return neighbors;

        }

    }

    

    return grid;

})

 

rbpathfinding.js

 

define(['util'], function(util) {

    var rbp = function (){

        this.grid = null;

        this.path = [];

    }



    rbp.prototype = {

        getPath: function (ox,oy,dx,dy,grid){

            this.grid = grid;

            var startPoint = grid.getPointAt(ox,oy);//起始点

            startPoint.walkable = false;

            var endPoint = grid.getPointAt(dx,dy);//终点

            step = grid.width * grid.height * 2;//最多走这些步数

            var next = startPoint;

            while(step){

                step--;

         

                next = findNext(next);

                

                if(next == 0){

                    var last = this.path.splice(-1);

                    last[0].walkable = false;

                    next = this.path[this.path.length - 1];//回溯

                }else{

                    next.walkable = false;

                    this.path.push(next);

                    if(next == endPoint){//判断到达

                        console.log('finish ``````');

                        var t= '';

                        for(var i in this.path){

                            t += '[' + this.path[i].x + ',' + this.path[i].y+'] ';

                        }

                        console.log(t);

                        step = 0;//结束

                    }

                }

            }

            

            return this.path;

            

            function findNext(point){

                var neighbor = grid.getRandomNeighbor(point);

                

                if(neighbor){

                    util.logP(neighbor);

                    return neighbor;

                }else{

                    console.log('not found');

                    return 0;

                }

            }

        },

        

    }

    

    return rbp;

})

 

 

 

main.js

 

require.config({

    paths: {

        pathfinding: 'pathfinding',

        node: 'node',

        grid: 'grid'

    }

});



require(['node','grid','rbpathfinding','util'], function(node,grid,rbp,util) {

    var map = {

        width: 5,

        height: 5

    }

    var grid = new grid(map)

    

    var startNode = {

        x: util.random(map.width -1 ),

        y: 0

    }

    

    var endNode = {

        x: util.random(map.width - 1),

        y: map.height - 1

    }

    

    util.logP(startNode,'Start Point');

    util.logP(endNode,'End Point');

  

    //调用

    var rbp = new rbp();

    var path = rbp.getPath(startNode.x,startNode.y,endNode.x,endNode.y,grid);

    

    console.log(path);

    //Start Point x,y:  4 0 VM10885:11

    //End Point x,y:  3 4 

    //Path [3,0] [2,0] [2,1] [1,1] [1,0] [0,0] [0,1] [0,2] [1,2] [2,2] [2,3] [3,3] [4,3] [4,4] [3,4]  

})

 

   至此,有了做个回溯算法,游戏可以说做出大半了。

  

你可能感兴趣的:(JavaScript)