Не удается прочитать свойство '-1' из неопределенного - PullRequest
1 голос
/ 23 июня 2011

Это моя первая попытка использования классов в проекте Javascript - я пытаюсь реализовать игру жизни Конвея в HTML5 Canvas. Вот код. Как вы можете видеть, первое поколение отрисовывается нормально, но что-то не так с функцией next(), которая не позволяет ему работать дальше. (Я заметил, что рассматриваемая ошибка на самом деле выдается в последней строке get(), одной из функций, вызываемых neighbors(), которая вызывается next(). Я не могу найти никаких проблем ни в одной функции , но ясно что-то неправильно!)

Ответы [ 4 ]

3 голосов
/ 23 июня 2011

Проблема в том, [что предположение о % неверно и, следовательно,] защитные функции в функциях get/set не работают должным образом:

-1 % 42 // results in -1

Счастливое кодирование.


Я бы рассмотрел удаление защит в функциях get/set и использование значений дозорного (или другого соседнего ребра) для границы (например, первая / последняя строка и столбец фактически никогда не отображаются на экране).

Это может избежать значительного количества проверок охраны - get/set будет называться aцелую кучу раз каждой итерации (я бы даже не использовал их в качестве функций).Я считаю удаление get/set и охранников «окей», потому что эти операции являются внутренними для процесса и тесно связаны с алгоритмом - они не подвергаются непосредственному воздействию, а JavaScript работает только так быстро.

Doing a »полная проверка соседей по сетке "составляет C * O(h*w) за цикл.Несмотря на ту же сложность, значительно меньший C может значительно ускорить выполнение программы.

1 голос
/ 23 июня 2011

Давайте рассмотрим первую ячейку. Скажем, x равно 0, а y равно 0. Во время обработки этой ячейки вы закончите проверкой this.map[-1][-1]. Поскольку this.map[-1] не определено, вы не сможете найти в нем элемент -1, даже если он действительно существует (чего не существует).

У вас есть несколько вариантов:

  • Проверьте, что x > 0 перед тем, как захватить что-нибудь слева от этой ячейки, и x < this.width - 1, прежде чем захватить что-нибудь справа от нее. Аналогичная история для y и this.height.
  • Убедитесь, что this.map[x - 1] или this.map[x + 1] определены, прежде чем пытаться получить доступ к чему-либо в нем. То же самое с y +/- 1 - если он не определен, считайте его ложным.
  • Определите this.map[-1] и this.map[whatever][-1] как ложные, а также this.map[this.width] и this.map[whatever][this.height].
  • Переделайте свою математику так, чтобы x - 1 стало (x + width - 1) % width. То же самое с y - 1. Это должно заставить карту обернуться вокруг.
1 голос
/ 23 июня 2011

Линия

x = x % this.width;

не работает должным образом:

-1 % 640 

дает

-1

Простое исправление:

x = (x + this.width) % this.width;
1 голос
/ 23 июня 2011

У вас есть этот цикл в next:

 for(var y = 0; y < this.height; y++){
     for(var x = 0; x < this.width; x++){
         newMap[x][y] = this.get(x, y);

         //Rule 1: any live cell with fewer than two live neighbors dies
         if(this.get(x, y) == true && this.neighbors(x, y) < 2){
             newMap[x][y] = false;
         }

         //...

так что в вашей первой итерации x и y равны нулю. Теперь посмотрим, что делает neighbors:

this.neighbors = function(x, y){
    n = 0;
    //...
    if(this.get(x-1, y-1)){n++;}
    //...
    return n;
}

Если x и y равны 0, он пытается проверить ячейку (-1,-1):

this.map[x][y] = val;

Но ваш map имеет только положительные целочисленные ключи.

Если вы хотите «обернуть», увеличьте значения в get, чтобы избежать отрицательных значений:

x = (x + this.width) % this.width;
y = (y + this.height) % this.height;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...