Hello! I am working on a sword fighting tournament game where 2 players are randomly picked to fight until there is a winner. This system is meant to work with any of players, and also accounts for byes. Keep in mind I have removed a lot of code that is unrelated to the logic, such as how I deal with the winner of the tournament, as well as setting the Status
attribute of players. I have also left out FightService
as it also doesn’t deal much with the tournament logic.
local Players = game:GetService('Players')
local FightService = require(script.Parent.FightService)
local TournamentService = {
Bracket = {}
}
function TournamentService:GenerateRound(Contestants)
local Round = {}
for _ = 1, math.ceil(#Contestants / 2) do
local ContestantCount = #Contestants
if ContestantCount > 1 then
local Fighter1 = Contestants[math.random(ContestantCount)]
local Fighter2 = Contestants[math.random(ContestantCount)]
while Fighter2 == Fighter1 do
Fighter2 = Contestants[math.random(ContestantCount)]
task.wait()
end
table.insert(Round, {
Fighter1,
Fighter2
})
table.remove(Contestants, table.find(Contestants, Fighter1))
table.remove(Contestants, table.find(Contestants, Fighter2))
elseif ContestantCount == 1 then
Round.Bye = {Contestants[1]}
end
end
table.insert(self.Bracket, Round)
return Round
end
function TournamentService:TournamentLoop()
local Contestants = table.clone(self.Contestants)
while #Contestants > 1 do
local Winners = {}
local Round = self:GenerateRound(Contestants)
for _, Fighters in Round do
local Winner = FightService:StartFight(Fighters)
if Winner then
table.insert(Winners, Winner)
end
end
Contestants = Winners
end
end
function TournamentService:StartTournament()
self.Contestants = Players:GetPlayers()
self:TournamentLoop()
end
function TournamentService:EndTournament()
self.Contestants = nil
table.clear(self.Bracket)
end
function TournamentService:RemovePlayer(Player)
local Round = self.Bracket[self.RoundIndex]
for FightIndex, Fight in Round do
for Index, Fighter in Fight do
if Player ~= Fighter then
continue
end
table.remove(Fight, Index)
if not next(Fight) then
if type(FightIndex) == 'number' then
table.remove(Round, FightIndex)
else
Round[FightIndex] = nil
end
return
end
local Fighter = Fight[1]
if Fighter and Fighter:GetAttribute('Status') ~= 'Fighting' then
if Round.Bye then
table.insert(Fight, Round.Bye[1])
Round.Bye = nil
else
Round.Bye = {Fighter}
table.remove(Round, FightIndex)
end
end
end
end
end
return TournamentService
local Players = game:GetService('Players')
local TournamentService = require(script.Parent.Services.TournamentService)
local function CheckPlayerCount()
return #Players:GetPlayers() >= 3
end
local function StartTournament()
TournamentService:StartTournament()
TournamentService:EndTournament()
end
while true do
if not CheckPlayerCount() then
Players.PlayerAdded:Wait()
if not CheckPlayerCount() then
continue
end
end
StartTournament()
end