js尋路算法
阿新 • • 發佈:2018-06-22
als div arr 遞歸 function margin 線路 length FN
f()=g()+h(); //g為每個節點到起點得距離;h為每個節點到終點得距離。兩個距離通過勾股定理可以算出;
以下代碼基本的解釋和註釋都有。不懂得可以留言哦
css
<style>
ul{
list-style: none;
margin: 0;
padding: 0;
border: 1px solid #f5f5f5;
border-right: none;
border-bottom: none;
margin: 100px auto;
}
ul li{
float: left;
border: solid 1px #f5f5f5;
border-left: none;
border-top: none;
display: inline-block;
background: black;
}
.start{
background: skyblue;
}
.end{
background: green;
}
.usual{
background: pink;
}
</style>
html
<body>
<ul id="map-ul"></ul>
<input id="btn" type="button" value="開始" />
</body>
js
<script>
var oUl = document.getElementById("map-ul");
var startBtn = document.getElementById("btn");
var Li = oUl.getElementsByTagName("li");
var beginLi = document.getElementsByClassName("start");
var endLi = document.getElementsByClassName("end");
var map = [
1,1,1,1,1,1,1,1,1,1,//0為起點;2為障礙物,3為終點
1,1,0,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,2,2,2,1,1,
1,1,1,1,1,2,1,1,1,1,
1,1,1,1,1,2,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,3,
1,1,1,1,1,1,1,1,1,1
];
var openArr = [];//可能要走的路線
var closeArr = [];//已經關閉的路線
var cols = Math.sqrt(map.length)
var sizeBox = 20;
//初始化
init()
function init(){
creatMap();//初始化地圖
startBtn.onclick = function(){
openFn();
}
}
function creatMap(){
oUl.style.width = cols * (sizeBox + 1) + 1 + "px";
oUl.style.height = cols * (sizeBox + 1) + 1 + "px";
for (var i=0;i<map.length;i++) {
var oLi = document.createElement("li");
oLi.style.width = sizeBox + "px";
oLi.style.height = sizeBox + "px";
oUl.appendChild(oLi)
if (map[i] == 2) {
oLi.className = "usual"
closeArr.push(oLi)//障礙物添加到關閉得線路
} else if(map[i] == 0){
oLi.className = "start"
openArr.push(oLi)//起始點添加到要走得線路
}else if(map[i] == 3){
oLi.className = "end"
}
}
}
function f(nodeLi){//nodeLi每個li節點
return g(nodeLi) + h(nodeLi);//g為節點到初始位置的距離,h為節點到結束位置的距離
}
function g(nodeLi){
//勾股定理算出距離
var x = beginLi[0].offsetLeft - nodeLi.offsetLeft;
var y = beginLi[0].offsetTop - nodeLi.offsetTop;
return Math.sqrt(x*x+y*y);
}
function h(nodeLi){
var x = endLi[0].offsetLeft - nodeLi.offsetLeft;
var y = endLi[0].offsetTop - nodeLi.offsetTop;
return Math.sqrt(x*x+y*y);
}
function openFn(){
//以起始位置為可能要走的第一個Li
var nowLi = openArr.shift();
if(nowLi == endLi[0]){
showLine();
return;
}
closeFn(nowLi);//將找過得節點添加到關閉的路線
findLi(nowLi);//尋找第一個Li周圍的可能要走的Li
openArr.sort(function(li1,li2){//將可能走得線路得節點通過距離從下到大排序。當下次循環得時候可以直接拿到上個最近得節點,
return li1.num - li2.num;
})
openFn();
}
function findLi(nowLi){
var result = [];//所有沒走過的路線。去除closeArr裏存在的路線
for (var i=0;i<Li.length;i++) {
if( filter(Li[i])){
result.push(Li[i])
}
}
function filter(Li){//如果closeArr裏沒有就添加到隊列
for (var i=0;i<closeArr.length;i++) {
if(closeArr[i] == Li){
return false;
}
}
for (var i=0;i<openArr.length;i++) {
if(openArr[i] == Li){
return false;
}
}
return true;
}
//在所有沒走過的節點找到與當前節點相鄰的8個方向的節點
for(var i=0;i<result.length;i++){
if(Math.abs(nowLi.offsetLeft - result[i].offsetLeft)<=21&&Math.abs(nowLi.offsetTop - result[i].offsetTop)<=21){
result[i].num = f(result[i]);
result[i].parent = nowLi;//設置指針
openArr.push(result[i])
}
}
}
function showLine(){
var result = [];
var lastLi = closeArr.pop();
var iNow = 0;
findParent(lastLi);
function findParent(li){
result.unshift(li);
if( li.parent == beginLi[0] ){
return;
}
findParent(li.parent);//通過指針遞歸
console.log(li.parent)
}
for (var i=0;i<result.length;i++) {
result[i].style.backgroundColor = "plum";
}
}
function closeFn(nowLi){
closeArr.push(nowLi);
}
</script>
js尋路算法