Fix small big with weapon set bonus in skillpoint test, bring python script up to date

This commit is contained in:
b 2021-01-10 01:48:40 -06:00
parent 50afcc753a
commit 6778181129
2 changed files with 101 additions and 45 deletions

View file

@ -69,86 +69,134 @@ for item in build_items:
setup(item) setup(item)
if all(x == 0 for x in item["reqs"]): if all(x == 0 for x in item["reqs"]):
fixed.append(item) fixed.append(item)
elif all(x == 0 for x in item["skillpoints"]): elif all(x == 0 for x in item["skillpoints"]) and item["set"] is None:
noboost.append(item) noboost.append(item)
else: else:
consider.append(item) consider.append(item)
setup(build_weapon) setup(build_weapon)
fixed = tuple(fixed) fixed = tuple(fixed)
noboost = tuple(noboost) noboost = tuple(noboost)
consider = tuple(consider)
"""
The way this code expects this to work:
sets is a map: setName -> setObject {
bonuses: array[bonusObject]
}
where each bonusObject is a mapping from id to boost value.
And the bonuses array describes the effect of equipping set items (0 index = 1 item).
"""
sets = dict()
# Apply the skillpoints an item gives to the build. # Apply the skillpoints an item gives to the build.
def apply_skillpoints(skillpoints, item): """
skillPoints: current skillpoint totals.
item: Item in uestion.
activeSetCounts: Mapping from setname to number of items currently worn (not including this one).
"""
def apply_skillpoints(skillpoints, item, activeSetCounts):
for i in range(5): for i in range(5):
skillpoints[i] += item["skillpoints"][i] skillpoints[i] += item["skillpoints"][i]
def remove_skillpoints(skillpoints, item): if item["set"] is not None:
for i in range(5): setName = item["set"]
skillpoints[i] -= item["skillpoints"][i] old_bonus = dict()
if setName in activeSetCounts:
setCount = activeSetCounts[setName]
old_bonus = sets[setName]["bonuses"][setCount-1]
activeSetCounts[setName] = setCount + 1
else:
setCount = 0
activeSetCounts[setName] = 1
new_bonus = sets[setName]["bonuses"][setCount]
skp_order = ["str","dex","int","def","agi"]
for i, skp in enumerate(skp_order):
delta = new_bonus[skp] - old_bonus[skp]
skillpoints[i] += delta
# Figure out (naively) how many skillpoints need to be applied to get the current item to fit. # Figure out (naively) how many skillpoints need to be applied to get the current item to fit.
# Doesn't handle -skp. # Doesn't handle -skp.
def apply_to_fit(skillpoints, item): def apply_to_fit(skillpoints, item, skillpoint_filter, activeSetCounts):
applied = [0, 0, 0, 0, 0] applied = [0, 0, 0, 0, 0]
total = 0 total = 0
for i, req, cur in zip(range(5), item["reqs"], skillpoints): for i, req, cur in zip(range(5), item["reqs"], skillpoints):
if item["skillpoints"][i] < 0 and skillpoint_filter[i]:
applied[i] -= item["skillpoints"][i]
total -= item["skillpoints"][i]
if (item["reqs"][i] == 0): if (item["reqs"][i] == 0):
continue continue
skillpoint_filter[i] = True
if req > cur: if req > cur:
diff = req - cur diff = req - cur
applied[i] += diff applied[i] += diff
total += diff total += diff
if item["set"] is not None:
setName = item["set"]
old_bonus = dict()
if setName in activeSetCounts:
setCount = activeSetCounts[setName]
old_bonus = sets[setName]["bonuses"][setCount-1]
activeSetCounts[setName] = setCount + 1
else:
setCount = 0;
activeSetCounts[setName] = 1
new_bonus = sets[setName]["bonuses"][setCount]
skp_order = ["str","dex","int","def","agi"]
for i, skp in enumerate(skp_order):
delta = new_bonus[skp] - old_bonus[skp]
if delta < 0 and skillpoint_filter[i]:
applied[i] -= delta
total -= delta
return applied, total return applied, total
# Permutations in js reference (also cool algorithm): # Permutations in js reference (also cool algorithm):
# https://stackoverflow.com/a/41068709 # https://stackoverflow.com/a/41068709
static_skillpoints_base = [0, 0, 0, 0, 0] static_skillpoints_base = [0, 0, 0, 0, 0]
static_activeSetCounts = dict()
# Separate out the no req items and add them to the static skillpoint base. # Separate out the no req items and add them to the static skillpoint base.
for item in fixed: for item in fixed:
apply_skillpoints(static_skillpoints_base, item) apply_skillpoints(static_skillpoints_base, item, static_activeSetCounts)
best = None best = consider + noboost;
final_skillpoints = None final_skillpoints = static_skillpoints_base[:]
best_skillpoints = [0, 0, 0, 0, 0] best_skillpoints = [0, 0, 0, 0, 0]
best_total = math.inf best_total = math.inf
best_activeSetCounts = dict()
allFalse = [False] * 5
if len(consider) or len(noboost):
# Try every combination and pick the best one. # Try every combination and pick the best one.
import itertools import itertools
for permutation in itertools.permutations(consider): for permutation in itertools.permutations(consider):
activeSetCounts = dict(best_activeSetCounts)
has_skillpoint = allFalse[:]
permutation += noboost permutation += noboost
skillpoints_applied = [0, 0, 0, 0, 0] skillpoints_applied = [0, 0, 0, 0, 0]
skillpoints = copy.copy(static_skillpoints_base) skillpoints = static_skillpoints_base[:]
total_applied = 0 total_applied = 0
for item in permutation: for item in permutation:
needed_skillpoints, total_diff = apply_to_fit(skillpoints, item) needed_skillpoints, total_diff = apply_to_fit(skillpoints, item, has_skillpoint, activeSetCounts)
for i in range(5): for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i] skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i] skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, item) apply_skillpoints(skillpoints, item, activeSetCounts)
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 total_applied += total_diff
if total_applied >= best_total: if total_applied >= best_total:
break break
needed_skillpoints, total_diff = apply_to_fit(skillpoints, build_weapon) needed_skillpoints, total_diff = apply_to_fit(skillpoints, build_weapon, has_skillpoint, activeSetCounts)
for i in range(5): for i in range(5):
skillpoints_applied[i] += needed_skillpoints[i] skillpoints_applied[i] += needed_skillpoints[i]
skillpoints[i] += needed_skillpoints[i] skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, build_weapon) apply_skillpoints(skillpoints, build_weapon, activeSetCounts)
total_applied += total_diff total_applied += total_diff
if total_applied < best_total: if total_applied < best_total:
@ -156,6 +204,18 @@ for permutation in itertools.permutations(consider):
final_skillpoints = skillpoints final_skillpoints = skillpoints
best_skillpoints = skillpoints_applied best_skillpoints = skillpoints_applied
best_total = total_applied best_total = total_applied
best_activeSetCounts = activeSetCounts
else:
best_total = 0
needed_skillpoints, total_diff = apply_to_fit(skillpoints, build_weapon, allFalse, best_activeSetCounts)
for i in range(5):
best_skillpoints[i] += needed_skillpoints[i]
final_skillpoints[i] += needed_skillpoints[i]
apply_skillpoints(skillpoints, build_weapon, best_activeSetCounts)
best_total += total_diff
equip_order = fixed + best
results = [equip_order, best_skillpoints, final_skillpoints, best_total, best_activeSetCounts];
print([i["displayName"] for i in fixed + best]) print([i["displayName"] for i in fixed + best])
print(best_skillpoints) print(best_skillpoints)

View file

@ -44,8 +44,6 @@ function calculate_skillpoints(equipment, weapon) {
} }
} }
// Figure out (naively) how many skillpoints need to be applied to get the current item to fit.
// Doesn't handle -skp.
function apply_to_fit(skillpoints, item, skillpoint_filter, activeSetCounts) { function apply_to_fit(skillpoints, item, skillpoint_filter, activeSetCounts) {
let applied = [0, 0, 0, 0, 0]; let applied = [0, 0, 0, 0, 0];
let total = 0; let total = 0;
@ -145,8 +143,6 @@ function calculate_skillpoints(equipment, weapon) {
total_applied += total_diff; total_applied += total_diff;
if (total_applied < best_total) { if (total_applied < best_total) {
console.log(pre);
console.log(skillpoints);
best = permutation; best = permutation;
final_skillpoints = skillpoints; final_skillpoints = skillpoints;
best_skillpoints = skillpoints_applied; best_skillpoints = skillpoints_applied;
@ -165,7 +161,7 @@ function calculate_skillpoints(equipment, weapon) {
best_skillpoints[i] += needed_skillpoints[i]; best_skillpoints[i] += needed_skillpoints[i];
final_skillpoints[i] += needed_skillpoints[i]; final_skillpoints[i] += needed_skillpoints[i];
} }
apply_skillpoints(final_skillpoints, weapon); apply_skillpoints(final_skillpoints, weapon, best_activeSetCounts);
best_total += total_diff; best_total += total_diff;
} }
let equip_order = fixed.concat(best); let equip_order = fixed.concat(best);