# How to Prevent math.random from picking the same player

So basically Im creating a Arena type of game where it picks 2 players but the problem I’m having is that its picking the same player

``````	local player1 = game.Players:GetChildren()[math.random(1,#game.Players:GetPlayers())]
local player2 = game.Players:GetChildren()[math.random(1,#game.Players:GetPlayers())]
``````

Is there a way to fix this?

Create a table with unpicked players, and make `math.random` pick out of the table. Once the player has been picked, remove them using `table.remove`. Example:

``````local tbl = {}
local plr1
local plr2
local function doFor(num)
if num == 1 then
plr1 = tbl[math.random(1, #tbl)]
for i = 1, #tbl do
if tbl[i] == plr1 then
table.remove(tbl, i)
end
end
elseif num == 2 then
plr2 = tbl[math.random(1, #tbl)]
for i = 1, #tbl do
if tbl[i] == plr2 then
table.remove(tbl, i)
end
end
end

end
for _, i in pairs(game.Players:GetPlayers()) do
table.insert(tbl, i.Name)
end
doFor(1)
if #game.Players:GetPlayers() == 2 then
doFor(2)
end
print(plr1, plr2) -- Doqee nil (only 1 person is in the server)
end)
``````

edit - fixed the issues, ty for the replies that noticed my errors
edit2 - use the method below instead, hence its more tidy and efficient

1 Like

`doFor(plr1)` will not tell the function to set the random player as the value of `plr1`. Instead, it will just call the function, giving the value of plr1 (which is nil) as an argument. the player will only be the value of the function’s parameter which will be garbagecollected soon after the function has finished running. You should add `return var` in the function and when calling it, do

``````plr1 = doFor()
plr2 = doFor()``````

I think you should put the math random number with a 2 and not a 1 then make an if statement of math random equals 1 and if it equals 2.

1 Like
1 Like

Alright this might not work because I can not test it but you can make a variable for the math random from 1 to 2 for the numbers then make a local function for the two players.

``````local player1 = game.Players:GetChildren()[math.random(1,#game.Players:GetPlayers())]
local player2 = game.Players:GetChildren()[math.random(1,#game.Players:GetPlayers())]

if player2 == player1 then
local x = game.Players:GetChildren()[math.random(1,#game.Players:GetPlayers())]
repeat wait() x = game.Players:GetChildren()[math.random(1,#game.Players:GetPlayers())] until x~= player1 -- this should be fast
player2 = x
end
``````

Just an okay method above… If you are talking about the player being picked every time they join that’s a whole other issue, on line one you would write:

``````math.randomseed(tick())
``````

The first code picks 2 players, checks if player one is player two, if so then a variable is defined and looped until its not player1 then sets player2 to itself

2 Likes

Its as simple as doing this:

``````local Players = game:GetService('Players'):GetPlayers()

local P1_Number = math.random(1, #Players)
local Player1 = Players[P1_Number]

table.remove(Players, P1_Number)

local P2_Number = math.random(1, #Players)
local Player2 = Players[P2_Number]
``````

I am a little confused why you need a long script to do this.
Also, @Doqee

``````for _, I in pairs(game.Players:GetPlayers()) do
table.insert(tbl, i.Name)
end
``````

This bit of code can cause duplicates of names in a table. I suggest simply getting the player table by saying:

``````local PlayerTbl = game:GetService('Players'):GetPlayers()
``````
1 Like

I can understand why you’re using a DoFor method, but there are other ways to do it as well. For example:

``````local ArenaTbl = {}
local PlayersTbl = game:GetService('Players'):GetPlayers()

function DoFor(Number)
If PlayersTbl <= 0 then return nil end

local PN = math.random(1, #PlayersTbl)
ArenaTbl['Player' .. Number] = PlayersTbl[PN]

table.remove(PlayersTbl, PN)
return true
end

function GetArenaPlayers()
PlayersTbl = game:GetService('Players')
ArenaTbl = {}

local S1 = DoFor(1)
local S2 = DoFor(2)

if not S1 then return end
if not S2 then return end

return ArenaTbl['Player1'], ArenaTbl['Player2']
end

local Player1, Player2 = GetArenaPlayers()
``````

This script is a little bit cleaner and more concise. It also uses a lot less space.

2 Likes

If I got this How would I fetch the players name? should I say S1.Name?