Hello! im trying to create a system where every 60 seconds, the teams are shuffled, (also resetting them). just need to know how i would do that?
You can use a shuffling algorithm to shuffle the players.
local function shuffle(t)
local j, temp
for i = #t, 1, -1 do
j = math.random(i)
temp = t[i]
t[i] = t[j]
t[j] = temp
end
end
Similar to cards, you get a list of players, shuffle them, then split it two.
local players = game.Players:GetPlayers()
shuffle(players)
for i,v in pairs(players) do
if i <= #players/2 then -- first half of the players
v.TeamColor = BrickColor.new("Bright blue")
else -- second half
v.TeamColor = BrickColor.new("Bright red")
end
v:LoadCharacter() -- reset
end
This code would not work.
- :GetPalyers() returns a table, not a dictionary. You iterate tables with ipairs().
- math.random() requires two parameters, a minimum and maximum.
- ‘function shuffle()’ does not a return a value, nor does it modify a non-local variable.
- The first value returned by pairs() is the key of the value, not an index.
Here’s a piece of code that would work:
function RandomizeTable(rt_Table)
local rt_Shuffled = {}
while #rt_table > 0 do
if #rt_Table == 1 then --Not sure if math.random(1,1) would throw an error. Remove this if statement if it doesn't.
table.insert(rt_Shuffled,rt_Table[1])
table.remove(rt_Table,1)
else
local rt_RandomNumber = math.random(1,#rt_Table)
table.insert(rt_Shuffled,rt_RandomNumber)
table.remove(rt_Table,rt_RandomNumber)
end
end
return rt_Shuffled
end
function TeamScramble()
--//Get and randomize list of players
Players = RandomizeTable(game.Players:GetPlayers())
--//Iterate through list.
for i,vPlayer in ipairs(Players) do
if i % 2 == 1 then --//Check via even or odd index.
--//Assign to team 1
else
--//Assign to team 2
end
vPlayer:LoadCharacter() -- reset
end
end
i have about 5 teams, is there a way i could make the max amount of players on each team custom?
You’d need more conditional statements if you have different amounts of max members per team. Something like:
--//Using tables to reduce line count.
Teams = {team1,team2,team3,team4,team5}
for i,vPlayer in ipairs(Players) do
local selectedTeam = (i % #Teams) + 1
--//Team assignment.
if Teams[SelectedTeam] < MaxPlayers then --Change to max players per specific team.
table.remove(Teams,SelectedTeam)
end
--Respawn Player
end
what about just making the max amount 1?
Why use teams at that point then?
im making a court game, i just need a team shuffling system every round
If the special teams are only one person, you can just select random players and then assign everyone else to the jury.
I will include a response just to address the points and give feedback:
- ipairs and pairs are technically distinct. However, in this scenario it functions identically. But yes, you’d use ipairs() in an array.
- math.random(x) is a valid parameter which will generate a random number between 1 to x
- shuffle() does not return a value because it takes advantage of pass by reference. The table passed as the parameter is the original table, and is modified directly by the function.
- same as point 1.
can you clarify on this and provide an example? Like a team with 1 member, a team with 3, and a team with 5?
got it, how would you use math.random for it though?
You can get a random element of a table by doing ‘MyTable[math.random(1,#MyTable])’. It works by selected a random index of the table.
local players = game:GetService("Players")
local teams = {
Defendant = game:GetService("Teams").Defendant,
Lawyer = game:GetService("Teams").Lawyer,
Judge = game:GetService("Teams").Judge,
Witness = game:GetService("Teams").Witness
}
local juryTeam = game:GetService("Teams").Jury
local selectionTime = 10
local resetTime = 60
local currentSelectionTime = 0
local currentResetTime = 0
local selectedPlayers = {}
local function SelectPlayers()
for _, player in ipairs(players:GetPlayers()) do
player.Team = juryTeam
end
selectedPlayers = {}
local availableTeams = {}
for name, team in pairs(teams) do
if team ~= juryTeam then
table.insert(availableTeams, name)
end
end
for i = 1, 5 do
local randomIndex = math.random(1, #availableTeams)
local selectedTeamName = availableTeams[randomIndex]
local selectedTeam = teams[selectedTeamName]
local allPlayers = players:GetPlayers()
local numPlayers = #allPlayers
local randomPlayerIndex = math.random(1, numPlayers)
local player = allPlayers[randomPlayerIndex]
if not selectedPlayers[player] then
player.Team = selectedTeam
table.insert(selectedPlayers, player)
table.remove(availableTeams, randomIndex)
end
end
end
game:GetService("RunService").Stepped:Connect(function(_, dt)
currentResetTime = currentResetTime + dt
if currentResetTime >= resetTime then
currentResetTime = 0
SelectPlayers()
end
currentSelectionTime = currentSelectionTime + dt
if currentSelectionTime >= selectionTime then
currentSelectionTime = 0
SelectPlayers()
end
end)
would this work?
- There is no defined order when using pairs(). Roblox documentation also reccomends using ipairs() for arrays.
2.You are correct about 2 and 3 actually. However, the function itself should probably not be local.
It’s got a lot of inefficiencies, but it should work.
A few things I want to clarify:
- You actually don’t need to use pairs or ipairs anymore. You can use general iteration and is more performant than both iterator functions. (Syntax - Luau)
- There actually is a slight performance increase in using local functions in top-level stacks because of how it traverses through the stacks internally. (Any advantage in declaring a function as local? - #31 by rogeriodec_games)
Other than that, I don’t know why you are opting for a RunService method of shuffling players. Here is a script with adjustable settings that just relies on minimal resources.
--!strict
-- Services
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")
-- Round Configuration
local MINIMUM_PLAYERS: number = 5 -- Minimum amount of players
local SELECTION_TIME: number = 10 -- Time before shuffle starts
local RESET_TIME: number = 10 -- Time before game resets
local SHUFFLE_EVENLY: boolean = true -- Determines whether to shuffle evenly (for non-guaranteed teams)
local RESPAWN_ON_SHUFFLE: boolean = true -- Determines whether to respawn players on shuffle
local VERBOSE: boolean = true -- Determines whether to output game status on console
-- Team Configuration
local TEAM_LIST: TeamList = {
[Teams.Judge] = {
MAX_PLAYERS = 1,
GUARANTEED = true
},
[Teams.Defendant] = {
MAX_PLAYERS = 1,
GUARANTEED = true
},
[Teams.Lawyer] = {
MAX_PLAYERS = 1,
GUARANTEED = true
},
[Teams.Witness] = {
MAX_PLAYERS = 10,
GUARANTEED = false
},
[Teams.Jury] = {
MAX_PLAYERS = 10,
GUARANTEED = false
},
}
-- Types
type TeamList = {
[Team]: TeamSettings
}
type TeamSettings = {
MAX_PLAYERS: number,
GUARANTEED: boolean
}
-- Function to print if verbose is set to true
-- This will not stack overflow with this pattern
local print = function(...: any): ()
if VERBOSE == true then
print(...)
end
end
-- Function to wait for minimum players
local function WaitForMinimumPlayers(): ()
if #Players:GetPlayers() < MINIMUM_PLAYERS then
print(`Waiting for at least {MINIMUM_PLAYERS} player(s)...`)
repeat
task.wait()
until #Players:GetPlayers() >= MINIMUM_PLAYERS
end
end
-- Function to set all players to a team
local function ResetTeams(team: Team?): ()
for _, player: Player in Players:GetPlayers() do
player.Team = team
end
end
-- Function to shuffle players
local function ShufflePlayers(): ()
local guaranteedTeams: {Team} = {}
local guaranteedTeamsCount: number = 0
local shuffledTeams: {Team} = {}
local shuffledTeamsCount: number = 0
-- Setup our team arrays with x amount of teams
for team: Team, teamSettings: TeamSettings in TEAM_LIST do
if teamSettings.GUARANTEED == true then
guaranteedTeamsCount += 1
for _ = 1, teamSettings.MAX_PLAYERS do
table.insert(guaranteedTeams, math.random(1, #guaranteedTeams + 1), team)
end
else
shuffledTeamsCount += 1
-- Only insert one so we can shuffle
-- with our specified settings
table.insert(shuffledTeams, math.random(1, #shuffledTeams + 1), team)
end
end
-- Shuffle our non-guaranteed teams
local nextTeamIndex: number = 1 -- used for even shuffling
for _ = 1, #Players:GetPlayers() - guaranteedTeamsCount do
if SHUFFLE_EVENLY == true then
-- Insert into the shuffled teams array via alternating
table.insert(shuffledTeams, shuffledTeams[nextTeamIndex])
nextTeamIndex += 1
if nextTeamIndex > shuffledTeamsCount then
nextTeamIndex = 1
end
else
-- Insert into the shuffled teams array via random
table.insert(shuffledTeams, shuffledTeams[math.random(1, shuffledTeamsCount)])
end
end
-- Shuffle our players and assign them a team
local shuffledPlayers: {Player} = {}
for _, player: Player in Players:GetPlayers() do
table.insert(shuffledPlayers, math.random(1, #shuffledPlayers + 1), player)
end
for _, player: Player in shuffledPlayers do
if #guaranteedTeams > 0 then
player.Team = guaranteedTeams[1]
table.remove(guaranteedTeams, 1)
else
player.Team = shuffledTeams[1]
table.remove(shuffledTeams, 1)
end
if RESPAWN_ON_SHUFFLE == true then
player:LoadCharacter()
end
end
end
-- Loop game
while true do
-- Reset team to Jury
print("Resetting teams back to jury...")
ResetTeams(Teams.Jury)
-- Wait for minimum players
WaitForMinimumPlayers()
-- Start selection timer
task.wait(SELECTION_TIME)
-- Shuffle players
print("Shuffling players...")
ShufflePlayers()
-- Start reset timer
task.wait(RESET_TIME)
end
the performance of iteration using generalized iteration,
pairs
andipairs
is comparable
The performance is generally the same.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.