Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

math.random with Tables Dictionary?

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

3 comments

0

#Types instead of #table?

0

nope

0

You don't have a table named "table" and you can't anyways.

3 answers

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
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

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)

This discussion is preserved as it was. New answers, comments, and votes are closed.