迷宫生成
戳我去GitHub看详细代码以及生成动画>>>>迷宫生成
下文所涉及的迷宫代码为:
- 只有一个出口,一个入口
- 解有且只有一个
- 方形画布,行与列均为奇数
- 墙与路径均占一个格子
- 路径连续
思路
- 初始化出如下图所示的图形,然后进行图的遍历
通过遍历目前的白色方块,然后按照某种方法连通两个方块(即把两者之间的蓝色方块变成白色)
// row, col, 迷宫的行数 列数
// paintProgressTime, 开启可视化展示时的间隔
// width = 500, height = 500 迷宫的宽高 默认500px
// 此demo所实现的迷宫为固定出口,固定入口, 解有且只有一个,行与列均为奇数
// demo中所有坐标相关的变量均代表的是第几行 第几列 从0开始
constructor(row, col, paintProgressTime, width = 500, height = 500) {
// 类名
this.class = Math.random().toFixed(2)
// Maze行列
this.row = row
this.col = col
// 迷宫的长宽
this.width = width
this.height = height
// 设置路与墙
this.road = ' '
this.wall = '#'
// 入口坐标(1, 0)
this.entryX = 1
this.entryY = 0
// 出口坐标(倒数第二行, 最后一列)
this.outX = row - 2
this.outY = col - 1
// 迷宫数据
this.maze = []
// 各节点的遍历情况
this.visited = []
// 设置上下左右的偏移坐标值(上右下左)
this.offset = [[-1, 0], [0, 1], [1, 0], [0, -1]]
// 可视化展示间隔
this.paintProgressTime = paintProgressTime
this.i = 0 // 可视化展示索引
}
// 初始化迷宫数据
initData(maze) {
for (let i = 0; i < this.row; i++) {
maze[i] = new Array(this.col).fill(this.wall) // 初始化二维数组
this.visited[i] = new Array(this.col).fill(false) // 初始化访问状态为false
for (let j = 0; j < this.col; j++) {
// 横纵坐标均为奇数 则是路
if (i % 2 === 1 && j % 2 === 1) {
maze[i][j] = this.road
}
}
}
// 入口及出口 则是路
maze[this.entryX][this.entryY] = this.road
maze[this.outX][this.outY] = this.road
return maze
}
// 初始化迷宫DOM
initDOM(maze) {
let oDiv = document.createElement('div')
oDiv.style.width = this.width + 'px'
oDiv.style.height = this.height + 'px'
oDiv.style.display = 'flex'
oDiv.style.flexWrap = 'wrap'
oDiv.style.marginBottom = '20px'
for (let i = 0; i < maze.length; i++) {
for (let j = 0; j < maze[i].length; j++) {
let oSpan = document.createElement('span')
oSpan.dataset.index = i + '-' + j + '-' + this.class
oSpan.style.width = (this.width / this.col).toFixed(2) + 'px'
oSpan.style.height = (this.height / this.row).toFixed(2) + 'px'
// 加边框
// oSpan.style.border = '1px solid #ccc'
// oSpan.style.boxSizing = 'border-box'
oSpan.style.background = maze[i][j] === this.wall ? '#4facfe' : '#fff'
oDiv.appendChild(oSpan)
}