Prim算法生成迷宫
程序员文章站
2022-05-14 12:09:30
初始化地图 js function initMaze(r,c){ let row = new Array(2 r + 1) for(let i = 0; i { const visited = [], key = [], parent = []; let {length} = graph; for( ......
初始化地图
function initmaze(r,c){ let row = new array(2 * r + 1) for(let i = 0; i < row.length; i++){ let column = new array(2 * c + 1) row[i] = column for(let j = 0; j < column.length; j++){ row[i][j] = 1 } } for(let i = 0; i < r; i++){ for(let j = 0; j < c; j++){ row[2 * i + 1][2 * j + 1] = 0 } } console.log(row) } initmaze(3,3)
计算二维数组坐标位置
let arr = [ [0,0,0], [0,0,0], [0,0,0] ] for(let i = 0; i < 9; i++){ let row = math.floor(i / 3) let column = i % 3 arr[row][column] = false } console.log(arr)
偏移量方向预制
let offset = [ { x:-1, y:0 }, { x:1, y:0 }, { x:0, y:-1 }, { x:0, y:1 } ] let x = 0 let y = 0 for(let i = 0; i < offset.length; i++){ x = x + offset[i].x y = y + offset[i].y console.log(x,y) }
随机数公式
1. 0-x之间的随机数: math.round(math.random()*x); 2. x至y之间的随机数 math.round(math.random()*(y-x)+x); 3. 1-x之间的随机数: math.ceil(math.random()*x);
prim算法
const inf = number.max_safe_integer function findminkey(graph,key,visited){ let min = inf let minindex //找到候选边中成本最小的节点 for(let v = 0; v < graph.length; v++){ if(!visited[v] && key[v] < min){ min = key[v] minindex = v } } return minindex } const prim = (graph) => { const visited = [], key = [], parent = []; let {length} = graph; for(let v = 0; v < length; v++){ visited[v] = false key[v] = inf } //把到第一个顶点的权值初始化为0 key[0] = 0 parent[0] = -1 //根节点不需要比 for(let i = 0; i < length - 1; i++){ //找到成本最小边的顶点 let u = findminkey(graph,key,visited) //标记下该顶点已被访问 visited[u] = true; //以及该顶点到对应其他顶点是不是成本最小的 //如果是那么就走到该顶点去 for(let v = 0; v < length; v++){ if(graph[u][v] && !visited[v] && graph[u][v] < key[v]) { parent[v] = u key[v] = graph[u][v] } } } return parent } const graph = [ [0,2,4,0,0,0], [2,0,2,4,2,0], [4,2,0,0,3,0], [0,4,0,0,3,2], [0,2,3,3,0,2], [0,0,0,2,2,0] ] const parent = prim(graph) console.log('edge weight') for (let i = 1; i < graph.length; i++) { console.log(parent[i] + ' - ' + i + ' ' + graph[i][parent[i]]); }
使用prim算法生成迷宫
- 生成2 * k + 1的迷宫,1表示墙,0表示路
- 随机选一个顶点,在该顶点上下左右随机抽取一个位置,如果没有访问过而且没有越界就选这个点生成迷宫
- 重复第2步
function roadmap(r,c){ let map = [] let rlen = 2 * r + 1 let clen = 2 * c + 1 for(let i = 0; i < rlen; i++){ map[i] = [] for(let j = 0; j < clen; j++){ //生成0101的格式 if((i ^ (i - 1)) === 1 && (j ^ (j - 1)) === 1){ map[i][j] = 0 }else{ map[i][j] = 1 } } } map[1][0] = 0; map[2 * r - 1][2 * c] = 0; return map } const mathutil = { randomint(a = 0,b){ if(typeof b === 'undefined'){ return math.floor(math.random() * a) } else { return math.floor(math.random() * (b - a) + a) } } } function maze(map){ let row = map.length >> 1 let col = map[0].length >> 1 let size = row * col let notaccessed = new array(size).fill(0) let accessed = [] let cur = mathutil.randomint(0,size) let offss = [-col,col,-1,1] //cur在notaccessed要走的偏移量 let offsr = [-1,1,0,0] //cur在map中row要走的偏移量 let offsc = [0,0,-1,1]//cur在map中col要走的偏移量 accessed.push(cur) notaccessed[cur] = 1 while(accessed.length < size){ let tr = math.floor(cur / row) let tc = cur % col let num = 0; let pos = -1 //判断四周格子是不是可以走 while(num++ < 4){ let dir = mathutil.randomint(0,4) nr = tr + offsr[dir] nc = tc + offsc[dir] if(nr >= 0 && nc >= 0 && nr < row && nc < col && notaccessed[cur + offss[dir]] === 0){ pos = dir break } } if(pos < 0){ //堵死的情况 cur = accessed[mathutil.randomint(0,accessed.length)] }else{ //可以走的情况 tr = 2 * tr + 1 tc = 2 * tc + 1 map[tr + offsr[pos]][tc + offsc[pos]] = 0 cur = cur + offss[pos] notaccessed[cur] = 1 accessed.push(cur) } } return map } function gemaze(r,c){ return maze(roadmap(r,c)) }