A*算法JS版本(转存的资料)

 

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3 <html>
  4 <head>
  5 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  6 <title>my rpg game - dh20156风之石</title>
  7 <style type="text/css">
  8 table {
  9     border-left:#CCC 1px solid;
 10     border-top:#CCC 1px solid;
 11     border-collapse:collapse;
 12 }
 13 td {
 14     border-right:#CCC 1px solid;
 15     border-bottom:#CCC 1px solid;
 16     height:10px;
 17     width:10px;
 18     font-size:0px;
 19     color:highlight;
 20 }
 21 </style>
 22 </head>
 23 <body>
 24 <script type="text/javascript">
 25 var map = function(){
 26     var owner = this;
 27     //起点
 28     this.startNode = [];
 29     //map table
 30     this.table = null;
 31     //清除颜色
 32     this.clearColor = function(){
 33         var xl = this.length;
 34         if(xl<1){
 35             return;
 36         }
 37         var yl = this[0].length;
 38         if(yl<1){
 39             return;
 40         }
 41         var maptable = this.table;
 42         maptable.style.display = 'none';
 43         for(var i=0;i<xl;i++){
 44             for(var n=0;n<yl;n++){
 45                 maptable.rows[i].cells[n].style.background='';
 46                 if(this[i][n]!=0){
 47                     maptable.rows[i].cells[n].style.background='background';
 48                 }
 49             }
 50         }
 51         maptable.style.display = 'block';
 52     }
 53     //寻路
 54     this.run = function(obj){
 55         var x0=0,y0=0,x1=0,y1=0;
 56         var _sn = this.startNode;
 57         var _en = this.endNode;
 58         if(_sn.length<1){
 59             obj.style.background = 'red';
 60             x0 = obj.parentNode.rowIndex;
 61             y0 = obj.cellIndex;
 62             this.startNode = [x0,y0];
 63         }else{
 64             this.clearColor();
 65             obj.style.background = 'red';
 66             x0 = _sn[0];
 67             y0 = _sn[1];
 68             x1 = obj.parentNode.rowIndex;
 69             y1 = obj.cellIndex;
 70             var path = this.getPath(x0,y0,x1,y1);
 71             this.showPath(path);
 72             this.startNode = [x1,y1];
 73         }
 74     }
 75     //点击事件
 76     this.click = function(event){
 77         event = event||window.event;
 78         var obj = event.srcElement||event.target;
 79         if(obj.tagName!='TD'){
 80             return;
 81         }
 82         owner.run(obj);
 83     }
 84     //创建视图
 85     this.setView = function(){
 86         var xl = this.length;
 87         if(xl<1){
 88             return;
 89         }
 90         var yl = this[0].length;
 91         if(yl<1){
 92             return;
 93         }
 94         var trstr = '<tr>'+new Array(yl+1).join('<td></td>')+'</tr>';
 95         var tbstr = '<table id="amap">'+new Array(xl+1).join(trstr)+'</table>';
 96         document.write(tbstr);
 97         var maptable = this.table = document.getElementById("amap");
 98         for(var i=0;i<xl;i++){
 99             for(var n=0;n<yl;n++){
100                 if(this[i][n]!=0){
101                     maptable.rows[i].cells[n].style.background='background';
102                 }
103             }
104         }
105         if(window.attachEvent){
106             this.table.attachEvent('onclick',this.click);
107         }else{
108             this.table.addEventListener('click',this.click,false);
109         }
110     }
111     //显示路径
112     this.showPath = function(path){
113         if(path!=undefined && path.length>0){
114             var maptable = this.table;
115             var pos = null;
116             var move = function(){
117                 if(path.length>0){
118                     pos = path.shift();
119                     maptable.rows[pos[0]].cells[pos[1]].style.background='red';
120                     window.setTimeout(arguments.callee,30);
121                 }
122             }
123             move();
124         }else{
125             document.title = 'Did not find the path!';
126         }
127     }
128 }
129 
130 var Astar = function(map){
131     //dh20156;
132     this.map = map;
133     //已探索列表
134     this.chkList = [];
135     //开放对象列表
136     this.openList = [];
137     //取G值
138     this.getG = function(x0,y0,x1,y1){
139         if(Math.abs(x0-x1)==1 && Math.abs(y0-y1)==1){
140             return 14;
141         }else{
142             return 10;
143         }
144     }
145     //取H值Diagonal Shortcut
146     this.getH = function(x0,y0,x1,y1){
147         var xDistance = Math.abs(x0-x1);
148         var yDistance = Math.abs(y0-y1);
149         if(xDistance > yDistance){
150             return (14*yDistance + 10*(xDistance-yDistance));
151         }else{
152             return (14*xDistance + 10*(yDistance-xDistance));
153         }
154     }
155     //节点对象
156     this.point = function(_f,_g,_h,_x,_y,_p){
157         this.f = _f;
158         this.g = _g;
159         this.h = _h;
160         this.x = _x;
161         this.y = _y;
162         this.p = _p;
163     }
164     //获取检测子节点对象
165     this.setPoints = function(_node,x1,y1){
166         var map = this.map;
167         var x = _node.x;
168         var y = _node.y;
169         var g = _node.g;
170         var t = x-1;
171         var b = x+1;
172         var l = y-1;
173         var r = y+1;
174         var maxX = map.length;
175         var maxY = map[0].length;
176         if(t>=0 && l>=0 && map[t][l]==0 && map[t][y]==0 && map[x][l]==0this.chkPoint(_node,x,y,g,t,l,x1,y1);//1
177         if(t>=0 && map[t][y]==0this.chkPoint(_node,x,y,g,x-1,y,x1,y1);//2
178         if(t>=0 && r<maxY && map[t][r]==0 && map[t][y]==0 && map[x][r]==0this.chkPoint(_node,x,y,g,t,r,x1,y1);//3
179         if(l>=0 && map[x][l]==0this.chkPoint(_node,x,y,g,x,y-1,x1,y1);//4
180         if(r<maxY && map[x][r]==0this.chkPoint(_node,x,y,g,x,y+1,x1,y1);//6
181         if(b<maxX && l>=0 && map[b][l]==0 && map[x][l]==0 && map[b][y]==0this.chkPoint(_node,x,y,g,b,l,x1,y1);//7
182         if(b<maxX && map[b][y]==0this.chkPoint(_node,x,y,g,x+1,y,x1,y1);//8
183         if(b<maxX && r<maxY && map[b][r]==0 && map[b][y]==0 && map[x][r]==0this.chkPoint(_node,x,y,g,b,r,x1,y1);//9
184     }
185     //检测子节点对象
186     this.chkPoint = function(_fnode,_x0,_y0,_g,_x1,_y1,_x2,_y2){
187         var open = this.openList;
188         var chk = this.chkList;
189         var _id = new String(_x1+'_'+_y1);
190         var _point = null;
191         if(undefined == (_point = chk[_id])){
192             _point = new this.point(0,0,0,_x1,_y1,_fnode);
193             open[open.length] = _point;
194             chk[_id] = _point;
195             _point.g = _g + this.getG(_x0,_y0,_x1,_y1);    //起点到当前点实际值
196             _point.h = this.getH(_x1,_y1,_x2,_y2);        //终点到当前点的估价
197             _point.f = _point.g + _point.h;
198         }else{
199             var _CNG = _g + this.getG(_x0,_y0,_x1,_y1);
200             if(_point.g>_CNG){//保留小G,替换parentNode
201                 _point.g = _CNG;
202                 _point.f = _point.g + _point.h;
203                 _point.p = _fnode;
204             }
205         }
206     }
207     //探索路径
208     this.getPath = function(x0,y0,x1,y1){
209         var st = new Date();
210         var tp = [];
211         var open = this.openList;
212         var map = this.map;
213         if(map[x0][y0]!=0 || map[x1][y1]!=0){
214             return tp;
215         }
216         var _sh = this.getH(x0,y0,x1,y1);
217         open[0= new this.point(_sh,0,_sh,x0,y0,null);
218         var oll=0,nowNode=null;
219         while(0<(oll=open.length)){
220             var maxNode,minIndex,minf=10000000000;
221             for(var i=0;i<oll;i++){
222                 maxNode = open[i];
223                 if(minf>maxNode.f){
224                     minf = maxNode.f;
225                     minIndex = i;
226                 }
227             }
228             nowNode = open[minIndex];
229             open[minIndex] = open[oll-1];
230             open.length--;
231             if(nowNode.x==x1 && nowNode.y==y1){
232                 while(nowNode.p!=null){
233                     tp.push([nowNode.x,nowNode.y]);
234                     nowNode = nowNode.p;
235                 }
236                 tp.push([x0,y0]);
237                 break;
238             }
239             this.setPoints(nowNode,x1,y1);
240         }
241         open = this.openList = this.chkList = map = [];
242         document.title = new Date()-st+' ms, '+tp.length+'steps.';
243         return tp.slice(0).reverse();
244     }
245 }
246 
247 var maps = [ // handest
248     [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
249     [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
250     [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],
251     [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],
252     [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],
253     [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
254     [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],
255     [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],
256     [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],
257     [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],
258     [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],
259     [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],
260     [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],
261     [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],
262     [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],
263     [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],
264     [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],
265     [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],
266     [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],
267     [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],
268     [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],
269     [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],
270     [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],
271     [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],
272     [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],
273     [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],
274     [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],
275     [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],
276     [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],
277     [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],
278     [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],
279     [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],
280     [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],
281     [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],
282     [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],
283     [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],
284     [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],
285     [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],
286     [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],
287     [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],
288     [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],
289     [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],
290     [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],
291     [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],
292     [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],
293     [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],
294     [0,0,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],
295     [0,0,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],
296     [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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],
297     [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
298 ];
299 
300 map.call(maps);
301 maps.setView();
302 Astar.call(maps,maps);
303 
304 </script>
305 <h1>Javascript版A*(a star)算法!</h1>
306 <h3>在白色表格中点击,第一次设置起点,第二次设置终点,将自动找到路径!</h3>
307 </body>
308 </html>

 

posted @ 2009-05-30 01:06  轻风尔尔  阅读(225)  评论(0编辑  收藏  举报