Skip to content

feat: 式舆防卫战自动配队 - #2599

Open
kawayiYokami wants to merge 25 commits into
OneDragon-Anything:mainfrom
kawayiYokami:feat/shiyu-defense-auto-team
Open

feat: 式舆防卫战自动配队#2599
kawayiYokami wants to merge 25 commits into
OneDragon-Anything:mainfrom
kawayiYokami:feat/shiyu-defense-auto-team

Conversation

@kawayiYokami

@kawayiYokami kawayiYokami commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

变更内容

  • 自动扫描游戏内预备编队,按角色属性与职业为 1~3 个目标选择不重复队伍。
  • 正式式舆防卫战普通节点与多间模式接入自动配队。
  • 废弃旧的式舆防卫战手工弱点与剧变队设置页;旧 YAML 配置类保留,但生产路径不再读取。
  • 添加“配队选择”开发工具,用于验证预备编队扫描、选择与预备出战。

预备编队扫描与选择

  • 增加扫描决策日志:记录卡位队名、重复卡片跳过、代理人数量、空队停止、扫描页码及继续拖动原因,便于定位扫描过程。
  • 使用固定坐标按住拖动翻页,向下扫描与向上回退使用相反方向,避免滚轮翻页受环境影响。
  • 识别到首个空队时停止扫描;相邻页面重复出现的队伍按名称去重。
  • 1P2P3P 任一标记缺失的队伍视为本期被禁用:不参与自动配队评分,但保留游戏列表序号,避免后续有效队伍翻页和点击错位。
  • 目标队伍已被游戏预选时,先取消该卡片的选中状态;仅在原按钮区域重新识别到 SELECT 后再选择。
  • 每次选择后等待同一按钮区域确认已选状态,再选择下一支队伍;所有目标确认选中后才进入预备出战。

提交拆分

  1. feat: 式舆防卫战自动配队
  2. feat(devtools): 添加配队选择
  3. fix: 让按住滑动更加稳定
  4. fix: 使用拖动翻页预备编队
  5. chore: 增强预备编队扫描日志
  6. fix: 跳过被禁用的预备编队
  7. fix: 取消预选的预备编队
  8. docs: 补充预备编队选择说明
  9. revert: 恢复滚轮灵敏度换算

验证

  • py_compilegit diff --check 已通过。
  • 未新增或运行测试。
  • 当前提交尚未完成游戏内实测。

Summary by CodeRabbit

  • 新功能
    • 新增“配队选择”开发工具,可配置目标数量及弱点、抗性类型。
  • 改进
    • 式舆防卫战扫描预备编队并按属性评分,自动选择互不重复的队伍。
    • 多间模式统一识别未完成房间并按顺序出战,提升选队状态确认与失败重试能力。
    • 优化鼠标拖拽操作稳定性。
  • 文档
    • 更新式舆防卫战玩法、节点进度、选队及多间模式说明。
    • 补充战斗系统、职业定位与自动配队评分说明。
  • 界面调整
    • 移除旧版式舆防卫战设置页面。

close #2652

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

重构式舆防卫战的预备编队扫描、OCR 目标识别、队伍评分和选队状态机。更新普通及多间模式流程。新增配队选择开发工具、配置界面和战斗机制文档。

Changes

式舆防卫战配队选择

Layer / File(s) Summary
配队测试工具与配置
src/zzz_od/application/devtools/shiyu_defense_team_test/*, src/zzz_od/gui/view/devtools/*
新增配队测试应用、配置和开发工具界面,支持配置最多三个目标及其弱点、抗性。
目标识别与队伍评分
src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py
拆分弱点、抗性 OCR 识别与队伍选择,并按伤害类型、职业、异常类型和代理人冲突计算队伍分数。
预备编队选队状态机
src/zzz_od/operation/choose_predefined_team.py, src/zzz_od/config/team_config.py
新增预备编队扫描、队伍配置写入、分页定位、队伍选择和选中状态确认。
普通与多间模式流程接入
src/zzz_od/application/shiyu_defense/shiyu_defense_app.py, src/one_dragon/base/controller/pc_controller_base.py, docs/game/gameplay/式舆防卫战.md, docs/game/screens/式舆防卫战.md, docs/game/gameplay/combat.md
更新普通及多间模式的目标识别、队伍索引、完成状态和战斗流程,并同步操作流程与战斗机制文档。拖拽操作新增起始延迟。

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ShiyuDefenseApp
  participant get_team_targets
  participant ChoosePredefinedTeam
  participant TeamConfig
  participant select_teams
  participant ShiyuDefenseBattle
  ShiyuDefenseApp->>get_team_targets: OCR 识别弱点、抗性和房间完成状态
  get_team_targets-->>ShiyuDefenseApp: 返回目标列表
  ShiyuDefenseApp->>ChoosePredefinedTeam: 传入目标列表并扫描预备编队
  ChoosePredefinedTeam->>TeamConfig: 写入编队名称和前三名代理人
  ChoosePredefinedTeam->>select_teams: 计算互斥队伍及总分
  select_teams-->>ChoosePredefinedTeam: 返回队伍索引和分数
  ChoosePredefinedTeam-->>ShiyuDefenseApp: 返回选队结果
  ShiyuDefenseApp->>ShiyuDefenseBattle: 使用当前队伍索引出战
  ShiyuDefenseBattle-->>ShiyuDefenseApp: 返回战斗结果并更新房间状态
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了 PR 的主要变更,即为式舆防卫战增加自动配队功能。
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kawayiYokami
kawayiYokami force-pushed the feat/shiyu-defense-auto-team branch from 7185cfa to 039948c Compare July 30, 2026 13:26
@kawayiYokami
kawayiYokami marked this pull request as ready for review July 30, 2026 13:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
docs/game/gameplay/式舆防卫战.md (1)

91-93: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

集中维护自动化实现细节,避免文档分叉。

当前扫描、评分、OCR 选队和多间模式状态流转同时写入玩法文档与画面文档,后续代码变更容易造成两处描述不一致。建议将实现流程集中到对应 skill/自动化文档;玩法文档和画面文档只保留必要概述并通过引用链接到唯一来源。

  • docs/gameplay/式舆防卫战.md#L91-L93: 保留玩法层流程概述,移除详细自动化节点链。
  • docs/game/screens/式舆防卫战.md#L64-L66: 将扫描与评分实现细节改为引用统一的自动化文档。
  • docs/game/screens/式舆防卫战.md#L68-L69: 将 OCR 定位和选中态判定细节集中到统一来源。
  • docs/game/screens/式舆防卫战.md#L131-L131: 将多间模式的实现说明改为引用统一流程文档。

依据编码规范:文档分层遵循“方法写 skill、具体内容写 doc”,玩法机制与自动化实现分开,并保持单一事实来源;重复内容应通过引用表达。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/game/gameplay/式舆防卫战.md` around lines 91 - 93,
自动化实现细节在玩法文档与画面文档重复,需集中维护并避免文档分叉。更新
docs/game/gameplay/式舆防卫战.md:91-93,仅保留玩法层流程概述并移除扫描、评分、OCR 选队及状态流转细节;更新
docs/game/screens/式舆防卫战.md:64-66、68-69、131-131,将对应实现说明分别替换为指向统一
skill/自动化流程文档的引用,确保唯一来源覆盖扫描评分、OCR 选中态判定和多间模式流程。

Source: Coding guidelines

src/zzz_od/application/shiyu_defense/shiyu_defense_app.py (1)

306-308: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

team_idx = -1 已冗余。

房间完成状态现在由 is_completed 表达,multi_room_select 也不再看 team_idx;再置 -1 只会让状态含义变模糊(-1 同时表示“未选出”和“已完成”)。建议删除该行。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_app.py` around lines 306 -
308, 删除 shiyu_defense_app.py 中完成当前房间的逻辑里对
self.room_teams[self.current_room_idx].team_idx 的 -1 赋值,仅保留 is_completed =
True;不要修改 result 返回或其他房间状态处理。
src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py (3)

161-167: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

agent_map 每次评分都重建。

_get_agents 会在回溯的每个候选队上被调用,而 AgentEnum → agent_id 的映射是静态的,建议提到模块级(或用 functools.cache)只构建一次。

♻️ 建议改动
-    def _get_agents(self, team: PredefinedTeamInfo) -> list[Agent]:
-        agent_map = {agent.value.agent_id: agent.value for agent in AgentEnum}
-        return [
-            agent_map[agent_id]
-            for agent_id in team.agent_id_list
-            if agent_id in agent_map
-        ]
+    def _get_agents(self, team: PredefinedTeamInfo) -> list[Agent]:
+        agent_map = _get_agent_map()
+        return [
+            agent_map[agent_id]
+            for agent_id in team.agent_id_list
+            if agent_id in agent_map
+        ]

模块级新增:

`@functools.cache`
def _get_agent_map() -> dict[str, Agent]:
    return {agent.value.agent_id: agent.value for agent in AgentEnum}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py` around
lines 161 - 167, 将 AgentEnum 到 agent_id 的静态映射从 _get_agents 中移出,新增模块级缓存辅助函数(如
_get_agent_map,使用 functools.cache)并仅构建一次;让 _get_agents 复用该缓存映射,同时保持现有按
team.agent_id_list 过滤并返回 Agent 的行为不变。

319-333: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

zip 替代 index() 反查。

target_text_list.index(target_text) 在两个伤害类型翻译文本相同时会取到错误枚举;直接同时遍历枚举与文本更稳妥。

♻️ 建议改动
-    for target_text in target_text_list:
-        if target_text in full_text:
-            result.append(dmg_type_list[target_text_list.index(target_text)])
+    for dmg_type, target_text in zip(dmg_type_list, target_text_list, strict=True):
+        if target_text in full_text:
+            result.append(dmg_type)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py` around
lines 319 - 333, Update _extract_dmg_types to iterate over dmg_type_list and
target_text_list together with zip, appending the paired DmgTypeEnum when its
translated text appears in full_text; remove the
target_text_list.index(target_text) reverse lookup.

28-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

建议用 ClassVar 标注不可变常量。

VOID_HUNTER_AGENT_ID_LIST 是可变类属性(Ruff RUF012),语义上是常量且仅做成员判断,改为 ClassVar[frozenset[str]] 既消除告警又让查找为 O(1)。

♻️ 建议改动
-    VOID_HUNTER_AGENT_ID_LIST: list[str] = [
-        'yixuan',
-        'hoshimi_miyabi',
-        'yeshunguang',
-        'remielle',
-    ]
-    VOID_HUNTER_SCORE_MULTIPLIER: float = 1.2
+    VOID_HUNTER_AGENT_ID_SET: ClassVar[frozenset[str]] = frozenset({
+        'yixuan',
+        'hoshimi_miyabi',
+        'yeshunguang',
+        'remielle',
+    })
+    VOID_HUNTER_SCORE_MULTIPLIER: ClassVar[float] = 1.2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py` around
lines 28 - 34, 将 VOID_HUNTER_AGENT_ID_LIST 标注为
ClassVar[frozenset[str]],并将现有列表初始化改为不可变 frozenset;保留所有成员值及成员判断语义,同时确保
VOID_HUNTER_SCORE_MULTIPLIER 不受影响。

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/game/screens/式舆防卫战.md`:
- Line 67: 更新 ChoosePredefinedTeam 的扫描规则,明确区分真正的空队与禁用编队:缺少 1P/2P/3P
标记的禁用编队应跳过并继续扫描,只有确认当前卡片是空队时才停止扫描;保留单人、双人队合法及既有自动战斗配置的说明。

In `@src/zzz_od/config/team_config.py`:
- Around line 71-84: Update update_team_by_idx to normalize members through a
shared _to_agent_id_list helper that takes only the first three agent IDs and
pads shorter lists with 'unknown'. Replace the duplicated padding logic in
update_team_members with the same helper, preserving the existing three-member
configuration limit.

In `@src/zzz_od/operation/choose_predefined_team.py`:
- Around line 274-281: Update the deduplication logic in the predefined-team
scanning flow around next_scanned_team_idx and _find_exact_team_name so cards
are identified by page and card position rather than team_name alone. Ensure
duplicate names still consume their own team_idx and remain aligned with the
game list, while preserving the existing skip behavior only for the same
physical card being rescanned.
- Around line 143-170: 为 pending_cancel_button_center 和
pending_select_button_center 的确认轮询增加尝试次数上限,避免持续 OCR 失败或状态未恢复时无限调用
round_wait。超限后调用 round_fail,或改用能让 node_max_retry_times 生效的
round_retry;确保成功确认时仍清理对应 pending 状态并继续原有流程。

---

Nitpick comments:
In `@docs/game/gameplay/式舆防卫战.md`:
- Around line 91-93: 自动化实现细节在玩法文档与画面文档重复,需集中维护并避免文档分叉。更新
docs/game/gameplay/式舆防卫战.md:91-93,仅保留玩法层流程概述并移除扫描、评分、OCR 选队及状态流转细节;更新
docs/game/screens/式舆防卫战.md:64-66、68-69、131-131,将对应实现说明分别替换为指向统一
skill/自动化流程文档的引用,确保唯一来源覆盖扫描评分、OCR 选中态判定和多间模式流程。

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_app.py`:
- Around line 306-308: 删除 shiyu_defense_app.py 中完成当前房间的逻辑里对
self.room_teams[self.current_room_idx].team_idx 的 -1 赋值,仅保留 is_completed =
True;不要修改 result 返回或其他房间状态处理。

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py`:
- Around line 161-167: 将 AgentEnum 到 agent_id 的静态映射从 _get_agents
中移出,新增模块级缓存辅助函数(如 _get_agent_map,使用 functools.cache)并仅构建一次;让 _get_agents
复用该缓存映射,同时保持现有按 team.agent_id_list 过滤并返回 Agent 的行为不变。
- Around line 319-333: Update _extract_dmg_types to iterate over dmg_type_list
and target_text_list together with zip, appending the paired DmgTypeEnum when
its translated text appears in full_text; remove the
target_text_list.index(target_text) reverse lookup.
- Around line 28-34: 将 VOID_HUNTER_AGENT_ID_LIST 标注为
ClassVar[frozenset[str]],并将现有列表初始化改为不可变 frozenset;保留所有成员值及成员判断语义,同时确保
VOID_HUNTER_SCORE_MULTIPLIER 不受影响。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d4d3e692-ec07-43a7-abc4-e41018e73521

📥 Commits

Reviewing files that changed from the base of the PR and between 012a1ee and 039948c.

📒 Files selected for processing (16)
  • docs/game/gameplay/式舆防卫战.md
  • docs/game/screens/式舆防卫战.md
  • src/one_dragon/base/controller/pc_controller_base.py
  • src/zzz_od/application/devtools/shiyu_defense_team_test/__init__.py
  • src/zzz_od/application/devtools/shiyu_defense_team_test/shiyu_defense_team_test_app.py
  • src/zzz_od/application/devtools/shiyu_defense_team_test/shiyu_defense_team_test_app_factory.py
  • src/zzz_od/application/devtools/shiyu_defense_team_test/shiyu_defense_team_test_config.py
  • src/zzz_od/application/devtools/shiyu_defense_team_test/shiyu_defense_team_test_const.py
  • src/zzz_od/application/shiyu_defense/shiyu_defense_app.py
  • src/zzz_od/application/shiyu_defense/shiyu_defense_app_setting.py
  • src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py
  • src/zzz_od/config/team_config.py
  • src/zzz_od/gui/app_setting/shiyu_defense_setting_interface.py
  • src/zzz_od/gui/view/devtools/app_devtools_interface.py
  • src/zzz_od/gui/view/devtools/shiyu_defense_team_test_interface.py
  • src/zzz_od/operation/choose_predefined_team.py
💤 Files with no reviewable changes (2)
  • src/zzz_od/application/shiyu_defense/shiyu_defense_app_setting.py
  • src/zzz_od/gui/app_setting/shiyu_defense_setting_interface.py

Comment thread docs/game/screens/式舆防卫战.md Outdated
Comment thread src/zzz_od/config/team_config.py
Comment thread src/zzz_od/operation/choose_predefined_team.py Outdated
Comment thread src/zzz_od/operation/choose_predefined_team.py Outdated
@ShadowLemoon ShadowLemoon added the test-branch 合入 test 分支 label Jul 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/zzz_od/config/team_config.py (1)

80-83: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

统一两个配置同步入口的三人上限。

这里已将 update_team_by_idx 的成员列表截断为 3 人,但 update_team_members 仍会把全部 members 写入配置(Line 94-97)。同一个 agent_id_list 因调用入口不同可能出现不同长度,破坏预备编队的三人约束。建议抽取统一的截断与 unknown 补齐逻辑,并由两个方法共同复用。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/config/team_config.py` around lines 80 - 83, 统一 update_team_by_idx
与 update_team_members 的 agent_id_list 生成逻辑:抽取共同的成员处理方法,将 members 截断为最多 3 人,并用
'unknown' 补齐至 3 人。让两个配置同步入口都复用该方法后再调用 self.update_team,确保无论入口如何调用都保持三人上限。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/zzz_od/config/team_config.py`:
- Around line 80-83: 统一 update_team_by_idx 与 update_team_members 的 agent_id_list
生成逻辑:抽取共同的成员处理方法,将 members 截断为最多 3 人,并用 'unknown' 补齐至 3 人。让两个配置同步入口都复用该方法后再调用
self.update_team,确保无论入口如何调用都保持三人上限。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6251b60c-f442-47db-baa8-563b4e4de4ae

📥 Commits

Reviewing files that changed from the base of the PR and between 039948c and 682f4fb.

📒 Files selected for processing (3)
  • docs/game/screens/式舆防卫战.md
  • src/zzz_od/config/team_config.py
  • src/zzz_od/operation/choose_predefined_team.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/game/screens/式舆防卫战.md

DoctorReid and others added 2 commits July 31, 2026 15:30
…to-team

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
战斗机制此前无文档(combat.md 是空模板),导致配队评分代码注释缺失、虚狩被直译成虚无猎人、染色分支不对称无依据可考。

- 新增 combat.md:属性克制/异常紊乱/失衡连携三条输出链路、风与流明(维琳娜/蕾米埃尔)的染色机制、职业系统、虚狩概念、自动配队评分依据
- team_utils 注释反哺:虚狩正名、染色分支 WIND/LUMIFLUX 不对称的依据(流明可变属性)、评分权重非真实伤害倍率

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>
normalized_text == 'SELECTED'
or normalized_text == 'TEAM'
or normalized_text.startswith('TEAM')
or re.fullmatch(r'\d{2}', normalized_text) is not None

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 \d{2} 会误匹配角色等级 "60"——SELECT 被 OCR 漏读时可能误点队伍(实测确认)

re.fullmatch(r"\d{2}", normalized_text) 原意是兜底识别选中态的队伍编号(TEAM 01/02),但角色等级也是两位数 "60",且落在 _find_selected_button 检测区(x_offset 300-850、y_offset 40-250)内,两者无法区分。

在实时选队截图上验证:_is_selected_text("60") → True;6 张卡 _find_selected_button 全部误判 SELECTED(命中全是 "60"),平时被 _find_select_button 先命中 SELECT 掩盖。一旦 OCR 把 SELECT 漏读(实测日志见过 +$ELECT/+SELEET)→ SELECTED 误判 → 走"取消预选"分支误点卡片 → 等 SELECT 恢复(不会)→ retry×3 → round_fail

建议去掉这条 \d{2}(选中态靠 TEAM 匹配即可)。代价:OCR 把 TEAM 也漏读时 round_fail(安全失败),而非误点。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py (2)

60-84: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

跳过已完成目标,并保留完成状态。

_search_target() 仍会为每个目标分配队伍。src/zzz_od/operation/choose_predefined_team.py 将完整的 shiyu_target_list 传入 select_teams()。已完成房间因此会占用 chosen_team_idx_setchosen_agent_id_set,可能使未完成房间无法找到可用组合。

_save_best() 重新创建 DefensePhaseTeamInfo 时也没有复制 is_completed。返回结果会丢失该状态。

请在递归入口跳过已完成目标,并在保存结果时复制 is_completed。已完成目标应保持 team_idx == -1score == 0,且不计入新组合评分。请增加已完成房间与未完成房间混合的回归测试。

建议修复
     def _search_target(self, target_idx: int) -> None:
         if target_idx >= len(self.target_list):
             self._save_best()
             return

         target = self.target_list[target_idx]
+        if target.is_completed:
+            target.team_idx = -1
+            target.score = 0
+            self._search_target(target_idx + 1)
+            return
+
         for team in self.candidate_team_list:
             ...

             result.team_idx = target.team_idx
             result.score = target.score
+            result.is_completed = target.is_completed

Also applies to: 86-97

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py` around
lines 60 - 84, Update _search_target() to detect completed targets at the
recursive entry, preserve their team_idx == -1 and score == 0 values, and
recurse to the next target without adding their teams or agents to the chosen
sets or scoring. Update _save_best() to copy each target’s is_completed state
when recreating DefensePhaseTeamInfo. Add a regression test covering mixed
completed and incomplete rooms, ensuring completed rooms do not block valid team
combinations.

254-322: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

识别失败必须走失败路径。

多间模式的房间 OCR 或区域识别缺失、解析失败时,当前改动返回未知目标。src/zzz_od/application/shiyu_defense/shiyu_defense_app.py 随后仍会记录目标并返回成功。后续流程可能把 team_idx == -1 解释为已完成或跳过,导致识别失败的房间被错误完成。

请让识别失败分支显式返回失败状态,并在 check_weakness() 中处理该状态。不要返回会继续进入选队流程的未知目标。

Based on learnings:多间模式的 OCR/区域识别失败必须立即失败或退出,不能落入 team_idx == -1 的已完成/跳过路径。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py` around
lines 254 - 322, Update get_team_targets_for_multi_room so OCR, missing-area,
and parsing failures return an explicit failure result instead of appending
unknown DefensePhaseTeamInfo entries; ensure callers can distinguish failure
from completed rooms. Update check_weakness in shiyu_defense_app.py to detect
and handle that failure immediately, preventing the result from reaching the
team-selection or team_idx == -1 completion path.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py`:
- Around line 60-84: Update _search_target() to detect completed targets at the
recursive entry, preserve their team_idx == -1 and score == 0 values, and
recurse to the next target without adding their teams or agents to the chosen
sets or scoring. Update _save_best() to copy each target’s is_completed state
when recreating DefensePhaseTeamInfo. Add a regression test covering mixed
completed and incomplete rooms, ensuring completed rooms do not block valid team
combinations.
- Around line 254-322: Update get_team_targets_for_multi_room so OCR,
missing-area, and parsing failures return an explicit failure result instead of
appending unknown DefensePhaseTeamInfo entries; ensure callers can distinguish
failure from completed rooms. Update check_weakness in shiyu_defense_app.py to
detect and handle that failure immediately, preventing the result from reaching
the team-selection or team_idx == -1 completion path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 172e7e32-2369-4b0f-bd2d-a009b9d3fbcb

📥 Commits

Reviewing files that changed from the base of the PR and between 682f4fb and 49b1f9d.

📒 Files selected for processing (3)
  • docs/game/gameplay/combat.md
  • src/zzz_od/application/shiyu_defense/shiyu_defense_app.py
  • src/zzz_od/application/shiyu_defense/shiyu_defense_team_utils.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/zzz_od/application/shiyu_defense/shiyu_defense_app.py

实测发现的两个 OCR 相关问题:

1. 多间配队候选不足(根因):旧逻辑用1P/2P/3P三标记判满员,3P文字OCR漏读会误判满员队禁用,导致候选不足、select_teams选不出3互斥队。改用核心技X/Y(分母=队伍人数)判满员(X/3为主、1P/2P/3P≥2兜底),并兼容OCR把斜线误识为1的连写(313=3/3)。
2. 进度误判完成:OCR把进度X/Y读成total<current(如2/1)时,choose_node_idx误判全部完成跳过整关。加total<current校验回退run_record。

配套文档:式舆防卫战玩法/画面doc补X/3含义(核心技羁绊非角色数)、进度X/Y(分母=人数),并纠正禁用措辞(防卫战无禁用代理人玩法)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: glm-5.2 <noreply@bigmodel.cn>

@DoctorReid DoctorReid left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本地完成一轮端到端实测(账号1 式舆防卫战剧变节点),已 push 修复(7bd1652,含 49b1f9d 文档):

实测发现并修复 3 处 OCR 相关问题:

  1. 多间配队候选不足(根因):扫描用 1P/2P/3P 三标记判满员,3P 文字 OCR 漏读会误判满员队禁用 → 候选不足 → select_teams 选不出 3 互斥队。改用核心技 X/Y(分母=队伍人数)判满员(X/3 为主、1P/2P/3P≥2 兜底),兼容斜线误识为 1 的连写(313=3/3)。
  2. 进度 OCR 误判完成:X/Y 读成 total<current(如 2/1)时 choose_node_idx 误判全部完成跳过整关 → 加 total<current 校验回退 run_record。
  3. _is_selected_text 的 \d{2} 误匹配等级 60 → 限 0 开头(0\d:选中态编号 01-09,排除等级)。

端到端验证:多间(节点5)扫描候选 11 → select_teams 选 3 满员互斥(简薇耀/仪玄/冰雅狼苍,避开 1 人测试队)→ 3 间战斗 → 领奖 → 回大世界,完整跑通。

另:combat.md 补战斗机制 + team_utils 注释(虚狩正名/染色依据/评分权重)。

建议 author 确认 X/3 判满员的修法,并补选配队单元测试。

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/zzz_od/application/shiyu_defense/shiyu_defense_app.py (1)

202-216: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

在进入选队前拒绝不完整的目标列表。

Line 202 和 Line 218 将识别结果直接传入后续状态机。若多间模式识别返回空列表,multi_room_select 会把节点标记为完成。若普通模式识别返回空列表,流程可能通过空配队选择,并在 shiyu_battle 访问 phase_team_list[0] 时失败。

多间模式必须验证列表长度为 len(ROOM_NAMES)。普通模式必须验证列表长度为 2。识别失败时返回受控失败或受限重试,不要继续选队。

建议修复
 self.room_teams = shiyu_defense_team_utils.get_team_targets_for_multi_room(
     self.ctx,
     self.last_screenshot,
     '式舆防卫战-三间选择',
     len(ROOM_NAMES),
 )
+if len(self.room_teams) != len(ROOM_NAMES):
+    return self.round_fail('多间模式房间目标识别失败')

 self.phase_team_list = shiyu_defense_team_utils.get_team_targets(
     self.ctx,
     self.last_screenshot,
 )
+if len(self.phase_team_list) != 2:
+    return self.round_fail('普通模式阶段目标识别失败')

Based on learnings: 多间模式中的 OCR 或区域识别失败必须进入失败路径,不能被解释为已完成房间。

Also applies to: 218-233

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/application/shiyu_defense/shiyu_defense_app.py` around lines 202 -
216, 在多间模式处理逻辑中,校验 get_team_targets_for_multi_room 返回的 self.room_teams 长度必须等于
len(ROOM_NAMES),不满足时进入受控失败或受限重试并禁止调用 round_success。同步检查普通模式识别结果,确保队伍列表长度必须为
2;识别结果不完整时同样停止后续选队流程,避免空列表进入 shiyu_battle。

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/game/screens/式舆防卫战.md`:
- Line 67: 同步更新 `docs/game/screens/式舆防卫战.md` 中 `ChoosePredefinedTeam`
的扫描规则描述,使其与 `_scan_team_page` 当前实现一致:仅当 `agent_list` 为空且核心技计数缺失或以 `/0`
结尾时停止扫描;识别到 `X/3` 或至少两个槽位标记时仍允许队伍参与评分。删除或改写“任一标记缺失即不可用”和“无头像即停止”等不符合实现的表述。

---

Outside diff comments:
In `@src/zzz_od/application/shiyu_defense/shiyu_defense_app.py`:
- Around line 202-216: 在多间模式处理逻辑中,校验 get_team_targets_for_multi_room 返回的
self.room_teams 长度必须等于 len(ROOM_NAMES),不满足时进入受控失败或受限重试并禁止调用
round_success。同步检查普通模式识别结果,确保队伍列表长度必须为 2;识别结果不完整时同样停止后续选队流程,避免空列表进入
shiyu_battle。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a12b29e-27d9-4d3b-89c6-7ca831ccd715

📥 Commits

Reviewing files that changed from the base of the PR and between 49b1f9d and 7bd1652.

📒 Files selected for processing (4)
  • docs/game/gameplay/式舆防卫战.md
  • docs/game/screens/式舆防卫战.md
  • src/zzz_od/application/shiyu_defense/shiyu_defense_app.py
  • src/zzz_od/operation/choose_predefined_team.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/game/gameplay/式舆防卫战.md

Comment thread docs/game/screens/式舆防卫战.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/zzz_od/operation/choose_predefined_team.py (1)

279-285: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

不要在队名 OCR 失败时压缩游戏列表下标。

Line 285 会跳过该物理卡片,但不会保留其下标。后续 team_idxnext_scanned_team_idx 按已识别卡片数量生成。

如果任意非空卡片的队名 OCR 失败,后续队伍的下标会提前。选择阶段会据此计算错误的翻页位置和标题区域,并可能点击错误队伍。

请按 current_scroll_page 和卡片行列位置计算物理下标。另一种方案是在当前页存在未识别卡片时重试或失败,不要继续使用压缩后的下标。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zzz_od/operation/choose_predefined_team.py` around lines 279 - 285,
更新预备编队扫描流程中处理 team_name 或 team_name_mr OCR 失败的分支,确保未识别但非空的物理卡片仍保留其真实下标,不要让后续队伍通过
next_scanned_team_idx 连续压缩。根据 current_scroll_page 及卡片的 title_x/title_y
行列位置计算并传播物理 team_idx;或者在当前页存在未识别卡片时重试或终止,禁止继续使用压缩后的索引。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/zzz_od/operation/choose_predefined_team.py`:
- Around line 279-285: 更新预备编队扫描流程中处理 team_name 或 team_name_mr OCR
失败的分支,确保未识别但非空的物理卡片仍保留其真实下标,不要让后续队伍通过 next_scanned_team_idx 连续压缩。根据
current_scroll_page 及卡片的 title_x/title_y 行列位置计算并传播物理
team_idx;或者在当前页存在未识别卡片时重试或终止,禁止继续使用压缩后的索引。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 06d7e4d5-d660-410d-a6c4-c8c22226d9d2

📥 Commits

Reviewing files that changed from the base of the PR and between 7bd1652 and 437fd6a.

📒 Files selected for processing (3)
  • docs/game/screens/式舆防卫战.md
  • src/zzz_od/config/team_config.py
  • src/zzz_od/operation/choose_predefined_team.py

@kawayiYokami

kawayiYokami commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

本地完成一轮端到端实测(账号1 式舆防卫战剧变节点),已 push 修复(7bd1652,含 49b1f9d 文档):

实测发现并修复 3 处 OCR 相关问题:

  1. 多间配队候选不足(根因):扫描用 1P/2P/3P 三标记判满员,3P 文字 OCR 漏读会误判满员队禁用 → 候选不足 → select_teams 选不出 3 互斥队。改用核心技 X/Y(分母=队伍人数)判满员(X/3 为主、1P/2P/3P≥2 兜底),兼容斜线误识为 1 的连写(313=3/3)。
  2. 进度 OCR 误判完成:X/Y 读成 total<current(如 2/1)时 choose_node_idx 误判全部完成跳过整关 → 加 total<current 校验回退 run_record。
  3. _is_selected_text 的 \d{2} 误匹配等级 60 → 限 0 开头(0\d:选中态编号 01-09,排除等级)。

端到端验证:多间(节点5)扫描候选 11 → select_teams 选 3 满员互斥(简薇耀/仪玄/冰雅狼苍,避开 1 人测试队)→ 3 间战斗 → 领奖 → 回大世界,完整跑通。

另:combat.md 补战斗机制 + team_utils 注释(虚狩正名/染色依据/评分权重)。

建议 author 确认 X/3 判满员的修法,并补选配队单元测试。

QQ_1785585397021 1P 2P 3P不是为了判满员,而是判禁用。

你用的ocr是V5还是V6,我反复测试没出现过一次漏读的

@kawayiYokami

Copy link
Copy Markdown
Contributor Author

@joshcai @DoctorReid 请求重新审查,请重点复查 7bd1652b56c5a2fbd3a326f40bdbbe64edc1d6fb 之后的实测修复提交。

这些提交来自游戏内实测,修复范围包括:

  • 统一预备编队名称中的空白,避免 OCR 结果与配置名称匹配不一致;
  • 修正一屏 6 个卡位、每次滚动推进 4 个真实序号时的选卡定位;
  • 延长前台拖动按住时间,提升预备编队翻页稳定性;
  • 补齐预备编队 6 个卡位的画面区域;
  • 按“缺少 nP 且第 n 名代理人头像变暗”判断禁用队;
  • 禁用队不参与评分但保留游戏真实序号,避免后续点击错位;
  • 将“配队选择”从开发工具迁移为可在“应用运行”手动添加的独立插件,并提供齿轮设置页,不加入一条龙;
  • 将正常 INFO 收敛为扫描与选择的关键阶段,OCR、亮度、槽位和禁用判定依据保留在 DEBUG,避免正常日志被诊断细节淹没。

这些修复共同保证实测中的扫描、禁用跳过、滚动定位、选择确认和插件入口稳定可用;日志分级仅是最后一项。

@ShadowLemoon

Copy link
Copy Markdown
Collaborator

合并前需要删除测试应用

Comment thread src/one_dragon/base/controller/pc_controller_base.py Outdated
@kawayiYokami

Copy link
Copy Markdown
Contributor Author

已按 review 意见处理,fairy 提交了 d02acc9

  • 新增 PcControllerBase.SLEEP_BEFORE_DRAG_START: float = 0.3 类常量,drag_mouse 中硬编码的 time.sleep(0.3) 改为 time.sleep(PcControllerBase.SLEEP_BEFORE_DRAG_START)
  • duration_drag 调整为 max(duration - PcControllerBase.SLEEP_BEFORE_DRAG_START - PcControllerBase.SLEEP_BEFORE_DRAG_END, PcControllerBase.DRAG_MIN_DURATION),拖动总时长语义统一为完整过程(按下停顿 + 移动 + 松前停顿)。

另外,配队选择测试应用已删除(c96a41c1),本地留了备份以便后续取用。

@DoctorReid

Copy link
Copy Markdown
Collaborator

漏读是v6的,画面好像是2560 × 1440,当时看的确挺稳定漏读,可以其他人测测看

@kawayiYokami

Copy link
Copy Markdown
Contributor Author

漏读是v6的,画面好像是2560 × 1440,当时看的确挺稳定漏读,可以其他人测测看

已经改用新方法

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test-branch 合入 test 分支

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[自动战斗] 自动战斗无法选中编队以及代码版本无法显示

4 participants