In summary : if i get 239/239 i enable some function, and if it’s not 239 but another random number, call other function
how can i achieve this and manage to do it in percentages?, what would 1/239 equal to in percentage?
In summary : if i get 239/239 i enable some function, and if it’s not 239 but another random number, call other function
how can i achieve this and manage to do it in percentages?, what would 1/239 equal to in percentage?
You could just do
local r = math.random(1,239)
if r == 239 then
-- Got lucky
else
-- Didn't get lucky
end
A 1/239 chance in decimal would literally just be 1 divided by 239, multiply that by 100 to get percent and you have about a 0.4184% chance
Thanks for the info, I think this could do it, but since my game needs to rely on accurate random functions, i don’t think math.random would be the best, But thanks anyways, i’ll have that in mind
math.random
generates usually perfectly fine random numbers unless you’re doing something that needs to be cryptographically secure.
Although you can use the new Random object which has slightly better results when making multiple random calls very close together.
Besides that, any number your computer generates is going to be puesdo-random in nature without using external sources.
Yeah, But Usually weighted systems make use of tables, which kinda concerns me
Weighted randomness still uses math.random though, they just make more numbers equal to each different type of thing.
Here’s a post that covers weighted randomness
You just reminded me, i got a weighted system a long time ago, but i forgot what it uses, or what to input
can you help me ?
local Chances = {
{Rarity = "Blood Hour", Chance = 50};
{Rarity = "Vision Hour", Chance = 30};
{Rarity = "Blackout", Chance = 10};
{Rarity = "Rare+", Chance = 7};
{Rarity = "Epic", Chance = 3};
}
local function GetRandomRarity()
local Sum = 0
for , Table in ipairs(Chances) do
Sum += Table.Chance
end
local RNG = Random.new():NextInteger(1, Sum)
local Weight = 0
for , Table in ipairs(Chances) do
Weight += Table.Chance
if Weight >= RNG then
return Table.Rarity
end
end
end
local RandomRarity = GetRandomRarity()
print(GetRandomRarity())
you see, the chances in the table are 50, 30, 10, 7 and 3, but how i know what porcentage they are?, or what is this system using?
for example, would i put “50” that is 50% or 0.5, that is also 50%?
For the future, this is not a “do it for me” category. You should at least understand the code given to you.
Anyways, weighted systems are essentially just a sum of all values. It doesn’t matter if your values are 50, 30, 10, 7, 3
or 5, 3, 1, 0.7, 0.3
, they both have the same odds for the items.
Getting the odds is also basic math: divide your weighted value by the sum all the weighted values (multiplied by 100 for the percentage).
Alright, thank you, sorry if i “sounded” too harsh or bad at the beginning, As for that, i said i already got the code, but i was asking for reference or guide in what to change, you can see
I wrote my own WeightedRandom
module a few months ago if you would like to use it:
--!strict
local WeightedRandom = {}
export type WeightedRandom<I> = typeof(setmetatable({} :: WeightedRandomClass<I>, {} :: WeightedRandomMetatable))
export type WeightedRandomClass<I> = {
Random: Random,
GetItems: (self: WeightedRandom<I>) -> {[I]: Item},
AddItem: (self: WeightedRandom<I>, item: I, weight: number, luckFactor: number?) -> (),
RemoveItem: (self: WeightedRandom<I>, item: I) -> (),
GetWeight: (self: WeightedRandom<I>, item: I, luckFactor: number?) -> number?,
GetWeights: (self: WeightedRandom<I>, luckFactor: number?) -> {[I]: number},
GetTotalWeight: (self: WeightedRandom<I>, luckFactor: number?) -> number,
GetProbability: (self: WeightedRandom<I>, item: I, luckFactor: number?) -> number?,
GetProbabilities: (self: WeightedRandom<I>, luckFactor: number?) -> {[I]: number},
Next: (self: WeightedRandom<I>, luckFactor: number?) -> I
}
export type WeightedRandomMetatable = {
__index: (self: any, index: any) -> any,
__newindex: (self: any, index: any, value: any) -> (),
__iter: (self: any) -> (),
__tostring: (self: any) -> string
}
export type Item = {
Weight: number,
LuckInfluence: number
}
local function clone<T>(t: T, deep: boolean?): T
t = table.clone(t :: any) :: any
if deep == true then
for index: any, value: any in t :: any do
if typeof(value) == "table" then
(t :: any)[index] = clone(value, true)
end
end
end
return t
end
function WeightedRandom.new<I>(random: Random?): WeightedRandom<I>
local items: {[I]: Item} = {}
local weightedRandomClass: WeightedRandomClass<I> = {
Random = random or Random.new(),
GetItems = function(weightedRandom: WeightedRandom<I>): {[I]: Item}
return clone(items, true)
end,
AddItem = function(weightedRandom: WeightedRandom<I>, item: I, weight: number, luckInfluence: number?): ()
items[item] = {
Weight = weight,
LuckInfluence = if luckInfluence ~= nil then luckInfluence else 0
}
end,
RemoveItem = function(weightedRandom: WeightedRandom<I>, item: I): ()
items[item] = nil
end,
GetWeight = function(weightedRandom: WeightedRandom<I>, item: I, luckFactor: number?): number?
if items[item] ~= nil then
return items[item].Weight + (items[item].Weight * (items[item].LuckInfluence * (if luckFactor ~= nil then luckFactor else 1)))
else
return nil
end
end,
GetWeights = function(weightedRandom: WeightedRandom<I>, luckFactor: number?): {[I]: number}
local weights: {[I]: number} = {}
for item: I in items do
weights[item] = weightedRandom:GetWeight(item, luckFactor) :: number
end
return weights
end,
GetTotalWeight = function(weightedRandom: WeightedRandom<I>, luckFactor: number?): number
local totalWeight: number = 0
for _: I, weight: number in weightedRandom:GetWeights(luckFactor) do
totalWeight += weight
end
return totalWeight
end,
GetProbability = function(weightedRandom: WeightedRandom<I>, item: I, luckFactor: number?): number?
if items[item] ~= nil then
return (weightedRandom:GetWeight(item, luckFactor) :: number) / weightedRandom:GetTotalWeight(luckFactor)
else
return nil
end
end,
GetProbabilities = function(weightedRandom: WeightedRandom<I>, luckFactor: number?): {[I]: number}
local probabilities: {[I]: number} = {}
for item: I in weightedRandom:GetWeights(luckFactor) do
probabilities[item] = weightedRandom:GetProbability(item, luckFactor) :: number
end
return probabilities
end,
Next = function(weightedRandom: WeightedRandom<I>, luckFactor: number?): I
local weightedItems: {[I]: number} = weightedRandom:GetWeights(luckFactor)
local totalWeight: number = weightedRandom:GetTotalWeight(luckFactor)
local randomWeight: number = weightedRandom.Random:NextNumber() * totalWeight
local lastItem: I = nil
for item: I, weight: number in weightedItems do
randomWeight -= weight
lastItem = item
if randomWeight <= 0 then
return item
end
end
return lastItem
end,
}
local weightedRandomMetatable: WeightedRandomMetatable = table.freeze({
__index = function(self: any, index: any): any
return weightedRandomClass[index]
end,
__newindex = function(self: any, index: any, value: any): ()
if index == "Random" then
if typeof(value) ~= "Random" then
error(`invalid value for index '{index}' (Random expected, got {typeof(value)})`, 2)
end
else
error(`{index} cannot be assigned to`, 2)
end
weightedRandomClass[index] = value
end,
__iter = function(self: any): ()
error(`attempted to iterate over a WeightedRandom`, 2)
end,
__tostring = function(self: any): string
return `WeightedRandom`
end
})
return table.freeze(setmetatable({}, weightedRandomMetatable)) :: any
end
return WeightedRandom
You can use it like so:
-- path to WeightedRandom
local WeightedRandom = require()
-- if you would like to strictly assign types
type WeightedRandom<I> = WeightedRandom.WeightedRandom<I>
-- creates a new WeightedRandom with strictly string items,
-- (or it automatically infers when using WeightedRandom:AddItem())
local myWeightedRandom: WeightedRandom<string> = WeightedRandom.new()
-- setup WeightedRandom
local someTableOdds = {
["Common"] = 50,
["Uncommon"] = 30,
["Rare"] = 10,
["Epic"] = 5,
["Legendary"] = 3,
["Mythical"] = 2
}
for rarity: string, weight: number in pairs(someTableOdds) do
myWeightedRandom:AddItem(rarity, weight)
-- optional 3rd parameter for luckInfluence
-- that defaults to 0
end
-- you can then use the following functions that includes an optional
-- luckFactor argument that defaults to 1
-- (multiplies the odds along with luckInfluence)
-- Get a random item with a luckFactor of 1 (default)
local chosenRarity: string = myWeightedRandom:Next()
print(`Chosen rarity: {chosenRarity}`)
-- Get probabilities with a luckFactor of 5
for rarity: string, probability: number in myWeightedRandom:GetProbabilities(5) do
print(`{rarity}: {probability * 100}`)
end
thank you so much, both of you
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.