|
| 1 | +diff --git a/autowsgr/ops/normal_fight.py b/autowsgr/ops/normal_fight.py |
| 2 | +index 29aea4a7..3e5cc979 100644 |
| 3 | +--- a/autowsgr/ops/normal_fight.py |
| 4 | ++++ b/autowsgr/ops/normal_fight.py |
| 5 | +@@ -154,6 +154,97 @@ def run_for_times( |
| 6 | + ) |
| 7 | + return self._results |
| 8 | + |
| 9 | ++ def run_for_times_condition( |
| 10 | ++ self, |
| 11 | ++ times: int, |
| 12 | ++ last_point: str, |
| 13 | ++ *, |
| 14 | ++ result: str = 'S', |
| 15 | ++ insist_time: float = 900.0, |
| 16 | ++ ) -> list[CombatResult] | bool: |
| 17 | ++ """有战果要求的多次运行。 |
| 18 | ++ |
| 19 | ++ 循环执行战斗直到满足预设条件。如果最后一个节点的战果未达到要求, |
| 20 | ++ 此次战斗不计入次数。超过指定时间仍未完成则返回 False。 |
| 21 | ++ |
| 22 | ++ Parameters |
| 23 | ++ ---------- |
| 24 | ++ times: |
| 25 | ++ 需要完成的次数。 |
| 26 | ++ last_point: |
| 27 | ++ 最后一个节点(如 "A"、"B" 等)。 |
| 28 | ++ result: |
| 29 | ++ 战果要求("S"、"A"、"B"、"C"、"D"、"SS"),默认为 "S"。 |
| 30 | ++ insist_time: |
| 31 | ++ 超时时间(秒)。如果超过这个时间仍未完成则返回 False,默认为 900 秒。 |
| 32 | ++ |
| 33 | ++ Returns |
| 34 | ++ ------- |
| 35 | ++ list[CombatResult] | bool |
| 36 | ++ 成功时返回战斗结果列表,超时返回 False。 |
| 37 | ++ |
| 38 | ++ Raises |
| 39 | ++ ------ |
| 40 | ++ ValueError: |
| 41 | ++ result 或 last_point 值不合法。 |
| 42 | ++ """ |
| 43 | ++ if result.upper() not in ['SS', 'S', 'A', 'B', 'C', 'D']: |
| 44 | ++ raise ValueError( |
| 45 | ++ f"战果要求: {result}, 不合法, 应为 'SS','S','A','B','C' 或 'D'", |
| 46 | ++ ) |
| 47 | ++ if ( |
| 48 | ++ len(last_point) != 1 |
| 49 | ++ or ord(last_point.upper()) > ord('Z') |
| 50 | ++ or ord(last_point.upper()) < ord('A') |
| 51 | ++ ): |
| 52 | ++ raise ValueError(f'最后一个节点: {last_point}, 不合法, 应为A到Z的字母') |
| 53 | ++ |
| 54 | ++ result_list = ['D', 'C', 'B', 'A', 'S', 'SS'] |
| 55 | ++ target_result_index = result_list.index(result.upper()) |
| 56 | ++ start_time = time.time() |
| 57 | ++ self._results = [] |
| 58 | ++ |
| 59 | ++ while times > 0: |
| 60 | ++ _log.info('[OPS] 条件战斗,剩余次数:{}', times) |
| 61 | ++ r = self.run() |
| 62 | ++ self._results.append(r) |
| 63 | ++ |
| 64 | ++ if r.flag == ConditionFlag.DOCK_FULL: |
| 65 | ++ _log.error('[OPS] 条件战斗,船坞已满,无法继续') |
| 66 | ++ return self._results |
| 67 | ++ |
| 68 | ++ # 获取最后一个节点的战果 |
| 69 | ++ fight_results = r.fight_results |
| 70 | ++ if not fight_results: |
| 71 | ++ _log.warning('[OPS] 条件战斗,未获取到有效战果') |
| 72 | ++ continue |
| 73 | ++ |
| 74 | ++ last_result = fight_results[-1] |
| 75 | ++ fight_result_index = result_list.index(last_result.grade) |
| 76 | ++ # 检查是否满足条件 |
| 77 | ++ finish = ( |
| 78 | ++ last_result.node == last_point.upper() and fight_result_index >= target_result_index |
| 79 | ++ ) |
| 80 | ++ |
| 81 | ++ if not finish: |
| 82 | ++ _log.info( |
| 83 | ++ '[OPS] 不满足预设条件 (节点={}, 战果={}), 此次战斗不计入次数,剩余次数: {}', |
| 84 | ++ last_result.node, |
| 85 | ++ last_result.grade, |
| 86 | ++ times, |
| 87 | ++ ) |
| 88 | ++ if time.time() - start_time > insist_time: |
| 89 | ++ return False |
| 90 | ++ else: |
| 91 | ++ start_time = time.time() |
| 92 | ++ times -= 1 |
| 93 | ++ _log.info( |
| 94 | ++ '[OPS] 完成了一次满足预设条件的战斗,剩余次数: {}', |
| 95 | ++ times, |
| 96 | ++ ) |
| 97 | ++ |
| 98 | ++ return self._results |
| 99 | ++ |
| 100 | + # ── 进入地图 ── |
| 101 | + |
| 102 | + def _enter_fight(self) -> None: |
| 103 | +@@ -273,6 +364,14 @@ def _handle_dock_full(self, result: CombatResult) -> None: |
| 104 | + # ═══════════════════════════════════════════════════════════════════════════════ |
| 105 | + |
| 106 | + |
| 107 | ++def get_normal_fight_plan(yaml_path: str) -> CombatPlan: |
| 108 | ++ """从 YAML 文件加载常规战计划。""" |
| 109 | ++ from autowsgr.infra.file_utils import resolve_plan_path |
| 110 | ++ |
| 111 | ++ resolved = resolve_plan_path(yaml_path, category='normal_fight') |
| 112 | ++ return CombatPlan.from_yaml(resolved) |
| 113 | ++ |
| 114 | ++ |
| 115 | + def run_normal_fight( |
| 116 | + ctx: GameContext, |
| 117 | + plan: CombatPlan, |
| 118 | +@@ -308,8 +407,5 @@ def run_normal_fight_from_yaml( |
| 119 | + - 策略名称 (如 ``"7-4千伪"``): 自动在 ``autowsgr/data/plan/normal_fight/`` |
| 120 | + 包数据目录中查找,可省略 ``.yaml`` 后缀。 |
| 121 | + """ |
| 122 | +- from autowsgr.infra.file_utils import resolve_plan_path |
| 123 | +- |
| 124 | +- resolved = resolve_plan_path(yaml_path, category='normal_fight') |
| 125 | +- plan = CombatPlan.from_yaml(resolved) |
| 126 | ++ plan = get_normal_fight_plan(yaml_path) |
| 127 | + return run_normal_fight(ctx, plan, times=times, fleet_id=fleet_id, fleet=fleet) |
| 128 | +diff --git a/examples/week.py b/examples/week.py |
| 129 | +new file mode 100644 |
| 130 | +index 00000000..abe28454 |
| 131 | +--- /dev/null |
| 132 | ++++ b/examples/week.py |
| 133 | +@@ -0,0 +1,18 @@ |
| 134 | ++import sys |
| 135 | ++ |
| 136 | ++from autowsgr.ops.normal_fight import NormalFightRunner, get_normal_fight_plan |
| 137 | ++from autowsgr.scheduler import launch |
| 138 | ++ |
| 139 | ++ |
| 140 | ++# run_for_times_condition的运行示例 |
| 141 | ++last_point = [None, 'A', 'F', 'I', 'I', 'I', 'J', 'M', 'L', 'O'] |
| 142 | ++i = int(float(sys.argv[1])) |
| 143 | ++ctx = launch('./usersettings.yaml') |
| 144 | ++# 这里修改为你自己的计划路径即可 |
| 145 | ++plan = get_normal_fight_plan('./week/' + sys.argv[1] + '.yaml') |
| 146 | ++runner = NormalFightRunner( |
| 147 | ++ ctx, |
| 148 | ++ plan, |
| 149 | ++ fleet_id=2, |
| 150 | ++) |
| 151 | ++runner.run_for_times_condition(1, last_point[i]) |
0 commit comments