Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions autowsgr/ui/map/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 裁剪区域 (第一列战役的底部文本区)。"""


# ── 出征地图节点切换 ──

Expand Down
32 changes: 32 additions & 0 deletions autowsgr/ui/map/panels/campaign.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import re
import time
from dataclasses import dataclass
from typing import TYPE_CHECKING
Expand All @@ -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,
Expand Down Expand Up @@ -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))
Comment on lines +61 to +66
_log.info(f'[UI] 战役次数识别成功: {remains}/{total}')
return remains, total

_log.warning(f'[UI] 战役次数识别失败: OCR 结果未匹配 ({text})')
return None

def recognize_difficulty(self) -> str | None:
"""通过检测难度按钮颜色识别当前难度。

Expand Down
Loading