Math.random choosing the same player

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve?
    I Want the math.random to choose a different player every time and not the same one

  2. What is the issue?
    Math.random not choosing a different player, and that’s making the same player get the same role

  3. What solutions have you tried so far?
    I took a look at the developers hub but didn’t find anything useful

I’m doing a werewolf game on Roblox, and I was doing the werewolf, villagers, and mayor, but, when I was testing it with my friend, he got the werewolf AND the mayor (which it wasn’t supposed to happen)

local module = {}
local Teams = game:GetService("Teams")
local StarterGui = game:GetService("StarterGui")
local Dead = Teams:WaitForChild("IuDied")
local Villager = Teams:WaitForChild("Narigudo")
local Werewolve = Teams:WaitForChild("Worfes")
local Lobby = Teams:WaitForChild("Lóbi")
local MayorTeam = Teams:WaitForChild("Maionese")
local RoleFrame = StarterGui:WaitForChild("Main").MainFrame
local RoleIcon = RoleFrame.RoleIcon
local RoleText = RoleFrame.Role
local RoleDescription = RoleFrame.RoleDescription
local WolfIcon = "http://www.roblox.com/asset/?id=70154084"
local WolfRole = "You Are a Werewolf"
local WolfDesc = "Kill All The Villagers"
local VillIcon = "http://www.roblox.com/asset/?id=13815236182"
local VillRole = "You Are a Villager"
local VillDesc = "Protect The Village"
local MayIcon = "http://www.roblox.com/asset/?id=180083570"
local MayRole = "You Are The Mayor"
local MayDesc = "Each Vote You do Counts twice"

function module.ChooseWolf()
	local Wolf = game.Players:GetPlayers() [math.random(1, #game.Players:GetPlayers())] --Chooses the wolves (Amount)
	local Mayor = game.Players:GetPlayers() [math.random(1, #game.Players:GetPlayers())]
	Wolf.Team = Werewolve
	Mayor.Team = MayorTeam
	
	local WolfValue = Instance.new("BoolValue")
	WolfValue.Name = "WolfValue"
	WolfValue.Parent = Wolf
	
	local MayorValue = Instance.new("BoolValue")
	MayorValue.Name = "MayorValue"
	MayorValue.Parent = MayorTeam
	
	for i, v in pairs(game.Players:GetPlayers()) do
		if v:FindFirstChild("WolfValue") then
			v.PlayerGui.Main.MainFrame.Visible = true
			v.PlayerGui.Main.MainFrame.RoleIcon.Image = WolfIcon
			v.PlayerGui.Main.MainFrame.Role.Text = WolfRole
			v.PlayerGui.Main.MainFrame.RoleDescription.Text = WolfDesc
			wait(5)
			v.PlayerGui.Main.MainFrame.Visible = false
		elseif v:FindFirstChild("MayorValue") then
			v.PlayerGui.Main.MainFrame.Visible = true
			v.PlayerGui.Main.MainFrame.RoleIcon.Image = MayIcon
			v.PlayerGui.Main.MainFrame.Role.Text = MayRole
			v.PlayerGui.Main.MainFrame.RoleDescription.Text = MayDesc
			wait(5)
			v.PlayerGui.Main.MainFrame.Visible = false
		else
			v.PlayerGui.Main.MainFrame.Visible = true
			v.PlayerGui.Main.MainFrame.RoleIcon.Image = VillIcon
			v.PlayerGui.Main.MainFrame.Role.Text = VillRole
			v.PlayerGui.Main.MainFrame.RoleDescription.Text = VillDesc
			wait(5)
			v.PlayerGui.Main.MainFrame.Visible = false
		end
	end
end

function module.TPplayers()
	for i, v in pairs(game.Players:GetPlayers()) do
		local character = v.Character
		if character then
			character.HumanoidRootPart.CFrame = workspace:WaitForChild("Map").TPpart.CFrame
		end
	end
end

function module.TPplayersBack()
	for i, v in pairs(game.Players:GetPlayers()) do
		v.Team = Lobby
		local character = v.Character
		if character then
			character.HumanoidRootPart.CFrame = workspace:WaitForChild("Lobby").SpawnLocation.CFrame
		end
	end
end
return module
3 Likes

I don’t really understand. Your math.random code is just telling it to pick a random player. Assuming you have only 2 players in your test game where it didn’t work. It’s a 50/50 chance that the same player will get the mayor and werewolf twice. Do you want to make it so that the player cant get 2 roles?

1 Like

You can achieve this by creating a table containing all players, then removing them from the table when they are selected for a special role.

Something like this:

local Players = game:GetService("Players")
local PossiblePlayers = Players:GetPlayers()

local MayorIndex = math.random(1,#PossiblePlayers)
local Mayor = PossiblePlayers[MayorIndex]
table.remove(PossiblePlayers,MayorIndex) -- Make sure the Mayor isn't considered when choosing werewolf

local WolfIndex = math.random(1,#PossiblePlayers)
local Wolf = PossiblePlayers[WolfIndex]
table.remove(PossiblePlayers,WolfIndex) -- Remove wolf too in case you want more roles in the future
2 Likes

yeah, that’s it, it may become a problem in the future

1 Like

It says that

ServerScriptService.Main.Functions:41: invalid argument #2 to ‘random’ (interval is empty), and it’s where it says

local MayorIndex = math.random(1, #PossiblePlayers)

1 Like

Make sure that you copied the

local PossiblePlayers = Players:GetPlayers()

above the

local MayorIndex = math.random(1,#PossiblePlayers)

Otherwise PossiblePlayers doesn’t exist and that error will show up.

1 Like

Yeah, I did that, but it keeps showing up, and when I do a team test with my friend this one does:

ServerScriptService.Main.Functions:32: invalid argument #2 to ‘random’ (interval is empty)
Stack Begin
Script ‘ServerScriptService.Main.Functions’, Line 32 - function ChooseWolf
Script ‘ServerScriptService.Main’, Line 14 - function startround
Script ‘ServerScriptService.Main’, Line 39
Stack End

Oh, sorry, did you define Players?

1 Like

I mean, I did write
local Players = game:GetService(“Players”)

Can you send your updated code so it’s a little easier for me to diagnose what the issue could be?

1 Like

of course, how do you make it so that it appears as a code again?

Forget it, figured it out

local module = {}
local Teams = game:GetService("Teams")
local StarterGui = game:GetService("StarterGui")
local Dead = Teams:WaitForChild("IuDied")
local Villager = Teams:WaitForChild("Narigudo")
local Werewolve = Teams:WaitForChild("Worfes")
local Lobby = Teams:WaitForChild("Lóbi")
local MayorTeam = Teams:WaitForChild("Maionese")
local RoleFrame = StarterGui:WaitForChild("Main").MainFrame
local RoleIcon = RoleFrame.RoleIcon
local RoleText = RoleFrame.Role
local RoleDescription = RoleFrame.RoleDescription
local WolfIcon = "http://www.roblox.com/asset/?id=70154084"
local WolfRole = "You Are a Werewolf"
local WolfDesc = "Kill All The Villagers"
local VillIcon = "http://www.roblox.com/asset/?id=13815236182"
local VillRole = "You Are a Villager"
local VillDesc = "Protect The Village"
local MayIcon = "http://www.roblox.com/asset/?id=180083570"
local MayRole = "You Are The Mayor"
local MayDesc = "Each Vote You do Counts twice"


function module.ChooseWolf()

	local Players = game:GetService("Players")
	local PossiblePlayers = Players:GetPlayers()
	local MayorIndex = math.random(1, #PossiblePlayers)
	local Mayor = PossiblePlayers[MayorIndex]
	table.remove(PossiblePlayers, MayorIndex) -- Make sure the Mayor isn't considered when choosing werewolf

	local WolfIndex = math.random(1, #PossiblePlayers)
	local Wolf = PossiblePlayers[WolfIndex]
	table.remove(PossiblePlayers, WolfIndex) -- Remove wolf too in case you want more roles in the future

	Wolf.Team = Werewolve
	Mayor.Team = MayorTeam
	
	local WolfValue = Instance.new("BoolValue")
	WolfValue.Name = "WolfValue"
	WolfValue.Parent = Wolf
	
	local MayorValue = Instance.new("BoolValue")
	MayorValue.Name = "MayorValue"
	MayorValue.Parent = Mayor
	
	for i, v in pairs(game.Players:GetPlayers()) do
		if v:FindFirstChild("WolfValue") then
			v.PlayerGui.Main.MainFrame.Visible = true
			v.PlayerGui.Main.MainFrame.RoleIcon.Image = WolfIcon
			v.PlayerGui.Main.MainFrame.Role.Text = WolfRole
			v.PlayerGui.Main.MainFrame.RoleDescription.Text = WolfDesc
			wait(5)
			v.PlayerGui.Main.MainFrame.Visible = false
		elseif v:FindFirstChild("MayorValue") then
			v.PlayerGui.Main.MainFrame.Visible = true
			v.PlayerGui.Main.MainFrame.RoleIcon.Image = MayIcon
			v.PlayerGui.Main.MainFrame.Role.Text = MayRole
			v.PlayerGui.Main.MainFrame.RoleDescription.Text = MayDesc
			wait(5)
			v.PlayerGui.Main.MainFrame.Visible = false
		else
			v.PlayerGui.Main.MainFrame.Visible = true
			v.PlayerGui.Main.MainFrame.RoleIcon.Image = VillIcon
			v.PlayerGui.Main.MainFrame.Role.Text = VillRole
			v.PlayerGui.Main.MainFrame.RoleDescription.Text = VillDesc
			wait(5)
			v.PlayerGui.Main.MainFrame.Visible = false
		end
	end
end

function module.TPplayers()
	for i, v in pairs(game.Players:GetPlayers()) do
		local character = v.Character
		if character then
			character.HumanoidRootPart.CFrame = workspace:WaitForChild("Map").TPpart.CFrame
		end
	end
end

function module.TPplayersBack()
	for i, v in pairs(game.Players:GetPlayers()) do
		v.Team = Lobby
		local character = v.Character
		if character then
			character.HumanoidRootPart.CFrame = workspace:WaitForChild("Lobby").SpawnLocation.CFrame
		end
	end
end
return module
1 Like

I don’t see any syntax issues, but I do have a concern – if there’s less than two players, it will error.

1 Like

but when me and my friend are testing, it errors even so, the same one, mind you

This will happen if there is only 1 player in the game. Make sure you only allow a round to start if there is at least 2 players.

make a variable called lastSelected.

repeat function selecting the random player until it does not select lastSelected (if lastSelected is nil it just picks random anyway.)

Then set lastSelected to the selected player.

ok fixed it, for anyone having the same problem, you can just add

while wolfIndex == mayorIndex do
    mayorIndex = math.random(1, #players)
end

Below the

local Mayor = game.Players:GetPlayers() [math.random(1, #game.Players:GetPlayers())]
Wolf.Team = Werewolve
Mayor.Team = MayorTeam

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.