Проблема, с которой вы сталкиваетесь, связана с тем, что в Ruby отсутствует концепция «многомерных массивов», отдельные массивы всегда одномерны .
Вы можете, однако, иметь вложенных массивов, которые являются массивами, которые содержат массивы, например [[], [], []]
.
Давайте посмотрим на два конкретных места:
red = Array.new # Note: this could as well be `red = []`
Итак, вы присвоили red
один пустой массив. Хорошо. Вот что вы делаете позже:
red[i][j] = ...
Нам даже не нужна остальная часть линии, она уже явно нарушена.
На самой первой итерации red
по-прежнему пустой массив . Таким образом, red[i]
- это nil
, поскольку внутри абсолютно ничего нет. nil
не имеет доступа к массиву ([]
и []=
), поэтому вы будете получать ошибки при чтении или записи в него, как если бы это был массив.
Таким образом, вам нужно red[i]
, чтобы быть фактическим массивом , чтобы вы могли помещать в него данные. Давайте сделаем это.
Поскольку вы заранее знаете размер ваших массивов, вы можете просто выделить и заполнить red
массивами соответствующей длины:
red = Array.new(width) { Array.new(height) }
Например, для width = 2
и height = 3
вот результат, который вы получите:
[
[nil, nil, nil],
[nil, nil, nil]
]
Итак, теперь, когда вы выделили все необходимые ячейки, вы можете начать перезаписывать nil
с чем-то значимым.
См. документы по Array.new
для различных способов создания массива.
Осторожно:
Я использовал «блочную» форму Array.new
по причине.
Начинающие часто допускают ошибку, используя одно значение для заполнения массива следующим образом:
red = Array.new(width, Array.new(height))
Хотя эта форма имеет свое применение, она не даст нужного вам эффекта: все записи в red
будут ссылаться на один и тот же массив , поэтому изменение любой отдельной строки будет выглядеть как будто все они изменены.
Примечание: вы, вероятно, захотите поменять размеры width
и height
, поскольку в графических программах обычно работают с массивами строк , а не столбцами. Зависит, хотя. Может не повлиять на вашу конкретную проблему.