Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

math.random with Tables Dictionary?

Asked by 6 years ago

local Types = { ["LeftPunch"] = {Id = 1784490345, DamagePart = "LeftHand", Damage = 10}, ["RightPunch"] = {Id = 1784483797, DamagePart = "RightHand", Damage = 10} }

local Type = Types[math.random(1, #table)] print(Type)

it keep saying interval is empty

0
#Types instead of #table? User#20279 0 — 6y
0
nope MaxOutGaming -3 — 6y
0
You don't have a table named "table" and you can't anyways. MooMooThalahlah 421 — 6y

3 answers

Log in to vote
2
Answered by 6 years ago
Edited 6 years ago

I did some reading up on why you can't print(Types[1]). Or print(#Types) keeps returning 0. Here's a quote from:

lua.users.org

The # operator doesn't count all the items in the table (!). Instead it finds the last integer (non-fractional number) key. Because of how it's implemented its results are undefined if all the integer keys in the table aren't consecutive. Which is why it shouldn't be used for tables used as sparse arrays[2]).

If you go to the website and click the "2" it will lead you to Wikipedia and you can read more about it.

Interval is empty because you tried to do math.random(1,0)

Not sure if this is the best approach but you can explicitly assign an Index value in your tables.

-- Assign your own index
local Types = { 
    ["LeftPunch"] = {Index = 1, Id = 1784490345, DamagePart = "LeftHand", Damage = 10},
    ["RightPunch"] = {Index = 2, Id = 1784483797, DamagePart = "RightHand", Damage = 10} 
}
local numOfPunches = 0

print("What is #table: " .. #table)
--print(math.random(1,0)) -- Interval is empty
--print(math.random(1,#table)) -- Interval is empty

print(#Types) -- Prints 0
-- Not what we wanted
print(Types[1]) -- Prints nil
-- Also not what we wanted

-- Counts how many entrys you have in your matrix
-- Useful if you plan to add or remove punches
for punchType,entry in pairs(Types) do
    numOfPunches = numOfPunches + 1
    print(punchType .. " " .. tostring(entry))
end
print("You have " .. numOfPunches .. " types of punches.\n")

local function RandomPunch()
    local rng = math.random(1,numOfPunches)

    for _,entry in pairs(Types) do
        -- Compare it to the Index assigned at the top
        if entry.Index == rng then
            print(entry.DamagePart .. " did " .. entry.Damage .. " damage.")
        end
    end
end

while wait(1) do
    RandomPunch()
end
Ad
Log in to vote
0
Answered by
hellmatic 1523 Moderation Voter
6 years ago
Edited 6 years ago
local Types = {
    Enabled = true 

    ,RightPunch = {
        Enabled = true 

        ,Damage = 10

        ,Id = 1784483797
        ,Hand = "RightHand"
     }

    ,LeftPunch = {
        Enabled = true 

        ,Damage = 10

        ,Id = 1784490345
        ,Hand = "LeftHand"
     }

}

local RightPunch = Types.RightPunch
local LeftPunch = Types.LeftPunch

local randomtype = nil 

function RANDOM()
    randomtype = math.random(1, 2) -- 1 = Right, 2 = Left

    if (randomtype == 1) then 
        print("Chose " .. RightPunch.Hand .. ". Damage:" .. RightPunch.Damage "")

    elseif (randomtype == 2) then 
        print("Chose " .. LeftPunch.Hand .. ". Damage:" .. LeftPunch.Damage "")
    end
end

function PUNCH()
    RANDOM()
end
Log in to vote
0
Answered by
Validark 1580 Snack Break Moderation Voter
6 years ago

Here is a generalized WeightedProbability Generator function. It is also installable through the RoStrap plugin. Documentation available here.

local WeightedProbabilities = {}

local WeightedProbabilityFunction =  {
    -- Generates option-picker functions from relative probabilities
    -- @readme https://github.com/RoStrap/WeightedProbabilityFunction/blob/master/README.md
    -- @rostrap WeightedProbabilityFunction
    -- @author Validark

    new = function(ProbabilityData)
        -- @param dictionary in the form: {
        --      [variant option1] = number Weight1;
        --      [variant option2] = number Weight2;
        -- }
        -- @returns a function that, when called, selects an option from its probability and returns it

        local n = 0
        local TotalWeight = 0
        local Options = {}
        local RelativeWeights = {}

        for Option, RelativeWeight in pairs(ProbabilityData) do
            assert(type(RelativeWeight) == "number", "ProbabilityData must be in the form {variant Option = number Weight}")
            assert(RelativeWeight >= 0, "Weights must be non-negative numbers")

            n = n + 1
            TotalWeight = TotalWeight + RelativeWeight

            Options[n] = Option
            RelativeWeights[n] = RelativeWeight
        end

        ProbabilityData = nil

        assert(TotalWeight ~= 0, "Please give an option with a weight greater than 0")

        for i = 1, n do
            RelativeWeights[i] = RelativeWeights[i] / TotalWeight
        end

        local function Pick(Picked)
            Picked = Picked or math.random()

            for i = 1, n do
                Picked = Picked - RelativeWeights[i]
                if Picked < 0 then
                    local Option = Options[i]
                    return WeightedProbabilities[Option] and Option() or Option
                end
            end
        end

        WeightedProbabilities[Pick] = true

        return Pick
    end
}

local Types = {
    LeftPunch = {
        Id = 1784490345;
        DamagePart = "LeftHand";
        Damage = 10;
    };

    RightPunch = {
        Id = 1784483797;
        DamagePart = "RightHand";
        Damage = 10;
    };
}

local RandomPunch = WeightedProbabilityFunction.new {
    [Types.LeftPunch] = 0.5;
    [Types.RightPunch] = 0.5;
}

table.foreach(RandomPunch(), print)

Answer this question