2013-04-21 3 views
0

Итак, я делаю тральщик в JS.Игра «Сапер» - превышена максимальная сумма стека вызовов

У меня есть эта функция:

function doSquare(x, y) { //takes x,y coordinates of a square. checks and acts accordingly to what's around it 
       var revealed = []; 
       var size = board.length; 
       var mines = countAround(x,y); 
       table.rows[x].cells[y].innerHTML = mines; 



       if (mines === 0) { 
        for (var i=Math.max(0,x-1), l = Math.min(x+1, size-1); i<=l; i++) { 
         for (var j=Math.max(0, y-1), k = Math.min(y+1, size-1); j<=k; j++) { 
          if (x == i && y==j) {continue;} 
          if (revealed.indexOf(i+"."+j) === -1) { 
           doSquare(i, j); 
           revealed.push(i+"."+j); 
          } 
         } 
        } 
       } 


      } 

строк и перевалы платы равны. countAround(x,y) возвращает количество мин вокруг (x, y); revealed - это массив, в котором хранятся квадраты, которые уже были обработаны, чтобы предотвратить их повторное использование.
Эта функция должна, когда щелкнуть квадрат, показать количество мин рядом с ней и записать ее в ячейку. Затем он проверяет каждый квадрат вокруг него, и если этот квадрат еще не был обработан (если он не находится в массиве revealed), функция doSquare() снова запускается на нем. Функция не будет «распространяться» с квадрата, если на квадрате есть какие-то мины рядом с ним.

Я получаю сообщение об ошибке: максимальный размер стека вызовов превышен. Но функция останавливает свое «распространение» при достижении квадрата с минами, а также не работает на квадрате, о котором уже позаботились. Поэтому мне хотелось бы объяснить, почему это происходит.

+0

Ваша петля/рекурсия убежала, я думаю. Проверьте свои условия и ограничители. – Joseph

ответ

1

Я думаю, проблема заключается в том, что «обнаружено» определено внутри вашей функции. Это означает, что каждый раз, когда вызывается функция, для функции создается локально локально. Поэтому квадрат без мин вокруг него вызовет doSquare для смежного квадрата, который в свою очередь может вызвать doSquare на исходном квадрате. Однако doSquare не помнит, что он уже проверил этот квадрат, так как для этого вызова создается новая локальная версия «обнаружена».

Решение:

Либо пройти «показал» в качестве аргумента doSquare так что все вызовы используют ту же переменную (т.е. function doSquare(x, y, revealed){..., что делает первоначальный вызов, как doSquare(x, y, []);, или объявить «показал» вне doSquare и слейте каждый раз, когда вы хотите проверить мины.

+0

Точно. Я пропустил это ... «Выявлено» было сброшено до пустого массива каждый раз при запуске функции , – frrlod

Смежные вопросы