JS中实现A*算法寻路
<html><head><title>use A* to find path...</title></head>
<body style="margin:0px">
<script>
/*
written by hjjboy
email:tianmashuangyi@163.com
qq:156809986
*/
var closelist=new Array(),openlist=new Array();
var gw=10,gh=10,gwh=14;
var p_start=new Array(2),p_end=new Array(2);
var s_path,n_path="";
var num,bg,flag=0;
var w=30,h=20;
function GetRound(pos){
var a=new Array();
a[0]=(pos[0]+1)+","+(pos[1]-1);
a[1]=(pos[0]+1)+","+pos[1];
a[2]=(pos[0]+1)+","+(pos[1]+1);
a[3]=pos[0]+","+(pos[1]+1);
a[4]=(pos[0]-1)+","+(pos[1]+1);
a[5]=(pos[0]-1)+","+pos[1];
a[6]=(pos[0]-1)+","+(pos[1]-1);
a[7]=pos[0]+","+(pos[1]-1);
return a;
}
function GetF(arr){
var t,G,H,F;
for(var i=0;i<arr.length;i++){
t=arr[i].split(",");
t[0]=parseInt(t[0]);t[1]=parseInt(t[1]);
if(IsOutScreen([t[0],t[1]])||IsPass(arr[i])||InClose([t[0],t[1]])||IsStart([t[0],t[1]])||!IsInTurn([t[0],t[1]]))
continue;
if((t[0]-s_path[3][0])*(t[1]-s_path[3][1])!=0)
G=s_path[1]+gwh;
else
G=s_path[1]+gw;
if(InOpen([t[0],t[1]])){
if(G<openlist[num][1]){
openlist[num][0]=(G+openlist[num][2]);
openlist[num][1]=G;
openlist[num][4]=s_path[3];
}
else{G=openlist[num][1];}
}
else{
H=(Math.abs(p_end[0]-t[0])+Math.abs(p_end[1]-t[1]))*gw;
F=G+H;
arr[i]=new Array();
arr[i][0]=F;arr[i][1]=G;arr[i][2]=H;arr[i][3]=[t[0],t[1]];arr[i][4]=s_path[3];
openlist[openlist.length]=arr[i];
}
if(maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#cccccc"&&maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#0000ff"&&maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#ff0000"&&maptt.rows[t[1]].cells[t[0]].style.backgroundColor!="#00ff00")
{
maptt.rows[t[1]].cells[t[0]].style.backgroundColor="#FF00FF";
//maptt.rows[t[1]].cells[t[0]].innerHTML="<font color=white>"+G+"</font>";
}
}
}
function IsStart(arr){
if(arr[0]==p_start[0]&&arr[1]==p_start[1])
return true;
return false;
}
function IsInTurn(arr){
if(arr[0]>s_path[3][0]){
if(arr[1]>s_path[3][1]){
if(IsPass((arr[0]-1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]-1)))
return false;
}
else if(arr[1]<s_path[3][1]){
if(IsPass((arr[0]-1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]+1)))
return false;
}
}
else if(arr[0]<s_path[3][0]){
if(arr[1]>s_path[3][1]){
if(IsPass((arr[0]+1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]-1)))
return false;
}
else if(arr[1]<s_path[3][1]){
if(IsPass((arr[0]+1)+","+arr[1])||IsPass(arr[0]+","+(arr[1]+1)))
return false;
}
}
return true;
}
function IsOutScreen(arr){
if(arr[0]<0||arr[1]<0||arr[0]>(w-1)||arr[1]>(h-1))
return true;
return false;
}
function InOpen(arr){
var bool=false;
for(var i=0;i<openlist.length;i++){
if(arr[0]==openlist[i][3][0]&&arr[1]==openlist[i][3][1]){
bool=true;num=i;break;}
}
return bool;
}
function InClose(arr){
var bool=false;
for(var i=0;i<closelist.length;i++){
if((arr[0]==closelist[i][3][0])&&(arr[1]==closelist[i][3][1])){
bool=true;break;}
}
return bool;
}
function IsPass(pos){
if((";"+n_path+";").indexOf(";"+pos+";")!=-1)
return true;
return false;
}
function Sort(arr){
var temp;
for(var i=0;i<arr.length;i++){
if(arr.length==1)break;
if(arr[i][0]<=arr[i+1][0]){
temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
if((i+1)==(arr.length-1))
break;
}
}
function main(){
GetF(GetRound(s_path[3]));
Sort(openlist);
s_path=openlist[openlist.length-1];
closelist[closelist.length]=s_path;
openlist[openlist.length-1]=null;
if(openlist.length==0){alert("找不到路径");return;}
openlist.length=openlist.length-1;
if((s_path[3][0]==p_end[0])&&(s_path[3][1]==p_end[1])){
getPath();
}
else{maptt.rows[s_path[3][1]].cells[s_path[3][0]].style.backgroundColor="#00ff00";setTimeout("main()",100);}
}
function getPath(){
var str="";
var t=closelist[closelist.length-1][4];
while(1){
str+=t.join(",")+";";
maptt.rows[t[1]].cells[t[0]].style.backgroundColor="#ffff00";
for(var i=0;i<closelist.length;i++){
if(closelist[i][3][0]==t[0]&&closelist[i][3][1]==t[1])
t=closelist[i][4];
}
if(t[0]==p_start[0]&&t[1]==p_start[1])
break;
}
alert(str);
}
function setPos(){
var h=(Math.abs(p_end[0]-p_start[0])+Math.abs(p_end[1]-p_start[1]))*gw;
s_path=[h,0,h,p_start,p_start];
}
function set(id,arr){
switch(id){
case 1:
p_start=arr;
maptt.rows[arr[1]].cells[arr[0]].style.backgroundColor="#ff0000";break;
case 2:
p_end=arr;maptt.rows[arr[1]].cells[arr[0]].style.backgroundColor="#0000ff";break;
case 3:
n_path+=arr.join(",")+";";maptt.rows[arr[1]].cells[arr[0]].style.backgroundColor="#cccccc";break;
default:
break;
}
}
function setflag(id){flag=id;}
</script>
<table id="maptt" cellspacing="1" cellpadding="0" border="0" bgcolor="#000000">
<script>
for(var i=0;i<h;i++){
document.write("<tr>");
for(var j=0;j<w;j++){
document.write('<td onclick="set(flag,['+j+','+i+']);" bgcolor="#ffffff" width="20" height="20"></td>');
}
document.write("</tr>");
}
</script>
</table>
<a href="javascript:setflag(1);">设置起点</a><br>
<a href='javascript:setflag(2);'>设置终点</a><br>
<a href='javascript:setflag(3);'>设置障碍点</a><br>
<input type="button" onclick="setPos();main();this.disabled=true;" value="find">
</body>
</html>
A*算法主要用到的是一个公式:F=G+H;
G,是指起始点到当前点的距离。
H,是指当前点到目的点的距离。
F,是两者之和。
为了方便起见,两点之间的距离直接取两者之间X方向的距离差+Y方向上的距离差。
在A*算法中,主要就是搜索一个点的周围八个方块(去掉不可走的),然后计算各个方块的F值,取F值最小的作为下一步需要走的方格,而把当前方格作为下一步的父方格。然后另下一步作为当前访格。依此轮回,直到找到目的方格为止。
http://astar.baidu.com/data/demo/ACRush.txt
http://www.blueidea.com/tech/multimedia/2005/3121.asp
http://bbs.blueidea.com/viewthread.php?tid=1640729
http://bbs.blueidea.com/viewthread.php?tid=2402659
JS中实现A*算法寻路的更多相关文章
- js 中的快速排序算法简单实现
对于快速排序,最早是在c++中看到,它是利用指针来交换顺序,其实无论哪种语言,原理 和 思想都是一样,然而真正用起来的时候就特别容易忽略一些事实,导致实现失败.废话少说,下面用js实现一下快速排序: ...
- JS中常见排序算法详解
本文将详细介绍在JavaScript中算法的用法,配合动图生动形象的让你以最快的方法学习算法的原理以及在需求场景中的用途. 有句话怎么说来着: 雷锋推倒雷峰塔,Java implements Java ...
- js中常用的算法排序
在工作中都会经常用到的一些基础算法,可以很快解决问题.这些都是在工作中总结的,希望可以帮助到大家. 一.数组乱序 arr.sort(function randomsort(a, b) { return ...
- JS中的排序算法-冒泡排序解析
冒泡排序算法 例子:10,8,9,6,4,20,5 从小到大排序 第一轮 1)10>8 交换数据 得到:8,10,9,6,4,20,5 2)10>9 交换数据 得到:8,9,10, ...
- js 中的算法题,那些经常看到的
js中遇到的算法题不是很多,可以说基本遇不到.但面试的时候,尤其是一些大公司,总是会出这样那样的算法题,考察一个程序员的逻辑思维能力.如下: 1.回文. 回文是指把相同的词汇或句子,在下文中调换位置或 ...
- JS 中 Tween 的使用
JavaScript Tween算法及缓动效果 Flash做动画时会用到Tween类,利用它可以做很多动画效果,例如缓动.弹簧等等.我这里要教大家的是怎么利用flash的Tween类的算法,来做j ...
- JS中几种常见的数组算法(前端面试必看)
JS中几种常见的数组算法 1.将稀疏数组变成不稀疏数组 /** * 稀疏数组 变为 不稀疏数组 * @params array arr 稀疏数组 * @return array 不稀疏的数组 */ f ...
- JS中常见算法问题
JS中常见算法问题 1. 阐述JS中的变量提升(声明提前) 答:将所有的变量提升当当前作用域的顶部,赋值留在原地.意味着我们可以在某个变量声明前就使用该变量. 虽然JS会进行变量提升,但并不会执行真正 ...
- 今天给大家分享一下js中常用的基础算法
今天给大家分享一下js中常用的基础算法,废话不多说,直接上代码: 1.两个数字调换顺序 ,b= function fun(a,b){ b = b - a ;// a = 2 ; b = 2 a = a ...
随机推荐
- NetBeans工具学习之道:NetBeans IDE Java 高速新手教程
欢迎使用 NetBeans IDE! 本教程通过指导您创建一个简单的 "Hello World" Java 控制台应用程序,简要介绍 NetBeans IDE 工作流.学习完本教程 ...
- Servlet上传文件
Servlet上传文件 1.准备工作 (1)利用FileUpload组件上传文件,须要到apache上下载commons-fileupload-1.3.1.jar 下载地址:http://common ...
- MemoryBarrier,Volatile
使用MemoryBarrier,Volatile进行同步 上一节介绍了使用信号量进行同步,本节主要介绍一些非阻塞同步的方法.本节主要介绍MemoryBarrier,volatile,Interlock ...
- Android网络通信Volley框架源代码浅析(三)
尊重原创 http://write.blog.csdn.net/postedit/26002961 通过前面浅析(一)和浅析(二)的分析.相信大家对于Volley有了初步的认识,可是假设想更深入的理解 ...
- OCEANIAERP对接-code盘点机并存储实时库存计划和方案的使用,实时库存,云清查方案
1. PDA手持设备按键说明 [Tab]键:使输入焦点在控件上切换. [ESC]键:弹出是否退出确认对话框,退出操作界面或程序. [OK]键:确认输入或选择,进入下一步操作. [C]键:删除键 ...
- 有意练习--Rails RESTful(一)
书要反复提及<哪里有天才>在说,大多数所谓的天才是通过反复刻意练习获得. 当你的练习时间达到10000几个小时后,.你将成为该领域的专家. 近期在学习rails怎样实现RESTful We ...
- 中介模式和学习日记Effective C++
中介模式(Mediator):利用中介对象来封装一组对象交互.中保使对象并不需要显式地相互引用,使得松耦合,的交互. (1).中介者模式非常easy在系统中应用,也非常easy在系统中误用.当系统出现 ...
- 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法(转)
对象的synchronized方法不能进入了,但它的其他非synchronized方法还是可以访问的 对每一个class只有一个thread可以执行synchronized static method ...
- remine chart2安装
http://blog.csdn.net/kufeiyun/article/details/9213911
- 离robots.txt启动网络爬虫之旅
要成为一个网络爬虫或搜索引擎(在这里,共同蜘蛛)它不会陌生,在搜索引擎爬虫的第一个文件或者访问该网站上浏览robots.txt该.robots.txt文件讲述了蜘蛛server哪些文件要观看正在. 当 ...