# Team Power Matchmaking "Power"

EDIT: Updated Module

I was making a team matchmaking system, easier said than done by a lot. Spend many hours on and with 190 lines I made it a module.

This is my first module and “complex system” but I want to see if I can make any improvements. The current system works off random and limited in what it can do, I already have a solution in mind to make it ALOT more efficient and less limited. I don’t know how to achieve this solution, so random it is for now.

This module takes a table of players and all of their “Power” to find the most optimal and fair teams.

Here it is: Matchmaking Module Place.rbxl (30.8 KB)

Code (190 Lines) Get full instructions in Download

``````local module = {}
module.BestMatch = function(Plrs,Values)
local x = 0--#Values
for i,v in pairs(Values) do
x +=1
end

--Makes sure number is even
if x % 2 == 0 then--Donot Touch or computer itself will crash

------------------------------
--Phase 1, Generate all Possible Combinations
----------------------------

--Factorial
local function factorial(n)
if (n == 0) then
return 1
else
return n * factorial(n - 1)
end
end
--
--Combinations
local Comination1 = factorial(x)
local Combination2 = factorial(x/2)
local Combination3 = factorial( (x)-(x/2) )
local formula = (Comination1) / (Combination2*Combination3)

local DifferentCombinations = {}

local NumTable = {}
for i = 1,x,1 do
table.insert(NumTable,#NumTable+1,i)
end

local function shallowCopy(original)
local copy = {}
for key, value in pairs(original) do
copy[key] = value
end
return copy
end

---Create a Random order of x Numbers
local function getrandomorder()
local output = {}
local tempnum = shallowCopy(NumTable)
while #output < x do
local num = math.random(1,#tempnum)
local newnum = tempnum[num]
table.insert(output,1,newnum)
table.remove(tempnum,table.find(tempnum,tempnum[num]))
end--while #output

--Seperate Tables
local output1 = {}
local output2 = {}
for i = 1, x,2 do
table.insert(output1,1,output[i])
table.insert(output2,1,output[i+1])
end
table.sort(output1)
table.sort(output2)

return {output1,output2}
end--getrandomorder

--Creates a table of all the possible combinations

local function CompareTables(tabA, tabB)
local Same = true
local keysA = {}
local keysB = {}

local function getResult()
if Same then return "Equal" end
return "Different"
end

for k, v in pairs(tabA) do
keysA[k] = v
end
for k, v in pairs(tabB) do
keysB[k] = v
end
for  k, v in pairs(keysA) do
if keysB[k] ==  nil then
local result = getResult()
return result
elseif keysB[k] ~= v then
Same = false
end
end
for  k, v in pairs(keysB) do
if keysA[k] ==  nil then
local result = getResult()
return result
elseif keysA[k] ~= v then
Same = false
end
end
local result = getResult()
return result
end

while #DifferentCombinations < (formula / 2) do
wait()
--Check if order is already used
local order = getrandomorder()
local result
local deb = false
for q,z in pairs(DifferentCombinations) do
if deb == false then
result = CompareTables(z[1],order[1])
if result == "Different" then
if CompareTables(z[1],order[2]) == "Equal" then
if CompareTables(z[2],order[1]) == "Equal" then
result = "Equal"
deb = true
end
end
end
if result == "Equal" then
deb = true
end
end
end

if result == "Different" or #DifferentCombinations == 0 then
table.insert(DifferentCombinations,1,order)
end
end

------------------------------
--Phase 2, Swap Numbers for players and find best combination
----------------------------

---Create Second Table with the Values
local PlayerValuesCombValues = {}
for i,v in pairs(DifferentCombinations) do
local insertedtable = {}
local Power = 0
for t,s in pairs(v) do
Power = 0
for l,q in pairs(s) do
Power += Values[q]
end
table.insert(insertedtable,Power)
end
table.insert(insertedtable,3,{v[1],v[2]})
table.insert(PlayerValuesCombValues,i,insertedtable)
end

--See What Combination is best
local LowestGap = math.huge
local LowestTable = {}
for i,v in pairs(PlayerValuesCombValues) do
local Gap = v[1] - v[2]
if Gap < 0 then--Make Gap a Positive Num
Gap = Gap*(-1)
end
if Gap < LowestGap then
LowestGap = Gap
LowestTable = shallowCopy(v)
end
end

---Finalize Best Combo
local BestTable = {}
for i,v in pairs(LowestTable[3]) do
local temptbl = {}
for q,e in pairs(v) do
table.insert(temptbl,Plrs[e])
end
table.insert(BestTable,temptbl)
temptbl = {}
end

return BestTable , LowestGap
else
return warn("Sent #Players were Odd.")
end
end--if even == true

return module
``````

If anyone is wondering, I currently randomly generate all the possible teams with numbers than replace it with the player’s power than find the best match. My solution to this would have all the different possible teams/combinations premade so I don’t need to continuously use random to find these combinations every time

1 Like

think your method might be best, just brute force it.
if you have issues on PC’s freezing, just add some waits to split the load
one of the best balancers I know is in forged alliance

maybe there are some ideas there you can use?

1 Like