Creating the best possible "controlled" random system

I’ve been facing an issue with my new elevator game recently. Even though it is random, people aren’t satisfied. What people really want is a controlled random system that is “random” but partly spoofed (referred to as “random” from here on). Currently here is my function for generating a list of 5 non-repeating floors and it works perfectly:

function generateFloors()
    local maps = game.ServerStorage.Floors:GetChildren()
    local clone = maps
    local final = {}
    for i = 1, 5 do
		random = Random.new(tick())
        local rand_num = random:NextInteger(1, #clone)
        local rand_map = clone[rand_num]
        table.insert(final, #final + 1, rand_map)
        table.remove(clone, rand_num)
    end
    return final
end

The only problem is it’s not “random” enough. I need to create a list of floors but more reactive to what floors have already been chose prior. For example: if a certain floor was just chosen, a few floors later it has the chance to appear again, but because it was very recent the chances of that happening are much lower but still possible.

If you have any ideas or suggestions, that would be very appreciated. Cheers!

If I am understanding this correctly, you want a psuedorandom floor generator that will lower the chances of a floor being picked based on when it was last seen. I do not know how good this approach is but you could add a second table with the maps chance percentage and change them every rotation. To implement this I would do the following:

function generateFloors()
    local maps = game.ServerStorage.Floors:GetChildren()
    local clone = maps
    local final = {}
    local percentageChance = {}
    for _,z in pairs(maps) do
        table.insert(percentageChance, 1)  -- Change 1 to whatever you want the starting percentage to be (1 = 100% chance)
    end

    for i = 1, 5 do
		random = Random.new(tick())
        local rand_num = random:NextInteger(1, #clone)
        local rand_map = clone[rand_num]
        local newPercChance = percentChance[rand_num]
        if math.Random() < newPercChance then
            table.insert(final, #final + 1, rand_map)
            newPercChance = 0
        end
        for q, w in pairs(percentChance) do
            w = w + 0.1 -- Change to whatever you want the percentage to go up by each pass
        end
    end
    return final
end

Basically what this will do is run through the randomizer like normal, but will only add the map to the final set if it passes the secondary percent chance. After each loop, it will increase the percentage of each map being picked by 0.1 (or 10%). This should work well enough for your scenario, just make sure that the percentageChance and maps tables do not get out of sync or it will cause problems.

2 Likes

Yep! That looks right! One change I’d make though: the place where you initialize the table holding all the percents of all the floors should be outside the function as every time the function would be called all percentages of floors that have already occurred would be reset. Other than that, thanks!

EDIT:
Also, I know this is a little late, but for people just checking this thread out, the script that I marked as answer did have some bugs and I had to change a few things, so message me if you really need to know how I got it fully working.

1 Like

I use AI style probability coding for mine.

What I do is have a value added to the choices. So if it’s just been chosen, then the value is very low. If it hasn’t been chosen for a long time, I increase the value.

What you can do is have them in a table. Then randomly choose the value from the table. If you just chose it, you then run it through a for loop and table.remove any entries that match. For every other, you insert an entry. Then you just randomly choose and entry between 1 and the length of the table.

Then you just play with your values. So if you want a super slight chance of the same turning up again, you can have 1 single entry for it, and insert the others like 10 times.

That’s how I do it anyway.

1 Like