Module:Sandbox/Mzs42/MathTest

From Fallen London Wiki (Staging)

Documentation for this module may be created at Module:Sandbox/Mzs42/MathTest/doc

local p = {}

local function error_msg(message)
	return '<strong class="error">Error: ' .. message .. '</strong>'
end

local function get_diff(quality, scaler, prob)
    return math.floor(quality * scaler / prob)
end

local function calc_diff(quality_str, prob_str, scaler, base_quality)
    local prob_list = {}
    for n in prob_str:gmatch('[+-]?%d+') do
    	local prob = tonumber(n)
    	if prob == nil or prob < 1 or prob > 100 then
    		return error_msg(
    			'Invalid success probability "' .. n ..
    			'". Probability must be an integer between 1 and 100, inclusive.')
    	end
        table.insert(prob_list, tonumber(n))
    end
    local i = 0
    local low = 0
    local high = 1000000
    for n in quality_str:gmatch('[+-]?%d+') do
        if i < #prob_list then
            local modifier = tonumber(n)
            if modifier == nil then
            	return error_msg('Invalid quality modifier: "' .. n .. '"')
            end
            local qual = base_quality + modifier
            if qual < 0 then
            	if base_quality == 0 then
        	    	return error_msg(
        	    		'Invalid quality level "' .. modifier ..
        		    	'". Total quality levels must be non-negative integers.')
        	    else
        	        return error_msg(
        	        	'Invalid total quality level ' .. base_quality ..
        	    	    ' + ' .. modifier .. ' = ' .. qual ..
        	    	    '. Quality levels must be non-negative integers.')
        	    end
            end
            local prob = prob_list[i + 1]
            if prob < 100 then
                low = math.max(low, get_diff(qual, scaler, prob + 1) + 1)
            end
            high = math.min(high, get_diff(qual, scaler, prob))
        end
        i = i + 1
    end
    if i ~= #prob_list then
        return error_msg(
        	'Must input same number of quality values as probability values. Got ' ..
        	i .. ' and ' .. #prob_list .. ', respectively.')
    end
    if low > high then
        return error_msg('Impossible input set')
    end
    if low == high then
        return 'Difficulty Level is exactly ' .. low
    end
    return 'Difficulty Level is in the range [' .. low .. '..' .. high .. ']'
end

function p.calc_diff(frame)
	local args = frame.args
	local parent_args = frame:getParent().args
	local quality_str = args.quality_levels or parent_args.quality_levels
	local prob_str = args.probabilities or parent_args.probabilities
	local scaler = tonumber(args.scaler or parent_args.scaler) or 60
	local base_quality = tonumber(args.base_quality or parent_args.base_quality) or 0
	return calc_diff(quality_str, prob_str, scaler, base_quality)
end

return p