改写战斗中替换group的逻辑

This commit is contained in:
Elaina 2024-10-13 01:24:58 +08:00
commit 7f89eb0db8
3890 changed files with 82290 additions and 0 deletions

View file

@ -0,0 +1,219 @@
from datetime import datetime, timedelta
import cv2
from mower.utils import config
from mower.utils import typealias as tp
from mower.utils.graph import SceneGraphSolver
from mower.utils.image import cropimg, loadres
from mower.utils.log import logger
from mower.utils.recognize import Scene
from mower.utils.translate_room import translate_room
from mower.utils.vector import sm, va
facility = {
"central": (
(-0.6551724137931034, -0.26436781609195403),
(2.3524904214559386, 1.1340996168582376),
),
"dormitory_1": (
(-0.6615384615384616, 0.9692307692307693),
(1.7538461538461538, 0.5115384615384616),
),
"dormitory_2": (
(-0.046153846153846156, 1.580769230769231),
(1.7461538461538462, 0.5115384615384616),
),
"dormitory_3": (
(-0.6615384615384616, 2.1884615384615387),
(1.7538461538461538, 0.5192307692307693),
),
"dormitory_4": (
(-0.046153846153846156, 2.7961538461538464),
(1.7461538461538462, 0.5230769230769231),
),
"factory": (
(2.689655172413793, 0.9540229885057471),
(1.1379310344827585, 0.5172413793103448),
),
"meeting": (
(2.0804597701149423, 0.3486590038314176),
(1.747126436781609, 0.5172413793103448),
),
"contact": (
(2.689655172413793, 1.5632183908045976),
(1.1379310344827585, 0.5172413793103448),
),
"room_1_1": (
(-4.626923076923077, 0.9692307692307693),
(1.126923076923077, 0.5115384615384616),
),
"room_1_2": (
(-3.403846153846154, 0.9692307692307693),
(1.123076923076923, 0.5115384615384616),
),
"room_1_3": (
(-2.184615384615385, 0.9692307692307693),
(1.1307692307692307, 0.5115384615384616),
),
"room_2_1": (
(-5.2384615384615385, 1.580769230769231),
(1.1346153846153846, 0.5115384615384616),
),
"room_2_2": (
(-4.015384615384615, 1.580769230769231),
(1.1307692307692307, 0.5115384615384616),
),
"room_2_3": (
(-2.7923076923076926, 1.580769230769231),
(1.126923076923077, 0.5115384615384616),
),
"room_3_1": (
(-4.6230769230769235, 2.1884615384615387),
(1.123076923076923, 0.5192307692307693),
),
"room_3_2": (
(-3.4000000000000004, 2.1884615384615387),
(1.123076923076923, 0.5192307692307693),
),
"room_3_3": (
(-2.180769230769231, 2.1884615384615387),
(1.126923076923077, 0.5192307692307693),
),
"train": (
(2.689655172413793, 2.18007662835249),
(1.1379310344827585, 0.5172413793103448),
),
}
class EnterRoomSolver(SceneGraphSolver):
def run(self, room: str, detail: bool = True):
"""
Args:
room: 房间名
detail: 打开进驻信息
"""
logger.info(f"进入房间:{translate_room(room)}")
self.room = room
self.detail = detail
self.wait_start()
super().run()
def timeout(self) -> bool:
return datetime.now() > self.start_time + timedelta(seconds=3)
def wait_start(self):
self.start_time = datetime.now()
def detect_room_number(self, img) -> int:
score = []
for i in range(1, 5):
digit = loadres(f"room/{i}")
result = cv2.matchTemplate(img, digit, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(max_val)
return score.index(max(score)) + 1
def detect_room(self) -> str:
color_map = {
"制造站": 25,
"贸易站": 99,
"发电站": 36,
"训练室": 178,
"加工站": 32,
}
img = cropimg(config.recog.img, ((568, 18), (957, 95)))
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
colored_room = None
for room, color in color_map.items():
mask = cv2.inRange(hsv, (color - 1, 0, 0), (color + 2, 255, 255))
if cv2.countNonZero(mask) > 1000:
colored_room = room
break
if colored_room in ["制造站", "贸易站", "发电站"]:
digit_1 = cropimg(img, ((211, 24), (232, 54)))
digit_2 = cropimg(img, ((253, 24), (274, 54)))
digit_1 = self.detect_room_number(digit_1)
digit_2 = self.detect_room_number(digit_2)
logger.debug(f"{colored_room}B{digit_1}0{digit_2}")
return f"room_{digit_1}_{digit_2}"
elif colored_room == "训练室":
logger.debug("训练室B305")
return "train"
elif colored_room == "加工站":
logger.debug("加工站B105")
return "factory"
white_room = ["central", "dormitory", "meeting", "contact"]
score = []
for room in white_room:
tpl = loadres(f"room/{room}")
result = cv2.matchTemplate(img, tpl, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
score.append(max_val)
room = white_room[score.index(max(score))]
if room == "central":
logger.debug("控制中枢")
elif room == "dormitory":
digit = cropimg(img, ((174, 24), (195, 54)))
digit = self.detect_room_number(digit)
if digit == 4:
logger.debug("宿舍B401")
else:
logger.debug(f"宿舍B{digit}04")
return f"dormitory_{digit}"
elif room == "meeting":
logger.debug("会客室1F02")
else:
logger.debug("办公室B205")
return room
@staticmethod
def segment(central: tp.Scope) -> dict[str, tp.Rectangle]:
top_left = central[0]
width = central[1][0] - central[0][0]
result = {}
for name, (position, size) in facility.items():
facility_top_left = va(top_left, sm(width, position))
scope = facility_top_left, va(facility_top_left, sm(width, size))
result[name] = (
(max(scope[0][0], 0), scope[0][1]),
(min(scope[1][0], 1920), scope[1][1]),
)
logger.debug(result)
return result
def transition(self) -> bool:
if (scene := self.scene()) == Scene.INFRA_MAIN:
score, scope = config.recog.match2d("control_central")
if score >= 0.9:
pos = self.segment(scope)[self.room]
self.ctap(pos, 1, config.screenshot_avg / 1000)
self.wait_start()
else:
config.recog.update()
elif scene in [Scene.CTRLCENTER_ASSISTANT, Scene.INFRA_DETAILS]:
if self.detect_room() == self.room:
if not self.detail:
self.tap((960, 540), interval=0)
return True
if self.find("room_detail"):
return True
if pos := self.find("arrange_check_in"):
if self.find("infra_overview_top_right"):
self.ctap(pos, 1, config.screenshot_avg / 1000)
else:
config.recog.update()
elif self.timeout():
self.scene_graph_step(Scene.INFRA_MAIN)
else:
config.recog.update()
else:
if self.timeout():
self.scene_graph_step(Scene.INFRA_MAIN)
else:
config.recog.update()
else:
self.scene_graph_step(Scene.INFRA_MAIN)