feat: Add Segmented Ribcage to appendages
Segmented Ribcages can be used to add more limb slots, but carry a variety of unusual requirements. In addition to a scaling cost in Nevercold Brass, they require an unfilled tail slot when applied. It may be prudent to clean up the partial sum formula using helper methods in the future, as it currently requires a considerable number of intermediate terms. itertools.repeat is now being used to perform exponentiation, rather than repeating terms directly.
This commit is contained in:
parent
b4319464a1
commit
bb21eccca8
|
@ -19,6 +19,17 @@ class Appendage(Enum):
|
|||
amalgamy = 2
|
||||
)
|
||||
|
||||
# Cost from this scales with segments and is partially implemented separately
|
||||
# Requires Torso Style 110
|
||||
# Requires initial tail slot
|
||||
SEGMENTED_RIBCAGE = Action(
|
||||
"Extend the tail end with another Segmented Ribcage",
|
||||
cost = Cost.ACTION.value + Cost.SEGMENTED_RIBCAGE.value,
|
||||
value = 250,
|
||||
limbs_needed = 2,
|
||||
segments = 1
|
||||
)
|
||||
|
||||
ALBATROSS_WING = Action(
|
||||
"Put an Albatross Wing on your (Skeleton Type)",
|
||||
cost = Cost.ACTION.value + Cost.ALBATROSS_WING.value,
|
||||
|
|
|
@ -4,6 +4,7 @@ __all__ = ['Adjustment', 'Appendage', 'Buyer', 'Declaration', 'DiplomatFascinati
|
|||
__author__ = "Jeremy Saklad"
|
||||
|
||||
from functools import partialmethod
|
||||
from itertools import chain, repeat
|
||||
from os import cpu_count
|
||||
|
||||
from ortools.sat.python import cp_model
|
||||
|
@ -328,10 +329,139 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non
|
|||
del add_joints, add_joints_amber_cost_multiple
|
||||
|
||||
|
||||
cost = model.NewIntVar('cost', lb = 0, ub = maximum_cost)
|
||||
model.Add(cost == cp_model.LinearExpr.WeightedSum(actions.values(), [int(action.value.cost) for action in actions.keys()]) + add_joints_amber_cost + sale_cost)
|
||||
# Calculate cost of adding segments.
|
||||
# This is a partial sum formula.
|
||||
add_segments_brass_cost = model.NewIntVar('add segments brass cost', lb = 0)
|
||||
|
||||
del sale_cost, add_joints_amber_cost
|
||||
add_segments = actions[Appendage.SEGMENTED_RIBCAGE]
|
||||
|
||||
# Additional segments may be added once the torso and skulls are chosen, so the sum of their properties are the starting point.
|
||||
base_segments = model.NewIntVar('base segments', lb = 0)
|
||||
model.Add(base_segments == cp_model.LinearExpr.WeightedSum([value for (key, value) in actions.items() if isinstance(key, (Torso, Skull))], [action.value.segments for action in chain(Torso, Skull)]))
|
||||
|
||||
first_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
25,
|
||||
*repeat(add_segments, 4),
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple first term'
|
||||
)
|
||||
|
||||
second_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
100,
|
||||
*repeat(add_segments, 3),
|
||||
base_segments,
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple second term'
|
||||
)
|
||||
|
||||
third_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
50,
|
||||
*repeat(add_segments, 3),
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple third term'
|
||||
)
|
||||
|
||||
fourth_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
150,
|
||||
*repeat(add_segments, 2),
|
||||
*repeat(base_segments, 2),
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple fourth term'
|
||||
)
|
||||
|
||||
fifth_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
150,
|
||||
*repeat(add_segments, 2),
|
||||
base_segments,
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple fifth term'
|
||||
)
|
||||
|
||||
sixth_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
25,
|
||||
*repeat(add_segments, 2),
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple sixth term'
|
||||
)
|
||||
|
||||
seventh_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
100,
|
||||
add_segments,
|
||||
*repeat(base_segments, 3),
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple seventh term'
|
||||
)
|
||||
|
||||
eighth_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
150,
|
||||
add_segments,
|
||||
*repeat(base_segments, 2),
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple eighth term'
|
||||
)
|
||||
|
||||
ninth_term, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
50,
|
||||
add_segments,
|
||||
base_segments,
|
||||
)
|
||||
),
|
||||
'add segments brass cost multiple ninth term'
|
||||
)
|
||||
|
||||
add_segments_brass_cost_multiple, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddDivisionEquality,
|
||||
num=first_term + second_term + third_term + fourth_term + fifth_term + sixth_term + seventh_term + eighth_term + ninth_term,
|
||||
denom=2
|
||||
),
|
||||
'add segments brass cost multiple'
|
||||
)
|
||||
|
||||
del first_term, second_term, third_term, fourth_term, fifth_term, sixth_term, seventh_term, eighth_term, ninth_term
|
||||
|
||||
add_segments_brass_cost, *_ = model.NewIntermediateIntVar(
|
||||
partialmethod(BoneMarketModel.AddMultiplicationEquality,
|
||||
variables=(
|
||||
add_segments_brass_cost_multiple,
|
||||
Cost.NEVERCOLD_BRASS.value,
|
||||
)
|
||||
),
|
||||
'add segments brass cost'
|
||||
)
|
||||
|
||||
del add_segments, base_segments, add_segments_brass_cost_multiple
|
||||
|
||||
|
||||
cost = model.NewIntVar('cost', lb = 0, ub = maximum_cost)
|
||||
model.Add(cost == cp_model.LinearExpr.WeightedSum(actions.values(), [int(action.value.cost) for action in actions.keys()]) + add_joints_amber_cost + add_segments_brass_cost + sale_cost)
|
||||
|
||||
del sale_cost, add_joints_amber_cost, add_segments_brass_cost
|
||||
|
||||
|
||||
# Type of skeleton
|
||||
|
@ -451,6 +581,14 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non
|
|||
.OnlyEnforceIf(model.BoolExpression(actions[Skull.SEGMENTED_RIBCAGE] > 0))
|
||||
|
||||
|
||||
# Appendage requirements
|
||||
|
||||
model.AddIf(model.BoolExpression(actions[Appendage.SEGMENTED_RIBCAGE] > 0),
|
||||
torso_style == 110,
|
||||
cp_model.LinearExpr.WeightedSum([value for (key, value) in actions.items() if isinstance(key, (Torso, Skull))], [action.value.tails_needed for action in chain(Torso, Skull)]) >= 1,
|
||||
)
|
||||
|
||||
|
||||
# Declaration requirements
|
||||
|
||||
model.AddIf(actions[Declaration.HUMANOID],
|
||||
|
|
Loading…
Reference in New Issue