diff --git a/arknights_mower/data/__init__.py b/arknights_mower/data/__init__.py index 5c1adcfc2..7b5bf66c9 100644 --- a/arknights_mower/data/__init__.py +++ b/arknights_mower/data/__init__.py @@ -66,26 +66,16 @@ 按tag分类组合干员 ''' -recruit_agent_list = {} -rarity_tags = [] - -for key in recruit_tag: - recruit_agent_list[key] = { - "min_level": 7, - "agent": [] - } - for opeartors in recruit_agent: - if key in recruit_agent[opeartors]['tags']: - if recruit_agent[opeartors]['stars'] < recruit_agent_list[key]["min_level"]: - recruit_agent_list[key]["min_level"] = recruit_agent[opeartors]['stars'] - - recruit_agent_list[key]["agent"].append( +agent_with_tags = {} +for item in recruit_tag: + agent_with_tags[item] = [] + for agent in recruit_agent: + if {item} < set(recruit_agent[agent]['tags']): + agent_with_tags[item].append( { - "name": recruit_agent[opeartors]['name'], - "level": recruit_agent[opeartors]['stars'], - }) -# 保底5星的tag -rarity_tags = [] -for key in recruit_agent_list: - if recruit_agent_list[key]['min_level'] >= 5: - rarity_tags.append(key) + 'id': agent, + 'name': recruit_agent[agent]['name'], + 'star': recruit_agent[agent]['stars'] + } + ) + diff --git a/arknights_mower/resources/recruit_no_lmb.png b/arknights_mower/resources/recruit_no_lmb.png index 63ced04df..84215496c 100644 Binary files a/arknights_mower/resources/recruit_no_lmb.png and b/arknights_mower/resources/recruit_no_lmb.png differ diff --git a/arknights_mower/solvers/recruit.py b/arknights_mower/solvers/recruit.py index 54ebb8764..ab2bdb9c7 100644 --- a/arknights_mower/solvers/recruit.py +++ b/arknights_mower/solvers/recruit.py @@ -7,7 +7,7 @@ import re import cv2 -from ..data import recruit_agent, recruit_tag, recruit_agent_list +from ..data import recruit_agent, agent_with_tags, recruit_tag from ..ocr import ocr_rectify, ocrhandle from ..utils import segment, rapidocr from .. import __rootdir__ @@ -42,6 +42,8 @@ def __init__(self, device: Device = None, recog: Recognizer = None) -> None: self.can_refresh = None self.enough_lmb = True + self.recruit_order = [6, 5, 1, 4, 3, 2] + def run(self, priority: list[str] = None, send_message_config={}, recruit_config={}): """ :param priority: list[str], 优先考虑的公招干员,默认为高稀有度优先 @@ -123,7 +125,7 @@ def transition(self) -> bool: logger.info(f"刷新次数:{refresh_res}") if self.permit_count is None: - recruit_ticket_img = self.recog.img[20:80, 1200:1390] + recruit_ticket_img = self.recog.img[20:80, 1230:1380] recruit_ticket_gray = cv2.cvtColor(recruit_ticket_img, cv2.COLOR_BGR2GRAY) try: res = rapidocr.engine(recruit_ticket_gray, use_det=False, use_cls=False, use_rec=True)[0][0][0] @@ -219,19 +221,17 @@ def recruit_tags(self) -> bool: logger.info(f'第{self.recruit_pos + 1}个位置上的公招标签:{tags}') # 计算招募标签组合结果 - best, need_choose = self.recruit_cal(tags) - - # 刷新标签 - if need_choose is False: - '''稀有tag或支援,不需要选''' - self.send_message(recruit_rarity.render(recruit_results=best['possible'], title_text="稀有tag通知"), + recruit_cal_result = self.recruit_cal(tags) + recruit_result_level = recruit_cal_result[0][1][0]['star'] + if len(recruit_cal_result) >= 1 and self.recruit_order.index(recruit_result_level) <= 2: + self.send_message(recruit_rarity.render(recruit_results=recruit_cal_result, title_text="稀有tag通知"), "出稀有标签辣", "html") - logger.debug('稀有tag,发送邮件') + logger.info('稀有tag,发送邮件') self.back() - return - # best为空说明是三星,刷新标签 - if not best: + return True + + if recruit_cal_result[0][1][0]['star'] == 3: # refresh if self.tap_element('recruit_refresh', detected=True): self.tap_element('double_confirm', 0.8, @@ -243,25 +243,25 @@ def recruit_tags(self) -> bool: if not self.enough_lmb: logger.info('龙门币不足 结束公招') self.back() - return + return False # 如果没有招募券则只刷新标签不选人 if not self.has_ticket: - logger.info('无招募券 结束公招') + logger.info('无招募券') self.back() - return + return False # best为空说明这次大概率三星 # 券数量少于预期值,仅招募四星或者停止招募,只刷新标签 - if self.permit_count <= self.recruit_config["permit_target"] and not best: - logger.info('不招三星 结束公招') + if self.permit_count <= self.recruit_config["permit_target"] and recruit_result_level == 3: + logger.info('不招三星') self.back() - return + return False choose = [] - if len(best) > 0: - choose = (next(iter(best))) - # tap selected tags + if recruit_result_level > 3: + choose = list(recruit_cal_result[0][0]) + # tap selected tags logger.info(f'选择标签:{list(choose)}') for x in ocr: color = self.recog.img[up + x[2][0][1] - 5, left + x[2][0][0] - 5] @@ -272,11 +272,11 @@ def recruit_tags(self) -> bool: # 9h为True 3h50min为False recruit_time_choose = self.recruit_config["recruitment_time"]["3"] - if len(best) > 0: - if best[choose]['level'] == 1: + if recruit_result_level >= 3: + if recruit_result_level == 1: recruit_time_choose = 230 else: - recruit_time_choose = self.recruit_config["recruitment_time"][str(best[choose]['level'])] + recruit_time_choose = self.recruit_config["recruitment_time"][str(recruit_result_level)] if recruit_time_choose == 540: # 09:00 @@ -300,20 +300,17 @@ def recruit_tags(self) -> bool: if self.permit_count > 1: self.permit_count -= 1 - if len(best) > 0: - logger_result = best[choose]['agent'] - self.agent_choose[str(self.recruit_pos + 1)] = best - - logger.info(f'第{self.recruit_pos + 1}个位置上的公招预测结果:{logger_result}') + if recruit_result_level > 3: + self.agent_choose[str(self.recruit_pos + 1)] = { + "tags": choose, + "result": recruit_cal_result[0][1] + } + logger.info(f'第{self.recruit_pos + 1}个位置上的公招预测结果:{recruit_cal_result[0][1]}') else: self.agent_choose[str(self.recruit_pos + 1)] = { - ('',): { - 'isRarity': False, - 'isRobot': False, - 'level': 3, - 'agent': [{'name': '随机三星干员', 'level': 3}]} + "tags": choose, + "result": [{'id': '', 'name': '随机三星干员', 'star': 3}] } - logger.info(f'第{self.recruit_pos + 1}个位置上的公招预测结果:{"随机三星干员"}') def recruit_result(self): @@ -349,192 +346,66 @@ def recruit_result(self): self.tap((self.recog.w // 2, self.recog.h // 2)) - def merge_agent_list(self, tags: [str], list_1: list[dict], list_2={}, list_3={}): - """ - 交叉筛选干员 - - tags:组合出的标签 - list_x:每个单独标签对应的干员池 - - return : 筛选出来的干员池,平均等级,是否稀有标签,是否支援机械 - """ - List1_name_dict = {} - merge_list = [] - isRarity = False - isRobot = False - level = 7 - - for operator in list_1: - if operator['level'] == 6 and "高级资深干员" not in tags: - continue - elif operator['level'] == 1 and "支援机械" not in tags: - continue - elif operator['level'] == 2: - continue - List1_name_dict[operator['name']] = operator - - for key in List1_name_dict: - if List1_name_dict[key]['level'] == 2: - print(List1_name_dict[key]) - - if len(tags) == 1 and not list_2 and not list_3: - for key in List1_name_dict: - if List1_name_dict[key]['level'] < level: - level = List1_name_dict[key]['level'] - merge_list.append(List1_name_dict[key]) - - elif len(tags) == 2 and not list_3: - for operator in list_2: - if operator['name'] in List1_name_dict: - if operator['level'] < level: - level = operator['level'] - merge_list.append(operator) - - - elif len(tags) == 3 and list_3: - List1and2_name_dict = {} - for operator in list_2: - if operator['name'] in List1_name_dict: - List1and2_name_dict[operator['name']] = operator - - for operator in list_3: - if operator['name'] in List1and2_name_dict: - if operator['level'] < level: - level = operator['level'] - merge_list.append(operator) - - if level >= 5: - isRarity = True - elif level == 1: - isRobot = True - logger.debug(f"merge_list{merge_list}") - - return merge_list, level, isRarity, isRobot - - def recruit_cal(self, tags: list[str]) -> (dict, bool): - possible_list = {} - has_rarity = False - has_robot = False - recruit_robot = self.recruit_config["recruit_robot"] + def recruit_cal(self, tags: list[str]): + logger.debug(f"选择标签{tags}") + self.recruit_order = [6, 5, 1, 4, 3, 2] + index_dict = {k: i for i, k in enumerate(self.recruit_order)} + combined_agent = {} + if '新手' in tags: + tags.remove('新手') for item in combinations(tags, 1): - # 防止出现类似情况 ['重', '装', '干', '员'] - - merge_temp, level, isRarity, isRobot = self.merge_agent_list(item, recruit_agent_list[item[0]]['agent']) - if len(merge_temp) > 0: - if has_rarity is False and isRarity: - has_rarity = isRarity - if has_robot is False and isRobot: - has_robot = isRobot - possible_list[item[0],] = { - "isRarity": isRarity, - "isRobot": isRobot, - "level": level, - "agent": merge_temp - } - + tmp = agent_with_tags[item[0]] + if "支援机械" not in item: + tmp = [x for x in tmp if x['star'] >= 3] + if "高级资深干员" not in item: + tmp = [x for x in tmp if x['star'] < 6] + tmp.sort(key=lambda k: k['star']) + combined_agent[item] = tmp for item in combinations(tags, 2): - merge_temp, level, isRarity, isRobot = self.merge_agent_list(item, recruit_agent_list[item[0]]['agent'], - recruit_agent_list[item[1]]['agent']) - if len(merge_temp) > 0: - if has_rarity is False and isRarity: - has_rarity = isRarity - if has_robot is False and isRobot: - has_robot = isRobot - possible_list[item[0], item[1]] = { - "isRarity": isRarity, - "isRobot": isRobot, - "level": level, - "agent": merge_temp - } + tmp = [j for j in agent_with_tags[item[0]] if j in agent_with_tags[item[1]]] + if len(tmp) == 0: + continue + if "支援机械" not in item: + tmp = [x for x in tmp if x['star'] >= 3] + if "高级资深干员" not in item: + tmp = [x for x in tmp if x['star'] < 6] + tmp.sort(key=lambda k: k['star']) + combined_agent[item] = tmp for item in combinations(tags, 3): - merge_temp, level, isRarity, isRobot = self.merge_agent_list(item, recruit_agent_list[item[0]]['agent'], - recruit_agent_list[item[1]]['agent'], - recruit_agent_list[item[2]]['agent']) - if len(merge_temp) > 0: - if has_rarity is False and isRarity: - has_rarity = isRarity - if has_robot is False and isRobot: - has_robot = isRobot - - possible_list[item[0], item[1], item[2]] = { - "isRarity": isRarity, - "isRobot": isRobot, - "level": level, - "agent": merge_temp - } - - logger.debug(f"公招可能性:{self.recruit_str(possible_list)}") - - rarity_list = { - "level": -1, - "possible": {} - } - normal_list = { - "level": -1, - "possible": {} - } - robot_list = {} - for key in list(possible_list.keys()): - # 五星六星选择优先级大于支援机械 - if possible_list[key]["isRarity"]: - if possible_list[key]["level"] > rarity_list["level"]: - rarity_list["level"] = possible_list[key]["level"] - rarity_list["possible"][key] = possible_list[key] - elif possible_list[key]["isRobot"]: - rarity_list["possible"][key] = possible_list[key] = possible_list[key] - else: - if possible_list[key]["level"] > normal_list["level"]: - normal_list["level"] = possible_list[key]["level"] - normal_list["possible"][key] = possible_list[key] - - # 筛选稀有tag - if rarity_list["possible"]: - for key in list(rarity_list["possible"].keys()): - if rarity_list["possible"][key]["level"] < rarity_list["level"]: - del rarity_list["possible"][key] - continue - for i in range(len(rarity_list["possible"][key]["agent"]) - 1, -1, -1): - if rarity_list["possible"][key]["agent"][i]['level'] != rarity_list["possible"][key]["level"]: - rarity_list["possible"][key]["agent"].remove(rarity_list["possible"][key]["agent"][i]) - logger.debug(f"rarity_list:{rarity_list}") - return rarity_list, False - - if robot_list and self.recruit_config["recruit_robot"]: - logger.debug(f"robot_list:{robot_list.popitem()}") - return robot_list, False - - # 筛选非稀有tag - - logger.debug(normal_list["level"]) - if normal_list["level"] < 4: - return {}, True - - for key in list(normal_list["possible"].keys()): - if normal_list["possible"][key]["level"] < normal_list["level"]: - del normal_list["possible"][key] + tmp1 = [j for j in agent_with_tags[item[0]] if j in agent_with_tags[item[1]]] + tmp = [j for j in tmp1 if j in agent_with_tags[item[2]]] + if len(tmp) == 0: continue - for i in range(len(normal_list["possible"][key]["agent"]) - 1, -1, -1): - if normal_list["possible"][key]["agent"][i]['level'] != normal_list["possible"][key]["level"]: - normal_list["possible"][key]["agent"].remove(normal_list["possible"][key]["agent"][i]) - - best = {} - # 4星=需要选择tag返回选择的tag,3星不选 - for key in normal_list["possible"]: - best[key] = normal_list["possible"][key] - break - logger.debug(f"normal_list:{normal_list}") - return best, True - - def recruit_str(self, recruit_result: dict): - if not recruit_result: - return "随机三星干员" - result_str = "{" - for key in recruit_result: - temp_str = "{[" + ",".join(list(key)) - temp_str = temp_str + "],level:" - temp_str = temp_str + str(recruit_result[key]["level"]) + ",agent:" - temp_str = temp_str + str(recruit_result[key]["agent"]) + "}," - result_str = result_str + temp_str - - return result_str + if "支援机械" not in item: + tmp = [x for x in tmp if x['star'] >= 3] + if "高级资深干员" not in item: + tmp = [x for x in tmp if x['star'] < 6] + tmp.sort(key=lambda k: k['star']) + combined_agent[item] = tmp + sorted_list = sorted(combined_agent.items(), key=lambda x: index_dict[x[1][0]['star']]) + + result_dict = {} + for item in sorted_list: + if item[1][0]['star'] == sorted_list[0][1][0]['star']: + result_dict[item[0]] = item[1] + + sorted_list = sorted(result_dict.items(), key=lambda x: len(x[1]), reverse=True) + logger.debug(f"before sort{sorted_list}") + if 3 <= sorted_list[0][1][0]['star'] <= 5: + for res in sorted_list[1:]: + if len(res[1]) != len(sorted_list[0][1]) and sorted_list[0][1][0]['star'] > 4: + continue + contain_all = True + for value in res[1]: + if value not in sorted_list[0][1]: + contain_all = False + if contain_all: + sorted_list.remove(res) + + logger.debug(f"recruit_cal result:{sorted_list}") + return sorted_list + # if len(sorted_list) > 1 and sorted_list[0][1][0]['star'] >= 5: + # print("do nothing") + # for item in sorted_list: + # print(item) diff --git a/arknights_mower/templates/email/recruit_rarity.html b/arknights_mower/templates/email/recruit_rarity.html index f9c21ae79..a83937143 100644 --- a/arknights_mower/templates/email/recruit_rarity.html +++ b/arknights_mower/templates/email/recruit_rarity.html @@ -16,18 +16,19 @@ - {% for choose in recruit_results %} + {% for result in recruit_results %} + {% endfor %} diff --git a/arknights_mower/templates/email/recruit_template.html b/arknights_mower/templates/email/recruit_template.html index 5b58f10a0..d47c67263 100644 --- a/arknights_mower/templates/email/recruit_template.html +++ b/arknights_mower/templates/email/recruit_template.html @@ -24,13 +24,21 @@ {% for pos,value in recruit_results.items() %} - {% for key,value in value.items() %} + + - - {% endfor %} + {% endfor %} {% endif %} {% if recruit_get_agent|length > 0 %} @@ -44,8 +52,11 @@ {% endfor %} {% endif %} - - + {% if permit_count is defined%} + + + {% endif %} +
标签选择预计干员名单
- {% for tags in choose %} - {{tags}} - {% endfor %} + {% for tag in result[0] %} + {{ tag }} + {% endfor %} - {% for agent in recruit_results[choose].agent %} - {{ agent.name }} - {% endfor %} + {% for agent in result[1] %} + {{ agent.name }} + {% endfor %}
{{ pos }} + {% if value.tags|length > 0 %} + {% for tag in value.tags %}{{ tag }}{% endfor %} + {% else %} + 未选择 + {% endif %} + + - {% for tag in key %} {% if tag != "" %} {{ tag }} {% else %} {{ - "未选择" }} {% endif %} {% endfor %} + {% for agent in value.result %} + {{ agent.name }} + {% endfor %} {% for agent in value.agent %} {{ agent.name }} {% endfor %}
剩余招募券数量{{permit_count}}剩余招募券数量{{permit_count}}