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

Efficient way to return something by chance?

Aloha, existent ones. I want to make a key-value dictionary where the key is a thing (string, number, etc.) and the value is the chance of it being returned. I can't supply any code (sorry) because I'm not too sure how to go about doing this.

Does anyone have a way to do this?

2 comments

0

If you want the value to be the chance of it being returned, that is just to complex and inefficient. I recommend that you change your code structure so you don't need to do that.

0

No problem. Glad I could help!

1 answer

✓ Accepted answer

Hello there! This is not too difficult/complex to do. The simplest method I could think of, was 1.) get the length of the dictionary, 2.) randomly choose a number in that length, 3.) loop until you reach that random number. Because the iterator, pairs, is arbitrary already, this should leave you with a pretty random selection. You cannot just get the length of a dictionary with the # operator in Lua. You would have to create your own method. I recently posted three different methods discussed here. Ok, so now to the example:

local function dictLengthFinder(tbl) -- using one of the three methods
	local length = 0
	for i,v in pairs(tbl) do
		length = length + 1
	end
	return length
end
local function getRan(dict)
	local dictLength = dictLengthFinder(dict)
	local ranIndex = math.random(dictLength)
	local counter = 1
	for i,v in pairs(dict) do
		if counter ~= ranIndex then
			counter = counter + 1
		else
			return v 
			--[[
				I don't know what you want here. 
				I will just return the value. 
				You could also return i if you wanted.
			--]]
		end
	end
end
local dict = {} -- some dictionary
local ranItem = getRan(dict)

I hope this helps. Have a great day scripting!

Edit:

For the value to determine the probability would be rather inefficient, and there are probably better ways you could structure your code in order to remove the need for this. I will, however, walk you through how to accomplish this. 1.) create a table named chanceTbl (for this example) 2.) loop through your dictionary and store the index value amount of times in the chanceTbl 3.) randomly select an index in the chanceTbl and return the value, which would be the index in your dictionary. Here is an example:

local function getRan(dict)
	local chanceTbl = {}
	for i,v in pairs(dict) do
		for num = 1, v do
			table.insert(chanceTbl, i)
		end
	end
	local ranIndex = math.random(#chanceTbl)
	--[[
		we are able to get the length of chanceTbl with # because all the 	
		indices are in numeric order because we used table.insert
	--]]
	local ranItem = chanceTbl[ranIndex] 
	--[[
		I used two different variables so that you could 
		clearly see what is going on. Note that you could 
		do this in one variable if you just defined the variable like this:
		local ranIndex = chanceTbl[math.random(#chanceTbl)] 
	--]]
	return ranItem
	--[[
		In fact, you could just return the whole statement:
		return chanceTbl[math.random(#chanceTbl)]	
	--]]
end
local dict = {} -- some dictionary
local ranItem = getRan(dict)

Good luck!

5 comments

0

The code is pretty self explanatory, but if you don't understand anything, feel free to comment below.

0

The second example assumes that you will be inputting probability in whole numbers.

0

For example: ["blue"] = 5, ["brown"] = 16, ["black"] = 30, ["bronze"] = 43.

0

Note: Those are not percentages. They are just the amount that will appear in the chanceTbl.

0

It seemed to work fine, thanks.

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