Module:RoundRobin: Difference between revisions

From TwogPedia
mNo edit summary
mNo edit summary
 
(5 intermediate revisions by the same user not shown)
Line 2: Line 2:
local cargo = mw.ext.cargo
local cargo = mw.ext.cargo
local getTeamPage = require('Module:Functions').getTeamPage
local getTeamPage = require('Module:Functions').getTeamPage
local getTeamDisplaytitle = require('Module:Functions').getTeamDisplaytitle
local getTournamentEndDate = require('Module:Functions').getTournamentEndDate


local RoundRobin = {}
local RoundRobin = {}
Line 23: Line 25:
for i = 1, args.emptyRows do
for i = 1, args.emptyRows do
local colorClass = ''
local colorClass = ''
if args.promote and i <= tonumber(args.promote)  then colorClass = 'promote'
if args.promote and i <= tonumber(args.promote)  then colorClass = 'promote'
elseif args.relegate and i > args.emptyRows - tonumber(args.relegate) then colorClass = 'relegate'
elseif args.relegate and i > args.emptyRows - tonumber(args.relegate) then colorClass = 'relegate'
else colorClass = 'stay' end
else colorClass = 'stay' end
 
local row = mw.html.create('tr')
local row = mw.html.create('tr'):addClass(colorClass)
local order = mw.html.create('td'):addClass(colorClass):wikitext(i .. '.')
local order = mw.html.create('td'):wikitext(i .. '.')
local team = mw.html.create('td'):attr('style', 'min-width: 100px'):wikitext('TBD')
local team = mw.html.create('td'):attr('style', 'min-width: 60px')
local winsLosses = mw.html.create('td'):attr('style', 'min-width: 40px'):addClass('bold'):wikitext('0-0')
local winsLosses = mw.html.create('td'):attr('style', 'min-width: 60px')
local mapScores = mw.html.create('td'):attr('style', 'min-width: 40px'):wikitext('0-0')
local mapScores = mw.html.create('td'):attr('style', 'min-width: 60px')
tableContainer:node(row:node(order):node(team):node(winsLosses):node(mapScores))
tableContainer:node(row:node(order):node(team):node(winsLosses):node(mapScores))
end
end
Line 43: Line 43:
local teams = mw.text.split(args.participants, ',')
local teams = mw.text.split(args.participants, ',')
local teamScores = {}
local teamScores = {}
local drawsPossible = false
local page = args.page and string.gsub(args.page, '_', ' ') or mw.title.getCurrentTitle().text
for i = 1, #teams do
for i = 1, #teams do
local teamInfo = {}
local teamInfo = {}
local team = getTeamPage(mw.text.trim(teams[i]))
local team = getTeamPage(mw.text.trim(teams[i]))
local tables = 'AllMatches'
local tables = 'AllMatches'
local fields = 'p1, p2, p1score, p2score, winner'
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")'
local whereStr = '_pageName="' .. page .. '" AND (p1="' .. team .. '" OR p2="' .. team .. '")'
if args.stage then whereStr = whereStr .. ' AND stage="' .. args.stage .. '"' end
if args.stage then whereStr = whereStr .. ' AND stage="' .. args.stage .. '"' end
local cargoArgs = {
local cargoArgs = {
where = whereStr
where = whereStr
}
}
       
results = cargo.query(tables, fields, cargoArgs)
results = cargo.query(tables, fields, cargoArgs)
local mapWins = 0
local mapWins = 0
Line 60: Line 61:
local wins = 0
local wins = 0
local losses = 0
local losses = 0
        local draws = 0
        local tieWins = 0
if #results > 0 then
if #results > 0 then
for j = 1, #results do
for j = 1, #results do
local result = results[j]
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
-- Check if the team in question is the first or second team in the db
if result.p1 == team then
elseif result.p1 == team then
if result.winner == '1' then wins = wins + 1 else losses = losses + 1 end
if result.winner == '1' then wins = wins + 1 else losses = losses + 1 end
mapWins = mapWins + result.p1score
mapWins = mapWins + result.p1score
Line 76: Line 92:
end
end
end
end
teamInfo.tieName = teams[i]
teamInfo.name = team
teamInfo.name = team
teamInfo.wins = wins
teamInfo.wins = wins
teamInfo.draws = draws
teamInfo.tieWins = tieWins
teamInfo.mapWins = mapWins
teamInfo.mapWins = mapWins
teamInfo.mapLosses = mapLosses
teamInfo.mapLosses = mapLosses
Line 91: Line 109:
if a.losses == b.losses then
if a.losses == b.losses then
if a.mapWins == b.mapWins then
if a.mapWins == b.mapWins then
if a.mapLosses < b.mapLosses then return true else return false end
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  
else  
if a.mapWins > b.mapWins then return true else return false end
if a.mapWins > b.mapWins then return true else return false end
Line 102: Line 124:
end
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
for i = 1, #teamScores do
local team = teamScores[i]
local team = teamScores[i]
local wins = team.wins or 0
local wins = team.wins or 0
local losses = team.losses or 0
local losses = team.losses or 0
local draws = team.draws or 0
local mapWins = team.mapWins or 0
local mapWins = team.mapWins or 0
local mapLosses = team.mapLosses or 0
local mapLosses = team.mapLosses or 0
Line 123: Line 175:
local order = mw.html.create('td'):wikitext(i .. '.'):addClass(colorClass)
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 team = mw.html.create('td'):wikitext('[[' .. team.name .. '|' .. getTeamDisplaytitle(team.name, getTournamentEndDate(page)) .. ']]')
local winsLosses = mw.html.create('td'):wikitext(wins .. '-' .. losses)
local winsLosses = mw.html.create('td'):wikitext(drawsPossible and wins  .. '-' .. draws .. '-' .. losses or wins .. '-' .. losses)
local mapScores = mw.html.create('td'):wikitext(mapWins .. '-' .. mapLosses)
local mapScores = mw.html.create('td'):wikitext(mapWins .. '-' .. mapLosses)
tableContainer:node(row:node(order):node(team):node(winsLosses):node(mapScores))
tableContainer:node(row:node(order):node(team):node(winsLosses):node(mapScores))

Latest revision as of 20:13, 12 November 2023

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 getTeamDisplaytitle = require('Module:Functions').getTeamDisplaytitle
local getTournamentEndDate = require('Module:Functions').getTournamentEndDate

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
	local page = args.page and string.gsub(args.page, '_', ' ') or mw.title.getCurrentTitle().text
	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 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 .. '|' .. getTeamDisplaytitle(team.name, getTournamentEndDate(page)) .. ']]')
		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