Module:Grind/dist
From Fallen London Wiki
Documentation for this module may be created at Module:Grind/dist/doc
local p = {}
local util = require('Module:Grind/util')
-- == Distribution manipulations ==
-- Multiplies effect distribution by a constant.
function p.effect_mul(effect, multiplier)
local eff = {}
if multiplier == 0 then
return eff
end
for resource, dist in pairs(effect) do
eff[resource] = {}
for delta, prob in pairs(dist) do
if eff[resource][delta * multiplier] == nil then
eff[resource][delta * multiplier] = 0
end
eff[resource][delta * multiplier] = eff[resource][delta * multiplier] + prob
end
end
return eff
end
-- Computes the sum of effect distributions.
function p.effect_sum(eff1, eff2)
local eff = {}
local resources = {}
for resource, _ in pairs(eff1) do
resources[resource] = true
end
for resource, _ in pairs(eff2) do
resources[resource] = true
end
for resource, _ in pairs(resources) do
local dist1 = eff1[resource]
local dist2 = eff2[resource]
eff[resource] = {}
if dist1 ~= nil and dist2 ~= nil then
for delta1, prob1 in pairs(dist1) do
for delta2, prob2 in pairs(dist2) do
local delta = delta1 + delta2
local prob = prob1 * prob2
-- check for NaN
if delta == delta then
if eff[resource][delta] == nil then
eff[resource][delta] = 0
end
eff[resource][delta] = eff[resource][delta] + prob
end
end
end
elseif dist1 ~= nil then
eff[resource] = dist1
else
eff[resource] = dist2
end
end
return eff
end
-- Multiplies the probabilities in effect distribution by a constant.
-- Used for distribution mixing.
function p.effect_mul_p(effect, multiplier)
local eff = {}
if multiplier == 0 then
return eff
end
for resource, dist in pairs(effect) do
eff[resource] = {}
for delta, prob in pairs(dist) do
eff[resource][delta] = prob * multiplier
end
end
return eff
end
-- Sums probabilities from effect distributions.
-- Used for distribution mixing.
function p.effect_sum_p(eff1, eff2)
local eff = {}
for resource, dist in pairs(eff1) do
eff[resource] = {}
for delta, prob in pairs(dist) do
eff[resource][delta] = prob
end
end
for resource, dist in pairs(eff2) do
if eff[resource] == nil then
eff[resource] = {}
end
for delta, prob in pairs(dist) do
if eff[resource][delta] == nil then
eff[resource][delta] = 0
end
eff[resource][delta] = eff[resource][delta] + prob
end
end
for resource, dist in pairs(eff) do
local total_p = 0
for _, prob in pairs(dist) do
total_p = total_p + prob
end
if total_p < 0.99 then
if eff[resource][0] == nil then
eff[resource][0] = 0
end
eff[resource][0] = eff[resource][0] + (1 - total_p)
end
end
return eff
end
-- Expected value of a distribution.
function p.expected_value(dist)
local delta = 0
for delta_i, prob_i in pairs(dist) do
delta = delta + delta_i * prob_i
end
return delta
end
-- Replaces each distribution with the expected value in effect.
function p.expected_effect(effect)
local eff = {}
for resource, dist in pairs(effect) do
local delta = p.expected_value(dist)
if delta ~= 0 then
eff[resource] = delta
end
end
return eff
end
-- Computes the probability of random value being in the specified range.
function p.range_prob(dist, range)
local rmin, rmax = util.parse_range(range)
if rmin == nil or rmax == nil then
return 0
end
local pr = 0
for delta, prob in pairs(dist) do
if rmin <= delta and delta <= rmax then
pr = pr + prob
end
end
return pr
end
-- Computes resource per action for the specified resource and effect.
function p.resource_per_action(eff, resource)
local a = eff.a
local r = eff.effect[resource] or 0
if r == 0 then
return 0
end
-- 1/0 is inf, it is fine
return r / a
end
return p