 # A New Random Library

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
``````
8 Likes

This is a nice utility, but there is already a RNG class built into Roblox called Random - perhaps you should change the name to something like “RandomUtility” ?

Also - I’d recommend using the `Random` class for your random generation, it’s much better than the `math.random` function.

4 Likes

Thanks for letting me know. I’ll add it ASAP

Also I forgot to thank @DrKittyWaffles for the shuffle code. It was heavily based off of what he did