muxrwc

厕所专栏

王辰ID:muxrwc
15112次访问,排名7157(-1)好友76人,关注者85
codeing,玩,睡,画画(很小的时候)
muxrwc的文章
原创 51 篇
翻译 1 篇
转载 12 篇
评论 25 篇
muxrwc的公告
昂。。。偶文采不好。。。。写文章好累,偶会慢慢更新滴。。。:D
最近评论
dh20156:确实太BT了。IE不严谨吧
s_liangchao1s:学习
cloudgamer:不错
dead_of_winter:对了 你给我看那个寻路 根本就是错的嘛 找不到最优路径的......
muxrwc:@.@数学不好的飘走...
文章分类
收藏
    相册
    WC
    喜欢的图片
    DHTML精英俱乐部-伟大的前辈们。。。
    伟大的aoao前辈。。。
    伟大的EMU前辈。。。
    伟大的FS前辈。。。
    伟大的JK前辈。。。
    伟大的winter同学...(RSS)
    伟大的兔老师。。。。
    伟大的月影大姐姐。。。
    伟大的水水前辈。。。
    伟大的石头君。。。
    伟大的顺子前辈。。。
    伟大的飘飘前辈。。。
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 JavaScript实现AStar算法收藏

    新一篇: with配合eval可改变function[[scope]]

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <title>A-Star</title>
    <script type="text/javascript">
    /*
    蛮好玩的东西。。。
    严重感谢winter。。。
    */

    var AStar = function () {
        this.tmin = -1;   //上部搜索最小值(不包括)
        this.rmax = -1;   //右部搜索最大值(不包括)
        this.bmax = -1;   //下部搜索最大值(不包括)
        this.lmin = -1;   //左部搜索最小值(不包括)
        this.initialize();
    };

    AStar.prototype = {

        constructor : AStar
       
        , pointSource : function () {
        //获取点对象构造的引用
            return this.constructor.Point;
        }
       
        , euclidean : function (a, b) {
            with (Math) { return round(10 * sqrt(pow(a.X - b.X, 2) + pow(a.Y - b.Y, 2))); }
        }
       
        , manhattan : function (a, b) {
            with (Math) { return abs(a.X - b.X) + abs(a.Y - b.Y); }
        }
       
        , initialize : function () {
        //初始化参数
            this.open = [];   //open表
            this.close = [];  //close表
            this.maps = {};  //已经发现点组
        }
       
        , makeID : function (x, y, limit) {
        //创造ID
            return x + y * limit;
        }
       
        , getMinNode : function () {
        //获取最佳节点
            var i = 1, o = this.open, l = o.length, min = i - 1, max = o[0].F, t = null;

            for (; i < l ; i ++) {
                t = o[i];
                if (t.F < max) { max = t.F, min = i; }
            }
            t = o[min], o[min] = o[l - 1], o.pop();

            return t;
        }
       
        , getNodes : function (node) {
        //获取子节点
            var map = this.Map, tmin = this.tmin, rmax = this.rmax, bmax = this.bmax, lmin = this.lmin, nodes = []
                , x = node.X, y = node.Y, t = y - 1, r = x + 1, b = y + 1, l = x - 1
                , _t = t > tmin && (map[t][x] === 0)
                , _r = r < rmax && (map[y][r] === 0)
                , _b = b < bmax && (map[b][x] === 0)
                , _l = l > lmin && (map[y][l] === 0), i = 0;
           
            if (_t) {
                nodes[i++] = [x, t];
                if (_l && (map[t][l] === 0)) nodes[i++] = [l, t];
                if (_r && (map[t][r] === 0)) nodes[i++] = [r, t];
            }
           
            if (_l) nodes[i++] = [l, y];
           
            if (_b) {
                nodes[i++] = [x, b];
                if (_l && (map[b][l] === 0)) nodes[i++] = [l, b];
                if (_r && (map[b][r] === 0)) nodes[i++] = [r, b];
            }
           
            if (_r) nodes[i++] = [r, y];
           
            return nodes;
        }
       
        , getAllPath : function (node) {
        //获取完整路径
            var path = [];
            do {
                path[path.length] = [node.X, node.Y];
            } while (node = node.P);
            path.reverse(), this.initialize();
           
            return path;
        }
       
        , loadMap : function (map) {
        //加载地图
            this.Map = map;
            this.limit = (this.bmax = map.length) * (this.rmax = map[0].length);
        }
       
        , search : function (start, goal) {
        //搜索
           
            var Point = this.pointSource()
                , open = this.open, close = this.close
                , makeID = this.makeID //放创造唯一值函数的引用.这样快
                , maps = this.maps //地图
                , limit = this.limit //地图最大值
                , euclidean = this.euclidean //计算代价的方法
                , GID = makeID(goal.X, goal.Y, limit) //终点的唯一值
                , nodes = []
                , length = 0
                , node = null, tempnode = null, tempg = 0
                , id = 0, i = 0, j = 0, _i = 0, _j = 0;
           
            open.push(new Point(null, start.X, start.Y)); //追加启始点
           
            while (length = open.length) {
                node = this.getMinNode(); //取最优点
               
                if (node.I != GID) { //若不是终点
                   
                    nodes = this.getNodes(node); //取该点所有所有临点
                   
                    for (i = 0, j = nodes.length ; i < j ; i ++) {
                        id = makeID(nodes[i][0], nodes[i][1], limit); //获取临点ID
                       
                        if (!(tempnode = maps[id])) { //如果没有查过
                            //创建点对象.放到open表.放到关联组
                            tempnode = open[open.length] = maps[id] = new Point(node, nodes[i][0], nodes[i][1]);
                            //计算代价值,估价值,总值
                            tempnode.F =
                                (tempnode.G = node.G + euclidean(tempnode, node)) + (tempnode.H = euclidean(tempnode, goal));
                            tempnode.I = id; //计算唯一标识
                        } else { //如果存在此点
                            tempg = node.G + euclidean(tempnode, node); //计算当前点到此临点的G值
                           
                            //如果此G值小于此临点的G值那么把这个临点抢过来。。。然后重新初始化一些参数
                            if (tempg < tempnode.G) tempnode.P = node, tempnode.G = tempg, tempnode.F = tempg + tempnode.H;
                        }
                    }
                   
                    close[close.length] = node; //放入close表
                } else {
                    return this.getAllPath(node); //已经找到最优路径.返回完整路径
                }
            }
            return (this.initialize(), []); //没有找到最优路径.返回空值
        }

    };

    AStar.Point = function (p, x, y) {
    //节点
        this.P = p;  //父节点
        this.X = x;  //x位置
        this.Y = y;  //y位置
        this.G = 0;  //g值
        this.H = 0;  //h值
        this.F = 0;  //f值
        this.I = 0;  //节点唯一值
    };

    var getPath = function () {
    //获取路径
        return path.length > 0 ? path.shift() : null;
    };

    var loadMap = function () {
    //加载地图
        var r, c, rary, cary;
       
        for (rary = [], r = 0 ; r < maps.length ; r ++) {
            for (cary = [], c = 0 ; c < maps[r].length ; c ++) {
                if (maps[r][c] == 0) {
                    cary[c] = '#FFFFFF';
                } else {
                    cary[c] = '#FFF000';
                }
            }
            rary[r] = '<td bgColor="' + cary.join('">&nbsp;<\/td><td bgColor="') + '">&nbsp;<\/td>'
        }
        document.body.innerHTML = '<table id="maps"><tr>' + rary.join('<\/tr><tr>') + '<\/tr><\/table>';
    };

    var resizeMap = function () {
    //重置地图
        var table = document.getElementById('maps'), r, c;
       
        for (r = 0 ; r < table.rows.length ; r ++) {
            for (c = 0 ; c < table.rows[r].cells.length ; c ++) {
                table.rows[r].cells[c].bgColor = (maps[r][c] == 0 ? '#FFFFFF' : '#FFF000');
            }
        }
    };

    var goGoal = function (start, end) {
    //查找路径
        var t = new Date;
        path = wc.search(start, end);
        document.title = new Date() - t + 'ms';
        window.status = path.length;

        if (path.length > 2) {
            path = path.slice(1, -1);
            moveToGoal();
        }
    };

    var moveToGoal = function () {
    //设置走路:D
        var temp;
        if (path.length > 0) {
            temp = path.shift();
            document.getElementById('maps').rows[temp[1]].cells[temp[0]].bgColor = '#FF0000';
            window.setTimeout(arguments.callee, 30);
        }
    };


    var maps = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,1,1,1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,0,1,0,0,1,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    ];

    var wc = new AStar; //创建ASatr对象
    wc.loadMap(maps); //载入地图


    window.onload = function () {
        var sn = 0;
        var start = { x : 0, y : 0 }, end = { x : 0, y : 0 };
       
        loadMap(); //显示地图
       
        var table = document.getElementById('maps');
       
        table.onmousedown = function (e) {
       
            var e = window.event || e;
       
            var obj = e.srcElement || e.target;
            if (obj.nodeName == 'TD') {
                if (sn) {
                    end.X = obj.cellIndex, end.Y = obj.parentNode.rowIndex;
                    obj.bgColor = '#000000';
                    window.setTimeout(function () {
                        goGoal(start, end);
                    }, 0);
                } else {
                    resizeMap();
                    obj.bgColor = '#000000';
                    start.X = obj.cellIndex, start.Y = obj.parentNode.rowIndex;
                }
                sn = Math.abs(sn - 1);
            }
        };
    };
    </script>
    <style type="text/css">
    table {
        border-left:#CCC 1px solid;
        border-top:#CCC 1px solid;
        border-collapse:collapse;
    }
    td {
        border-right:#CCC 1px solid;
        border-bottom:#CCC 1px solid;
        height:10px;
        width:10px;
        font-size:0;
    }
    </style>
    </head>
    <body>
    </body>
    </html>

    发表于 @ 2008年04月02日 20:20:00|评论(loading...)|编辑

    旧一篇: 愚人节小程序....

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © muxrwc