And I want to loop through all the cards and pick on depending on its rarity.
Basically the rarer it is the less chance you will get it(Like and loot box lol)
How would I do this?
Well, the way you want it is not the way everyone makes something like that. But it’s close. Here is a small code which will give you the results you want.
local cards = {
ProCard = {
rarity = 30
},
noobCard = {
rarity = 50
},
ExtremeCard = {
rarity = 0.5
}
}
local Max = 100
function PickRandomCard(Max)
local Random = math.random(1,Max)
local Rarity,MaxRarity
for i,v in pairs(cards) do
if v.rarity > MaxRarity then
MaxRarity = v.rarity
Rarity = v
end
end
return Rarity
end
The higher the rarity number, the lower the chance of getting the card
I played around with it for a little while.
But it is not picking doubles.
This is what I have right now:
local cards = {
ProCard = {
rarity = 51
},
noobCard = {
rarity = 50
},
ExtremeCard = {
rarity = 10
}
}
local Max = 100
function PickRandomCard(Max)
local Random = math.random(1,Max)
local Rarity = 0
local maxrarity = 0
for i,v in pairs(cards) do
if v.rarity > maxrarity then
maxrarity = v.rarity
Rarity = v
print(Rarity,maxrarity)
if maxrarity == cards.ExtremeCard.rarity then
warn('LEGENDARY CARD!!')
end
end
end
end
while true do
PickRandomCard(Max)
task.wait()
end
And basically it always prints 50 then 51. It never does 50 then 50 again, or 51 then 51. So any way to fix this?
Also dont ask why I’m making it run multiple times. I just want to see what it will give me
You are doing loop in loop; get rid of that, and it will be better. In fact, I designed this function to be used with return. The way you made just broke the entire purpose of what I did
Assuming you want to throw in probability distribution, we can write a function to calculate that.
local cards = {
ProCard = 30,
noobCard = 50,
ExtremeCard = 0.5
}
local function createDistribution(cards)
local distribution = {}
local total = 0
for card, rarity in pairs(cards) do
total = total + rarity
end
local accumulate = 0
for card, rarity in pairs(cards) do
accumulate = accumulate + rarity
distribution[card] = accumulate / total
end
return distribution
end
Then we can make a simple function to draw a card using this distribution.
local function drawCard(distribution)
local rand = math.random()
for card, prob in pairs(distribution) do
if rand <= prob then
return card
end
end
end
Here is the usage:
local distribution = createDistribution(cards)
local card = drawCard(distribution)
print(card)
Please do note, the higher the rarity value, the more common the card (it occupies a larger portion of the probability distribution). If you want to make higher rarity values mean a card is less common, you could invert the rarity in the createDistribution function, for example by changing total = total + rarity to total = total + 1/rarity and accumulate = accumulate + rarity to accumulate = accumulate + 1/rarity .
Here is the output:
local cards = {
ProCard = 30,
noobCard = 50,
ExtremeCard = 10
}
local function createDistribution(cards)
local distribution = {}
local total = 0
for card, rarity in pairs(cards) do
total = total + rarity
end
local accumulate = 0
for card, rarity in pairs(cards) do
accumulate = accumulate + rarity
distribution[card] = accumulate / total
end
return distribution
end
local function drawCard(distribution)
local rand = math.random()
for card, prob in pairs(distribution) do
if rand <= prob then
return card
end
end
end
local distribution = createDistribution(cards)
local dict = {}
for n = 0, 100 do
local card = drawCard(distribution)
if dict[card] then
dict[card] = dict[card] + 1
else
dict[card] = 0
end
end
for i, v in next, dict do
print(i, v / 100, "\n")
end
Ok, I fixed the code. Should work fine now, sorry for the errors.
local cards = {
ProCard = {
rarity = 30
},
noobCard = {
rarity = 50
},
ExtremeCard = {
rarity = 0.5
}
}
local Max = 100
function PickRandomCard(Max)
local Random = math.random(1,Max)
local Rarity
for i,v in pairs(cards) do
if v.rarity > Random then
Rarity = v
end
end
return Rarity
end
print(PickRandomCard(50).rarity)
I noticed that It pulls the same card a lot sometimes. I got the noobCard 15 time lol.
I also noticed that yes it did give me 1 single extreme card so yes it is very rare lol!
As a side note, while it’s possible to store additional information with the card rarity (like the table structure you initially proposed), it’s generally better to keep the data structure simple and specific to its purpose to avoid unnecessary complexity. This follows the single responsibility principle, making your code more maintainable and scalable. For instance, a separate table or dictionary could be used to store the card stats, keeping the draw chance and card stats distinct.
Well yes true. the reason I did this is cause I was also going to have other values so thats why.
Also I changed it so it loops through cards in a folder in ServerStorage.
But for some reason it keeps picking the legendary card instead of picking the common card.
And I have no idea why this is happening.
heres my code.
I didnt really change anything. It still should be picking the smallest value the littlest amount of time
local cards = game:GetService('ServerStorage'):FindFirstChild('Cards'):GetChildren()
local cardFolder = game:GetService('ServerStorage'):FindFirstChild('Cards')
-- get right cards
local function createDistribution(cards)
-- get the cards so we can draw from cards later
local distribution = {}
local total = 0
for card, item in pairs(cards) do
total = total + item.Rarity.Value
end
local accumulate = 0
for card, item in pairs(cards) do
accumulate = accumulate + item.Rarity.Value
local cardName = item.Name
local cardDetails = {
card = item,
rarityValue = accumulate / total
}
distribution[cardName] = cardDetails
end
return distribution
end
local function drawCard(distribution) -- draw a card from the cards.
local rand = math.random()
for card, prob in pairs(distribution) do
if rand <= prob.rarityValue then
return card -- gets the card!
end
end
end
local function getCard()
local distribution = createDistribution(cards)
local card = drawCard(distribution)
return card
end
local function displayCards(cards,player)
local debris = game:GetService('Debris')
local ui = player.PlayerGui:FindFirstChild('DisplayCards')
local sf = ui:FindFirstChild('SF')
local template = script:FindFirstChild('CardTemplate') -- the template of cards
ui.Enabled = true
for _, card in pairs(cards) do -- loop through the cards and display them
local cardItem = cardFolder:FindFirstChild(card) -- get the card
local Item = template:Clone() -- make the template
Item.Visible = true
-- set values
Item.Rarity.Text = cardItem.Rarity.Value
Item.ItemName.Text = cardItem.Name
Item.Parent = sf
debris:AddItem(Item,3)
end
wait(3)
ui.Enabled = false
end
workspace.GetCard:FindFirstChild('Propmt').Triggered:Connect(function(player)
local cards = {getCard(),getCard(),getCard()}
print(cards)
displayCards(cards,player)
end)
workspace.GetPack:FindFirstChild('Propmt').Triggered:Connect(function(player)
local cards = {getCard(),getCard(),getCard(),getCard(),getCard(),getCard(),getCard(),getCard(),getCard(),getCard()}
displayCards(cards,player)
end)