Почему для этих значений установлены неправильные переменные?

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

Этот код используется для игры по добыче полезных ископаемых, которую я делаю в Roblox, которая используется для генерации руды.

--[[
an ore can have one of these different 'spawn types' that is predefined when the game starts which dictates what 'OreTypes' it can have,
and if there are multiple OreTypes under one SpawnType,
then percent values will be given controlling the odds of one OreType being chosen over the other.
]]--
OreSpawnTypes = {} 

-- all the different ore Types
OreTypes = {} 

--[[ 
creates a new ore type with its name, the ore's base value, 
and variables defining how it looks in game. 
ignore 'chance=0' that's just for defining purposes
]]--
function add_ore_type(n,ov,bc,mat,ref,tran) -- 
    OreTypes[n] = {
        BrickColor=bc,
        Material=mat,
        Reflectance=ref,
        Transparency=tran,
        Name=n,
        ore_value=ov,
        chance=0
    }
end

--[[
when used in 'add_spawn_type' to keep track of the previous ore type, 
that was just created by it, to be used in 'add_ore'
to add the different ores do the ore type
--]]
local name = ""

--[[
creates a new spawn type, and sets the name variable to the key
of the ore type listed in the OreSpawnTypes table
--]]
function add_spawn_type(n)
    OreSpawnTypes[n] = {}
    name=n
end

--[[
adds one of the defined ores from 'OreTypes' and with a number form 1-100,
adds it to the previously created spawntype
--]]
function add_ore(ch,n)
    local o = OreTypes[n]
    o.chance = ch

    OreSpawnTypes[name][#OreSpawnTypes[name]+1] = o
end

-- what I use to view the table
function show_spawn_types()

print("------------------------------------------------")

for k,v in pairs(OreSpawnTypes) do
    print(k.."=")
    for k2,v2 in pairs(v) do
        print("                "..k2.."=")
        for k3,v3 in pairs(v2) do
            print("                        "..k3.."="..v3)
        end
    end
end
end

-- this next part is where the ore types are set and the ores are set to each one.

add_ore_type("grass",2,"Earth green","Plastic",0,0)
add_ore_type("ground",4,"Earth green","Slate",0,0)
add_ore_type("rock",8,"Dark stone grey","Slate",0,0)

add_spawn_type("grass")
add_ore(100,"grass") --<NOTE ARGUMENT ONE

add_spawn_type("grass/ground")
add_ore(50,"grass") --<NOTE ARGUMENT ONE
add_ore(50,"ground") --<NOTE ARGUMENT ONE

add_spawn_type("ground")
add_ore(100,"ground") --<NOTE ARGUMENT ONE

add_spawn_type("rock")
add_ore(100,"rock") --<NOTE ARGUMENT ONE

show_spawn_types()

ниже приведен список руд, которые я планирую добавить. некоторые используются в приведенном выше коде.

--[[ 
0= all_grass
1= grass/ground
2= ground 
3= rock
4= rock/stone
5= stone
6= stone/limestone/slate
7= gold deposit
8= silver deposit
9= nickel deposit
10= copper deposit
11= emerald deposit
12= saphire deposit
13= ruby deposit
14= diamond deposit
15= rare mineral deposit
16= super rare ores 1
17= super rare ores 2
18= radioactive ores
--]]

Проблема в том, что на выходе show_spawn_types() он показывает:

grass=
            1=
                    Transparency=0
                    BrickColor=Earth green
                    Reflectance=0
                    chance=50 --<NOTE THESE VARIABLES
                    Material=Plastic
                    Name=grass
                    ore_value=2
rock=
            1=
                    Transparency=0
                    BrickColor=Dark stone grey
                    Reflectance=0
                    chance=100 --<NOTE THESE VARIABLES
                    Material=Slate
                    Name=rock
                    ore_value=8
ground=
            1=
                    Transparency=0
                    BrickColor=Earth green
                    Reflectance=0
                    chance=100 --<NOTE THESE VARIABLES
                    Material=Slate
                    Name=ground
                    ore_value=4
grass/ground=
            1=
                    Transparency=0
                    BrickColor=Earth green
                    Reflectance=0
                    chance=50 --<NOTE THESE VARIABLES
                    Material=Plastic
                    Name=grass
                    ore_value=2
            2=
                    Transparency=0
                    BrickColor=Earth green
                    Reflectance=0
                    chance=100 --<NOTE THESE VARIABLES
                    Material=Slate
                    Name=ground
                    ore_value=4

Если вы заметите первый аргумент в функции add_ore() и сравните его с их значениями в выходных данных, единственная связанная руда типа спауна «трава» имеет шанс появления 50, когда я установил его равным 100 в функции. Кроме того, первая подключенная руда имеет шанс появления 100, тогда как он должен быть 50.

Я проверял это многими способами, я поместил функцию print() в функцию добавления руды, где установлена ​​переменная вероятности появления. И в этих отладках это показывает, что переменная устанавливается правильно, но дело в том, что ... Нигде в коде я не устанавливаю случайную переменную после этого, если только значения каким-то образом не `` смешиваются '', но даже тогда Я проверил, чтобы убедиться, что он устанавливает значение для правильного типа спауна.

Есть ли что-то, чего мне не хватает, или я нашел ошибку в lua ???

ПРИМЕЧАНИЕ. Я предлагаю вам скопировать и вставить код в командную строку lua, отредактировать код и ввести функции печати для отладки частей кода. Должно работать правильно.


person Andrew900460    schedule 01.09.2015    source источник


Ответы (1)


Переменные в Lua содержат ссылки на таблицы, поэтому назначение не создает новую таблицу. Например:

 a = {chance=100}
 b = a
 b.chance = 50
 print(a.chance) -- outputs 50

Проблема проявляется в этой функции:

function add_ore(ch,n)
    local o = OreTypes[n]
    o.chance = ch
    OreSpawnTypes[name][#OreSpawnTypes[name]+1] = o
end

Последняя строка помещает в таблицу еще одну ссылку (не копию), и поэтому в следующий раз, когда вы вызовете add_ore с тем же именем для n, изменение o.chance = ch повлияет на все ссылки на OreTypes[n].

Вы можете создать копию таблицы o перед ее изменением.

local copy = {}
for k, v in pairs(OreTypes[n]) do copy[k] = v end
copy.chance = ch
OreSpawnTypes[name][#OreSpawnTypes[name]+1] = copy

Похоже, что у вас есть прототип, и вы хотите создать его варианты. Копировать проще всего, но Lua поддерживает прототипы с метатаблицами, которые могут вас заинтересовать.

person ryanpattison    schedule 01.09.2015
comment
Мне это интересно, но какой из них менее требователен к процессору? Я предполагаю, что это метатаблицы - person Andrew900460; 02.09.2015
comment
Метатаблицы немного сложнее в вычислениях, они применяются после сбоя поиска, поэтому они могут выполнять два поиска, но они могут быть намного более эффективными с точки зрения памяти. Однако с такими крошечными таблицами ни один из них не будет иметь значения, и чистый поддерживаемый код имеет гораздо большую ценность. - person ryanpattison; 02.09.2015