379 lines
16 KiB
Python
379 lines
16 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
# -------------------------------
|
|
# File : calc_core
|
|
# DateTime : 2020/6/10 0010 21:30
|
|
# Author : Chen Ji
|
|
# Email : fzls.zju@gmail.com
|
|
# -------------------------------
|
|
from copy import *
|
|
from multiprocessing import Queue
|
|
from typing import List
|
|
from PublicReference.utils.minheap import MinHeap, expected_qsize
|
|
|
|
|
|
class CalcData():
|
|
def __init__(self):
|
|
self.是输出职业 = True
|
|
self.智慧产物限制 = 3
|
|
|
|
self.minheap_queue = None # type: Queue
|
|
self.角色属性A = None
|
|
|
|
# 被分配的计算范围
|
|
self.mode_index = 0 # 0-极速模式,1-套装模式,2-散件模式
|
|
# 在并发搜索任务组中分配到的开始序号:极速模式和套装模式时,任务组定义为按照原搜索组合算法得到的有效穿戴组合等;散件模式时,定义为0-level层串行搜索形成的所有子树
|
|
self.start_index = 0
|
|
self.end_index = 0 # 在并发搜索任务组中分配到的结束序号,描述同上
|
|
|
|
# 原始数据
|
|
self.装备选择状态: list[int] = [] # 各个装备的选择状况,第i个位置为0表示装备i未选择,否则表示已选择
|
|
self.拥有百变怪 = False # 是否勾选了百变怪
|
|
self.神话属性选项: list[int] = [
|
|
] # 每个神话四个选项,第4*k~4*k+3下标表示第k个神话的词条选择(k从0开始计数)
|
|
self.改造产物选项: list[int] = []
|
|
|
|
# 根据原始数据在计算线程计算出的一些数据
|
|
self.有效武器列表 = []
|
|
self.有效防具套装 = []
|
|
self.有效首饰套装 = []
|
|
self.有效特殊套装 = []
|
|
self.有效上链左套装 = []
|
|
self.有效镯下右套装 = []
|
|
self.有效环鞋指套装 = []
|
|
self.有效总套装列表 = [
|
|
self.有效防具套装, self.有效首饰套装, self.有效特殊套装, self.有效上链左套装, self.有效镯下右套装,
|
|
self.有效环鞋指套装
|
|
]
|
|
|
|
self.有效部位列表 = []
|
|
|
|
# 最终结果
|
|
self.minheap = None # type: MinHeap
|
|
|
|
def pre_calc_needed_data(self):
|
|
from PublicReference.equipment.equ_list import 总套装列表, 部位列表, equ
|
|
|
|
self.有效武器列表.clear()
|
|
for j in range(6):
|
|
self.有效总套装列表[j].clear()
|
|
|
|
self.有效部位列表.clear()
|
|
for i in range(12):
|
|
self.有效部位列表.append([])
|
|
|
|
for i in range(len(self.装备选择状态)):
|
|
if self.装备选择状态[i] == 1:
|
|
temp = equ.get_equ_by_id(i)
|
|
if temp.部位 == '武器':
|
|
self.有效武器列表.append(temp.名称)
|
|
for j in range(6):
|
|
if (temp.所属套装 in 总套装列表[j]) and (temp.所属套装
|
|
not in self.有效总套装列表[j]):
|
|
self.有效总套装列表[j].append(temp.所属套装)
|
|
self.有效部位列表[部位列表.index(temp.部位)].append(temp.名称)
|
|
|
|
count = 0
|
|
count2 = 0
|
|
for i in equ.get_equ_list():
|
|
if i.品质 == '神话':
|
|
if self.是输出职业 == True:
|
|
i.属性1选择 = self.神话属性选项[count * 4 + 0]
|
|
i.属性2选择 = self.神话属性选项[count * 4 + 1]
|
|
i.属性3选择 = self.神话属性选项[count * 4 + 2]
|
|
i.属性4选择 = self.神话属性选项[count * 4 + 3]
|
|
else:
|
|
i.属性1选择_BUFF = self.神话属性选项[count * 4 + 0]
|
|
i.属性2选择_BUFF = self.神话属性选项[count * 4 + 1]
|
|
i.属性3选择_BUFF = self.神话属性选项[count * 4 + 2]
|
|
i.属性4选择_BUFF = self.神话属性选项[count * 4 + 3]
|
|
count += 1
|
|
if self.是输出职业 == True and i.所属套装 == '智慧产物':
|
|
i.属性1选择 = self.改造产物选项[count2 * 4 + 0]
|
|
i.属性2选择 = self.改造产物选项[count2 * 4 + 1]
|
|
i.属性3选择 = self.改造产物选项[count2 * 4 + 2]
|
|
i.属性4选择 = self.改造产物选项[count2 * 4 + 3]
|
|
count2 += 1
|
|
pass
|
|
|
|
|
|
def calc_core(data: CalcData):
|
|
"""
|
|
|
|
:type minheap_queue: Queue
|
|
:type 角色属性A: 角色属性
|
|
:type 有效穿戴组合: List[str]
|
|
:type 有效穿戴套装: List[str]
|
|
:type 百变怪列表: str
|
|
"""
|
|
# 计算伤害具体算法
|
|
|
|
# 根据装备选择情况,预计算一些数据
|
|
data.pre_calc_needed_data()
|
|
|
|
# 寻找本任务对应的各个组合并调用计算函数
|
|
if data.mode_index in [0, 1]:
|
|
calc_speed_and_set_mode(data)
|
|
else:
|
|
calc_single_mode(data)
|
|
|
|
# 全部计算完后,将剩余结果传入结果队列
|
|
data.minheap_queue.put(deepcopy(data.minheap))
|
|
|
|
|
|
def calc_speed_and_set_mode(data):
|
|
from PublicReference.equipment.equ_list import 部位列表, equ
|
|
套装组合 = []
|
|
套装适用 = []
|
|
|
|
for a in data.有效防具套装:
|
|
for b in data.有效首饰套装:
|
|
for c in data.有效特殊套装:
|
|
# 533
|
|
套装组合.append([a, a, a, a, a, b, b, b, c, c, c])
|
|
套装适用.append([
|
|
a + '[2]', a + '[3]', a + '[5]', b + '[2]', b + '[3]',
|
|
c + '[2]', c + '[3]'
|
|
])
|
|
|
|
for a in data.有效防具套装:
|
|
for d in data.有效上链左套装:
|
|
for e in data.有效镯下右套装:
|
|
for f in data.有效环鞋指套装:
|
|
# 3332
|
|
套装组合.append([d, a, e, a, f, e, d, f, f, d, e])
|
|
套装适用.append([
|
|
a + '[2]', d + '[2]', d + '[3]', e + '[2]', e + '[3]',
|
|
f + '[2]', f + '[3]'
|
|
])
|
|
套装组合.append([a, a, e, a, f, e, d, f, f, d, e])
|
|
套装适用.append([
|
|
a + '[2]', d + '[2]', a + '[3]', e + '[2]', e + '[3]',
|
|
f + '[2]', f + '[3]'
|
|
])
|
|
套装组合.append([d, a, a, a, f, e, d, f, f, d, e])
|
|
套装适用.append([
|
|
a + '[2]', d + '[2]', d + '[3]', e + '[2]', a + '[3]',
|
|
f + '[2]', f + '[3]'
|
|
])
|
|
套装组合.append([d, a, e, a, a, e, d, f, f, d, e])
|
|
套装适用.append([
|
|
a + '[2]', d + '[2]', d + '[3]', e + '[2]', e + '[3]',
|
|
f + '[2]', a + '[3]'
|
|
])
|
|
|
|
if data.mode_index == 1:
|
|
for a in data.有效防具套装:
|
|
for b in data.有效首饰套装:
|
|
for c in data.有效特殊套装:
|
|
for d in data.有效防具套装:
|
|
if d != a:
|
|
# 2333 占套装模式90%计算量
|
|
套装组合.append([a, a, a, d, d, b, b, b, c, c, c])
|
|
套装组合.append([a, a, d, a, d, b, b, b, c, c, c])
|
|
套装组合.append([a, d, a, a, d, b, b, b, c, c, c])
|
|
套装组合.append([d, a, a, a, d, b, b, b, c, c, c])
|
|
套装组合.append([a, a, d, d, a, b, b, b, c, c, c])
|
|
套装组合.append([a, d, a, d, a, b, b, b, c, c, c])
|
|
套装组合.append([d, a, a, d, a, b, b, b, c, c, c])
|
|
套装组合.append([a, d, d, a, a, b, b, b, c, c, c])
|
|
套装组合.append([d, a, d, a, a, b, b, b, c, c, c])
|
|
套装组合.append([d, d, a, a, a, b, b, b, c, c, c])
|
|
for x in range(10):
|
|
套装适用.append([
|
|
a + '[2]', a + '[3]', d + '[2]', b + '[2]',
|
|
b + '[3]', c + '[2]', c + '[3]'
|
|
])
|
|
|
|
# 极速模式与套装模式
|
|
count = -1
|
|
current_index = -1
|
|
for temp in 套装组合:
|
|
count += 1
|
|
for k in [-1, 0, 5, 8]:
|
|
temp1 = []
|
|
sign = 0
|
|
if data.拥有百变怪:
|
|
sign2 = '空'
|
|
else:
|
|
sign2 = '无'
|
|
for x in range(11):
|
|
品质 = '史诗'
|
|
if k == x:
|
|
品质 = '神话'
|
|
index = equ.get_id_by_index(temp[x], 品质, 部位列表[x])
|
|
if data.装备选择状态[index] == 1:
|
|
sign += 1
|
|
else:
|
|
if sign2 == '空' and equ.get_equ_by_id(
|
|
index).品质 != '神话' and equ.get_equ_by_id(
|
|
index).所属套装 not in [
|
|
'精灵使的权能', '大自然的呼吸', '能量主宰'
|
|
]:
|
|
sign += 1
|
|
sign2 = equ.get_equ_by_id(index).名称
|
|
temp1.append(equ.get_equ_by_id(index).名称)
|
|
if sign == 11:
|
|
for i in data.有效武器列表:
|
|
current_index += 1
|
|
if current_index < data.start_index:
|
|
# 尚未到本工作线程需要计算的范围
|
|
continue
|
|
if current_index > data.end_index:
|
|
# 本工作线程需要计算的范围已全部完成,直接退出
|
|
return
|
|
calc_damage(temp1 + [i], 套装适用[count], sign2, data)
|
|
# logger.warning("consumer {} {} {} - {}".format(
|
|
# data.mode_index, data.start_index, data.end_index, current_index
|
|
# ))
|
|
pass
|
|
|
|
|
|
# 11层循环顺序
|
|
顺序 = [5, 8, 1, 3, 2, 4, 6, 9, 7, 10]
|
|
顺序字典 = {0: 0, 5: 1, 8: 2, 1: 3, 3: 4, 2: 5, 4: 6, 6: 7, 9: 8, 7: 9, 10: 10}
|
|
|
|
|
|
def 筛选(名称, x, 装备, 套装, 神话, 种类, data):
|
|
from PublicReference.equipment.equ_list import equ
|
|
|
|
i = equ.get_id_by_name(名称)
|
|
装备[x] = 名称
|
|
|
|
for k in 顺序[顺序字典[x]:]:
|
|
套装[k] = '无'
|
|
|
|
当前装备 = equ.get_equ_by_id(i)
|
|
|
|
if 当前装备.所属套装2 != '无':
|
|
套装[x] = 当前装备.所属套装2
|
|
else:
|
|
套装[x] = 当前装备.所属套装
|
|
|
|
count = []
|
|
num = 0
|
|
for j in 套装:
|
|
if j == '智慧产物':
|
|
num += 1
|
|
if num > 种类[1]:
|
|
return 1
|
|
elif (j != '无') and (j not in count):
|
|
count.append(j)
|
|
|
|
if len(count) > 种类[0]:
|
|
return 1
|
|
elif x == 10 and 种类[0] > 4:
|
|
种类[0] = max(min(种类[0], len(count)), 4)
|
|
|
|
if x == 0:
|
|
神话[5] = 0
|
|
神话[8] = 0
|
|
elif x == 5:
|
|
神话[8] = 0
|
|
|
|
if 当前装备.品质 == '神话':
|
|
神话[x] = 1
|
|
if sum(神话) > 1:
|
|
return 1
|
|
else:
|
|
神话[x] = 0
|
|
|
|
return 0
|
|
|
|
|
|
def calc_single_mode(data):
|
|
from PublicReference.equipment.equ_list import equ
|
|
current_index = -1
|
|
装备 = ['无'] * 12
|
|
套装 = ['无'] * 11
|
|
神话 = [0] * 11
|
|
种类 = [11, data.智慧产物限制]
|
|
|
|
for a1 in data.有效部位列表[0]:
|
|
if 筛选(a1, 0, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a2 in data.有效部位列表[5]:
|
|
if 筛选(a2, 5, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a3 in data.有效部位列表[8]:
|
|
if 筛选(a3, 8, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a4 in data.有效部位列表[1]:
|
|
if 筛选(a4, 1, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
current_index += 1
|
|
if current_index < data.start_index:
|
|
continue # 尚未到本工作线程需要计算的范围
|
|
if current_index > data.end_index:
|
|
return # 本工作线程需要计算的范围已全部完成,直接退出
|
|
for a5 in data.有效部位列表[3]:
|
|
if 筛选(a5, 3, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a6 in data.有效部位列表[2]:
|
|
if 筛选(a6, 2, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a7 in data.有效部位列表[4]:
|
|
if 筛选(a7, 4, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a8 in data.有效部位列表[6]:
|
|
if 筛选(a8, 6, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a9 in data.有效部位列表[9]:
|
|
if 筛选(a9, 9, 装备, 套装, 神话, 种类, data):
|
|
continue
|
|
for a10 in data.有效部位列表[7]:
|
|
if 筛选(a10, 7, 装备, 套装, 神话, 种类,
|
|
data):
|
|
continue
|
|
for a11 in data.有效部位列表[10]:
|
|
if 筛选(a11, 10, 装备, 套装, 神话, 种类,
|
|
data):
|
|
continue
|
|
套装字典 = {}
|
|
for i in 套装:
|
|
if i != '智慧产物' and i != '无':
|
|
套装字典[i] = 套装字典.get(
|
|
i, 0) + 1
|
|
套装名称 = []
|
|
for i in 套装字典.keys():
|
|
if 套装字典[i] >= 2 and (
|
|
i + '[2]'
|
|
) in equ.get_suit_name():
|
|
套装名称.append(i + '[2]')
|
|
if 套装字典[i] >= 3 and (
|
|
i + '[3]'
|
|
) in equ.get_suit_name():
|
|
套装名称.append(i + '[3]')
|
|
if 套装字典[i] >= 5 and (
|
|
i + '[5]'
|
|
) in equ.get_suit_name():
|
|
套装名称.append(i + '[5]')
|
|
for a12 in data.有效部位列表[11]:
|
|
装备[11] = a12
|
|
calc_damage(
|
|
装备, 套装名称, '空', data)
|
|
pass
|
|
|
|
|
|
def calc_damage(有效穿戴组合, 有效穿戴套装, 百变怪, data: CalcData):
|
|
角色属性A = deepcopy(data.角色属性A)
|
|
|
|
角色属性A.穿戴装备(有效穿戴组合, 有效穿戴套装)
|
|
if data.是输出职业:
|
|
damage = 角色属性A.伤害计算()
|
|
else:
|
|
damage = 角色属性A.BUFF计算(2)
|
|
|
|
data.minheap.add((damage, ) + tuple(角色属性A.装备栏) + (damage, ) +
|
|
tuple(角色属性A.套装栏) + (百变怪, ))
|
|
data.minheap.processed_result_count += 1
|
|
|
|
if data.minheap.processed_result_count >= data.minheap.batch_size:
|
|
# 动态调整批量大小
|
|
if data.minheap_queue.qsize() > expected_qsize:
|
|
data.minheap.update_batch_size()
|
|
# 同步
|
|
data.minheap_queue.put(deepcopy(data.minheap))
|
|
# 重置
|
|
data.minheap.reset()
|