diff --git a/src/arcaea_offline_ocr/scenarios/b30/base.py b/src/arcaea_offline_ocr/scenarios/b30/base.py new file mode 100644 index 0000000..7d3492a --- /dev/null +++ b/src/arcaea_offline_ocr/scenarios/b30/base.py @@ -0,0 +1,22 @@ +from abc import abstractmethod +from typing import TYPE_CHECKING, List + +from arcaea_offline_ocr.scenarios.base import OcrScenario, OcrScenarioResult + +if TYPE_CHECKING: + from arcaea_offline_ocr.types import Mat + + +class Best30Scenario(OcrScenario): + @abstractmethod + def components(self, img: "Mat", /) -> List["Mat"]: ... + + @abstractmethod + def result(self, component_img: "Mat", /, *args, **kwargs) -> OcrScenarioResult: ... + + @abstractmethod + def results(self, img: "Mat", /, *args, **kwargs) -> List[OcrScenarioResult]: + """ + Commonly a shorthand for `[self.result(comp) for comp in self.components(img)]` + """ + ... diff --git a/src/arcaea_offline_ocr/scenarios/base.py b/src/arcaea_offline_ocr/scenarios/base.py new file mode 100644 index 0000000..35e13c9 --- /dev/null +++ b/src/arcaea_offline_ocr/scenarios/base.py @@ -0,0 +1,38 @@ +from abc import ABC +from dataclasses import dataclass, field +from datetime import datetime +from typing import Sequence, Optional + +from arcaea_offline_ocr.providers import ImageIdProviderResult + + +@dataclass(kw_only=True) +class OcrScenarioResult: + song_id: str + rating_class: int + score: int + + song_id_results: Sequence[ImageIdProviderResult] = field(default_factory=lambda: []) + partner_id_results: Sequence[ImageIdProviderResult] = field( + default_factory=lambda: [] + ) + + pure: Optional[int] = None + pure_inaccurate: Optional[int] = None + pure_early: Optional[int] = None + pure_late: Optional[int] = None + far: Optional[int] = None + far_inaccurate: Optional[int] = None + far_early: Optional[int] = None + far_late: Optional[int] = None + lost: Optional[int] = None + + played_at: Optional[datetime] = None + max_recall: Optional[int] = None + clear_status: Optional[int] = None + clear_type: Optional[int] = None + modifier: Optional[int] = None + + +class OcrScenario(ABC): + pass diff --git a/src/arcaea_offline_ocr/scenarios/device/base.py b/src/arcaea_offline_ocr/scenarios/device/base.py new file mode 100644 index 0000000..070bfb0 --- /dev/null +++ b/src/arcaea_offline_ocr/scenarios/device/base.py @@ -0,0 +1,8 @@ +from abc import abstractmethod + +from arcaea_offline_ocr.scenarios.base import OcrScenario, OcrScenarioResult + + +class DeviceScenarioBase(OcrScenario): + @abstractmethod + def result(self) -> OcrScenarioResult: ...