简体   繁体   English

如何阻止我的递归除法迷宫算法堵塞漏洞?

[英]How to stop my recursive division maze algorithm from plugging holes?

Relevant work is below, as well as an image.相关工作如下,还有一张图片。 The problem becomes even more apparent when I increase the recursion (lowering the base case to < 2).当我增加递归(将基本情况降低到 < 2)时,问题变得更加明显。 I think it's happening because the 'hole' can appear in the same spot as the node but I've made them distinct as well and it didn't solve the issue.我认为这是因为“洞”可以出现在与节点相同的位置,但我也将它们分开了,但并没有解决问题。 It happens on both horizontal and vertical walls.它发生在水平和垂直墙壁上。

问题视觉

divide: function (graph, height, width) {
      if (width < 4 || height < 4) {
        return
      }
      let vertical = Boolean(width > height)
      if (width === height) {
        const flip = Math.floor(Math.random() * 2)
        if (flip === 0) {
          vertical = true
        } else {
          vertical = false
        }
      }
      const node = graph[Math.floor(width / 2)][Math.floor(height / 2)]
      const hole = graph[Math.floor(Math.random() * width)][Math.floor(Math.random() * height)]
      if (vertical) {
        graph.forEach(row => {
          row.forEach(n => {
            if (n.row === node.row && !n.isStart && !n.isEnd && n.col !== hole.col) {
              setTimeout(() => {
                n.isWall = true
                document.getElementById(n.name).classList.add('wallNode')
              }, n.col * 20)
            }
          })
        })
        const rightGraph = []
        const leftGraph = []
        for (let i = 0; i < graph.length; ++i) {
          const rightRow = []
          const leftRow = []
          for (let j = 0; j < graph[i].length; ++j) {
            if (i > Math.floor(width / 2) && j < height) {
              rightRow.push(graph[i][j])
            } else if (i < Math.floor(width / 2) && j < height) {
              leftRow.push(graph[i][j])
            }
          }
          // It's 4AM don't judge me
          if (rightRow.length !== 0) {
            rightGraph.push(rightRow)
          }
          if (leftRow.length !== 0) {
            leftGraph.push(leftRow)
          }
        }
        setTimeout(() => {
          this.divide(rightGraph, height, rightGraph.length)
        }, height * 5)
        setTimeout(() => {
          this.divide(leftGraph, height, rightGraph.length)
        }, height * 5)
      } else {
        graph.forEach(row => {
          row.forEach(n => {
            if (n.col === node.col && !n.isStart && !n.isEnd && n.row !== hole.row) {
              setTimeout(() => {
                n.isWall = true
                document.getElementById(n.name).classList.add('wallNode')
              }, n.row * 20)
            }
          })
        })
        const upperGraph = []
        const lowerGraph = []

        for (let i = 0; i < graph.length; ++i) {
          const upRow = []
          const lowRow = []
          for (let j = 0; j < graph[i].length; ++j) {
            if (i < width && j < Math.floor(height / 2)) {
              upRow.push(graph[i][j])
            } else if (i < width && j > Math.floor(height / 2)) {
              lowRow.push(graph[i][j])
            }
          }
          upperGraph.push(upRow)
          lowerGraph.push(lowRow)
        }
        setTimeout(() => {
          this.divide(upperGraph, upperGraph[0].length, width)
        }, width * 5)
        setTimeout(() => {
          this.divide(lowerGraph, lowerGraph[0].length, width)
        }, width * 5)
      }
    },

It's almost this.差不多就是这个了。 You have to keep track of all the holes in the ancestry line.您必须跟踪血统中的所有漏洞。

 var sketch = function (p) { with(p) { var queue = []; var Qpos = 0; var stack = []; var vertical = (myRand(2) === 0); p.setup = function() { createCanvas(330, 330); background(255); myRect(0,0,64,64,0); strokeWeight(1); stroke(0); //rect(1, 1, 199, 199); strokeWeight(5); var parent = {'x':1,'y':1,'width':63,'height':63 ,'vertical':1, 'parent':null ,'hole':{'x':0,'y':0}}; stack.push(parent); frameRate(60); }; p.draw = function() { diviseMaze(); }; function myRand (val) { return floor(Math.random() * val); } function diviseMaze() { if (stack.length <= 0) return; var region = stack.pop(); if (region.width < 2 || region.height < 2) return; if (region.width === 2 && region.height === 2) return; // console.log(JSON.stringify(region)) var vertical = 0; if (region.width === 2) { vertical = 0; } else if (region.height === 2) { vertical = 1; } else if (region.parent) { vertical = (region.parent.vertical+1)%2; } region.vertical = vertical; var node = {'x':region.x + floor((region.width + myRand(2*region.width))/4) ,'y':region.y + floor((region.height + myRand(2*region.height))/4) }; if (region.width === 2) { node.x = region.x + myRand(2); } else if (region.width === 3) { node.x = region.x + 1; } if (region.height === 2) { node.y = region.y + myRand(2); } else if (region.height === 3) { node.y = region.y + 1; } var hole = {'x':region.x + myRand(region.width), 'y':region.y + myRand(region.height)}; region.hole = hole; if (vertical) { var leftRegion = {}; leftRegion.x = region.x; leftRegion.y = region.y; leftRegion.width = node.x - region.x; leftRegion.height = region.height; leftRegion.vertical = null; leftRegion.parent = region; leftRegion.hole = null; var rightRegion = {}; rightRegion.x = region.x + leftRegion.width + 1; rightRegion.y = region.y; rightRegion.width = region.width-1 - leftRegion.width; rightRegion.height = region.height; rightRegion.vertical = null; rightRegion.parent = region; rightRegion.hole = null; stack.push(rightRegion); stack.push(leftRegion); { let x = (node.x); let y1 = (region.y); let y2 = (region.y + region.height - 1); // stroke(0); // line(x, y1, x, y2); myLine(x, y1, x, y2, 0); } hole.x = node.x; // checked the holes for all the ancestry var r = region.parent, list = []; while (r) { if (r.hole.x === node.x && ( r.hole.y === region.y-1 || r.hole.y === region.y+region.height) ) { list.push(r.hole); } r = r.parent; } if (list.length > 1) { hole.y = region.y; myPoint(hole.x, hole.y, 255); hole.y = region.y + region.height - 1; myPoint(hole.x, hole.y, 255); return; } if (list.length > 0) { if (list[0].y < region.y) { hole.y = list[0].y + 1; } else { hole.y = list[0].y - 1; } } } else { var topRegion = {}; topRegion.x = region.x; topRegion.y = region.y; topRegion.width = region.width; topRegion.height = node.y - region.y; topRegion.vertical = null; topRegion.parent = region; topRegion.hole = null; var botRegion = {}; botRegion.x = region.x; botRegion.y = region.y + topRegion.height + 1; botRegion.width = region.width; botRegion.height = region.height-1 - topRegion.height; botRegion.vertical = null; botRegion.parent = region; botRegion.hole = null; stack.push(botRegion); stack.push(topRegion); { let x1 = (region.x); let x2 = (region.x + region.width - 1); let y = (node.y); // stroke(0); // line(x1, y, x2, y); myLine(x1, y, x2, y, 0); } hole.y = node.y; // checked the holes for all the ancestry var r = region.parent, list = []; while (r) { if (r.hole.y === node.y && ( r.hole.x === region.x-1 || r.hole.x === region.x+region.width) ) { list.push(r.hole); } r = r.parent; } if (list.length > 1) { hole.x = region.x; myPoint(hole.x, hole.y, 255); hole.x = region.x + region.width - 1; myPoint(hole.x, hole.y, 255); return; } if (list.length > 0) { if (list[0].x < region.x) { hole.x = list[0].x + 1; } else { hole.x = list[0].x - 1; } } } myPoint(hole.x, hole.y, 255); } function myPoint (x,y,c) { strokeWeight(1); stroke(255); fill(c) rect(x*5, y*5, 5, 5); noFill(); } function myLine (x1,y1,x2,y2,c) { if (x1 === x2) { if (y2 < y1) { let temp = y2; y2 = y1; y1 = temp; } for (var y = y1; y <= y2; ++y) { myPoint(x1, y, c); } } else if (y1 == y2) { if (x2 < x1) { let temp = x2; x2 = x1; x1 = temp; } for (var x = x1; x <= x2; ++x) { myPoint(x, y1, c); } } else { //todo } } function myRect (x1,y1,x2,y2,c) { if (x2 < x1) { let temp = x2; x2 = x1; x1 = temp; } if (y2 < y1) { let temp = y2; y2 = y1; y1 = temp; } myLine (x1+1,y1,x2,y1,c); myLine (x2,y1+1,x2,y2,c); myLine (x1,y2,x2-1,y2,c); myLine (x1,y1,x1,y2-1,c); } } }; let node = document.createElement('div'); window.document.getElementById('p5-container').appendChild(node); new p5(sketch, node);
 body { background-color:#efefef; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script> <div id="p5-container"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM