diff --git a/arknights_mower/solvers/base_schedule.py b/arknights_mower/solvers/base_schedule.py index 1e4f019c7..ba6ca7fe5 100644 --- a/arknights_mower/solvers/base_schedule.py +++ b/arknights_mower/solvers/base_schedule.py @@ -18,7 +18,7 @@ from ..utils import character_recognize, detector, segment from ..utils.digit_reader import DigitReader from ..utils.operators import Operators, Operator, Dormitory -from ..utils.scheduler_task import SchedulerTask, scheduling, find_next_task, TaskTypes +from ..utils.scheduler_task import SchedulerTask, scheduling, find_next_task, TaskTypes, check_dorm_ordering from ..utils import typealias as tp from ..utils.device import Device from ..utils.log import logger @@ -102,6 +102,7 @@ def run(self) -> None: self.error = False self.handle_error(True) scheduling(self.tasks) + check_dorm_ordering(self.tasks,self.op_data) if len(self.tasks) > 0: # 找到时间最近的一次单个任务 self.task = self.tasks[0] diff --git a/arknights_mower/tests/scheduler_task_tests.py b/arknights_mower/tests/scheduler_task_tests.py index 8f5506170..a5ee3870c 100644 --- a/arknights_mower/tests/scheduler_task_tests.py +++ b/arknights_mower/tests/scheduler_task_tests.py @@ -1,7 +1,14 @@ from datetime import datetime, timedelta import unittest -from arknights_mower.utils.scheduler_task import scheduling, SchedulerTask, TaskTypes, find_next_task +from unittest.mock import patch, MagicMock +from arknights_mower.utils.plan import Plan, Room, PlanConfig +from arknights_mower.utils.scheduler_task import scheduling, SchedulerTask, TaskTypes, find_next_task, \ + check_dorm_ordering +from ..utils.operators import Operators + +with patch.dict('sys.modules', {'save_action_to_sqlite_decorator': MagicMock()}): + from ..solvers.record import save_action_to_sqlite_decorator class TestScheduling(unittest.TestCase): @@ -73,3 +80,81 @@ def test_find_next(self): meta_data="room", compare_type=">") self.assertEqual(res1, None) self.assertNotEqual(res2, None) + + def test_check_dorm_ordering_add_plan_1(self): + # 测试 方程有效 + task1 = SchedulerTask(time=datetime.now(), + task_plan={'dormitory_1': ['Current', 'Current', '夕', 'Current', 'Current'],'central': ['麒麟R夜刀', 'Current', 'Current', 'Current', 'Current']}, task_type=TaskTypes.SHIFT_OFF, meta_data="") + tasks = [task1] + op_data = self.init_opdata() + check_dorm_ordering(tasks, op_data) + # 生成额外宿舍任务 + self.assertEqual(2, len(tasks)) + self.assertEqual(1, len(tasks[0].plan)) + # 老plan含有见行者 + self.assertEqual("见行者", tasks[1].plan["dormitory_1"][3]) + + def test_check_dorm_ordering_add_plan_2(self): + # 测试 方程有效 + task1 = SchedulerTask(time=datetime.now(), + task_plan={'dormitory_1': ['Current', 'Current', '夕', 'Current', 'Current'],'central': ['麒麟R夜刀', 'Current', 'Current', 'Current', 'Current']}, task_type=TaskTypes.SHIFT_OFF, meta_data="") + tasks = [task1] + op_data = self.init_opdata() + # 预设干员位置 + op_data.operators["见行者"].current_index = -1 + op_data.operators["见行者"].current_room = "meeting" + op_data.operators["麒麟R夜刀"].current_index = 3 + op_data.operators["麒麟R夜刀"].current_room = "dormitory_1" + check_dorm_ordering(tasks, op_data) + # 生成额外宿舍任务 + self.assertEqual(2, len(tasks)) + self.assertEqual(1, len(tasks[0].plan)) + # 老plan不变 + self.assertEqual("Current", tasks[1].plan["dormitory_1"][3]) + + def test_check_dorm_ordering_not_plan(self): + # 测试 方程有效 + task1 = SchedulerTask(time=datetime.now(), + task_plan={'dormitory_1': ['Current', 'Current', 'Current', '夕', 'Current'],'central': ['麒麟R夜刀', 'Current', 'Current', 'Current', 'Current']}, task_type=TaskTypes.SHIFT_OFF, meta_data="") + tasks = [task1] + op_data = self.init_opdata() + # 预设干员位置 + op_data.operators["红"].current_index = -1 + op_data.operators["红"].current_room = "meeting" + op_data.operators["焰尾"].current_index = 2 + op_data.operators["焰尾"].current_room = "dormitory_1" + check_dorm_ordering(tasks, op_data) + + # 如果VIP位已经被占用,则不会生成新任务 + self.assertEqual(1, len(tasks)) + + + def init_opdata(self): + agent_base_config = PlanConfig("稀音,黑键,伊内丝,承曦格雷伊", "稀音,柏喙,伊内丝", "见行者") + plan_config = {"central": [Room("夕", "", ["麒麟R夜刀"]), + Room("焰尾", "", ["凯尔希"]), + Room("森蚺", "", ["凯尔希"]), + Room("令", "", ["火龙S黑角"]), + Room("薇薇安娜", "", ["玛恩纳"])], + "meeting": [Room("伊内丝", "", ["陈", "红"]), Room("见行者", "", ["陈", "红"])], + "dormitory_1": [Room("塑心", "", []), + Room("冰酿", "", []), + Room("Free", "", []), + Room("Free", "", []), + Room("Free", "", [])] + } + plan = { + "default_plan": Plan(plan_config, agent_base_config), + "backup_plans": [] + } + op_data = Operators(plan) + op_data.init_and_validate() + # 预设干员位置 + op_data.operators["冰酿"].current_room= op_data.operators["塑心"].current_room= op_data.operators["见行者"].current_room ="dormitory_1" + op_data.operators["红"].current_room = op_data.operators["玛恩纳"].current_room = "dormitory_1" + op_data.operators["冰酿"].current_index = 0 + op_data.operators["塑心"].current_index = 1 + op_data.operators["红"].current_index = 2 + op_data.operators["见行者"].current_index = 3 + op_data.operators["玛恩纳"].current_index = 4 + return op_data diff --git a/arknights_mower/utils/scheduler_task.py b/arknights_mower/utils/scheduler_task.py index 1f1af6251..aa38bf365 100644 --- a/arknights_mower/utils/scheduler_task.py +++ b/arknights_mower/utils/scheduler_task.py @@ -17,6 +17,7 @@ class TaskTypes(Enum): NOT_SPECIFIC = ("", "空任务", 2) RECRUIT = ("recruit", "公招", 2) SKLAND = ("skland", "森空岛签到", 2) + RE_ORDER = ("宿舍排序", "宿舍排序", 2) def __new__(cls, value, display_value, priority): obj = object.__new__(cls) @@ -105,6 +106,40 @@ def scheduling(tasks, run_order_delay=5, execution_time=0.75, time_now=None): tasks.sort(key=lambda x: x.time) +def check_dorm_ordering(tasks, op_data): + # 仅当下班的时候才触发宿舍排序任务 + plan = op_data.plan + if tasks[0].type == TaskTypes.SHIFT_OFF: + extra_plan = {} + for room, v in tasks[0].plan.items(): + # 非宿舍则不需要清空 + if room.startswith('dorm'): + # 是否检查过vip位置 + pass_first_free = False + for idx, agent in enumerate(v): + # 如果当前位置非宿管 且无人员变动(有变动则是下班干员) + if "Free" == plan[room][idx].agent and agent == "Current": + # 如果高优先不变,则跳过逻辑判定 + if not pass_first_free: + break + current = next((obj for obj in op_data.operators.values() if + obj.current_room == room and obj.current_index == idx), None) + if current: + if current.resting_priority != "high": + # 替换成高优先的实际名字 + if current.is_high(): + v[idx] = current.name + if room not in extra_plan: + extra_plan[room] = copy.deepcopy(v) + # 新生成移除任务 --> 换成任意干员 + extra_plan[room][idx] = "Free" + if "Free" == plan[room][idx].agent and not pass_first_free: + pass_first_free = True + if extra_plan: + tasks.insert(0, SchedulerTask(task_plan=extra_plan, time=tasks[0].time - timedelta(seconds=1), + task_type=TaskTypes.RE_ORDER)) + + class SchedulerTask: time = None type = ''