From 24ebea75e9d6466ac29a86b7f611180685a70288 Mon Sep 17 00:00:00 2001 From: yltx <2326439151@qq.com> Date: Sat, 16 May 2026 20:57:28 +0800 Subject: [PATCH] feat: add get_campaign_remains --- autowsgr/ui/map/data.py | 3 +++ autowsgr/ui/map/panels/campaign.py | 32 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/autowsgr/ui/map/data.py b/autowsgr/ui/map/data.py index cbe50920..3c89b8ff 100644 --- a/autowsgr/ui/map/data.py +++ b/autowsgr/ui/map/data.py @@ -315,6 +315,9 @@ def parse_map_title(text: str) -> MapIdentity | None: CLICK_DIFFICULTY: tuple[float, float] = (0.800, 0.130) """切换难度。""" +CAMPAIGN_REMAIN_CROP: tuple[float, float, float, float] = (0.08, 0.82, 0.25, 0.92) +"""战役剩余次数 OCR 裁剪区域 (第一列战役的底部文本区)。""" + # ── 出征地图节点切换 ── diff --git a/autowsgr/ui/map/panels/campaign.py b/autowsgr/ui/map/panels/campaign.py index bf9ac81c..0c69817c 100644 --- a/autowsgr/ui/map/panels/campaign.py +++ b/autowsgr/ui/map/panels/campaign.py @@ -2,6 +2,7 @@ from __future__ import annotations +import re import time from dataclasses import dataclass from typing import TYPE_CHECKING @@ -11,6 +12,7 @@ from autowsgr.ui.map.base import BaseMapPage from autowsgr.ui.map.data import ( CAMPAIGN_POSITIONS, + CAMPAIGN_REMAIN_CROP, CLICK_DIFFICULTY, DIFFICULTY_EASY_COLOR, DIFFICULTY_HARD_COLOR, @@ -38,6 +40,36 @@ class CampaignPanelMixin(BaseMapPage): # ── 查询 ───────────────────────────────────────────────────────────── + def get_campaign_remains(self) -> tuple[int, int] | None: + """获取战役剩余次数。 + + Returns + ------- + tuple[int, int] | None + 返回 (剩余次数, 总次数),如 (0, 8)。如果识别失败返回 None。 + """ + self.ensure_panel(MapPanel.BATTLE) + time.sleep(0.5) + screen = self._ctrl.screenshot() + img = PixelChecker.crop(screen, *CAMPAIGN_REMAIN_CROP) + + ocr = self._ocr + if ocr is None: + _log.warning('[UI] 无法获取战役次数: 未提供 OCR 引擎') + return None + + results = ocr.recognize(img) + text = ''.join([r.text for r in results]).replace(' ', '') + m = re.search(r'(\d+)[/|](\d+)', text) + if m: + remains = int(m.group(1)) + total = int(m.group(2)) + _log.info(f'[UI] 战役次数识别成功: {remains}/{total}') + return remains, total + + _log.warning(f'[UI] 战役次数识别失败: OCR 结果未匹配 ({text})') + return None + def recognize_difficulty(self) -> str | None: """通过检测难度按钮颜色识别当前难度。