Module:RoundRobin

From TwogPedia
Revision as of 22:59, 14 October 2023 by Couchor (talk | contribs)

Documentation for this module may be created at Module:RoundRobin/doc

local getArgs = require('Module:Arguments').getArgs
local cargo = mw.ext.cargo
local getTeamPage = require('Module:Functions').getTeamPage

local RoundRobin = {}

local VariablesLua = mw.ext.VariablesLua

function RoundRobin.main(frame)
	local args = getArgs(frame)

	local tableContainer = mw.html.create('table'):addClass('rr-table')
	
	if args.title then
		local header = mw.html.create('tr'):node(mw.html.create('th'):attr('colspan', 4):wikitext(args.title))
		tableContainer:node(header)
	end
	
	local results = {}
	
	-- If no participants, then create empty table
	if not args.participants and args.emptyRows then
		for i = 1, args.emptyRows do
			local colorClass = ''
			if args.promote and i <= tonumber(args.promote)  then colorClass = 'promote'
			elseif args.relegate and i > args.emptyRows - tonumber(args.relegate) then colorClass = 'relegate'
			else colorClass = 'stay' end
			local row = mw.html.create('tr')
			local order = mw.html.create('td'):addClass(colorClass):wikitext(i .. '.')
			local team = mw.html.create('td'):attr('style', 'min-width: 100px'):wikitext('TBD')
			local winsLosses = mw.html.create('td'):attr('style', 'min-width: 40px'):addClass('bold'):wikitext('0-0')
			local mapScores = mw.html.create('td'):attr('style', 'min-width: 40px'):wikitext('0-0')
			tableContainer:node(row:node(order):node(team):node(winsLosses):node(mapScores))
		end
		return tableContainer
	end
	
	local multipleRounds = 1
	if args.multiple then multipleRounds = tonumber(args.multiple) end
	
	local teams = mw.text.split(args.participants, ',')
	local teamScores = {}
	local drawsPossible = false

	for i = 1, #teams do
		local teamInfo = {}
		local team = getTeamPage(mw.text.trim(teams[i]))
		local tables = 'AllMatches'
		local fields = 'p1, p2, p1score, p2score, winner, bestof, tiebreak'
		local page = args.page or mw.title.getCurrentTitle().text
		local whereStr = '_pageName="' .. page .. '" AND (p1="' .. team .. '" OR p2="' .. team .. '") AND (winner IS NOT NULL AND winner != "0")'
		if args.stage then whereStr = whereStr .. ' AND stage="' .. args.stage .. '"' end
		local cargoArgs = {
			where = whereStr
		}
        
		results = cargo.query(tables, fields, cargoArgs)
		local mapWins = 0
		local mapLosses = 0
		local wins = 0
		local losses = 0
        local draws = 0
        local tieWins = 0
		if #results > 0 then
			for j = 1, #results do
				local result = results[j]
				-- If tiebreaker match
				if result.tiebreak == "1" then
					if result.p1 == team and result.winner == '1' then 
						tieWins = tieWins + 1
					elseif result.p2 == team and result.winner == '2' then
						tieWins = tieWins + 1
					end
                -- if was a draw
                elseif result.winner == '3' then
                	drawsPossible = true
                    draws = draws + 1
                    mapWins = mapWins + result.bestof / 2
                    mapLosses = mapLosses + result.bestof / 2
				-- Check if the team in question is the first or second team in the db
				elseif result.p1 == team then
					if result.winner == '1' then wins = wins + 1 else losses = losses + 1 end
					mapWins = mapWins + result.p1score
					mapLosses = mapLosses + result.p2score
				else 
					if result.winner == '2' then wins = wins + 1 else losses = losses + 1 end
					mapWins = mapWins + result.p2score
					mapLosses = mapLosses + result.p1score
				end
				-- determine if the team in question won
			end
		end
		teamInfo.tieName = teams[i]
		teamInfo.name = team
		teamInfo.wins = wins
		teamInfo.draws = draws
		teamInfo.tieWins = tieWins
		teamInfo.mapWins = mapWins
		teamInfo.mapLosses = mapLosses
		teamInfo.losses = losses
		
		table.insert(teamScores, teamInfo)
	end

	-- Sort table by wins, then by mapwins and then by lower amount of maplosses
	table.sort(teamScores, function(a,b) 
		if a.wins == b.wins then
			if a.losses == b.losses then
				if a.mapWins == b.mapWins then
					if a.mapLosses == b.mapLosses then
						if a.tieWins > b.tieWins then return true else return false end
					else
						if a.mapLosses < b.mapLosses then return true else return false end
					end
				else 
					if a.mapWins > b.mapWins then return true else return false end
				end
			else 
				if a.losses < b.losses then return true else return false end
			end
		else
			if a.wins > b.wins then return true else return false end
		end
	end)
    
    local tieTeams = args.ties and mw.text.split(args.ties, ',') or {}
    local tiePlacements = args.tiePlacements and mw.text.split(args.tiePlacements, ',') or {}

	-- Create a new table to store the result
	local resultTable = {}
	
	-- Iterate over the elements in the first table
	for _, tieName in ipairs(tieTeams) do
		tieName = mw.text.trim(tieName)
	    -- Find the index in teamScores where tieName matches
	    local index
	    for i, entry in ipairs(teamScores) do
	        if entry.tieName == tieName then
	            index = i
	            break
	        end
	    end
	
	    -- If index is found, remove the element from tieTeams and insert at the new position
	    if index then
	    	local toEnter = teamScores[index]
	    	table.remove(teamScores, index)
	        -- Get the new position from the tiePlacements table
	        local newPosition = tonumber(tiePlacements[_])
	        -- Insert the element at the new position in teamScores
	        table.insert(teamScores, newPosition, toEnter)
	    end
	end
	
	for i = 1, #teamScores do
		local team = teamScores[i]
		local wins = team.wins or 0
		local losses = team.losses or 0
		local draws = team.draws or 0
		local mapWins = team.mapWins or 0
		local mapLosses = team.mapLosses or 0
		local colorClass = ''
		
		if args.promote and i <= tonumber(args.promote)  then colorClass = 'promote'
		elseif args.relegate and i > #teamScores - tonumber(args.relegate) then colorClass = 'relegate'
		else colorClass = 'stay'end
		
		local row = mw.html.create('tr')
		
		-- If all matches in the group have been played
		if #results >= ((#teams * (#teams - 1)) / 2) * multipleRounds then 
			row:addClass(colorClass)
		end
		local order = mw.html.create('td'):wikitext(i .. '.'):addClass(colorClass)
		
		local team = mw.html.create('td'):wikitext('[[' .. team.name .. '|' .. mw.text.split(team.name, '/')[2] .. ']]')
		local winsLosses = mw.html.create('td'):wikitext(drawsPossible and wins  .. '-' .. draws .. '-' .. losses or wins .. '-' .. losses)
		local mapScores = mw.html.create('td'):wikitext(mapWins .. '-' .. mapLosses)
		tableContainer:node(row:node(order):node(team):node(winsLosses):node(mapScores))
	end
	
	return tableContainer
end

return RoundRobin