Module:Territories

From NPOWiki
Revision as of 04:07, 8 September 2025 by Bobogoobo (talk | contribs) (create)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Documentation [edit]

This page is a stub - it only covers the very basics of its subject. More information should be added to make the page informative and useful. If no more information is available, the page should be considered for a merge, redirect, or deletion.

Details: documentation to be written

If you can correct the issue, please edit the page to do so, then remove this notice.
Please see Template:Territory for usage information. Use the template rather than invoking the module. Data for this module is imported from Module:Territories/data.

The above documentation is transcluded from Module:Territories/doc.

local p = {}
local territories = mw.loadData('Module:Territories/data')

--Create keyed index of territories from the data (which is an array)
local function makeIndex()
	local index = {}
	for i, tt in ipairs(territories) do
		if index[tt.id] then
			mw.log('Duplicate territory found: ' .. tt.id .. ' at index ' .. i)
			tt.id = tt.id .. "_"
		end
		index[tt.id] = tt
	end
	return index
end
p.index = makeIndex()

--Table functions do not work with mw.loadData, so this function returns a new table of the given territory's neighbors.
--Expects a territory object as input.
local function getNeighbors(tt)
	local neighbors = {}
	for _, n in ipairs(tt.neighbors) do
		table.insert(neighbors, n)
	end
	return neighbors
end

local function lookup(tt, prop)
	local data = p.index[tt]
	
	if prop == 'coordinates' then
		return '(' .. data.coordinates.x .. ', ' .. data.coordinates.y .. ')'
	elseif prop == 'x' or prop == 'y' then
		return data.coordinates[prop]
	elseif prop == 'neighbors' then
		return table.concat(getNeighbors(data), ', ')
	elseif not data[prop] then
		return '<span class="error">invalid property: ' .. prop .. '</span>'
	else
		return data[prop]
	end
end

local function stats(tt, prop, stat)
	if stat == 'overall' then
		--Overall territories stats
		local total = 0
		local possible = 26 * 26 * 26
		local sectors = {0, 0, 0, 0, 0, 0, 0}
		for _, terr in ipairs(territories) do
			total = total + 1
			sectors[terr.sector] = sectors[terr.sector] + 1
		end
		local out = {
			'*Total territories: ' .. total,
			'*Possible three-letter territories: ' .. possible .. ' (' .. mw.ustring.format('%.2f', total/possible*100) .. '% used)',
			'*By sector:',
		}
		for i, sCount in ipairs(sectors) do
			table.insert(out, '**Sector ' .. i .. ': ' .. sCount)
		end
		return table.concat(out, '\n')
	elseif stat == 'neighbors' then
		--Return formatted list of neighbors of the given territory
		return #getNeighbors(p.index[tt])
	elseif stat == 'connected' then
		--Return boolean indicating whether the two given territories are connected
		prop = mw.ustring.upper(prop or '')
		if prop == '' then
			return '<span class="error">two territories required for stat=connected</span>'
		end
		for _, n in ipairs(p.index[tt].neighbors) do
			if n == prop then
				return true
			end
		end
		return false
	else
		return '<span class="error">invalid stat parameter</span>'
	end
end

--To allow for console testing and requiring this module
function p.call(args)
	local tt = mw.ustring.upper(args[1] or '')
	local prop = args[2]
	local stat = args.stat
	
	if tt ~= '' and not p.index[tt] then
		return '<span class="error">territory "' .. tt .. '" not found</span>'
	end
	
	if stat and stat ~= '' then
		return stats(tt, prop, stat)
	else
		return lookup(tt, prop)
	end
end

function p.main(frame)
	return p.call(frame:getParent().args)
end

return p