Создание отдельных таблиц Lua для каждого объекта в массиве

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

На самом деле я мало что пробовал, так как я новичок в программировании и не нашел в Интернете почти никакой информации, касающейся моей конкретной проблемы.

Вам следует уточнить, что вы подразумеваете под словами «Но я не могу найти способ создавать новые таблицы Lua, поскольку присвоение новой переменной таблице не копирует ее.», желательно с минимальным воспроизводимым примером (т. е. , некоторый код) для резервного копирования.

Oka 20.08.2024 02:20

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

Piglet 20.08.2024 07:46

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

Gabriel 21.08.2024 00:14
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Допустим, ваш массив выглядит следующим образом (и имейте в виду, что массивы Lua представляют собой таблицы с числовыми индексами):

monsters = {[1] = "orc", [2] = "troll", [3] = "ogre"}

да, у вас возникнут проблемы, если вы попытаетесь создать один шаблон таблицы «статистика» и присвоить его каждому имени монстра в массиве:

stats = {["strength"] = 15, ["health"] = 10}

monster_stats = {} -- initialize new table for stats

for k,v in ipairs(monsters) do
        monster_stats[v] = stats
end

monster_stats["orc"].strength = 10 -- change strength

print(monster_stats["orc"].strength)

print(monster_stats["troll"].strength)

выход:

10
10

Мы хотим изменить только силу орка, но в конечном итоге мы изменяем силу каждого. Это потому, что и monster_stats["orc"] и monster_stats["troll"] указать на ту же таблицу в памяти. Вам нужен способ клонировать таблицу — и пример есть на lua.org[0].

Добавьте эту функцию в начало вашего скрипта, и теперь вы сможете вызывать clone() во время присваивания. На этот раз все идет так, как задумано, потому что переменная «статистика» каждого монстра указывает на отдельную таблицу в памяти.

function clone (t)           -- t is a table
  local new_t = {}           -- create a new table
  local i, v = next(t, nil)  -- i is an index of t, v = t[i]
  while i do
    new_t[i] = v
    i, v = next(t, i)        -- get next index
  end
  return new_t
end
    
monsters = {[1] = "orc", [2] = "troll", [3] = "ogre"}

stats = {["strength"] = 15, ["health"] = 10}

monster_stats = {} -- initialize new table for stats

for k,v in ipairs(monsters) do
        monster_stats[v] = clone(stats)
end

monster_stats["orc"].strength = 10 -- change strength

print(monster_stats["orc"].strength)

print(monster_stats["troll"].strength)

выход:

10
15

Вы можете увидеть, что все таблицы теперь разделены, распечатав значения самих таблиц:

print(monster_stats["orc"])
print(monster_stats["troll"])
print(monster_stats["ogre"])

выход:

table: 0x55be070536b0
table: 0x55be07053bc0
table: 0x55be07053c80

Ссылки:

[0] https://www.lua.org/manual/2.4/node31.html

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

Gabriel 20.08.2024 04:13

@Габриэль - нет такой вещи, как глупый вопрос (en.wikipedia.org/wiki/No_ such_thing_as_a_stupid_question). Ответ — нет, функция клонирования продолжает создавать новые таблицы при каждом вызове благодаря ключевому слову «local». Я отредактировал свой ответ, чтобы продемонстрировать.

ebcode 20.08.2024 05:36

ваша функция клонирования не «клонирует» таблицу. он полностью игнорирует возможную метатаблицу.

Piglet 20.08.2024 09:07

Спасибо! Это проясняет то, что меня интересовало, спасибо за объяснение!

Gabriel 21.08.2024 00:12

Другие вопросы по теме