写在前面:
虽然说prim算法和A*算法不难理解。但是由于对编程语言掌握的不够扎实,导致实现起来比较困难,写的不是很好。其次由于着急着手写的太快,导致需求没有记清楚,最后还有部分功能 没有实现。(文末提供原码)
代码实现:
主要分为两部分:第一、prim算法生成迷宫;第二、A*算法解迷宫。
结构部分:
<div id="canv">
<canvas id="stage"></canvas>
</div>
<ul id="ul"></ul>
<input type="button" value="开始寻路" id="input" />
<button class="rebuild" onclick="javascript:window.location.reload()">点击刷新</button>
样式部分:
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
#ul {
overflow: hidden;
border: 1px #000 solid;
border-bottom: none;
border-right: none;
position: absolute;
top: 0px;
right: 525px;
}
#ul li {
box-sizing: border-box;
border-top: none;
border-left: none;
float: left;
}
#ul li.sty1 {
background-color: red;
}
#ul li.sty2 {
background-color: skyblue;
}
#ul li.sty3 {
background-color: black;
}
#input {
width: 100px;
position: absolute;
right: 638.5px;
top: 340px;
}
#stage {
border: 1px solid lightgray;
}
.rebuild {
width: 100px;
text-align: center;
cursor: pointer;
position: absolute;
left: 626.5px;
top: 310px;
}
#canv {
width: 302px;
height: 302px;
left: -1000px;
position: absolute;
}
代码逻辑部分:
prim算法生成迷宫:
设置基本的canvas画板:
window.onload = function () {
var stage = document.querySelector('#stage')
var ctx = stage.getContext('2d')
stage.width = 300
stage.height = 300
生成某个区域内的随机数x=[min, max)
function randInt(min, max) {
max = max || 0
min = min || 0
var step = Math.abs(max - min)
var start = arguments.length < 2 ? 0 : min //参数只有一个的时候st=0;
var result = start + Math.ceil(Math.random() * step) - 1
return result
}
prim算法生成连通图的二维数组:
// 动态生成二维数组
function init(r, c) {
var array = new Array(2 * r + 1)
// 全部置1
for (let i = 0; i < array.length; i++) {
var cols = 2 * c + 1
array[i] = new Array(cols)
for (let j = 0; j < array[i].length; j++) {
array[i][j] = 3
}
}
// 中间特定格子置0
for (let i = 0; i < r; i++)
for (let j = 0; j < c; j++) {
array[2 * i + 1][2 * j + 1] = 0
}
r
处理数组,产生最终的数组:
function process(arr) {
// 声明已访问队列visitedQueue, 没有被访问队列unVisitedQueue
var vedQueue = []
var unvedQueue = []
// var r = arr.length >> 1
// var c = arr[0].length >> 1
// 7行7列,15行15列,再转回7行7列
var r = (arr.length - 1) / 2
var c = (arr[0].length - 1) / 2
var count = r * c
// 没有被访问队列全部置0
for (var i = 0; i < count; i++) {
unvedQueue[i] = 0
}
// 定义空单元上下左右偏移
var offs = [-c, c, -1, 1]
var offR = [-1, 1, 0, 0]
var offC = [0, 0, -1, 1]
// 随机从unvedQueue取出一个位置
var uvqRandNum = randInt(count)
unvedQueue[uvqRandNum] = 1
vedQueue.push(uvqRandNum)
while (vedQueue.length < count) {
var ls = -1
var offPos = -1
// 找出uvqRandNum位置在二维数组中的坐标
var pr = (uvqRandNum / c) | 0
var pc = uvqRandNum % c
var co = 0
var o = 0
// 随机取上下左右四个单元
while (++co < 5) {
o = randInt(0, 5)
ls = offs[o] + uvqRandNum
var tpr = pr + offR[o]
var tpc = pc + offC[o]
if (tpr >= 0 && tpc >= 0 && tpr <= r - 1 && tpc <= c - 1 && unvedQueue[ls] == 0) {
offPos = o
break