-
-
Save d34dh0r53/4c7a76a3c274c2ab78f1 to your computer and use it in GitHub Desktop.
Destiny Item Infusion Calculator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""Destiny Item Infusion Calculator | |
Calculates infusion possibilities, showing costs and final light. | |
Usage: | |
infuse.py [-x] ITEM ITEM [ITEM ...] | |
Arguments: | |
Light levels of items to consider for infusion. | |
At least two items are required, but multiple items can be provided | |
in any order; duplicates will be pruned. The lowest light item is | |
considered the one to infuse, and the highest light item is considered | |
the target. All infusion paths will be calculated. | |
ITEM Integer light level of item (e.g., 280) | |
Options: | |
-x --exotic Base item is exotic | |
--version Show version | |
""" | |
from docopt import docopt | |
import functools | |
import itertools | |
# Legendary Mark cost per infusion | |
COST = 3 | |
def permutate(low, high, mid): | |
""" | |
Calculate permutations | |
<- low:1, high:5, mid: 2 3 | |
1 5 | |
1 2 5 | |
1 3 5 | |
1 2 3 5 | |
""" | |
# Initialize permutations | |
perms = [[low, high]] | |
# For each sublist of middle values | |
for l in range(1, len(mid) + 1): | |
# For each permutation of sublist | |
for perm in itertools.combinations(mid, l): | |
# Store [low, permutation, high] list | |
perms.append(list(itertools.chain([low], perm, [high]))) | |
return perms | |
def infuse(base, target, exotic=False): | |
"""Infuse base item with target item""" | |
# Store difference in items | |
diff = target - base | |
# When items are close in light | |
if diff < (4 if exotic else 6): | |
# No penalty, just return target light | |
return target | |
# Otherwise assess penalty | |
else: | |
# Resulting light is 80% of the difference | |
return round(diff * 0.8) + base | |
def walk(items, exotic=False): | |
"""Walk an infusion path""" | |
# Store path reduction by chaining infusions | |
result = functools.reduce(lambda x, y: infuse(x, y, exotic), items) | |
# Send it back with the step cost | |
return (result, (len(items) - 1) * COST, items) | |
def calculate(args): | |
"""Calculate infusion paths""" | |
# Is item exotic? | |
exotic = args['--exotic'] | |
# Get unique sorted list of items as integers | |
items = list(sorted(map(int, set(args['ITEM'])))) | |
# Store lowest, highest and inbetween | |
low = items[0] | |
high = items[-1] | |
mid = items[1:-1] | |
print("##### Infusing {} light item towards {} light target #####".format( | |
low, high)) | |
# Get permutations | |
perms = permutate(low, high, mid) | |
# Walk each path and store results, sorted by light result | |
paths = sorted([walk(perm, exotic) | |
for perm in perms], key=lambda index: index[0]) | |
# Initialize best light/least marks and least marks/best light | |
light_marks = marks_light = (0, 100, ) | |
# Collect results | |
for path in paths: | |
# Extract parts | |
light, marks, steps = path | |
# If light is best we've seen, or same light but least marks | |
if (light > light_marks[0] or | |
(light == light_marks[0] and marks < light_marks[1])): | |
# Store it | |
light_marks = (light, marks, steps) | |
# If marks is least we've seen, or same marks but best light | |
if (marks < marks_light[1] or | |
(marks == marks_light[1] and light > marks_light[0])): | |
# Store it | |
marks_light = (light, marks, steps) | |
# Print each possible path | |
print("Light: {}, Marks: {}, Infusion: {}".format( | |
light, marks, " -> ".join(map(str, steps)))) | |
# Show best light, but least marks | |
light, marks, steps = light_marks | |
print() | |
print("##### Best light with least marks #####") | |
print("Light: {}, Marks: {}, Infusion: {}".format( | |
light, marks, " -> ".join(map(str, steps)))) | |
# Show least marks, but best light | |
light, marks, steps = marks_light | |
print() | |
print("##### Least marks with best light #####") | |
print("Light: {}, Marks: {}, Infusion: {}".format( | |
light, marks, " -> ".join(map(str, steps)))) | |
# Entry point | |
if __name__ == "__main__": | |
calculate(docopt(__doc__, version="Infuse 1.0")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment