Fix small big with weapon set bonus in skillpoint test, bring python script up to date
This commit is contained in:
parent
50afcc753a
commit
6778181129
2 changed files with 101 additions and 45 deletions
|
@ -69,86 +69,134 @@ for item in build_items:
|
|||
setup(item)
|
||||
if all(x == 0 for x in item["reqs"]):
|
||||
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)
|
||||
else:
|
||||
consider.append(item)
|
||||
setup(build_weapon)
|
||||
fixed = tuple(fixed)
|
||||
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.
|
||||
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):
|
||||
skillpoints[i] += item["skillpoints"][i]
|
||||
|
||||
def remove_skillpoints(skillpoints, item):
|
||||
for i in range(5):
|
||||
skillpoints[i] -= item["skillpoints"][i]
|
||||
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]
|
||||
skillpoints[i] += delta
|
||||
|
||||
# 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):
|
||||
def apply_to_fit(skillpoints, item, skillpoint_filter, activeSetCounts):
|
||||
applied = [0, 0, 0, 0, 0]
|
||||
total = 0
|
||||
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):
|
||||
continue
|
||||
skillpoint_filter[i] = True
|
||||
if req > cur:
|
||||
diff = req - cur
|
||||
applied[i] += 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
|
||||
|
||||
# Permutations in js reference (also cool algorithm):
|
||||
# https://stackoverflow.com/a/41068709
|
||||
|
||||
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.
|
||||
for item in fixed:
|
||||
apply_skillpoints(static_skillpoints_base, item)
|
||||
apply_skillpoints(static_skillpoints_base, item, static_activeSetCounts)
|
||||
|
||||
best = None
|
||||
final_skillpoints = None
|
||||
best = consider + noboost;
|
||||
final_skillpoints = static_skillpoints_base[:]
|
||||
best_skillpoints = [0, 0, 0, 0, 0]
|
||||
best_total = math.inf
|
||||
best_activeSetCounts = dict()
|
||||
|
||||
allFalse = [False] * 5
|
||||
|
||||
if len(consider) or len(noboost):
|
||||
|
||||
# Try every combination and pick the best one.
|
||||
import itertools
|
||||
for permutation in itertools.permutations(consider):
|
||||
activeSetCounts = dict(best_activeSetCounts)
|
||||
has_skillpoint = allFalse[:]
|
||||
|
||||
permutation += noboost
|
||||
|
||||
skillpoints_applied = [0, 0, 0, 0, 0]
|
||||
skillpoints = copy.copy(static_skillpoints_base)
|
||||
skillpoints = static_skillpoints_base[:]
|
||||
total_applied = 0
|
||||
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):
|
||||
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
|
||||
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)
|
||||
apply_skillpoints(skillpoints, item, activeSetCounts)
|
||||
total_applied += total_diff
|
||||
if total_applied >= best_total:
|
||||
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):
|
||||
skillpoints_applied[i] += needed_skillpoints[i]
|
||||
skillpoints[i] += needed_skillpoints[i]
|
||||
apply_skillpoints(skillpoints, build_weapon)
|
||||
apply_skillpoints(skillpoints, build_weapon, activeSetCounts)
|
||||
total_applied += total_diff
|
||||
|
||||
if total_applied < best_total:
|
||||
|
@ -156,6 +204,18 @@ for permutation in itertools.permutations(consider):
|
|||
final_skillpoints = skillpoints
|
||||
best_skillpoints = skillpoints_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(best_skillpoints)
|
||||
|
|
|
@ -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) {
|
||||
let applied = [0, 0, 0, 0, 0];
|
||||
let total = 0;
|
||||
|
@ -145,8 +143,6 @@ function calculate_skillpoints(equipment, weapon) {
|
|||
total_applied += total_diff;
|
||||
|
||||
if (total_applied < best_total) {
|
||||
console.log(pre);
|
||||
console.log(skillpoints);
|
||||
best = permutation;
|
||||
final_skillpoints = skillpoints;
|
||||
best_skillpoints = skillpoints_applied;
|
||||
|
@ -165,7 +161,7 @@ function calculate_skillpoints(equipment, weapon) {
|
|||
best_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;
|
||||
}
|
||||
let equip_order = fixed.concat(best);
|
||||
|
|
Loading…
Reference in a new issue