js版 a星算法(原创:算法独立出来了)
a星算法的原理,网络上基本都有,这里就不在介绍了,网络上的a星和例子结合的过于密切,不利于复用,如果你只需要代码,不需要了解原理,此文会对你有帮助
图片见附件,代码如下:
window.AStar = {};(function(aStar){//start:起始节点[i,j] , end:最终节点[i,j] map:地图数据(2d)arr,marker:可以通过的标识(例子用的是1)aStar.find_path = function(start,end,map,marker){var open = [];var close = [];var s_p = start;var e_p = end;var map_arr = map;var tra_marker = marker;var G = 0;var H = 0;var F = 0;//加入起始节点 [x, y , G ,F ,father]open.push([s_p[0],s_p[1],0,(Math.abs(e_p[0]-s_p[0]) + Math.abs(e_p[1]-s_p[1])),null]);return function(obj){//重拍,取最小的一个var count = 0;for(var i = obj[0]-1,ilen = i+3 ; i < ilen ; i++){for(var j = obj[1]-1,jlen = j+3 ;j < jlen; j++){//遍历周围八节点,排除自己if(i == obj[0] && j == obj[1])continue;//排除穿越的情况if(!((i == obj[0] ) || ( j == obj[1])) && ( map_arr[i] && map_arr[obj[0]] && map_arr[i][obj[1]] != tra_marker && map_arr[obj[0]][j] != tra_marker))continue;if(i == e_p[0] && j == e_p[1]){open.push([i,j,G,F,obj]);var ways = [];var ele = obj;do{ways.unshift(ele);ele = ele[4];}while(ele[4] != null);return ways;}if(map_arr[i] && map_arr[i][j] && map_arr[i][j] == tra_marker && is_exist(open,[i,j]) == -1 && is_exist(close,[i,j]) == -1){G = ( i == obj[0] ) || ( j == obj[1] ) ? obj[2]+1.0 : obj[2]+1.4 ;H = Math.sqrt((e_p[0] - i)*(e_p[0] - i) + (e_p[1] - j)*(e_p[1] - j));F = G + H;open.push([i,j,G,F,obj]);count++;}}}close.push(open.shift());var o;if(open[0] && open[0][4] == obj[4]){o = count == 0 ? get_other(open,obj) : (arr_sort(open),open[0]);}else{o = (arr_sort(open),open[0]);}if(o){return arguments.callee(o);}else{return [];}}(open[0])}//获取其他节点var get_other = function(arr,o){var a = [];for(var i = 0 ; i < arr.length ; i++){if(o && arr[i][4] == o[4]){return arr[i];}}if(o[4]){return arguments.callee(o[4]);}else{return null;}}//对数组进行重排列var arr_sort = function(){function s(a,b){return a[3] - b[3];}return function(arr){arr.sort(s);}}();//数组中是否存在此元素var is_exist = function(arr,p){for(var i = 0 ; i < arr.length ; i++){if(arr[i][0] == p[0] && arr[i][1] == p[1]){return i;}}return -1;}})(window.AStar)
<script src="a_star.js"></script><link rel="stylesheet" type="text/css" href="reset.css" /><script>var state = 1;var w = 20;var h = 10;var map_arr = [];var start,end;window.onload = function(){var map = document.getElementById("map");var arr = [];arr.push("<table border="1">");for(var i = 0 ; i < h ; i++){arr.push("<tr>");if(!map_arr[i]) map_arr[i] = [];for(var j = 0 ; j < w ;j++){arr.push("<td id=""+i+"-"+j+"" style="width:50px;height:50px;border:1px solid #000" onclick="td(" + i + "," + j + ")"></td>");map_arr[i][j] = 1;}arr.push("</tr>");}arr.push("</table>");map.innerHTML = arr.join("");}function td(x,y){var e = document.getElementById( x + "-" + y);switch(state){case 1:start = [x,y];e.style.backgroundColor = "#0f0";break;case 2:end = [x,y];e.style.backgroundColor = "#f00";break;case 3:e.style.backgroundColor = "#000";map_arr[x][y] = 0;break;}}function changeS(value){state = value;}function find_path(){var ways = AStar.find_path(start,end,map_arr,1);if(ways.length == 0 ){alert("no ways!~~~");return ;}for(var i = 0;i < ways.length; i++){ var e = document.getElementById(ways[i][0]+"-"+ways[i][1]);e.style.backgroundColor = "#00f";}}</script><body><div id="map"></div><input type="button" onclick="changeS(1);" value="添加起始"/><input type="button" onclick="changeS(2);" value="添加终点" /><input type="button" onclick="changeS(3);" value="添加障碍物" /><input type="button" onclick="find_path();" value="生成路径" /></body>