JS-BFA演算法及ui實現
今天貼個程式碼Breadth-First-Algorithm
目錄
今天貼個程式碼Breadth-First-Algorithm
2. Breadth-First-Algorithm.html - 演算法實現
1. BFA實現演算法流程
2. 程式碼裡有什麼
- html grid使用
- canvas drawline
- JS寫innerHtml
- mouse down and up position - get
3. Breadth-First-Algorithm.html - 演算法實現
map由generateMap.html[見下]生成;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Bredth-First-Algorithm</title>
</head>
<body>
<button type="button" onclick="run()">start</button>
<button type="button" onclick="location.reload()">refresh</button>
<a id="iteration"></a>
<a id="panel" style="display: grid;"></a>
<script type="text/javascript">
const colors = ["black", "blue", "green", "red"];
const pxSize = 20, lineWidth = 3;
const timeStep = 100;
// 0 - obstacle; 1 - blank; 2 - start; 3 - goal
const start = 2, goal = 3, obstacle = 0, blank = 1;
const map = [[2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1], [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1], [1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1], [1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1], [1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1], [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1], [1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 3, 1, 1, 1, 0, 1, 1, 1, 1, 1]];
const row = map.length;
const col = map[0].length;
document.getElementById("panel").style.width = pxSize * row + "px";
document.getElementById("panel").style.height = pxSize * col + "px";
document.getElementById("panel").style.gridTemplateColumns = (pxSize + "px ").repeat(row);
document.getElementById("panel").style.gridTemplateRows = (pxSize + "px ").repeat(col);
//add grid - num at row * col
var addGridStringText = "<canvas id='myCanvas' width=" + pxSize * row + " height=" + pxSize * row + " style='position:absolute; solid #000000;'></canvas>" + "<canvas id='myCanvasForFinalPath' width=" + pxSize * row + " height=" + pxSize * row + " style='position:absolute; solid #000000;'></canvas>";
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++)
addGridStringText += "<div row='" + i + "' col='" + j + "' id='" + i + "_" + j + "' style=\"border:1px solid white; background-color:" + colors[map[i][j]] + "\"></div>";
}
document.getElementById("panel").innerHTML = addGridStringText;
function drawLine(from, to) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth = lineWidth;
ctx.moveTo(pxSize * (from.colAt + 0.5), pxSize * (from.rowAt + 0.5));
ctx.lineTo(pxSize * (to.colAt + 0.5), pxSize * (to.rowAt + 0.5));
ctx.stroke();
}
function drawFinalPathLine(from, to) {
var c = document.getElementById("myCanvasForFinalPath");
var ctx = c.getContext("2d");
ctx.strokeStyle = '#cc0000';
ctx.lineWidth = lineWidth;
ctx.moveTo(pxSize * (from.colAt + 0.5), pxSize * (from.rowAt + 0.5));
ctx.lineTo(pxSize * (to.colAt + 0.5), pxSize * (to.rowAt + 0.5));
ctx.stroke();
}
function Node(parent, rowat, colat) {
this.parent = parent;
this.rowAt = rowat;
this.colAt = colat;
if (parent != null) drawLine(parent, this);
this.getMapValue = function () {
return map[rowAt][colAt];
}
//from left top and normal clock order
this.addNeightBor = function () {
rowAt = this.rowAt;
colAt = this.colAt;
rightTop = [rowAt - 1, colAt + 1];
if (rightTop[0] >= 0 && rightTop[1] < col && map[rightTop[0]][rightTop[1]] != obstacle && notContain(rightTop)) { node = new Node(this, rightTop[0], rightTop[1]); openList.push(node); createdList.push(node); }
right = [rowAt, colAt + 1];
if (right[1] < col && map[right[0]][right[1]] != obstacle && notContain(right)) { node = new Node(this, right[0], right[1]); openList.push(node); createdList.push(node); }
rightBott = [rowAt + 1, colAt + 1];
if (rightBott[0] < row && rightBott[1] < col && map[rightBott[0]][rightBott[1]] != obstacle && notContain(rightBott)) { node = new Node(this, rightBott[0], rightBott[1]); openList.push(node); createdList.push(node); }
bott = [rowAt + 1, colAt];
if (bott[0] < row && map[bott[0]][bott[1]] != obstacle && notContain(bott)) { node = new Node(this, bott[0], bott[1]); openList.push(node); createdList.push(node); }
leftBott = [rowAt + 1, colAt - 1];
if (leftBott[0] < row && leftBott[1] >= 0 && map[leftBott[0]][leftBott[1]] != obstacle && notContain(leftBott)) { node = new Node(this, leftBott[0], leftBott[1]); openList.push(node); createdList.push(node); }
left = [rowAt, colAt - 1];
if (left[1] >= 0 && map[left[0]][left[1]] != obstacle && notContain(left)) { node = new Node(this, left[0], left[1]); openList.push(node); createdList.push(node); }
leftTop = [rowAt - 1, colAt - 1];
if (leftTop[0] >= 0 && leftTop[1] >= 0 && map[leftTop[0]][leftTop[1]] != obstacle && notContain(leftTop)) { node = new Node(this, leftTop[0], leftTop[1]); openList.push(node); createdList.push(node); }
//can not use top, top is already defined as window class in JS
topNode = [rowAt - 1, colAt];
if (topNode[0] >= 0 && map[topNode[0]][topNode[1]] != obstacle && notContain(topNode)) { node = new Node(this, topNode[0], topNode[1]); openList.push(node); createdList.push(node); }
}
}
function notContain(testNode) {
for (i = 0; i < createdList.length; i++) {
if (createdList[i].rowAt == testNode[0] && createdList[i].colAt == testNode[1]) return false;
}
return true;
}
var openList;
var closedList;
var createdList;
var startNode;
var currentNode;
function run() {
startNode = getStartNode();
openList = [];
openList.push(startNode);
createdList = [];
createdList.push(startNode);
closedList = [];
iterationTime = 0;
//start iteration procedure
if (openList.length != 0) {
iteration();
}
}
function iteration() {
//after 2s, remove highlight of currentNode
if (currentNode != null) document.getElementById(currentNode.rowAt + "_" + currentNode.colAt).style.border = "1px solid white";
currentNode = openList.shift();
//highlight currentNode
document.getElementById(currentNode.rowAt + "_" + currentNode.colAt).style.border = "1px solid red";
console.log("currentNode is(" + currentNode.rowAt + "," + currentNode.colAt + ")")
currentNode.addNeightBor();
closedList.push(currentNode);
document.getElementById("iteration").innerText = "iteration:" + ++iterationTime;
if (currentNode.getMapValue() == goal) {
//find path through closedList
var node = closedList[closedList.length - 1]; //goal node
var path = new Array(node);
while (node.getMapValue != startNode.getMapValue) {
node = node.parent;
path.unshift(node);
}
for (i = path.length - 1; i > 0; i--) {
drawFinalPathLine(path[i], path[i].parent);
}
return;
} else setTimeout(() => {
iteration();
}, timeStep);
}
function getStartNode() {
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
if (map[i][j] == start)
return new Node(null, i, j);
}
}
}
</script>
</body>
</html>
4. generateMap.html - 生成地圖陣列
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>GenerateMapForBFS</title>
</head>
<body>
<label>row_num:</label>
<input type="text" id="num_row"><br>
<label>col_num:</label>
<input type="text" id="num_col"><br>
<button type="button" onclick="setRowAndCol()">set</button>
<button type="button" onclick="setColor(this)" style="background:black">curr_color</button>
<button type="button" onclick="generate()">generate</button><br>
<a id="panel" onmousedown="mousedown(event)" onmouseup="mouseup(event)" style="display:grid;"></a>
<div id="resultField"></div>
<script type="text/javascript">
//default rowNum and colNum
var rowNum = 10, colNum = 10;
//showed grid size
const pxSize = 20;
var color = "black";
function setRowAndCol() {
var addGridStringText = "";
if (document.getElementById("num_row").value != "")
rowNum = parseInt(document.getElementById("num_row").value);
if (document.getElementById("num_col").value != "")
colNum = parseInt(document.getElementById("num_col").value);
document.getElementById("panel").style.width = pxSize + "px";
document.getElementById("panel").style.gridTemplateColumns = (pxSize + "px ").repeat(colNum);
document.getElementById("panel").style.gridTemplateRows = (pxSize + "px ").repeat(rowNum);
document.getElementById("panel").style.width = pxSize + "px";
for (i = 0; i < rowNum; i++) {
for (j = 0; j < colNum; j++)
addGridStringText += "<div row='" + i + "' col='" + j + "' id='" + i + "_" + j + "' style=\"border:1px solid white; background-color: black; \"></div>";
}
document.getElementById("panel").innerHTML = addGridStringText;
}
function changeColor(div) {
if (div.style.backgroundColor == "black") div.style.backgroundColor = "blue";
else if (div.style.backgroundColor == "blue") div.style.backgroundColor = "green";
else if (div.style.backgroundColor == "green") div.style.backgroundColor = "red";
else if(div.style.backgroundColor == "red") div.style.backgroundColor = "black";
}
function generate() {
var map = [];
for (i = 0; i < rowNum; i++) {
var tempMap = [];
for (j = 0; j < colNum; j++) {
var element = document.getElementById(i + "_" + j);
if (element.style.backgroundColor == "black") tempMap.push(0);
else if(element.style.backgroundColor == "blue") tempMap.push(1);
else if(element.style.backgroundColor == "green") tempMap.push(2);
else if(element.style.backgroundColor == "red") tempMap.push(3);
}
map.push(tempMap);
}
result = "[";
for (i = 0; i < rowNum; i++) {
innerResult = "";
for (j = 0; j < colNum; j++)
if (j != colNum - 1) innerResult += map[i][j] + ","; else innerResult += map[i][j];
if (i != rowNum - 1) result += "[" + innerResult + "],";
else result += "[" + innerResult + "]]"
}
document.getElementById("resultField").innerText = result;
}
//get mouse drag position and resopned draw color
var mouseDownAt = [0, 0], mouseUpAt = [0, 0];
function mousedown(e) {
mouseDownAt[0] = Math.floor((e.pageY - document.getElementById("panel").offsetTop) / pxSize);
mouseDownAt[1] = Math.floor((e.pageX - document.getElementById("panel").offsetLeft) / pxSize);
}
function mouseup(e) {
mouseUpAt[0] = Math.floor((e.pageY - document.getElementById("panel").offsetTop) / pxSize);
mouseUpAt[1] = Math.floor((e.pageX - document.getElementById("panel").offsetLeft) / pxSize);
leftTopRow = mouseDownAt[0] < mouseUpAt[0] ? mouseDownAt[0] : mouseUpAt[0];
leftTopCol = mouseDownAt[1] < mouseUpAt[1] ? mouseDownAt[1] : mouseUpAt[1];
rightBottRow = mouseDownAt[0] > mouseUpAt[0] ? mouseDownAt[0] : mouseUpAt[0];
rightBottCol = mouseDownAt[1] > mouseUpAt[1] ? mouseDownAt[1] : mouseUpAt[1];
for (i = leftTopRow; i <= rightBottRow; i++) {
for (j = leftTopCol; j <= rightBottCol; j++) {
document.getElementById(i + "_" + j).style.backgroundColor = color;
}
}
}
function setColor(button) {
if (button.style.backgroundColor == "black") {
button.style.backgroundColor = "blue";
color = "blue";
} else if(button.style.backgroundColor == "blue") {
button.style.backgroundColor = "green";
color = "green";
}else if(button.style.backgroundColor == "green") {
button.style.backgroundColor = "red";
color = "red";
} else if(button.style.backgroundColor == "red") {
button.style.backgroundColor = "black";
color = "black";
}
}
</script>
</body>
</html>
5. 截圖及相關功能說明
- 兩個canvas控制路徑連線和最終路徑連線。
- 改變設定的pxSize等常量可控制相關引數如迭代時間,畫筆粗細,grid大小
- 生成地圖可以拖動,用onmousedown和onmouseup獲得座標點來實現
- 顏色對應點型別:start-green,red-goal,bule-path,black-obstacle
- B站紀念視訊
相關文章
- Android沉浸式UI實現及原理AndroidUI
- Android 沉浸式 UI 實現及原理AndroidUI
- Svm演算法原理及實現演算法
- 演算法-排序演算法思想及實現演算法排序
- WIN10UI—實現思路分享及程式碼Win10UI
- sku演算法介紹及實現演算法
- Flutter 側滑欄及城市選擇UI的實現FlutterUI
- 機器學習分享——KNN演算法及numpy實現機器學習KNN演算法
- CRC演算法原理、推導及實現演算法
- 蟻群演算法原理及Matlab實現演算法Matlab
- dijkstra and A* search 演算法心得及JS實現演算法JS
- kmp演算法實現原理及簡單示例KMP演算法
- HMAC-MD5演算法原理及實現Mac演算法
- HTML原生UI的實現HTMLUI
- js實現資料結構及演算法之排序演算法JS資料結構演算法排序
- 棧的模擬實現及常見演算法演算法
- 共識演算法PoS及Go語言實現演算法Go
- 常見排序演算法原理及JS程式碼實現排序演算法JS
- 求取眾數及重數的演算法實現(Java)演算法Java
- 令牌桶演算法原理及實現(圖文詳解)演算法
- Hybris UI的Route(路由)實現UI路由
- Vue+Element UI實現CRUDVueUI
- 面試必備:八種排序演算法原理及Java實現面試排序演算法Java
- 淺談常見的七種加密演算法及實現加密演算法
- 差分進化演算法介紹及matlab實現演算法Matlab
- 圖解氣泡排序及演算法優化(Java實現)圖解排序演算法優化Java
- 圖解選擇排序及演算法優化(Java實現)圖解排序演算法優化Java
- 全面瞭解歸併排序演算法及程式碼實現排序演算法
- 一致性hash演算法原理及go實現演算法Go
- 裁剪演算法 - Cohen Sutherland Clipping的原理及Java實現演算法Java
- SAP 電商雲 Spartacus UI 的 Product Category Navigation UI 實現UIGoNavigation
- AOP如何實現及實現原理
- **超詳細的**10種排序演算法原理及 JS 實現排序演算法JS
- 資料結構與演算法 | 棧的實現及應用資料結構演算法
- Warshall‘s algorithm 演算法的實現及優化(修改版)Go演算法優化
- 各種排序演算法總結及C#程式碼實現排序演算法C#
- react-navigation使用介紹及UI元件外實現統一跳轉ReactNavigationUI元件
- SAP 電商雲 Spartacus UI 的響應式 UI 實現細節UI