Создание двухмерных массивов в Ruby

Следующая статья является частью серии. Дополнительные статьи в этой серии см. В разделе «Клонирование игры 2048 в Ruby». Для полного и окончательного кода см. Суть.

Теперь, когда мы знаем, как будет работать алгоритм, пришло время подумать о данных, с которыми будет работать этот алгоритм. Здесь есть два основных варианта: квартира массив какой-то, или двумерный массив. У каждого есть свои преимущества, но прежде чем принять решение, нам нужно что-то учесть.

СУХИЕ Пазлы

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

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

instagram viewer
Рубин (или, точнее, как вы хотите, чтобы он был адресован и что на самом деле означают данные), вы должны решить, хотите ли вы стек строк (где каждая строка сетки представлена ​​массивом) или стек столбцов (где каждый столбец является массивом). Поскольку мы работаем со строками, мы выберем строки.

Как вращается этот двумерный массив, мы узнаем после того, как на самом деле построим такой массив.

Построение двумерных массивов

Метод Array.new может принимать аргумент, определяющий размер нужного вам массива. Например, Array.new (5) создаст массив из 5 нулевых объектов. Второй аргумент дает вам значение по умолчанию, поэтому Array.new (5, 0) даст вам массив [0,0,0,0,0]. Так как же создать двумерный массив?

Неправильный путь, и я вижу, как люди часто пытаются, это сказать Array.new (4, Array.new (4, 0)). Другими словами, массив из 4 строк, каждая строка является массивом из 4 нулей. И это, кажется, работает на первых порах. Однако запустите следующий код:

Это выглядит просто. Создайте массив нулей 4x4, установите верхний левый элемент равным 1. Но распечатайте это, и мы получим ...

Это устанавливает весь первый столбец в 1, что дает? Когда мы создали массивы, сначала вызывается самый внутренний вызов Array.new, составляя одну строку. Одна ссылка на эту строку дублируется 4 раза, чтобы заполнить самый внешний массив. Каждая строка ссылается на один и тот же массив. Измени один, измени их все.

Вместо этого нам нужно использовать третий способ создания массива в Ruby. Вместо передачи значения в метод Array.new мы передаем блок. Блок выполняется каждый раз, когда методу Array.new требуется новое значение. Так что, если бы вы сказали Array.new (5) {gets.chomp}, Ruby остановится и попросит ввести 5 раз. Так что все, что нам нужно сделать, это просто создать новый массив внутри этого блока. Таким образом, мы в конечном итоге Array.new (4) {Array.new (4,0)}. Теперь давайте попробуем этот тестовый пример снова.

И это так, как вы ожидаете.

Таким образом, хотя Ruby не поддерживает двухмерные массивы, мы все равно можем делать то, что нам нужно. Просто помните, что массив верхнего уровня содержит Ссылки к подмассивам, и каждый подмассив должен ссылаться на разные массивы значений.

То, что представляет этот массив, зависит от вас. В нашем случае этот массив представлен в виде строк. Первый индекс - это строка, которую мы индексируем, сверху вниз. Чтобы проиндексировать верхний ряд головоломки, мы используем а [0], чтобы индексировать следующую строку вниз, мы используем а [1]. Чтобы проиндексировать конкретную плитку во втором ряду, мы используем а [1] [п]. Однако, если бы мы выбрали колонны... это было бы то же самое. Ruby понятия не имеет, что мы делаем с этими данными, и, поскольку технически он не поддерживает двумерные массивы, то, что мы здесь делаем, является хаком. Доступ к нему только по соглашению, и все будет держаться вместе. Забудьте, что должны делать данные внизу, и все может быстро развалиться.

instagram story viewer