I’m trying to get a good shotgun spread for my game, but sometimes I come across the occasional duplicate, causing my entire shotgun to shoot straight in one line. I’ve looked through all the devforum posts about duplicate math.randoms but I still can’t find any good solution. Here’s what I’ve done so far
local function random(divide)
return math.random(-spread,spread)/divide
end
local function makerandom(division)
local randomtable = {}
local randomspread = random(division)
if table.find(randomtable, randomspread) then
repeat random(division) until not table.find(randomtable, randomspread)
return randomspread
else
table.insert(randomtable,#randomtable+1,randomspread)
return randomspread
end
end
How can I make this more efficient or get rid of duplicate randoms?
You’re creating a new, empty randomtable each time makerandom() is called, so you’re not actually checking for duplicates. You need to define that table outside of the makerandom function, so that multiple calls to makerandom can add to it.
Once you get that fixed, you’ll also need to be sure that all your randomspread rolls get added to the randomtable, and your code currently won’t add them if it has to re-roll for a duplicate, since you have a return inside your if statement that returns a value of randomspread without adding it to the randomtable.
This is great! But I’m getting a script timeout every time I activate the tool.
local randomtable = {}
local function random(divide)
return math.random(-spread,spread)/divide
end
local function makerandom(division)
local randomspread = random(division)
if table.find(randomtable, randomspread) then
repeat random(division) until not table.find(randomtable, randomspread)
table.insert(randomtable,#randomtable+1,randomspread)
return randomspread
else
table.insert(randomtable,#randomtable+1,randomspread)
return randomspread
end
end
```
That’s because you have an infinite loop. Your repeat loop is always checking table.find(randomtable, randomspread) with the same value of randomspread. You can’t throw away the return value from random(division), you need to be doing randomspread = random(division) inside the loop so the value changes.
Your if-then is also unnecessary and makes the code harder to read. Consider doing just this:
local function makerandom(division)
repeat
randomspread = random(division)
until not table.find(randomtable,randomspread)
table.insert(randomtable,randomspread)
return randomspread
end
local randomtable = {}
local function random(divide)
return math.random(-spread,spread)/divide
end
local function makerandom(division)
local randomspread = random(division)
if table.find(randomtable, randomspread) then
repeat randomspread = random(division) until not table.find(randomtable,randomspread)
table.insert(randomtable,#randomtable+1,randomspread)
return randomspread
else
table.insert(randomtable,#randomtable+1,randomspread)
return randomspread
end
end
I’m still getting the script timeout, what should I do? Sorry if I’m being a bit dull here.
Try what I added above. If it still hangs, it means your random() function is being called with values for spread and divide that result in it generating fewer possible outcomes than the number of times you’re calling it, i.e. it’s running out of unique values.
I would advise against the table. That shouldn’t be necessary and it is a very expensive calculation to run per bullet, especially up to infinite times per bullet.