Javascript Can';I don’我不知道如何将洪水填充例行程序更改为DFS 1
我一直在使用洪水填充例行程序,该程序检查特定类型的块,然后找到相同类型的所有连接块,并将它们更改为“石头”类型 我主要对块的坐标感兴趣,不想更改它们,但当我删除“ChangetoStone”语句时,它似乎无休止地运行。 在研究之后,深度优先搜索似乎会起作用,但不确定如何实现这一点-似乎我只需要仔细检查洪水的填充情况,但我尝试的每件事都会在第一次迭代时无休止地循环或停止。 这是原始程序Javascript Can';I don’我不知道如何将洪水填充例行程序更改为DFS 1,javascript,minecraft,Javascript,Minecraft,我一直在使用洪水填充例行程序,该程序检查特定类型的块,然后找到相同类型的所有连接块,并将它们更改为“石头”类型 我主要对块的坐标感兴趣,不想更改它们,但当我删除“ChangetoStone”语句时,它似乎无休止地运行。 在研究之后,深度优先搜索似乎会起作用,但不确定如何实现这一点-似乎我只需要仔细检查洪水的填充情况,但我尝试的每件事都会在第一次迭代时无休止地循环或停止。 这是原始程序 //交互 变量节点1={ xy:[] }; var-blockp; //启动块类型和位置 blockp=wor
//交互
变量节点1={
xy:[]
};
var-blockp;
//启动块类型和位置
blockp=world.getBlock(npc.getBlockX(),npc.getBlockY()-1,npc.getBlockZ()+1);
node1.xy[0]=npc.getBlockX();
node1.xy[1]=npc.getBlockZ()+1;
node1.xy[2]=npc.getBlockY()-1;
//
var floodfill=功能(名称B,节点){
if(nameb==“minecraft:stone”| | nameb==null){
返回;
}
var blkname;
var xy0=node.xy[0];
var xy1=node.xy[1];
var xy2=node.xy[2];
//
//我想删除的行
setBlock(node.xy[0],node.xy[2],node.xy[1],world.createItem(“地雷工艺:石头”,0,1));
//
//收集所有块的x y z位置
world.getTempData(“X_corr”).push(node.xy[0]);
world.getTempData(“Y_corr”).push(node.xy[2]);
world.getTempData(“Z_corr”).push(node.xy[1]);
//
node.xy[0]=xy0;
node.xy[1]=xy1+1;
node.xy[2]=xy2;
if(world.getBlock(node.xy[0],node.xy[2],node.xy[1])==null){
blkname=null;
}否则{
blkname=world.getBlock(node.xy[0],node.xy[2],node.xy[1]).name;
}
洪水填充(blkname,节点);
//
node.xy[0]=xy0;
node.xy[1]=xy1-1;
node.xy[2]=xy2;
if(world.getBlock(node.xy[0],node.xy[2],node.xy[1])==null){
blkname=null;
}否则{
blkname=world.getBlock(node.xy[0],node.xy[2],node.xy[1]).name;
}
洪水填充(blkname,节点);
//
node.xy[0]=xy0+1;
node.xy[1]=xy1;
node.xy[2]=xy2;
if(world.getBlock(node.xy[0],node.xy[2],node.xy[1])==null){
blkname=null;
}否则{
blkname=world.getBlock(node.xy[0],node.xy[2],node.xy[1]).name;
}
洪水填充(blkname,节点);
//
node.xy[0]=xy0-1;
node.xy[1]=xy1;
node.xy[2]=xy2;
if(world.getBlock(node.xy[0],node.xy[2],node.xy[1])==null){
blkname=null;
}否则{
blkname=world.getBlock(node.xy[0],node.xy[2],node.xy[1]).name;
}
洪水填充(blkname,节点);
//
node.xy[0]=xy0;
node.xy[1]=xy1;
node.xy[2]=xy2+1;
说:“上去”+blkname);
if(world.getBlock(node.xy[0],node.xy[2],node.xy[1])==null){
blkname=null;
}否则{
blkname=world.getBlock(node.xy[0],node.xy[2],node.xy[1]).name;
说:“上去”+blkname);
}
洪水填充(blkname,节点);
//
node.xy[0]=xy0;
node.xy[1]=xy1;
node.xy[2]=xy2-1;
if(world.getBlock(node.xy[0],node.xy[2],node.xy[1])==null){
blkname=null;
}否则{
blkname=world.getBlock(node.xy[0],node.xy[2],node.xy[1]).name;
}
洪水填充(blkname,节点);
//
返回;
}
洪水填充(区块名称,节点1)代码>让我从洪水泛滥永不停止的原因开始:它不知道何时必须停止,因为所有的积木都不会改变。程序认为它以前从未遇到过这个块,并且一遍又一遍地查看它
深度优先搜索是一种搜索方法,它可以进行更深入的搜索,直到无法再进行搜索为止。当你撞到一个部分的末端时,你会返回,直到你遇到一件你以前从未见过的东西,然后尽可能深入到与之相关的任何东西中
广度优先搜索正好相反。它检查连接到startpoint的内容,检查所有内容,然后检查其所有子项及其子项,依此类推
因为您希望查找彼此连接的所有块,所以选择哪种搜索方法没有区别,因为它们将查找具有相同O(n)复杂度的所有项
我个人不知道你想做什么,但我想让它尽可能普遍
对于这两种搜索,block
应该有一个名为visitored
的变量或类似的变量,您可以使用它来表示您以前是否遇到过此块。您可能需要自己创建这个变量。
您还需要找到块
连接到的所有块
的方法,并将其作为数组或列表返回。在示例中,我将调用此函数neights()
要实现DFS,您需要一个。堆栈是后进先出的数据结构,这意味着最后进入的是第一个出来的。将某些内容放入堆栈称为推送。将项目取出称为pop
以下是DFS的伪代码:
DFS(Block start) {
Stack stack = new stack();
stack.push(start); // Put the first block in the stack
while(stack.count > 0) {
Block current = stack.pop();
if(current.visited)
continue; // if we've already seen this block, don't bother
current.visited = true;
/* YOU CAN DO ANYTHING YOU WANT WITH THE BLOCK HERE */
Block[] neighbours = current.neighbours();
foreach(neighbour in neighbours)
stack.push(neighbour);
}
}
BFS是不同的,稍微更适合你正在尝试做的事情。它使用一个数据库,以先进先出的顺序存储它需要搜索的所有内容。这意味着搜索树下更远的东西将在以后搜索,这通常更适合于任何搜索。向队列中添加内容称为enqueue
,将下一个内容取出称为dequeue
以下是BFS的伪代码:
BFS(Block start)
Queue queue = new Queue();
queue.enqueue(start); // Put the first block in the stack
while(queue.count > 0) {
Block current = queue.dequeue();
if(current.visited)
continue; // if we've already seen this block, don't bother
current.visited = true;
/* YOU CAN DO ANYTHING YOU WANT WITH THE BLOCK HERE */
Block[] neighbours = current.neighbours();
foreach(neighbour in neighbours)
queue.enqueue(neighbour);
}
}
正如您所看到的,这两种搜索方法非常相似,它们都在O(n)中运行
祝你好运