如何防止此地图生成器创建这样的接触角:
-X
X-
或者
X-
-X
这是生成器的简化示例:http: //jsfiddle.net/fDv9C/2/
由于您创建板的方式,在生成期间进行此检查非常困难。我创建了检查板之后的简单功能。它使用洪水算法。这里是小提琴http://jsfiddle.net/jzTEX/8/(蓝色背景是原图,红色背景是检查后的地图)
基本上我们创建第二个数组grid2
。填充后grid
我们递归运行floodV
函数
function floodV(x,y) {
var shiftArray = [[0,1],[0,-1],[1,0],[-1,0]];
grid2[y][x]=1;
for(var k=0;k<4;k++) {
var x1=x+shiftArray[k][0];
var y1=y+shiftArray[k][1];
if(grid[y1][x1] == 1 && grid2[y1][x1] == 0 && checkV(x1,y1)) {
grid2[y1][x1] = 1;
floodV(x1,y1);
}
}
}
带有检查功能
function checkV(x,y) {
var checkVarr = [[-1,-1], [-1,1], [1,1], [1,-1]];
for(var k=0;k<4;k++) {
if(grid[y+checkVarr[k][0]][x+checkVarr[k][1]] == 1 && grid[y+checkVarr[k][0]][x] == 0 && grid[y][x+checkVarr[k][1]] == 0 && grid2[y+checkVarr[k][0]][x+checkVarr[k][1]] == 1)
return false;
}
return true;
}
这并不完美,因为我们有时会丢弃地图的大部分,但如果我们尝试开始添加新元素,我们必须再次检查整个地图(在值得的情况下)。
您的问题几乎可以自行回答。
这是小提琴:http: //jsfiddle.net/qBJVY/
if (!!grid[y][x] && !!grid[y+1][x+1] && !grid[y+1][x] && !grid[y][x+1]) {
good=false;
grid[y+1][x]=2;
}
它只是检查您不想要的组合并修补它们。它总是添加一个网格点,以免断开地图的任何部分。
这反过来可能会导致可能出现问题的另一种情况,但如果它改变了任何东西(即,如果它发现问题),它将再次检查。这可以进行优化,例如通过递归调整任何更改的内容,但通常只需要 1 或 2 遍。那里有一个限制器,不允许超过 100 次通过,以防万一出现无法修复的不可预见的情况(不过,我想不出这种情况 :))。
这就是我所做的:http: //jsfiddle.net/fDv9C/13/
魔法发生在哪里?向下滚动到第 53 到 58 行:
var bottom = y_next + 1;
var left = x_next - 1;
var right = x_next + 1;
var top = y_next - 1;
if (grid[top][left] || grid[top][right] ||
grid[bottom][left] || grid[bottom][right]) continue;
简而言之,您的接触角点只能出现在计算出的下一个位置。因此,如果下一个位置的四个角落邻居中的任何一个存在,则必须计算另一个下一个位置。
i
当碰巧获得尽可能多的路径时,您甚至可以减少计数器(尽管它并没有真正产生很大的不同):
var bottom = y_next + 1;
var left = x_next - 1;
var right = x_next + 1;
var top = y_next - 1;
if (grid[top][left] || grid[top][right] ||
grid[bottom][left] || grid[bottom][right]) {
i--;
continue;
}
在此处查看演示:http: //jsfiddle.net/fDv9C/12/
编辑:我无法抗拒。我必须创建一个自动地图生成器,这样我就不需要一直点击运行:http: //jsfiddle.net/fDv9C/14/