Add support for fractions of skeleton attributes

This commit is contained in:
TheTaques 2021-08-24 13:10:39 +02:00
parent e2bb3fd073
commit a86525324e
1 changed files with 24 additions and 8 deletions

View File

@ -22,6 +22,7 @@ from .data.torsos import Torso
# This multiplier is applied to the profit margin to avoid losing precision due to rounding.
PROFIT_MARGIN_MULTIPLIER = 10000000
ATTRIBUTE_MULTIPLIER = 10000000
# This is the highest number of attribute to calculate fractional exponents for.
MAXIMUM_ATTRIBUTE = 100
@ -197,21 +198,36 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non
model.Add(tentacles == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.tentacles for action in actions.keys()]))
# Amalgamy calculation
multiplied_amalgamy = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied amalgamy')
model.Add(multiplied_amalgamy == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.amalgamy*ATTRIBUTE_MULTIPLIER) for action in actions.keys()]))
amalgamy = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'amalgamy')
model.Add(amalgamy == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.amalgamy for action in actions.keys()]))
model.AddDivisionEquality(amalgamy, multiplied_amalgamy, ATTRIBUTE_MULTIPLIER)
del multiplied_amalgamy
# Antiquity calculation
multiplied_antiquity = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied antiquity')
model.Add(multiplied_antiquity == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.antiquity*ATTRIBUTE_MULTIPLIER) for action in actions.keys()]))
antiquity = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'antiquity')
model.Add(antiquity == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.antiquity for action in actions.keys()]))
model.AddDivisionEquality(antiquity, multiplied_antiquity, ATTRIBUTE_MULTIPLIER)
del multiplied_antiquity
# Menace calculation
multiplied_menace = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied menace')
model.Add(multiplied_menace == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.menace*ATTRIBUTE_MULTIPLIER) for action in actions.keys()]))
menace = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'menace')
model.Add(menace == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.menace for action in actions.keys()]))
model.AddDivisionEquality(menace, multiplied_menace, ATTRIBUTE_MULTIPLIER)
del multiplied_menace
# Implausibility calculation
multiplied_implausibility = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied implausibility')
model.Add(multiplied_implausibility == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.implausibility*ATTRIBUTE_MULTIPLIER) for action in actions.keys()]))
implausibility = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'implausibility')
model.Add(implausibility == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.implausibility for action in actions.keys()]))
model.AddDivisionEquality(implausibility, multiplied_implausibility, ATTRIBUTE_MULTIPLIER)
del multiplied_implausibility
# Counter-church calculation
# Calculate amount of Counter-church from Holy Relics of the Thigh of Saint Fiacre
@ -1204,16 +1220,16 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non
model.Add(net_profit == total_revenue - cost)
# This is necessary to preserve some degree of precision after dividing
multiplied_net_profit = model.NewIntVar(cp_model.INT32_MIN*PROFIT_MARGIN_MULTIPLIER, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'multiplied net profit')
multiplied_net_profit = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied net profit')
model.AddMultiplicationEquality(multiplied_net_profit, [net_profit, PROFIT_MARGIN_MULTIPLIER])
absolute_multiplied_net_profit = model.NewIntVar(0, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'absolute multiplied net profit')
absolute_multiplied_net_profit = model.NewIntVar(0, cp_model.INT32_MAX, 'absolute multiplied net profit')
model.AddAbsEquality(absolute_multiplied_net_profit, multiplied_net_profit)
absolute_profit_margin = model.NewIntVar(cp_model.INT32_MIN*PROFIT_MARGIN_MULTIPLIER, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'absolute profit margin')
absolute_profit_margin = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'absolute profit margin')
model.AddDivisionEquality(absolute_profit_margin, absolute_multiplied_net_profit, total_revenue)
profit_margin = model.NewIntVar(cp_model.INT32_MIN*PROFIT_MARGIN_MULTIPLIER, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'profit margin')
profit_margin = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'profit margin')
positive_net_profit = model.NewIntermediateBoolVar('positive net profit', net_profit, cp_model.Domain.FromFlatIntervals([0, cp_model.INT_MAX]))
model.Add(profit_margin == absolute_profit_margin).OnlyEnforceIf(positive_net_profit)