Javascript 为什么我的迷宫生成器无法检测p5.js中是否访问过某个单元格?

Javascript 为什么我的迷宫生成器无法检测p5.js中是否访问过某个单元格?,javascript,vector,p5.js,maze,Javascript,Vector,P5.js,Maze,我正在尝试制作一个迷宫发生器,到目前为止,几乎所有的东西都在工作。我可以将我的位置设置为随机的pos,然后重复standard()功能。在函数中,我将pos添加到posList,然后选择一个随机方向。接下来,我通过反向运行所有posList向量来检查该单元是否已被访问。我还没有执行回溯的代码。如果visted=false则我移动到正方形并执行有待生成的path()函数。然而,出于某种原因,移动器无法检测是否有人访问过某个小区。我正在使用p5.js。我做错了什么 var posList = [];

我正在尝试制作一个迷宫发生器,到目前为止,几乎所有的东西都在工作。我可以将我的位置设置为随机的
pos
,然后重复
standard()
功能。在函数中,我将
pos
添加到
posList
,然后选择一个随机方向。接下来,我通过反向运行所有
posList
向量来检查该单元是否已被访问。我还没有执行回溯的代码。如果
visted=false
则我移动到正方形并执行有待生成的
path()
函数。然而,出于某种原因,移动器无法检测是否有人访问过某个小区。我正在使用p5.js。我做错了什么

var posList = [];
var pos;
var tempo;
var boole = false;
var direc;
var mka = 0;
function setup() {
  createCanvas(400, 400);
  //Set up position
  pos = createVector(floor(random(3)), floor(random(3)));
  frameRate(1)
}

//Choose a direction
function direct(dire) {
  if(dire === 0) {
    return(createVector(0, -1));
  } else if(dire === 1) {
    return(createVector(1, 0));
  } else if(dire === 2) {
    return(createVector(0, 1));
  } else {
    return(createVector(-1, 0));
  }
}

/foLo stands fo forLoop
function foLo() {
  //If we have checked less than three directions and know there is a possibility for moving
  if(mka < 4) {
    //tempoRARY, this is what we use to see if the cell has been visited
    tempo = createVector(pos.x + direct(direc).x, pos.y + direct(direc).y);
    //Go through posList backwards
    for(var i = posList.length - 1; i >= 0; i --) {
      //If the cell has been visited or the cell is off of the screen
      if(tempo ===  posList[i]) {
        //Change the direction
        direc ++;
        //Roll over direction value
        if(direc === 4) {
          direc = 0;
        }
        //Re-execute on next frame
        foLo();
        //The cell has been visited
        boole = false;
        //Debugging
        console.log(direc)
        mka++;
      } else if(tempo.x < 0 || tempo.x > 2 || tempo.y < 0 || tempo.y > 2) {
        direc ++;
        if(direc === 4) {
          direc = 0;
        }
        foLo();
        boole = false;
        console.log(direc)
        mka++;
      }
    }
    //If it wasn't visited (Happens every time for some reason)
    if(boole === true) {
      //position is now the temporary value
      pos = tempo;
      console.log("works")
      mka = 0;
    }
  }
}

function standard() {
  //Add pos to posList
  posList.push(pos);
  //Random direction
  direc = floor(random(4));
  //Convert to vector
  direct(direc);
  foLo();
  //Tracks pos
  fill(255, 255, 0);
  rect(pos.x*100+50, pos.y*100+50, 50, 50)
}

function draw() {
  background(255);
  fill(0);
  noStroke();
  //draw grid
  for(var i = 0; i < 4; i ++) {
    rect(i*100,0,50,350);
    rect(0, i*100, 350, 50);
  }
  standard();
  boole = true;
  console.log(pos)
  console.log(posList);
}
var posList=[];
var-pos;
变音节拍;
var boole=false;
var-direc;
var mka=0;
函数设置(){
createCanvas(400400);
//设置位置
pos=createVector(floor(random(3)),floor(random(3));
帧率(1)
}
//选择一个方向
功能直接(dire){
如果(可怕===0){
返回(createVector(0,-1));
}否则如果(可怕===1){
返回(createVector(1,0));
}否则如果(可怕===2){
return(createVector(0,1));
}否则{
返回(createVector(-1,0));
}
}
/foLo代表loop
函数foLo(){
//如果我们检查了不到三个方向,并且知道有可能移动
if(mka<4){
//暂时的,这是我们用来查看手机是否被访问过的
tempo=createVector(pos.x+direc.x,pos.y+direc.y);
//向后浏览posList
对于(var i=posList.length-1;i>=0;i--){
//如果该单元已被访问或该单元不在屏幕上
if(节奏===posList[i]){
//改变方向
direc++;
//翻滚方向值
如果(direc==4){
direc=0;
}
//在下一帧重新执行
foLo();
//该牢房已被查访
布尔=假;
//调试
console.log(direc)
mka++;
}else if(tempo.x<0 | | tempo.x>2 | | tempo.y<0 | | tempo.y>2){
direc++;
如果(direc==4){
direc=0;
}
foLo();
布尔=假;
console.log(direc)
mka++;
}
}
//如果它没有被访问(由于某种原因每次都会发生)
如果(布尔===真){
//位置现在是临时值
pos=节奏;
控制台日志(“工作”)
mka=0;
}
}
}
功能标准(){
//将pos添加到posList
posList.push(pos);
//随机方向
direc=地板(随机(4));
//转换为向量
直接(direc);
foLo();
//跟踪位置
填充(255,255,0);
矩形(位置x*100+50,位置y*100+50,50,50)
}
函数绘图(){
背景(255);
填充(0);
仰泳();
//绘制网格
对于(变量i=0;i<4;i++){
rect(i*100,0,50350);
rect(0,i*100350,50);
}
标准();
布尔=真;
控制台日志(pos)
console.log(posList);
}

您的问题在于比较两个向量的行
如果(tempo===posList[i]){
:这永远不会是真的

您可以使用以下代码(例如在
setup()
中)验证:

这是因为尽管具有相同的值
v1
v2
,但它们引用了两个不同的对象

您可以使用该函数。该文档有以下示例:

let v1 = createVector(10.0, 20.0, 30.0);
let v2 = createVector(10.0, 20.0, 30.0);
let v3 = createVector(0.0, 0.0, 0.0);
print(v1.equals(v2)); // true
print(v1.equals(v3)); // false
这可能不会为您提供一个有效的算法,因为我怀疑您有其他逻辑错误(但我可能错了,或者您稍后会调试它们),但至少这部分代码会达到您的预期效果


另一种解决方案是使用
集合
而不是你的职位列表。这种解决方案的缺点是你必须调整你的代码来处理“出格”位置情况。但是,当您想要跟踪访问的项目时,
Set
通常是一个很好的解决方案,因为访问时间是恒定的。这意味着要定义一个已经访问过的位置,它总是需要相同的时间(您将执行类似于
visitedSet.has(positionToCheck)的操作)
,而对于迭代列表的解决方案,访问的单元格越多,检查该单元格是否在列表中所需的时间就越长

Set
解决方案将要求您在通过正弦将向量添加到集合之前对向量进行变换,我在前面已经解释过,您不能简单地比较向量。因此,您可以使用如下内容检查向量的字符串表示:

const visitedCells = new Set();
const vectorToString = (v) => `${v.x},{$v.y}` // function to get the vector representation

// ...
visitedCells.add(vectorToString(oneCell)); // Mark the cell as visited

visited = visitedCells.has(vectorToString(anotherCell))

还有一个一般性的建议,你应该注意你的变量和函数名

// foLo stands fo forLoop
function foLo() {
是一个很大的气味:当你看到你的函数调用时,你的函数名应该是描述性的。必须找到函数声明旁边的注释会使代码不那么可读。你可以调用它
generateMaze()
,这样你就不用看函数代码就知道它在做什么

同样适用于

//tempoRARY, this is what we use to see if the cell has been visited
tempo = createVector(pos.x + direct(direc).x, pos.y + direct(direc).y);
例如,您可以简单地将
tempo
重命名为
cellToVisit

或者
boole
:命名一个布尔
boole
不会传递很多信息


当您刚刚编写代码时,这可能看起来像是一些小细节,但当您的代码将有几百行,或者在休息几天后再次阅读时,您会感谢您的照顾。

好的!我现在明白了。我知道向量是如何不同的对象。此外,我可以同意您的看法,即有可能除了其他错误,我对编码还比较陌生。非常感谢!@TheCodedMasterCubing这是一个很好的开始编码的主题!我还添加了一小段关于如何查找访问的单元格的内容。这对于小迷宫可能没有用,但对于较大的迷宫,您可能需要它。出于好奇,我用它制作了一个迷宫生成器五月五日
//tempoRARY, this is what we use to see if the cell has been visited
tempo = createVector(pos.x + direct(direc).x, pos.y + direct(direc).y);