我一直在使用洪水填充例程来检查某种类型的块,然后查找所有相同类型的连接块,并将它们更改为键入" stone" 我主要感兴趣的是块的坐标,并且不想改变它们,但是当我删除"更改为stone"声明似乎无休止地运行。 在研究之后,似乎深度优先搜索可以工作但不确定如何实现 - 似乎我只需要调整洪水填充,但我尝试的一切都无休止地循环或在第一次迭代时停止。 这是原始计划。
//interact
var node1 = {
xy : []
};
var blockp;
//starting block type and position
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 = function (nameb, node) {
if (nameb == "minecraft:stone" || nameb == null) {
return;
}
var blkname;
var xy0 = node.xy[0];
var xy1 = node.xy[1];
var xy2 = node.xy[2];
//
//Line I would like to remove
world.setBlock(node.xy[0], node.xy[2], node.xy[1], world.createItem("minecraft:stone", 0, 1));
//
// collect x y z positions for all blocks
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;
} else {
blkname = world.getBlock(node.xy[0], node.xy[2], node.xy[1]).name;
}
floodfill(blkname, node);
//
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;
} else {
blkname = world.getBlock(node.xy[0], node.xy[2], node.xy[1]).name;
}
floodfill(blkname, node);
//
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;
} else {
blkname = world.getBlock(node.xy[0], node.xy[2], node.xy[1]).name;
}
floodfill(blkname, node);
//
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;
} else {
blkname = world.getBlock(node.xy[0], node.xy[2], node.xy[1]).name;
}
floodfill(blkname, node);
//
node.xy[0] = xy0;
node.xy[1] = xy1;
node.xy[2] = xy2 + 1;
npc.say("go up " + blkname);
if (world.getBlock(node.xy[0], node.xy[2], node.xy[1]) == null) {
blkname = null;
} else {
blkname = world.getBlock(node.xy[0], node.xy[2], node.xy[1]).name;
npc.say("go up " + blkname);
}
floodfill(blkname, node);
//
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;
} else {
blkname = world.getBlock(node.xy[0], node.xy[2], node.xy[1]).name;
}
floodfill(blkname, node);
//
return;
}
floodfill(blockp.name, node1);

答案 0 :(得分:0)
让我首先了解为什么洪水填充永远不会结束:它不知道什么时候必须停止,因为没有一个块发生变化。该程序认为它之前从未遇到过阻塞,并再次看到它,并再次看到......
深度优先搜索是一种更深入的搜索方法,直到它不再存在。当你撞到一个部件的末端时,你会回去,直到你遇到一个你以前从未见过的物品,然后在与之相关的任何东西中潜水。
广度优先搜索恰恰相反。它会检查连接到起始点的内容,检查所有内容,然后检查所有子项及其子项,等等。
因为你想找到所有相互连接的块,所以你选择哪种搜索方法没有区别,因为它们会找到相同O(n)复杂度的所有项目。
我个人对你正在尝试做的事情一无所知,但我试图尽可能保持这种普遍性。
对于这些搜索中的任何一个,block
应该有一个名为visited
的变量或类似的变量,您可以用它来表示您之前是否遇到此阻止。您可能必须自己创建此变量。
您还需要一种方法来查找block
所连接的block
并将其作为数组或列表返回。在示例中,我将调用此函数neighbours()
。
要实施DFS,您需要Stack。堆栈是一个LIFO数据结构,这意味着最后出现的是第一件事。将某些东西放入堆栈称为push
。将该项目取回称为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是不同的,稍微适合您要做的事情。它使用Queue来存储以先进先出顺序搜索所需的所有内容。这意味着稍后将搜索搜索树下方的内容,这通常更适合任何搜索。向队列中添加内容称为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)time complexity中运行。
祝你好运!