wynnbuilder-idk/skillpoint_test.py

166 lines
4.7 KiB
Python
Raw Normal View History

import json
import math
import copy
with open("clean.json") as infile:
data = json.load(infile)
def clean_item(item):
if not "displayName" in item:
item["displayName"] = item["name"];
return item
items = data["items"]
item_map = {clean_item(item)["displayName"]: item for item in items}
2021-01-07 06:41:41 +00:00
# build_items_names = [
# "Cumulonimbus",
# "Soulflare",
# "Leictreach Makani",
# "Slayer",
# "Intensity",
# "Moon Pool Circlet",
# "Diamond Static Bracelet",
# "Royal Stormy Amulet"
# ]
# build_weapon_name = "Fatal"
# build_items_names = [
# "Morph-Stardust",
# "Morph-Steel",
# "Morph-Iron",
# "Morph-Gold",
# "Morph-Topaz",
# "Morph-Emerald",
# "Morph-Amethyst",
# "Morph-Ruby"
# ]
# build_weapon_name = "Cascade"
build_items_names = [
2021-01-07 06:41:41 +00:00
"Blue Mask",
"Sparkling Plate",
"Gemini",
"Slayer",
2021-01-07 06:41:41 +00:00
"Draoi Fair",
"Moon Pool Circlet",
2021-01-07 06:41:41 +00:00
"Prowess",
"Diamond Fusion Necklace"
]
2021-01-07 06:41:41 +00:00
build_weapon_name = "Praesidium"
build_items = [item_map[item] for item in build_items_names]
build_weapon = item_map[build_weapon_name]
for item in build_items:
print(item)
print("-------------------------------")
print(build_weapon)
2021-01-07 02:02:28 +00:00
# Consolidate skillpoint and req into arrays for ease of processing.
def setup(item):
item["skillpoints"] = [item["str"], item["dex"], item["int"], item["def"], item["agi"]]
item["has_negstat"] = any(x < 0 for x in item["skillpoints"])
item["reqs"] = [item["strReq"], item["dexReq"], item["intReq"], item["defReq"], item["agiReq"]]
fixed = []
consider = []
2021-01-07 06:41:41 +00:00
noboost = []
for item in build_items:
setup(item)
2021-01-07 06:41:41 +00:00
if all(x == 0 for x in item["reqs"]):
fixed.append(item)
2021-01-07 06:41:41 +00:00
elif all(x == 0 for x in item["skillpoints"]):
noboost.append(item)
else:
consider.append(item)
setup(build_weapon)
2021-01-07 06:41:41 +00:00
fixed = tuple(fixed)
noboost = tuple(noboost)
2021-01-07 02:02:28 +00:00
# Apply the skillpoints an item gives to the build.
def apply_skillpoints(skillpoints, item):
2021-01-07 02:02:28 +00:00
for i in range(5):
skillpoints[i] += item["skillpoints"][i]
2021-01-07 06:41:41 +00:00
def remove_skillpoints(skillpoints, item):
for i in range(5):
skillpoints[i] -= item["skillpoints"][i]
2021-01-07 02:02:28 +00:00
# Figure out (naively) how many skillpoints need to be applied to get the current item to fit.
# Doesn't handle -skp.
def apply_to_fit(skillpoints, item):
applied = [0, 0, 0, 0, 0]
2021-01-07 06:41:41 +00:00
total = 0
for i, req, cur in zip(range(5), item["reqs"], skillpoints):
if (item["reqs"][i] == 0):
continue
if req > cur:
2021-01-07 06:41:41 +00:00
diff = req - cur
applied[i] += diff
total += diff
return applied, total
# Permutations in js reference (also cool algorithm):
# https://stackoverflow.com/a/41068709
static_skillpoints_base = [0, 0, 0, 0, 0]
2021-01-07 02:02:28 +00:00
# Separate out the no req items and add them to the static skillpoint base.
for item in fixed:
apply_skillpoints(static_skillpoints_base, item)
best = None
2021-01-07 06:41:41 +00:00
final_skillpoints = None
best_skillpoints = [0, 0, 0, 0, 0]
best_total = math.inf
2021-01-07 02:02:28 +00:00
# Try every combination and pick the best one.
import itertools
for permutation in itertools.permutations(consider):
2021-01-07 06:41:41 +00:00
permutation += noboost
skillpoints_applied = [0, 0, 0, 0, 0]
skillpoints = copy.copy(static_skillpoints_base)
2021-01-07 06:41:41 +00:00
total_applied = 0
for item in permutation:
2021-01-07 06:41:41 +00:00
needed_skillpoints, total_diff = apply_to_fit(skillpoints, item)
for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, item)
2021-01-07 06:41:41 +00:00
total_applied += total_diff
if total_applied >= best_total:
break
if total_applied < best_total:
for item in permutation:
remove_skillpoints(skillpoints, item)
needed_skillpoints, total_diff = apply_to_fit(skillpoints, item)
for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, item)
total_applied += total_diff
if total_applied >= best_total:
break
needed_skillpoints, total_diff = apply_to_fit(skillpoints, build_weapon)
for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, build_weapon)
total_applied += total_diff
if total_applied < best_total:
best = permutation
2021-01-07 06:41:41 +00:00
final_skillpoints = skillpoints
best_skillpoints = skillpoints_applied
best_total = total_applied
2021-01-07 06:41:41 +00:00
print([i["displayName"] for i in fixed + best])
print(best_skillpoints)
2021-01-07 06:41:41 +00:00
print(final_skillpoints)
print(best_total)
#def attempt(skillpoints, items_in_order):