Skip to content

Instantly share code, notes, and snippets.

@zyr17
Last active May 12, 2022 04:47
Show Gist options
  • Select an option

  • Save zyr17/ecd6646201b10c27f7124518808e95f5 to your computer and use it in GitHub Desktop.

Select an option

Save zyr17/ecd6646201b10c27f7124518808e95f5 to your computer and use it in GitHub Desktop.
Genshin Affix Weight by Characters
#%%
from pkgutil import get_data
import formulas
import os
import re
# https://bbs.nga.cn/read.php?tid=25843014
# Modified 优菈 阿贝多 甘雨 八重 魈 丽莎, make final result depends on actual atk.. etc
# https://pan.baidu.com/s/1MClQpeRQPg6onzL2dgZiLw passcode: pxrh
# updated 2.6
filename = 'Genshin2.5.xlsx'
# elemental recharge weight. As it usually not effect final number, need a special
# weight to evaluate its value. details for function `calc_er_weight`
er_weight = 0.5
#%%
# consts
sub_attrs = ['hp', 'atk', 'def', 'hpp', 'atkp', 'defp', 'em', 'er', 'cr', 'cd']
sub_attr_names = [
['生命值', '生命'],
['攻击力', '攻击', '实际攻击'],
['防御力', '防御'],
['生命值', '生命'],
['攻击力', '攻击', '实际攻击'],
['防御力', '防御'],
['元素精通', '精通'],
['充能', '充能效率', '元素充能', '元素充能效率'],
['暴率', '暴击率'],
['暴伤', '暴击伤害']
]
# characters use Q, but Q is not shown in action
Q_characters = ['云堇', '诺艾尔', '托马', '魈', '雷泽', '空/荧(雷)', '神里绫华', '七七']
# characters that value is any, which attr is important
any_characters = [
['申鹤', 'atk'],
['云堇', 'def'],
['五郎', 'er'],
]
# https://bbs.nga.cn/read.php?tid=24270728 https://bbs.nga.cn/read.php?tid=27497061
sub_attr_base_one = 0.0389
sub_attr_base = [7680, 500, 595, 1.5, 1.5, 1.875, 600, 1.66666667, 1, 2]
sub_attr_base = [x * sub_attr_base_one for x in sub_attr_base]
#%%
# functions
def get_data_indices_from_labels(label_line):
# from label line, get indices of different sub_attrs, following with two atk columns
indices = []
for sub_attr_name in sub_attr_names:
for name in sub_attr_name:
i = -1
if name in label_line:
i = label_line.index(name)
break
indices.append(i)
for nn in [['数值预估', '伤害预估'], ['角色白值'], ['武器白值']]:
for n in nn:
if n in label_line:
indices.append(label_line.index(n))
break
return indices
def get_exact_number(label_indices, data_line, solution_line):
# get exact number for one sub_attr
cbase = {}
cbase['atk'] = solution_line[label_indices[-1]] + solution_line[label_indices[-2]]
cbase['hp'] = 0
cbase['def'] = 0
for attr in ['hp', 'def']:
if label_indices[sub_attrs.index(attr)] != -1:
# have hp or def, try to get base
data = data_line[label_indices[sub_attrs.index(attr)]]
if data == '':
continue
assert data[0] == '=' # must start with =
while data[0] < '0' or data[0] > '9':
data = data[1:]
cbase[attr] = int(data.split('*')[0].split('+')[0].split('(')[0])
print(data_line[:4], cbase)
values = []
for base, name in zip(sub_attr_base, sub_attrs):
if name in ['atkp', 'defp', 'hpp']:
values.append(base * cbase[name[:-1]])
else:
values.append(base)
return values
def get_improve_percent(excel, label_indices, name, data, solution, up_values):
result_index = label_indices[-3]
def enhance_cr(value, cr = None):
# when critical damage is used in result formula, enhance the result with critical rate
cd_index = label_indices[sub_attrs.index('cd')]
if name[cd_index] in data[result_index]:
print('use critical damage, start enhance')
cd = solution[cd_index]
value /= 1 + cd
cr_index = label_indices[sub_attrs.index('cr')]
if cr is None:
cr = solution[cr_index]
return value * (1 + cr * cd)
return value
current_baseline = enhance_cr(solution[result_index])
if current_baseline == 'any':
# characters value is any
current_baseline = 0
for cname, aname in any_characters:
if data[0] == cname:
result_index = label_indices[sub_attrs.index(aname)]
current_baseline = solution[result_index]
break
print('character with any', current_baseline, result_index)
if current_baseline == 0:
current_baseline = 1e-10
base_dict = dict(zip(name, data))
improve = []
for sub, index, value in zip(sub_attrs, label_indices, up_values):
if index == -1 or (sub == 'cd' and '珊瑚宫心海' == solution[0]):
improve.append(0)
continue
# now_dict = base_dict.copy()
# now_dict[name[index]] = solution[index] + value
s_data = solution[index]
if s_data in ['/', 'any', '']: # if any or / or empty, assume is zero
s_data = 0
res = excel.calculate(
inputs = {
name[index]: s_data + value
},
outputs = [ name[result_index] ]
).get(name[result_index])
try:
res = res.value[0][0]
except:
pass
if sub == 'cr':
res = enhance_cr(res, s_data + value)
else:
res = enhance_cr(res)
imp = (res - current_baseline) / current_baseline
improve.append(imp)
er_index = sub_attrs.index('er')
improve[er_index] = max(improve[er_index], calc_er_weight(label_indices, up_values, solution, improve))
norm = max(improve)
if norm != 0:
improve = [x / norm for x in improve]
# for name, imp in zip(sub_attr_names, improve):
# print(name[0], imp)
return improve
# Based on er_need_action and main_attr and sub_attr, select characters that
# need elemental recharge. If appear in sub_attr, use number in sub_attr as target,
# else use biggest weight in [hpp, atkp, defp]. Finally, multiply predifined weight.
def calc_er_weight(label_indices, up_values, solution, improvements):
imp = 0
er_index = label_indices[sub_attrs.index('er')]
if er_index != -1:
imp = up_values[er_index] / solution[er_index]
else:
best = 0
if 'Q' in ''.join([str(x) for x in solution]) or solution[0] in Q_characters: # if use Q or in whitelist
print('character use Q')
for attr in ['atkp', 'defp', 'hpp']:
i = improvements[sub_attrs.index(attr)]
best = max(best, i)
imp = best
return imp * er_weight
#%%
# read xls
xl_model = formulas.ExcelModel().loads(filename).finish()
# %%
# extract data to arrays
names = [[''] * 26 for _ in range(1000)]
datas = [[''] * 26 for _ in range(1000)]
solutions = [[''] * 26 for _ in range(1000)]
calc_res = dict(xl_model.calculate())
d = xl_model.to_dict()
for key in d:
if '正表' in key: # only consider main table
columnnum = ord(key.split('!')[-1][0]) - 65
linenum = int(key.split('!')[-1][1:])
if linenum > 10: # is data
datas[linenum][columnnum] = d[key]
names[linenum][columnnum] = key
solutions[linenum][columnnum] = calc_res[key].value[0][0]
# %%
# for one line (charactor|weapon|set|mainattr), calculate all improvements
results = {}
for i in range(len(names[:])):
if datas[i][0] == '角色':
label_line = datas[i]
label_indices = get_data_indices_from_labels(label_line)
continue
if datas[i][0] != '':
# real data here
label = '|'.join(datas[i][:4])
up_values = get_exact_number(label_indices, datas[i], solutions[i])
# print(label, up_values)
up_percent = get_improve_percent(xl_model, label_indices, names[i], datas[i], solutions[i], up_values)
results[label] = up_percent
#%%
print(results)
# %%
def s_align(s, length):
res = s
minus = 0
for i in s:
if ord(i) > 128:
minus += 1
res += ' ' * (length - len(s) - minus)
return res
fl = s_align('名称', 40)
for i in sub_attr_names:
fl += s_align(i[0], 10)
print('-' * 20)
print(fl)
for k in results:
l = s_align(k, 40)
for i in results[k]:
l += '%-10.2f' % i
print(l)
print('-' * 20)
"""
名称 生命值 攻击力 防御力 生命值 攻击力 防御力 元素精通 充能 暴率 暴伤
胡桃|护摩之杖|追忆4|生火暴 0.16 0.14 0.00 0.49 0.29 0.00 1.00 0.00 0.92 0.72
胡桃|护摩之杖|追忆4|精火暴 0.20 0.17 0.00 0.62 0.37 0.00 0.68 0.00 1.00 0.78
胡桃|匣里灭辰|追忆4|生火暴 0.18 0.20 0.00 0.55 0.33 0.00 0.64 0.00 0.85 1.00
胡桃|匣里灭辰|追忆4|精火暴 0.21 0.23 0.00 0.65 0.39 0.00 0.45 0.00 0.85 1.00
胡桃|护摩之杖|魔女4|生火暴 0.18 0.15 0.00 0.55 0.32 0.00 0.96 0.00 1.00 0.78
胡桃|护摩之杖|魔女4|精火暴 0.21 0.18 0.00 0.64 0.38 0.00 0.62 0.00 1.00 0.78
胡桃|匣里灭辰|魔女4|生火暴 0.19 0.21 0.00 0.57 0.35 0.00 0.58 0.00 0.85 1.00
胡桃|匣里灭辰|魔女4|精火暴 0.22 0.24 0.00 0.67 0.41 0.00 0.42 0.00 0.85 1.00
托马|西风长枪|2旗印2千岩|充生暴 0.48 0.00 0.00 0.98 0.00 0.00 0.00 1.00 0.00 0.00
托马|黑缨枪|2旗印2千岩|充生生 0.32 0.00 0.00 0.65 0.00 0.00 0.00 1.00 0.00 0.00
宵宫|飞雷之弦振|追忆4|攻火暴 0.00 0.29 0.00 0.00 0.81 0.00 0.00 0.00 1.00 0.94
宵宫|弓藏|追忆4|攻火暴 0.00 0.26 0.00 0.00 0.66 0.00 0.00 0.00 0.85 1.00
烟绯|四风原典|乐团4|攻火暴 0.00 0.35 0.00 0.00 0.89 0.00 0.93 0.45 0.89 1.00
烟绯|流浪乐章|乐团4|攻火暴 0.00 0.38 0.00 0.00 0.85 0.00 0.37 0.43 0.88 1.00
可莉|四风原典|魔女4|攻火暴 0.00 0.32 0.00 0.00 0.88 0.00 1.00 0.00 0.87 0.98
可莉|流浪乐章|魔女4|攻火暴 0.00 0.35 0.00 0.00 0.87 0.00 0.38 0.00 0.88 1.00
迪卢克|狼的末路|魔女4|精火暴 0.00 0.27 0.00 0.00 0.77 0.00 0.62 0.39 0.85 1.00
迪卢克|螭骨剑|魔女4|攻火暴 0.00 0.34 0.00 0.00 0.87 0.00 1.00 0.44 0.86 0.93
辛焱|无工之剑|2苍白2骑士|攻物暴 0.00 0.20 0.00 0.00 0.51 0.00 0.00 0.25 0.77 1.00
辛焱|白影剑|2苍白2骑士|攻物暴 0.00 0.29 0.00 0.00 0.65 0.00 0.00 0.33 0.77 1.00
辛焱|祭礼大剑|千岩4|防防防 0.00 0.00 0.40 0.00 0.00 1.00 0.00 0.00 0.00 0.00
辛焱|白影剑|千岩4|防防防 0.00 0.00 0.40 0.00 0.00 1.00 0.00 0.00 0.00 0.00
安柏|终末嗟叹之诗|宗室4|攻火暴 0.00 0.24 0.00 0.00 0.59 0.00 0.00 0.30 0.77 1.00
安柏|阿莫斯之弓|乐团4|攻火暴 0.00 0.23 0.00 0.00 0.57 0.00 0.73 0.00 0.77 1.00
香菱|天空之脊|旗印4|充火暴 0.00 0.00 0.00 0.00 0.00 0.00 0.85 0.51 0.80 1.00
香菱|天空之脊|旗印4|精火暴 0.00 0.00 0.00 0.00 0.00 0.00 0.56 0.66 0.80 1.00
香菱|渔获|旗印4|充火暴 0.00 0.00 0.00 0.00 0.00 0.00 0.86 0.50 0.90 1.00
香菱|渔获|旗印4|精火暴 0.00 0.00 0.00 0.00 0.00 0.00 0.57 0.64 0.90 1.00
班尼特|风鹰剑|宗室4|充火暴 0.00 0.19 0.00 0.00 0.51 0.00 1.00 0.55 0.77 0.99
班尼特|天空之刃|宗室4|充火暴 0.00 0.22 0.00 0.00 0.53 0.00 1.00 0.43 0.77 0.98
班尼特|风鹰剑|少女4|充生治 0.39 0.00 0.00 0.94 0.00 0.00 0.00 1.00 0.00 0.00
班尼特|天空之刃|少女4|充生治 0.41 0.00 0.00 1.00 0.00 0.00 0.00 0.83 0.00 0.00
神里绫人|波乱月白经津|回响4|攻水暴 0.06 0.29 0.00 0.15 0.78 0.00 0.00 0.00 1.00 0.94
神里绫人|磐岩结绿|沉沦4|攻水暴 0.13 0.25 0.00 0.34 0.62 0.00 0.00 0.00 1.00 0.83
神里绫人|黑剑|回响4|攻水暴 0.06 0.32 0.00 0.17 0.77 0.00 0.00 0.00 1.00 1.00
珊瑚宫心海|不灭月华|海染4|生水治 0.38 0.10 0.00 1.00 0.26 0.00 0.00 0.50 0.00 0.00
珊瑚宫心海|试做金珀|海染4|生水治 0.38 0.12 0.00 1.00 0.26 0.00 0.00 0.50 0.00 0.00
珊瑚宫心海|讨龙英杰谭|千岩4|生生治 0.38 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00
珊瑚宫心海|试做金珀|千岩4|生生治 0.38 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00
达达利亚|冬极百星|2沉沦2角斗|攻水暴 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.77 0.86
达达利亚|天空之翼|2沉沦2角斗|攻水暴 0.00 0.25 0.00 0.00 0.73 0.00 1.00 0.36 0.77 0.87
达达利亚|弓藏|2沉沦2角斗|攻水暴 0.00 0.25 0.00 0.00 0.60 0.00 1.00 0.30 0.77 0.99
行秋|祭礼剑|2沉沦2宗室|攻水暴 0.00 0.34 0.00 0.00 0.67 0.00 0.00 0.61 0.77 1.00
行秋|磐岩结绿|旗印4|充水暴 0.07 0.40 0.00 0.15 0.89 0.00 0.00 0.70 0.97 1.00
莫娜|流浪乐章|旗印4|攻水暴 0.00 0.32 0.00 0.00 0.76 0.00 1.00 0.30 0.77 0.88
莫娜|讨龙英杰谭|宗室4|充水暴 0.00 0.46 0.00 0.00 0.94 0.00 0.00 0.26 0.77 1.00
莫娜|试做金珀|宗室4|充水暴 0.00 0.41 0.00 0.00 0.98 0.00 0.00 0.26 0.77 1.00
芭芭拉|不灭月华|少女4|生生治 0.52 0.00 0.00 1.00 0.00 0.00 0.00 0.50 0.00 0.00
芭芭拉|讨龙英杰谭|少女4|生生治 0.52 0.00 0.00 1.00 0.00 0.00 0.00 0.50 0.00 0.00
芭芭拉|试做金珀|少女4|生生治 0.52 0.00 0.00 1.00 0.00 0.00 0.00 0.50 0.00 0.00
早柚|狼的末路|翠绿4|精攻治 0.00 0.39 0.00 0.00 1.00 0.00 0.00 0.50 0.00 0.00
早柚|西风大剑|翠绿4|精攻治 0.00 0.48 0.00 0.00 1.00 0.00 0.00 0.50 0.00 0.00
枫原万叶|苍古自由之誓|翠绿4|精精精 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
枫原万叶|铁蜂刺|翠绿4|精精精 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
魈|和璞鸢|辰砂4|攻风暴 0.00 0.24 0.00 0.00 0.74 0.00 0.00 0.37 0.93 1.00
魈|护摩之杖|辰砂4|攻风暴 0.03 0.26 0.00 0.08 0.76 0.00 0.00 0.38 1.00 0.94
魈|决斗之枪|辰砂4|攻风暴 0.00 0.30 0.00 0.00 0.72 0.00 0.00 0.36 1.00 0.90
温迪|终末嗟叹之诗|翠绿4|精精精 0.00 0.00 0.00 0.00 0.00 0.00 0.73 1.00 0.00 0.00
温迪|西风猎弓|翠绿4|精精精 0.00 0.00 0.00 0.00 0.00 0.00 0.94 1.00 0.00 0.00
温迪|绝弦|翠绿4|充精精 0.00 0.00 0.00 0.00 0.00 0.00 0.93 1.00 0.00 0.00
琴|腐殖之剑|2翠绿2角斗|攻攻治 0.00 0.45 0.00 0.00 1.00 0.00 0.00 0.77 0.00 0.00
琴|西风剑|2翠绿2角斗|攻攻治 0.00 0.48 0.00 0.00 1.00 0.00 0.00 0.72 0.00 0.00
琴|风鹰剑|2翠绿2角斗|充攻治 0.00 0.37 0.00 0.00 1.00 0.00 0.00 0.64 0.00 0.00
砂糖|祭礼残章|翠绿4|充精精 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
砂糖|试做金珀|翠绿4|充精精 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
砂糖|讨龙英杰谭|翠绿4|充精精 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
空/荧(风)|西风剑|翠绿4|精精精 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00
八重神子|神乐之真意|平雷4|攻雷暴 0.00 0.34 0.00 0.00 0.96 0.00 0.50 0.00 1.00 0.94
八重神子|天空之卷|平雷4|攻雷暴 0.00 0.25 0.00 0.00 0.75 0.00 0.56 0.00 0.85 1.00
八重神子|匣里日月|平雷4|攻雷暴 0.00 0.38 0.00 0.00 0.97 0.00 0.55 0.00 1.00 1.00
八重神子|流浪乐章|平雷4|攻雷暴 0.00 0.22 0.00 0.00 0.56 0.00 0.64 0.00 1.00 1.00
雷电将军|薙草之稻光|旗印4|充雷暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.47 0.77 1.00
雷电将军|渔获|旗印4|充攻暴 0.00 0.32 0.00 0.00 0.82 0.00 0.00 0.43 0.90 1.00
九条裟罗|天空之翼|旗印4|充雷暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.39 1.00 0.98
九条裟罗|祭礼弓|旗印4|充雷暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.29 0.77 1.00
刻晴|雾切之回光|2如雷2角斗|攻雷暴 0.00 0.29 0.00 0.00 0.86 0.00 0.00 0.00 1.00 0.94
刻晴|磐岩结绿|2如雷2角斗|攻雷暴 0.00 0.27 0.00 0.00 0.69 0.00 0.00 0.00 1.00 0.76
刻晴|匣里龙吟|2如雷2角斗|攻雷暴 0.00 0.28 0.00 0.00 0.70 0.00 0.00 0.00 1.00 1.00
雷泽|螭骨剑|角斗4|攻物暴 0.00 0.35 0.00 0.00 0.79 0.00 0.00 0.39 0.88 1.00
雷泽|狼的末路|角斗4|攻物暴 0.00 0.22 0.00 0.00 0.55 0.00 0.00 0.27 0.77 1.00
菲谢尔|绝弦|2如雷2角斗|攻雷暴 0.00 0.28 0.00 0.00 0.64 0.00 0.00 0.00 0.77 1.00
菲谢尔|天空之翼|2如雷2角斗|攻雷暴 0.00 0.27 0.00 0.00 0.75 0.00 0.00 0.00 0.89 1.00
丽莎|四风原典|2如雷2角斗|攻雷暴 0.00 0.33 0.00 0.00 0.82 0.00 0.00 0.00 0.89 1.00
丽莎|流浪乐章|宗室4|攻雷暴 0.00 0.25 0.00 0.00 0.55 0.00 0.00 0.27 0.88 1.00
北斗|狼的末路|旗印4|充雷暴 0.00 0.23 0.00 0.00 0.58 0.00 0.00 0.29 0.77 1.00
北斗|螭骨剑|旗印4|充攻暴 0.00 0.32 0.00 0.00 0.70 0.00 0.00 0.32 0.88 1.00
空/荧(雷)|西风剑|旗印4|充雷暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00
申鹤|息灾|2角斗2追忆|攻攻攻 0.00 0.32 0.00 0.00 1.00 0.00 0.00 0.72 0.00 0.00
申鹤|薙草之稻光|2角斗2追忆|攻攻攻 0.00 0.37 0.00 0.00 1.00 0.00 0.00 0.59 0.00 0.00
申鹤|天空之脊|2角斗2追忆|攻攻攻 0.00 0.34 0.00 0.00 1.00 0.00 0.00 0.58 0.00 0.00
申鹤|西风长枪|2角斗2追忆|攻攻攻 0.00 0.38 0.00 0.00 1.00 0.00 0.00 0.60 0.00 0.00
神里绫华|雾切之回光|冰风4|攻冰暴 0.00 0.18 0.00 0.00 0.54 0.00 0.00 0.27 1.00 0.42
神里绫华|天目影打刀|冰风4|攻冰暴 0.00 0.19 0.00 0.00 0.46 0.00 0.00 0.23 1.00 0.53
优菈|松籁响起之时|苍白4|攻物暴 0.00 0.24 0.00 0.00 0.78 0.00 0.00 0.39 1.00 1.00
优菈|狼的末路|苍白4|攻物暴 0.00 0.24 0.00 0.00 0.67 0.00 0.00 0.34 1.00 1.00
优菈|螭骨剑|苍白4|攻物暴 0.00 0.35 0.00 0.00 0.89 0.00 0.00 0.45 1.00 0.91
甘雨|阿莫斯之弓|冰风4|攻冰暴 0.00 0.14 0.00 0.00 0.40 0.00 0.00 0.00 1.00 0.42
甘雨|破魔之弓|冰风4|攻冰暴 0.00 0.16 0.00 0.00 0.38 0.00 0.00 0.00 1.00 0.42
甘雨|试做澹月|冰风4|攻冰暴 0.00 0.13 0.00 0.00 0.33 0.00 0.00 0.00 1.00 0.42
甘雨|阿莫斯之弓|乐团4|攻冰暴 0.00 0.22 0.00 0.00 0.63 0.00 0.00 0.00 1.00 0.80
甘雨|破魔之弓|乐团4|攻冰暴 0.00 0.26 0.00 0.00 0.61 0.00 0.00 0.00 1.00 0.80
甘雨|试做澹月|乐团4|攻冰暴 0.00 0.21 0.00 0.00 0.53 0.00 0.00 0.00 1.00 0.80
凯亚|西风剑|旗印4|攻冰暴 0.00 0.39 0.00 0.00 0.79 0.00 0.00 0.26 0.93 1.00
凯亚|磐岩结绿|旗印4|充冰暴 0.00 0.42 0.00 0.00 0.96 0.00 0.00 0.30 1.00 0.93
重云|狼的末路|2冰风2宗室|攻冰暴 0.00 0.23 0.00 0.00 0.57 0.00 0.00 0.29 0.93 1.00
重云|螭骨剑|2冰风2宗室|攻冰暴 0.00 0.36 0.00 0.00 0.79 0.00 0.00 0.39 1.00 0.97
七七|祭礼剑|海染4|攻攻治 0.00 0.45 0.00 0.00 1.00 0.00 0.00 0.50 0.00 0.00
七七|风鹰剑|海染4|攻攻治 0.00 0.35 0.00 0.00 1.00 0.00 0.00 0.50 0.00 0.00
七七|笛剑|海染4|攻攻治 0.00 0.42 0.00 0.00 1.00 0.00 0.00 0.50 0.00 0.00
迪奥娜|祭礼弓|2少女2千岩|生生生 0.54 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00
罗莎莉亚|西风长枪|宗室4|攻冰暴 0.00 0.26 0.00 0.00 0.63 0.00 0.00 0.32 0.59 1.00
埃洛伊|西风猎弓|2冰风2角斗|攻冰暴 0.00 0.36 0.00 0.00 0.74 0.00 0.00 0.37 0.93 1.00
荒泷一斗|赤角石溃杵|华馆4|防岩暴 0.00 0.13 0.00 0.00 0.30 0.00 0.00 0.15 1.00 0.83
荒泷一斗|螭骨剑|华馆4|防岩暴 0.00 0.17 0.00 0.00 0.38 0.00 0.00 0.19 1.00 1.00
荒泷一斗|白影剑|华馆4|防岩暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.85 1.00
五郎|西风猎弓|流放4|充岩暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00
阿贝多|辰砂之纺锤|华馆4|防岩暴 0.00 0.00 0.24 0.00 0.00 0.65 0.00 0.00 0.77 1.00
阿贝多|辰砂之纺锤|磐岩4|防岩暴 0.00 0.00 0.28 0.00 0.00 0.78 0.00 0.00 0.77 1.00
阿贝多|辰砂之纺锤|千岩4|防岩暴 0.00 0.00 0.28 0.00 0.00 0.78 0.00 0.00 0.77 1.00
钟离|黑缨枪|千岩4|生生生 0.35 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00
钟离|护摩之杖|千岩4|生生生 0.11 0.15 0.00 0.31 0.38 0.00 0.00 0.19 0.78 1.00
钟离|护摩之杖|2磐岩2宗室|生岩暴 0.15 0.22 0.00 0.44 0.57 0.00 0.00 0.29 0.89 1.00
诺艾尔|赤角石溃杵|华馆4|防岩暴 0.00 0.13 0.00 0.00 0.28 0.00 0.00 0.14 1.00 0.85
诺艾尔|螭骨剑|华馆4|防岩暴 0.00 0.15 0.00 0.00 0.32 0.00 0.00 0.16 0.88 1.00
诺艾尔|白影剑|华馆4|防岩暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.77 1.00
凝光|四风原典|2磐岩2角斗|攻岩暴 0.00 0.18 0.00 0.00 0.45 0.00 0.00 0.23 1.00 0.49
凝光|尘世之锁|2磐岩2角斗|攻岩暴 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.49
凝光|流浪乐章|2磐岩2角斗|攻岩暴 0.00 0.19 0.00 0.00 0.42 0.00 0.00 0.21 1.00 0.44
空/荧(岩)|雾切之回光|2磐岩2角斗|攻岩暴0.00 0.27 0.00 0.00 0.72 0.00 0.00 0.36 0.86 1.00
空/荧(岩)|磐岩结绿|2磐岩2角斗|攻岩暴 0.00 0.31 0.00 0.00 0.69 0.00 0.00 0.35 0.97 1.00
空/荧(岩)|黑剑|2磐岩2角斗|攻岩暴 0.00 0.33 0.00 0.00 0.71 0.00 0.00 0.36 0.88 1.00
云堇|薙草之稻光|华馆4|防防防 0.00 0.00 0.43 0.00 0.00 1.00 0.00 0.35 0.00 0.00
云堇|天空之脊|华馆4|防防防 0.00 0.00 0.43 0.00 0.00 1.00 0.00 0.37 0.00 0.00
云堇|西风长枪|华馆4|防防暴 0.00 0.00 0.43 0.00 0.00 1.00 0.00 0.35 0.00 0.00
"""
print()
#%%
# show set names
setnames = set()
for key in results:
s = key.split('|')[2]
s = re.split(r'[0-9]', s)
for i in s:
setnames.add(i)
setnames.remove('')
print(setnames)
#%%
# show main names
mainnames = set()
for key in results:
m = key.split('|')[3]
for i in m:
mainnames.add(i)
print(mainnames)
#%%
# get use and not use main for every set
uses = {}
nuses = {}
for key in setnames:
uses[key] = [set(), set(), set()]
nuses[key] = [mainnames.copy(), mainnames.copy(), mainnames.copy()]
for key in results:
s = key.split('|')[2]
s = re.split(r'[0-9]', s)
m = key.split('|')[3]
for i in s:
if len(i) == 0:
continue
for num, j in enumerate(m):
uses[i][num].add(j)
if j in nuses[i][num]:
nuses[i][num].remove(j)
for key in uses:
for num in range(len(uses[key])):
print(key, num, uses[key][num], nuses[key][num])
#%%
# get max weight from sets
maxw = {}
for s in setnames:
maxw[s] = [0] * 10
for key in results:
v = results[key]
s = key.split('|')[2]
s = re.split(r'[0-9]', s)
for i in s:
if len(i) == 0:
continue
for j in range(len(v)):
maxw[i][j] = max(v[j], maxw[i][j])
for s in maxw:
print(s, maxw[s])
#%%
# get every character possible sets
char2set = {}
for key in results:
c = key.split('|')[0]
s = key.split('|')[2]
s = re.split(r'[0-9]', s)
if c not in char2set:
char2set[c] = set()
for i in s:
char2set[c].add(i)
print(char2set)
#%%
# consts for below
mainname = {
'生': 'hpp',
'攻': 'atkp',
'防': 'defp',
'充': 'er',
'精': 'em',
'暴': 'cr',
'爆': 'cd',
'水': 'hydroDB',
'物': 'physicalDB',
'风': 'anemoDB',
'雷': 'electroDB',
'岩': 'geoDB',
'冰': 'cryoDB',
'火': 'pyroDB',
'治': 'hb',
}
dbname = [ '水', '物', '风', '雷', '岩', '冰', '火' ]
setname = {
'华馆': 'HuskOfOpulentDreams',
'角斗': 'GladiatorsFinale',
'沉沦': 'HeartOfDepth',
'旗印': 'EmblemOfSeveredFate',
'苍白': 'PaleFlame',
'冰风': 'BlizzardStrayer',
'宗室': 'NoblesseOblige',
'海染': 'OceanHuedClam',
'翠绿': 'ViridescentVenerer',
'磐岩': 'ArchaicPetra',
'千岩': 'TenacityOfTheMillelith',
'平雷': 'Thundersoother',
'乐团': 'WanderersTroupe',
'追忆': 'ShimenawasReminiscence',
'骑士': 'BloodstainedChivalry',
'魔女': 'CrimsonWitchOfFlames',
'少女': 'MaidenBeloved',
'如雷': 'ThunderingFury',
# '流放': '',
'流星': 'RetracingBolide',
'渡火': 'Lavawalker',
'辰砂': 'VermillionHereafter',
'余响': 'EchoesOfAnOffering',
}
positions = ["sands", "goblet", "circlet"]
position_names = ["沙", "杯", "头"]
#%%
# count set use time
usetimes = {}
for key in setname:
usetimes[key] = 0
for key in char2set:
for i in char2set[key]:
if i in usetimes:
usetimes[i] += 1
print(usetimes)
#%%
# generate filter from weight and main above
import json
used_multiplier = 2
unused_multiplier = 0
minkeep = 2
maxkeep = 5
flower_minkeep = 10
flower_maxkeep = 20
filter_template = '{"main":[],"stars":[],"level":[0,20],"set":[],"position":[],"lock":[],"character":[],"subCount":[],"includeSub":[],"includeSubCount":0,"excludeSub":[],"excludeSubCount":0,"scoreFilters":{"cur":{"value":0,"equation":3},"md":{"value":0,"equation":3},"tot":{"value":0,"equation":3}},"scoreWeight":{"hp":0.3,"atk":0.5,"def":0.3,"hpp":1,"atkp":1,"defp":1,"em":1,"er":1,"cr":1.5,"cd":1.5,"hpprop":0,"defprop":0,"main":0,"set":0},"useRankFilter":true,"rankGroup":{"main":true,"set":true,"position":true},"rankAscend":false,"rankSelectNumber":10,"rankReverseSelect":false,"rankScoreName":"md"}'
results = [{
'comment': '先全解锁',
'lock': 'unlock',
'showFilter': False,
'filter': json.loads(filter_template)
}]
results[0]['filter']['useRankFilter'] = False
for sname in setname:
for posnum, [pname, pcommentname] in enumerate(zip(positions, position_names)):
def onefilter(comment, addpos, selectnum, nogroup = False):
filter = json.loads(filter_template)
if nogroup:
filter['rankGroup'] = {
"main":False,
"set":False,
"position":False
}
filter['position'].append(pname)
filter['set'].append(setname[sname])
if sname in maxw:
for k, v in zip(sub_attrs, maxw[sname]):
filter['scoreWeight'][k] = float('%.2f' % v)
for mname in addpos:
filter['main'].append(mainname[mname])
if mname == '暴': # critical, also add damage
filter['main'].append('cd')
filter['rankSelectNumber'] = selectnum
return {
'comment': comment,
'lock': 'lock',
'showFilter': False,
'filter': filter
}
u = set()
nu = mainnames.copy()
nudb = set()
if sname in uses:
u = uses[sname][posnum].copy()
nu = nuses[sname][posnum].copy()
for key in dbname:
if key in nu:
nu.remove(key)
nudb.add(key)
if len(u) > 0:
results.append(onefilter(
'现在用上的' + sname + pcommentname,
u,
min(maxkeep, max(minkeep, usetimes[sname] * used_multiplier))
))
if len(nu) > 0:
results.append(onefilter(
'现在用不上的' + sname + pcommentname,
nu,
min(maxkeep, max(minkeep, usetimes[sname] * unused_multiplier))
))
"""
if len(nudb) > 0 and pcommentname == '杯':
results.append(onefilter(
'现在用不上的' + sname + '加伤' + pcommentname,
nudb,
min(maxkeep, max(minkeep, usetimes[sname] * unused_multiplier)),
True
))
"""
filter = json.loads(filter_template)
filter['position'] = ["flower", "plume"]
filter['set'].append(setname[sname])
if sname in maxw:
for k, v in zip(sub_attrs, maxw[sname]):
filter['scoreWeight'][k] = float('%.2f' % v)
filter['rankSelectNumber'] = min(flower_maxkeep, max(flower_minkeep, usetimes[sname] * used_multiplier))
results.append({
'comment': sname + '花羽',
'lock': 'lock',
'showFilter': False,
'filter': filter
})
print(json.dumps(results, indent = 2))
# %%
# lock best out of suit
used_multiplier = 2
minkeep = 5
maxkeep = 10
# get count for every part
mainuses = {}
for key in mainname:
mainuses[key] = [0, 0, 0]
for s in uses:
for snum, mains in enumerate(uses[s]):
for m in mains:
mainuses[m][snum] += 1
# print(mainuses)
filter_template = '{"main":[],"stars":[],"level":[0,20],"set":[],"position":[],"lock":[],"character":[],"subCount":[],"includeSub":[],"includeSubCount":0,"excludeSub":[],"excludeSubCount":0,"scoreFilters":{"cur":{"value":0,"equation":3},"md":{"value":0,"equation":3},"tot":{"value":0,"equation":3}},"scoreWeight":{"hp":0.3,"atk":0.5,"def":0.3,"hpp":1,"atkp":1,"defp":1,"em":1,"er":1,"cr":1.5,"cd":1.5,"hpprop":0,"defprop":0,"main":0,"set":0},"useRankFilter":true,"rankGroup":{"main":true,"set":true,"position":true},"rankAscend":false,"rankSelectNumber":10,"rankReverseSelect":false,"rankScoreName":"md"}'
# base score, used when no available score
base_score = {"hp":0.3,"atk":0.5,"def":0.3,"hpp":1,"atkp":1,"defp":1,"em":1,"er":1,"cr":1.5,"cd":1.5,"hpprop":0,"defprop":0,"main":0,"set":0}
# simply focus atk
atk_score = {"hp":0,"atk":0.3,"def":0,"hpp":0,"atkp":1,"defp":0,"em":1,"er":1,"cr":2,"cd":2,"hpprop":0,"defprop":0,"main":0,"set":0}
# for non-atk, enumerate hp atk def em, always with er
non_atk_score = {"hp":0,"atk":0,"def":0,"hpp":0,"atkp":0,"defp":0,"em":0,"er":1,"cr":0,"cd":0,"hpprop":0,"defprop":0,"main":0,"set":0}
all_results = []
atk_main_name = [ '攻', '暴', '水', '物', '风', '雷', '岩', '冰', '火', '精' ]
for mname in mainname:
for pnum, pname in enumerate(position_names):
maddname = mainname[mname]
comment = f'散件{mname}{pname}'
if mname == '爆':
mname = '暴'
if mainuses[mname][pnum] == 0:
continue # not valid position and main
if mname in atk_main_name:
# atk main
filter = json.loads(filter_template)
filter['rankGroup'] = {
"main":False,
"set":False,
"position":False
}
filter['main'].append(maddname)
filter['position'].append(positions[pnum])
filter['scoreWeight'] = atk_score.copy()
filter['rankSelectNumber'] = min(maxkeep, max(minkeep, mainuses[mname][pnum] * used_multiplier))
all_results.append({
'comment': comment,
'lock': 'lock',
'showFilter': False,
'filter': filter
})
else:
# other main
for i in ['攻', '防', '生', '精']:
filter = json.loads(filter_template)
filter['rankGroup'] = {
"main":False,
"set":False,
"position":False
}
filter['main'].append(maddname)
filter['position'].append(positions[pnum])
filter['scoreWeight'] = non_atk_score.copy()
filter['scoreWeight'][mainname[i]] = 1
if i != '精':
filter['scoreWeight'][mainname[i][:-1]] = 0.5
filter['rankSelectNumber'] = min(maxkeep, max(minkeep, mainuses[mname][pnum] * used_multiplier))
all_results.append({
'comment': comment + '主' + i,
'lock': 'lock',
'showFilter': False,
'filter': filter
})
print(json.dumps(all_results, indent = 2))
#%%
# combine two part
print(json.dumps(results + all_results, indent = 2))
# %%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment