Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
6

Randomly Select Player?

Asked by 10 years ago

I have been trying to think of a way to randomly select a player, which I can do, but I can't figure out a way to give people a better chance of being picked if they have a specific gamepass. I'm not quite sure how I would be able to do this, does anybody know a way how to do this? Any help would be appreciated. I have provided the code I use to randomly select one player, all I need to do is find a way to increase the odds for somebody that has the gamepass without making them selected too often or not as often.

players = {}

function start()
    wait(1)
    players = game.Players:GetPlayers()
    local selected = players[math.random(1, #players)].Name
    print(selected)
end

3 answers

Log in to vote
2
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
10 years ago

This problem is to find a random choice, given different weights to each choice.

Think of the weight as the number of raffle tickets each player has. Let's say normal users have 1, but players with a game pass have 10 (though this is easy to configure).

This model works like this:

  • Only one player can win
  • Everyone, even with poor odds, has a small chance to win
  • If many people have low odds, together they can have higher odds than someone else (e.g., doesn't guarantee something like 50% of raffles go to owners of the gamepass if the non-owners significantly outnumber)

To figure out who wins, we pick a random number from the total number of raffle tickets, rather than the total number of players.

To figure out which player has that ticket, we just assign the tickets sequentially to each player. That is, the first one (or ten) is the first player, the next one (or ten) is the next player's, and so on.


An implementation looks like this:

local weights = {};
local totalWeight = 0;
-- 1) Count number of raffle tickets
-- (can actually be non-integer, too)
for i,v in pairs(players) do
    weights[i] = 1;
    if if game:GetService("GamePassService"):PlayerHasPass(v,ID) then
        weights[i] = 10;
        -- 10 times more likely than non-owners to win
    end
    -- Weight can include anything else that would influence
    -- odds, including other upgrades.
    totalWeight = totalWeight + weights[i];
end

-- 2) Pick winning raffle ticket (can also be non-integer)
local winner = math.random() * totalWeight;


-- 3) Figure out which person owns that ticket
for i = 1, #weights do
    winner = winner - weights[i];
    if winner <= 0 then
        choice = players[i];
        break;
    end
end

-- choice is a player from `players` who won the raffle
-- according to the weight at the corresponding entry in
-- `weights`
Ad
Log in to vote
0
Answered by
RedCombee 585 Moderation Voter
10 years ago

I would suggest using a for loop, checking through all the players for a gamepass. If they have it, they can have a (Percent) greater chance to be selected.

for i,v in pairs(game.Players:GetPlayers()) do
    if game:GetService("GamePassService"):PlayerHasPass(v,ID) then
        percentage = Instance.new("NumberValue",v)
        percentage.Value = #game.Players:GetPlayers() / 100 + Percent -- Based on how many players are in-game and how much you want the percent to increase, you can pull off a fraction of other players' perentages in upcoming code to make it equal to 100%.
    end
end
Log in to vote
0
Answered by
Perci1 4988 Trusted Moderation Voter Community Moderator
10 years ago

To add on to what red said, you could also create a table and if the player has the pass, insert their name twice.

local players = {}

for i,v in pairs(game.Players:GetPlayers()) do
    if game:GetService("GamePassService"):PlayerHasPass(v,ID) then
        players:insert(v.Name)
    end
    players:insert(v.Name)
end

Answer this question