我正在制作高度地图编辑器。基本上它是一个数字网格,您可以通过+/- 1更改任何位置。编辑器然后确保在任何触摸的8个图块之间只能存在1的差异。
我使用递归函数执行此操作。基本上它看着它的8个邻居并根据需要调整它们。如果有任何调整,请在所有8个邻居上调用该函数。
我在弄乱了一段时间后出现Uncaught RangeError: Maximum call stack size exceeded
错误,我无法看到他们来自哪里。我正在做检查,以确保我不会尝试访问不存在的网格位置......
功能如下:
var moveDown = function (x, y) {
var updated = false;
if (x-1 >= 0 && Math.abs(grid[x][y] - grid[x-1][y]) > 1) {
grid[x-1][y] -= 1;
updated = true;
}
if (x-1 < size && Math.abs(grid[x][y] - grid[x+1][y]) > 1) {
grid[x+1][y] -= 1;
updated = true;
}
if (y-1 >= 0 && Math.abs(grid[x][y] - grid[x][y-1]) > 1) {
grid[x][y-1] -= 1;
updated = true;
}
if (y+1 < size && Math.abs(grid[x][y] - grid[x][y+1]) > 1) {
grid[x][y+1] -= 1;
updated = true;
}
if (x-1 >= 0 && y-1 >= 0 && Math.abs(grid[x][y] - grid[x-1][y-1]) > 1) {
grid[x-1][y-1] -= 1;
updated = true;
}
if (x-1 >= 0 && y+1 < size && Math.abs(grid[x][y] - grid[x-1][y+1]) > 1) {
grid[x-1][y+1] -= 1;
updated = true;
}
if (x+1 < size && y-1 >= 0 && Math.abs(grid[x][y] - grid[x+1][y-1]) > 1) {
grid[x+1][y-1] -= 1;
updated = true;
}
if (x+1 < size && y+1 < size && Math.abs(grid[x][y] - grid[x+1][y+1]) > 1) {
grid[x+1][y+1] -= 1;
updated = true;
}
if (updated) {
if (x-1 >= 0) { moveDown(x-1, y); }
if (x+1 < size) { moveDown(x+1, y); }
if (y-1 >= 0) { moveDown(x, y-1); }
if (y+1 < size) { moveDown(x, y+1); }
if (x-1 >= 0 && y-1 >= 0) { moveDown(x-1, y-1); }
if (x-1 >= 0 && y+1 < size) { moveDown(x-1, y+1); }
if (x+1 < size && y-1 >= 0) { moveDown(x+1, y-1); }
if (x+1 < size && y+1 < size) { moveDown(x+1, y+1); }
}
}
我有一个小提琴here。看起来我可以内联它,所以我也这样做了。
var size = 15
var grid;
var active = {x: -1, y: -1};
var moveDown = function (x, y) {
var updated = false;
if (x-1 >= 0 && Math.abs(grid[x][y] - grid[x-1][y]) > 1) {
grid[x-1][y] -= 1;
updated = true;
}
if (x-1 < size && Math.abs(grid[x][y] - grid[x+1][y]) > 1) {
grid[x+1][y] -= 1;
updated = true;
}
if (y-1 >= 0 && Math.abs(grid[x][y] - grid[x][y-1]) > 1) {
grid[x][y-1] -= 1;
updated = true;
}
if (y+1 < size && Math.abs(grid[x][y] - grid[x][y+1]) > 1) {
grid[x][y+1] -= 1;
updated = true;
}
if (x-1 >= 0 && y-1 >= 0 && Math.abs(grid[x][y] - grid[x-1][y-1]) > 1) {
grid[x-1][y-1] -= 1;
updated = true;
}
if (x-1 >= 0 && y+1 < size && Math.abs(grid[x][y] - grid[x-1][y+1]) > 1) {
grid[x-1][y+1] -= 1;
updated = true;
}
if (x+1 < size && y-1 >= 0 && Math.abs(grid[x][y] - grid[x+1][y-1]) > 1) {
grid[x+1][y-1] -= 1;
updated = true;
}
if (x+1 < size && y+1 < size && Math.abs(grid[x][y] - grid[x+1][y+1]) > 1) {
grid[x+1][y+1] -= 1;
updated = true;
}
if (updated) {
if (x-1 >= 0) { moveDown(x-1, y); }
if (x+1 < size) { moveDown(x+1, y); }
if (y-1 >= 0) { moveDown(x, y-1); }
if (y+1 < size) { moveDown(x, y+1); }
if (x-1 >= 0 && y-1 >= 0) { moveDown(x-1, y-1); }
if (x-1 >= 0 && y+1 < size) { moveDown(x-1, y+1); }
if (x+1 < size && y-1 >= 0) { moveDown(x+1, y-1); }
if (x+1 < size && y+1 < size) { moveDown(x+1, y+1); }
}
}
var moveUp = function (x, y) {
var updated = false;
if (x-1 >= 0 && Math.abs(grid[x][y] - grid[x-1][y]) > 1) {
grid[x-1][y] += 1;
updated = true;
}
if (x-1 < size && Math.abs(grid[x][y] - grid[x+1][y]) > 1) {
grid[x+1][y] += 1;
updated = true;
}
if (y-1 >= 0 && Math.abs(grid[x][y] - grid[x][y-1]) > 1) {
grid[x][y-1] += 1;
updated = true;
}
if (y+1 < size && Math.abs(grid[x][y] - grid[x][y+1]) > 1) {
grid[x][y+1] += 1;
updated = true;
}
if (x-1 >= 0 && y-1 >= 0 && Math.abs(grid[x][y] - grid[x-1][y-1]) > 1) {
grid[x-1][y-1] += 1;
updated = true;
}
if (x-1 >= 0 && y+1 < size && Math.abs(grid[x][y] - grid[x-1][y+1]) > 1) {
grid[x-1][y+1] += 1;
updated = true;
}
if (x+1 < size && y-1 >= 0 && Math.abs(grid[x][y] - grid[x+1][y-1]) > 1) {
grid[x+1][y-1] += 1;
updated = true;
}
if (x+1 < size && y+1 < size && Math.abs(grid[x][y] - grid[x+1][y+1]) > 1) {
grid[x+1][y+1] += 1;
updated = true;
}
if (updated) {
if (x-1 >= 0) { moveUp(x-1, y); }
if (x+1 < size) { moveUp(x+1, y); }
if (y-1 >= 0) { moveUp(x, y-1); }
if (y+1 < size) { moveUp(x, y+1); }
if (x-1 >= 0 && y-1 >= 0) { moveUp(x-1, y-1); }
if (x-1 >= 0 && y+1 < size) { moveUp(x-1, y+1); }
if (x+1 < size && y-1 >= 0) { moveUp(x+1, y-1); }
if (x+1 < size && y+1 < size) { moveUp(x+1, y+1); }
}
}
var init = function () {
$('#board').mouseleave(function () {
active.x = -1;
active.y = -1;
})
.mousemove(function () {
active.x = -1;
active.y = -1;
});
$('#reset').click(function () {
for(var x=0; x<size; x++) {
for(var y=0; y<size; y++) {
grid[x][y] = 1;
}
}
});
$(window).keydown(function (e) {
if (e.keyCode === 119 || e.keyCode === 87) {
// W
grid[active.x][active.y] += 1;
moveUp(active.x, active.y);
}
if (e.keyCode === 115 || e.keyCode === 83) {
// S
grid[active.x][active.y] -= 1;
moveDown(active.x, active.y);
}
});
grid = [];
for(var x=0; x<size; x++) {
grid[x] = [];
var row = $('<div class="row">');
for(var y=0; y<size; y++) {
grid[x][y] = 1;
var cell = $('<div id="C' + x + '_' + y + '" class="cell">');
cell.data('x', x).data('y', y);
cell.mousemove(function (e) {
var $this = $(this);
active.x = $this.data('x');
active.y = $this.data('y');
e.stopPropagation();
});
row.append(cell)
}
$('#board').append(row);
}
setInterval(function () {
for(var x=0; x<size; x++) {
for(var y=0; y<size; y++) {
$('#C' + x + '_' + y).text(grid[x][y]);
}
}
$('#info').text('x: ' + active.x + ' y: ' + active.y);
}, 100);
};
init();
&#13;
#board {
padding: 20px;
z-index: -1;
}
.row {
height: 25px;
}
.cell {
position: relative;
display: inline-block;
width: 25px;
height: 25px;
border: 1px solid black;
text-align: center;
line-height: 25px;
cursor: default;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="board"></div>
<div id="info"></div>
<p>
Click on the board once to set focus. This lets the keyboard work. Press <strong>S</strong> to make a tile go down, press <strong>W</strong> to make a tile go up.
</p>
<button id="reset">Reset</button>
&#13;
答案 0 :(得分:0)
Uncaught RangeError: Maximum call stack size exceeded
当递归函数没有断点时会发生此错误。当您从该功能调用任何功能或类似的功能时。然后执行然后调用函数进入堆栈并且被调用函数进入内存执行。如果在递归之前没有返回语句或条件,则处理器堆栈将变满并抛出此错误消息。
在您的情况下,您从moveDown
致电moveDown
,但有一个条件始终为真且有责任再次致电moveDown
,或与moveUp
相同
只需使用断点进行调试,您就会得到错误的地方。