You may have noticed that math.random()
doesn’t do much, and there could be certain circumstances where you need a specific type of random. Random.new() has more features but sometimes you may need more. This is why I want to give you guys a more advanced random number generator.
The first feature is super simple. It just returns exactly what Roblox would return. I added this so that you wouldn’t need to use math.random()
or Random.new()
again.
RandomUtility = {}
function RandomUtility.new(m,n)
if tonumber(m) then
return Random.new():NextInteger(m,n)
else
return m[Random.new():NextInteger(1,#m)]
end
end
RandomUtility.new(1,10) --returns random number from 1-10
You can also return keys from tables using this.
local fruits = {"Apple","Banana","Orange","Pineapple"}
RandomUtility.new(fruits) --returns random fruit
And lastly you can specify which integers to include and exclude
local Numbers = {1,3,6,9,11}
RandomUtility.new(Numbers) --Only returns odd numbers
The second feature that I want to show is it’s ability to evade duplicates using the RandomUtility.shuffle()
function. Obviously when something is random, there’s a chance that it may repeat, even if the chances are low.
You can stop that problem with this function:
RandomUtility = {}
function RandomUtility.shuffle(m,n,_dataTable)
local _table
local function returnRandom(a,b,c)
if not _dataTable then
_table=a;c=b;b=#a;a=1
end
local rand = Random.new():NextInteger(a,b)
repeat
rand = Random.new():NextInteger(a,b)
wait()
until (not c[rand])
c[rand] = true
if b == #c then
for i, int in ipairs(c) do
if int == true then
table.clear(c)
c[rand] = true
end
wait()
end
end
if _dataTable then
return rand
else
return _table[rand]
end
end
if tonumber(m) then
return returnRandom(m,n,_dataTable)
else
return returnRandom(m,n)
end
end
After you have that base, you can simply do something like this to stop duplicates one after another.
local save = {} --Data gets stored inside a table so you need to give it an empty table to work with
RandomUtility.shuffle(1,10,save) --Stops numbers from repeating twice. For example, would return something like 3,1,6,9 instead of 3,1,1,6
NOTE: This isn’t very efficient with large numbers because as you generate more and more numbers, the chance that you encounter a new number goes down, and this script repeats random until it finds a new one. So if you did something like Random.shuffle(1,10000,save)
, There would be a 1 in 10000 chance to generate a new number, and the way that it finds new numbers is that it generates them randomly. I’m currently working on a more efficient shuffle, and any recommendations on how to go about this would be appreciated.
You can also get a random shuffle with keys in tables. This stops the same key from returning.
local save = {}
local fruits = {"Apple","Banana","Orange","Pineapple"}
RandomUtility.shuffle(fruits,save)
Once again, this also means that you can make a table of integers to specify which integers to include and exclude.
local save = {}
local Numbers = {2,4,6,8,10}
RandomUtility.shuffle(Numbers,save) --Only returns even numbers
The last thing that I want to show is RandomUtility.precise()
. You may notice that if you do math.random(0,0.5)
or Random.new():NextInteger(0,0.5)
, it will always return 0. The reason is because math.random
only allows for whole integers. With RandomUtility.precise()
, you can get decimals up to the 100000000th point. The code for that is:
RandomUtility = {}
function RandomUtility.precise(m,n,decimalPlaces)
if decimalPlaces then
local num = math.clamp(decimalPlaces,0,8)
local rand = Random.new():NextInteger(m*10^num,n*10^num)
return rand/10^num
else
local rand = Random.new():NextInteger(m*10^8,n*10^8)
return rand/10^8
end
end
RandomUtility.precise(1,10,5) --Returns a random value from 1-10 with 5 decimal points after the whole number. Example: 5.12345 instead of 5
RandomUtility.precise(0,0.5,3) --Example: Would return 0.255 instead of 0
Those are all of the features that I currently added. If you have any recommendations for another type of random to add, optimization, etc, then please let me know. Also PLEASE tell me if you encounter any bugs and if there are any errors in this topic. Other than that, thank you for reading.
WHOLE CODE:
RandomUtility = {}
function RandomUtility.new(m,n)
if tonumber(m) then
return Random.new():NextInteger(m,n)
else
return m[Random.new():NextInteger(1,#m)]
end
end
function RandomUtility.shuffle(m,n,_dataTable)
local _table
local function returnRandom(a,b,c)
if not _dataTable then
_table=a;c=b;b=#a;a=1
end
local rand = Random.new():NextInteger(a,b)
repeat
rand = Random.new():NextInteger(a,b)
wait()
until (not c[rand])
c[rand] = true
if b == #c then
for i, int in ipairs(c) do
if int == true then
table.clear(c)
c[rand] = true
end
wait()
end
end
if _dataTable then
return rand
else
return _table[rand]
end
end
if tonumber(m) then
return returnRandom(m,n,_dataTable)
else
return returnRandom(m,n)
end
end
function RandomUtility.precise(m,n,decimalPlaces)
if decimalPlaces then
local num = math.clamp(decimalPlaces,0,8)
local rand = Random.new():NextInteger(m*10^num,n*10^num)
return rand/10^num
else
local rand = Random.new():NextInteger(m*10^8,n*10^8)
return rand/10^8
end
end