#!/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()