Refactor declaration requirements

Declaration requirements now use helper methods and generator
expressions to increase readability and compactness.

Requirements are ordered and grouped by quantity.

The comments on declaration requirements have been removed, as the new
pattern is far easier to read.
This commit is contained in:
Jeremy Saklad 2021-09-27 16:01:41 -05:00
parent 6f0e0ac379
commit 06dd19bb45
Signed by: Jeremy Saklad
GPG Key ID: 9CA2149583EDBF84
1 changed files with 63 additions and 67 deletions

View File

@ -436,82 +436,78 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non
.OnlyEnforceIf(actions[Declaration.CURATOR]) .OnlyEnforceIf(actions[Declaration.CURATOR])
# Humanoid requirements # Declaration requirements
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.HUMANOID])
model.Add(legs == 2).OnlyEnforceIf(actions[Declaration.HUMANOID])
model.Add(arms == 2).OnlyEnforceIf(actions[Declaration.HUMANOID])
model.AddLinearExpressionInDomain(torso_style, cp_model.Domain.FromFlatIntervals([10, 20])).OnlyEnforceIf(actions[Declaration.HUMANOID])
for prohibited_quality in [tails, fins, wings]:
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.HUMANOID])
# Ape requirements model.AddIf(actions[Declaration.HUMANOID],
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.APE]) (part == 0 for part in (tails, fins, wings)),
model.Add(arms == 4).OnlyEnforceIf(actions[Declaration.APE]) skulls == 1,
model.AddLinearExpressionInDomain(torso_style, cp_model.Domain.FromFlatIntervals([10, 20])).OnlyEnforceIf(actions[Declaration.APE]) (part == 2 for part in (legs, arms)),
for prohibited_quality in [legs, tails, fins, wings]: cp_model.BoundedLinearExpression(torso_style, (10, 20)),
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.APE]) )
# Monkey requirements model.AddIf(actions[Declaration.APE],
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.MONKEY]) (part == 0 for part in (legs, tails, fins, wings)),
model.Add(arms == 4).OnlyEnforceIf(actions[Declaration.MONKEY]) skulls == 1,
model.Add(tails == 1).OnlyEnforceIf(actions[Declaration.MONKEY]) arms == 4,
model.AddLinearExpressionInDomain(torso_style, cp_model.Domain.FromFlatIntervals([10, 20])).OnlyEnforceIf(actions[Declaration.MONKEY]) cp_model.BoundedLinearExpression(torso_style, (10, 20)),
for prohibited_quality in [legs, fins, wings]: )
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.MONKEY])
# Bird requirements model.AddIf(actions[Declaration.MONKEY],
model.Add(legs == 2).OnlyEnforceIf(actions[Declaration.BIRD]) (part == 0 for part in (legs, fins, wings)),
model.Add(wings == 2).OnlyEnforceIf(actions[Declaration.BIRD]) (part == 1 for part in (skulls, tails)),
model.Add(torso_style >= 20).OnlyEnforceIf(actions[Declaration.BIRD]) arms == 4,
for prohibited_quality in [arms, fins]: cp_model.BoundedLinearExpression(torso_style, (10, 20)),
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.BIRD]) )
model.Add(tails < 2).OnlyEnforceIf(actions[Declaration.BIRD])
# Curator requirements model.AddIf(actions[Declaration.BIRD],
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.CURATOR]) (part == 0 for part in (arms, fins)),
model.Add(arms == 2).OnlyEnforceIf(actions[Declaration.CURATOR]) tails < 2,
model.Add(legs == 2).OnlyEnforceIf(actions[Declaration.CURATOR]) (part == 2 for part in (legs, wings)),
model.Add(wings == 2).OnlyEnforceIf(actions[Declaration.CURATOR]) torso_style >= 20,
for prohibited_quality in [fins, tails]: )
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.CURATOR])
# Reptile requirements model.AddIf(actions[Declaration.CURATOR],
model.Add(torso_style >= 20).OnlyEnforceIf(actions[Declaration.REPTILE]) (part == 0 for part in (fins, tails)),
model.Add(tails == 1).OnlyEnforceIf(actions[Declaration.REPTILE]) skulls == 1,
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.REPTILE]) (part == 2 for part in (arms, legs, wings)),
for prohibited_quality in [fins, wings, arms]: )
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.REPTILE])
model.Add(legs < 5).OnlyEnforceIf(actions[Declaration.REPTILE])
# Amphibian requirements model.AddIf(actions[Declaration.REPTILE],
model.Add(torso_style >= 20).OnlyEnforceIf(actions[Declaration.AMPHIBIAN]) (part == 0 for part in (fins, wings, arms)),
model.Add(legs == 4).OnlyEnforceIf(actions[Declaration.AMPHIBIAN]) (part == 1 for part in (tails, skulls)),
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.AMPHIBIAN]) legs < 5,
for prohibited_quality in [tails, fins, wings, arms]: torso_style >= 20,
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.AMPHIBIAN]) )
# Fish requirements model.AddIf(actions[Declaration.AMPHIBIAN],
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.FISH]) (part == 0 for part in (tails, fins, wings, arms)),
model.Add(fins >= 2).OnlyEnforceIf(actions[Declaration.FISH]) skulls == 1,
model.Add(tails <= 1).OnlyEnforceIf(actions[Declaration.FISH]) legs == 4,
model.Add(torso_style >= 20).OnlyEnforceIf(actions[Declaration.FISH]) torso_style >= 20,
for prohibited_quality in [arms, legs, wings]: )
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.FISH])
# Insect requirements model.AddIf(actions[Declaration.FISH],
model.Add(skulls == 1).OnlyEnforceIf(actions[Declaration.INSECT]) (part == 0 for part in (arms, legs, wings)),
model.Add(legs == 6).OnlyEnforceIf(actions[Declaration.INSECT]) tails <= 1,
model.Add(torso_style >= 20).OnlyEnforceIf(actions[Declaration.INSECT]) skulls == 1,
for prohibited_quality in [arms, fins, tails]: fins >= 2,
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.INSECT]) torso_style >= 20,
model.Add(wings < 5).OnlyEnforceIf(actions[Declaration.INSECT]) )
# Spider requirements model.AddIf(actions[Declaration.INSECT],
model.Add(legs == 8).OnlyEnforceIf(actions[Declaration.SPIDER]) (part == 0 for part in (arms, fins, tails)),
model.Add(tails <= 1).OnlyEnforceIf(actions[Declaration.SPIDER]) skulls == 1,
model.Add(torso_style >= 20).OnlyEnforceIf(actions[Declaration.SPIDER]) wings < 5,
for prohibited_quality in [skulls, arms, wings, fins]: legs == 6,
model.Add(prohibited_quality == 0).OnlyEnforceIf(actions[Declaration.SPIDER]) torso_style >= 20,
)
model.AddIf(actions[Declaration.SPIDER],
(part == 0 for part in (skulls, arms, wings, fins)),
tails <= 1,
legs == 8,
torso_style >= 20,
)
# Skeleton must have no unfilled skulls # Skeleton must have no unfilled skulls
model.Add(cp_model.LinearExpr.ScalProd(actions.values(), [action.value.skulls_needed for action in actions.keys()]) == 0) model.Add(cp_model.LinearExpr.ScalProd(actions.values(), [action.value.skulls_needed for action in actions.keys()]) == 0)