Манипуляции с массивами, и тигры, и медведи, о боже!

Проблема

Один аспект моей игровой сетки, который мне не нравился, заключался в том, что если пользователь выбрал несколько ячеек, а затем изменил размер сетки, ячейки прыгали по всей доске. При создании логики рендеринга я понимал, что это произойдет, но я решил оставить это в ледяном ящике, пока все не будет в основном работать.

Допустим, пользователь выбрал эту милую маленькую букву Т:

Если они увеличили размер сетки, когда симпатичный маленький T превратился в беспорядок:

Или, если кто-то выбрал этот маленький крестик с квадратом из большей сетки:

И решили довольно резко уменьшить размер сетки, они в конечном итоге не только измельчают, но и переставляют:

Это выглядит не очень хорошо, не так ли?

Исправление 1 - Рост сетки

Исправить это было относительно легко, потому что у меня уже была функция, которая переворачивала плоскую сетку ячеек:

В массив с накоплением:

Сначала я думал только об обновлении плоского массива, точно определяя, сколько индексов будет вставлено перед первой ячейкой, а затем между 6-й и 7-й и т. Д. Я быстро понял, что если бы я просто превратил их в отдельные фрагменты, я возможно, можно было бы быстрее объединить каждый измененный массив вместе.

Мой growCellArray(array, alpha) принимает два аргумента. Исходный плоский массив и альфа того, сколько ячеек нужно добавить к общей ширине / высоте массива. Я начинаю с массива 5x5 и передаю alpha из 2, создавая массив 7x7.

Я знаю, что нам нужно будет сложить массив мертвых ячеек вверху и внизу, поэтому сначала создайте его.

  • Я довольно часто использую метод Array.from () на протяжении всего проекта, поэтому зациклился на нем.
  • Мы можем получить размеры сетки, получив квадратный корень из длины сглаженного массива, который затем я могу добавить альфа, чтобы получить длину новой строки.

Затем нам нужно обработать обновление уже существующих массивов, которые могут иметь или не иметь активных ячеек, выбранных пользователем. Все, что изменяется в этих строках, - это передняя и конечная части массивов. К каждой стороне всегда будет добавлено дополнительное количество alpha / 2 ячеек.

Таким образом, я конвертирую плоский массив в его подмассивы, а затем заполняю каждую сторону новыми ячейками. Оператор распространения делает это проще простого.

Возврат был немного сложнее, потому что я мог просто распределить их вместе, потому что мой раздел updatedRows представляет собой единый массив других массивов. Итак, мне нужно объединить их вместе.

Итак, теперь это:

Становится меньшей T, сохраняя своих соседей и относительное положение:

Исправление 2 - сжатие сетки

Сжатие работает по-разному, потому что части массива разрушаются на каждом ходу. Однако нужны те же аргументы. array текущего состояния и alpha, представляющие то, что мы будем отрубать.

  1. Сначала я разбиваю все на их подмассивы.
  2. Затем я возвращаю массив с удаленными первым и последним разделами для каждого подмассива.
  3. Затем я фильтрую все подмассивы и избавляюсь от первого и последнего.
  4. Затем я собрал все массивы вместе, чтобы получить сплющенный массив, который использует мой рендеринг.

Примечание

Здесь я объединяю несколько разных методов вместе, а также использую тройной, но я стараюсь, чтобы такие вещи были удобочитаемыми. Правильный интервал и название имеют решающее значение для понимания вещей позже. Иногда я просматриваю переполнение стека и вижу сообщения, в которых есть несколько символов, использованных для создания чего-либо. Как, черт возьми, это полезно? Я полагаю, что приведенный выше пример мог бы быть сложным, если бы кто-то не был знаком с различными методами массива, поэтому комментарии могут быть полезны в этом случае. Избегая семантических проблем, связанных с правильным именованием каждого шага редактирования, можно избежать путаницы, если я выберу нелепые имена переменных. Мне нравится хорошее сочетание правильно названных переменных для хранения вещей и связанных вместе методов в более сложных сценариях.

Вот продукт нашей окончательной функции усадки. Наши T и Square меняются с:

К большему относительно позиционированию:

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

Еще не все!

Первоначально опубликовано на gist.github.com.