Holy Relics have been nerfed, with different values for each torso type.
The new values don't follow an obvious formula, unfortunately, so they
have to be hard-coded for each Torso Style value.
This will need to be maintained going forward if new Torso Styles become
possible.
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.
The cost of adding joints is dependent on the current amount, which may
be affected by both the torso and skulls.
The new implementation still ignores the effects of other Appendage
actions, since joints may be added before doing anything else. This may
warrant revisiting in the future.
OR-Tools 9.3 no longer seems to use more than one worker by default, so
this parameter is once again set by the script.
The parameter has also been changed from num_search_workers to
num_workers internally, though the former is mapped to the latter.
Buyer requirements now use helper methods and control flow to increase
readability and compactness.
The main benefit of this is no longer having to declare intermediate
variables.
This function has been obsoleted by the ability to pass partial methods
as parameters to helper functions.
Use of this function has been replaced with partial methods accordingly.
In addition, the following code style has been applied: partial methods that
contain a nested partial method have the function arguments broken into
distinct lines. This means that the bottom partial method is formatted in the
same manner as a partial method without any nesting.
This function has been obsoleted by the ability to pass partial methods
as parameters to helper functions.
Use of this function has been replaced with partial methods accordingly.
This has allowed some intermediate variables to be removed entirely,
allowing for further simplification.
The Trifling Diplomat fascinations that previously exhibited quasi-cubic
scaling have a new formula using the mean of amalgamy, antiquity, and
menace.
To eliminate unnecessary reptition, all fascinations have been
completely refactored and combined using the new helper methods and design patterns.
A comment has been added to mark The Trifling Diplomat's code, since it
is noticeably less readable than that of other refactored buyers.
This update, despite ostensibly being a minor version, includes breaking
changes that must be accounted for.
Overflow is much more strictly checked, so the magnitude of certain
constants has been decreased.
CP-SAT's default number of workers has been changed to reflect the
default of this script. As such, the script no longer needs to change
that parameter unless a specific number of workers has been specified.
In light of the breaking changes, the OR-Tools version is now pinned at
9.1 instead of being permitted to use future minor versions.
Buyer requirements now use helper methods and control flow to increase
readability and compactness.
The main benefit of this is no longer having to declare intermediate variables directly.
This is a work-in-progress, as some buyers have complex formulae that
necessitate more work or additional helper methods to refactor.
Amalgamy, antiquity, menace, and implausibility are now clamped to be
non-negative. This simplifies a number of calculations, eliminates a few
insiduous calculation errors, and reflects the actual game.
This change impacts the output of the program, which previously showed
negative values even though they weren't actually possible.
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.
The replacement method, BoolExpression, accepts a
BoundedLinearExpression directly, and uses memoization to reuse Boolean
variables. This technique is unsuitable for other methods, as
constraints need to be applied separately, but in this case it is fine.
The new method is much easier to understand, and far easier to read at
call sites.
Variable names are generated from the expression, rather than being
explicitly specified.
The new subclass, BoneMarketModel, overrides CpModel's methods with
improvements such as default parameters and support for enforcement
literals.
This should allow substantial improvements to the readability of the
solver in the future.
In addition, various lists have been replaced with tuples where
appropriate.
Inline string expressions are far easier to read, particularly for
complicated strings like the skeleton printer's output.
Care has been taken to ensure that no behavior has been changed in the
process.
The Investment-Minded Ambassador yields 80% of their former secondary
revenue, while the Tentacled Entrepreneur and Teller of Terrors yield
400% of theirs.
Zoological Mania's bonus is now saved upon skeleton declaration,
and used when calculating results rather than being added to value
directly.
Not all buyers benefit from the bonus, so this change better reflects
the actual game.
A crash caused by failing to specify Zoological Mania has been fixed.
Vake skulls now have diminishing returns beyond the first skull.
Menace calculation has been reorganized to accomodate the change.
Vake skulls are no longer capped, as the new scaling has been fully
implemented.
Vake skulls now have scaling implausibility, which is calculated using a
partial sum formula.
Implausibility calculation has been reorganized to accomodate the
change.
Vake skulls now have diminishing returns beyond the first skull, which
are calculated using a partial sum formula similar to joint addition.
Value calculation has been reorganized to accomodate the change.
All scripts are now contained in a package named "bonemarketsolver".
The command-line interface has been moved to __main__.py.
The solver script has been moved to solve.py.
Relative module imports are now used where appropriate.
The invocation method of the CLI has changed: instead of running Python
itself, you can now use "pipenv run bone_market_solver".
The README has been updated to reflect the new usage method.