mower-ng/mower/solvers/infra/base_choose.py

209 lines
7.4 KiB
Python

from copy import deepcopy
from datetime import datetime
from mower.data import agent_list
from mower.solvers.infra.base_mixin import BaseMixin
from mower.solvers.infra.enter_room import EnterRoomSolver
from mower.solvers.infra.filter import RIIC_Filter
from mower.solvers.infra.riic_free_fill import RIIC_FreeFillSolver
from mower.solvers.infra.riic_tag_choose import RIICTagChoose
from mower.utils import config
from mower.utils.character_recognize import operator_room_select
from mower.utils.graph.utils import SceneGraphSolver
from mower.utils.image import cropimg
from mower.utils.log import logger
from mower.utils.scene import Scene
class RIIC_ChooseSolver(SceneGraphSolver, BaseMixin):
solver_name = "基建选人"
def run(self, room: str, agents: list, wait_time: float = 0) -> bool:
if agents == []:
raise ValueError("干员列表为空")
logger.info(f"选择干员: {agents}")
self.agents = agents
self.agents_copy = deepcopy(agents)
self.cleard = False
self.filter = False
self.agent = None
self.choosed = []
# self.final_check = False
# self.check = []
self.tmp_data = None
self.tmp_left = None
self.wait_time = wait_time
self.room = room
self.start_time = datetime.now()
self.success = False
self.tap_time = datetime.now() # 临时解决多选
self.check_room()
self.interval = config.screenshot_avg / 500 # 截图延迟
try:
return super().run()
except ValueError as e:
logger.error(e.__traceback__)
return False
def riic_agent_choose(self):
if self.success:
return True
if self.agent is None:
if len(self.agents_copy) > 0:
self.agent = [self.agents_copy.pop(0), True] # True 说明还没选职业
else:
# 检查排序等
return True
return
agent_name = self.agent[0]
if agent_name == "Free":
self.choosed.append(RIIC_FreeFillSolver().run())
self.agent = None
return
agents = dict(operator_room_select(config.recog.img))
if len(self.agents) > 1:
for i in agents:
if self.is_choosed(agents[i]) and agents[i][0][0] < 1600:
if i not in self.agents and i not in self.choosed:
logger.debug(f"选人时存在错误选择 {i}")
# self.tap_element("choose_agent/clear", interval=0.1)
# self.agents_copy = deepcopy(self.agents)
# self.choosed = []
# self.agent = None
return
if agent_name in agents.keys():
if self.is_choosed(agents[agent_name]):
logger.debug(f"干员选好:{self.agent}")
self.choosed.append(agent_name)
self.tmp_left = None
self.agent = None
return
if agents[agent_name][0][0] > 1600:
self.swipe_noinertia((1000, 540), (-500, 0))
return
self.ctap(
agents[agent_name], interval=config.screenshot_avg / 500, max_seconds=5
)
return
elif self.agent[1]: # 筛一下职业
if len(self.agents) > 1:
if self.tmp_left is None:
self.tmp_left = list(agents.keys())[0]
self.swipe_noinertia((1000, 540), (300, 0))
return
elif self.tmp_left != list(agents.keys())[0]:
self.swipe_noinertia((1000, 540), (1000, 0))
self.tmp_left = list(agents.keys())[0]
return
if agent_name == "阿米娅":
tag = "ALL"
else:
tag = agent_list[agent_name]["profession"]
if RIICTagChoose().run(tag):
self.agent[1] = False
self.sleep(self.interval)
return
if list(agents.keys())[-1] == self.tmp_data or list(agents.keys())[-1] is None:
raise ValueError(f"选择干员: {self.agent}失败 滑动次数过多")
self.swipe_noinertia((1000, 540), (-1900, 0))
self.tmp_data = list(agents.keys())[-1]
def is_choosed(self, scope) -> bool:
if (
cropimg(
config.recog.img,
[
[scope[0][0] + 0, scope[0][1] - 86],
[scope[0][0] + 1, scope[0][1] - 85],
],
)[0][0][0]
< 50
) and cropimg(
config.recog.img,
[
[scope[0][0] + 0, scope[1][1] + 209],
[scope[0][0] + 1, scope[1][1] + 210],
],
)[0][0][0] < 50:
return True
return False
def check_wait_time(self) -> float:
return max(
self.wait_time - (datetime.now() - self.start_time).total_seconds(), 0
)
def check_room(self):
if (
(scene := self.scene()) == Scene.INFRA_DETAILS
) and not EnterRoomSolver().detect_room() == self.room:
logger.info(self.room)
EnterRoomSolver().run(self.room)
elif (
scene in [Scene.ORDER_LIST, Scene.FACTORY_ROOMS]
and not self.detect_room_inside() == self.room
):
EnterRoomSolver().run(self.room)
def transition(self) -> bool:
if (datetime.now() - self.tap_time).total_seconds() > 300:
EnterRoomSolver().run(self.room)
return True
if (scene := self.scene()) == Scene.RIIC_OPERATOR_SELECT:
if pos := self.find("choose_agent/riic/open_profession"):
self.ctap(pos, interval=self.interval)
else:
if self.filter is False:
if RIIC_Filter().run("技能", ascending=False):
self.filter = True
if self.cleard is False:
# 没有选上的,或只进驻一个人
agents = dict(operator_room_select(config.recog.img))
contain_choose = False
for i in agents:
if self.is_choosed(agents[i]):
contain_choose = True
if contain_choose is False or len(self.agents) == 1:
self.cleard = True
else:
self.tap_element("choose_agent/clear", interval=0.1)
return
if self.riic_agent_choose():
self.sleep(self.check_wait_time())
self.tap_element("confirm_blue")
self.success = True
elif self.find("room_detail"):
if self.success:
return True
else:
self.tap((1600, 200))
elif scene in [Scene.ORDER_LIST, Scene.FACTORY_ROOMS]:
if self.success:
return True
else:
self.tap((500, 970))
elif scene == Scene.INFRA_ARRANGE_ORDER:
self.scene_graph_step(Scene.RIIC_OPERATOR_SELECT)
elif scene == Scene.INFRA_ARRANGE_CONFIRM:
self.scene_graph_step(Scene.RIIC_OPERATOR_SELECT)
elif scene in self.waiting_scene:
self.waiting_solver()
else:
EnterRoomSolver().run(self.room)