#!/usr/bin/env python3 """verify_mixed_step.py — 混合步长 A*(2格跑+1格走) 全图离线验证.""" from __future__ import annotations import sys import time from collections import deque sys.path.insert(0, "src") from pbot.bot.pathfind import LearnedGrid, astar, load_walls_from_map def cross_check(path, walls): pairs = list(zip(path, path[1:])) for a, b in pairs: step = max(abs(b[0] - a[0]), abs(b[1] - a[1])) if b in walls: return False if step == 2: mid = ((a[0] + b[0]) // 2, (a[1] + b[1]) // 2) if mid in walls: return False return True def farthest(start, walls, lim=1024): dq = deque([start]) seen = {start} while dq: x, y = dq.popleft() for dx in (-1, 0, 1): for dy in (-1, 0, 1): n = (x + dx, y + dy) if n not in seen and n not in walls \ and 0 <= n[0] < lim and 0 <= n[1] < lim: seen.add(n) dq.append(n) return max(seen, key=lambda c: abs(c[0] - start[0]) + abs(c[1] - start[1])) def main(): cases = [ ("d601 蜈蚣洞穴 (38,25)->(163,73) [昨晚失败场景]", "assets/maps/d601.map", (38, 25), (163, 73)), ("d401 矿区 (83,10)->(177,19) [实跑回归]", "assets/maps/d401.map", (83, 10), (177, 19)), ("d011 天然洞穴 BFS最远点", "assets/maps/d011.map", None, None), ("0139 等待图 BFS最远点", "assets/maps/0139.map", None, None), ("d022 沃玛寺庙 BFS最远点", "assets/maps/d022.map", None, None), ("d613 生死之间 BFS最远点", "assets/maps/d613.map", None, None), ("0 比奇大城 BFS最远点", "assets/maps/0.map", None, None), ("3 盟重 BFS最远点", "assets/maps/3.map", None, None), ] all_ok = True for label, mp, s, g in cases: walls = load_walls_from_map(mp) if s is None: s = next(c for c in ((x, y) for y in range(10, 200, 5) for x in range(10, 200, 5)) if c not in walls) g = farthest(s, walls) grid = LearnedGrid() grid.mark_from_map(walls) t0 = time.time() path = astar(s, g, grid, max_expand=2_000_000) ms = (time.time() - t0) * 1000 if path is None: print(f"X {label}: 无路!") all_ok = False continue ok = cross_check(path, walls) if not ok: all_ok = False legs = list(zip(path, path[1:])) n1 = sum(1 for a, b in legs if max(abs(b[0] - a[0]), abs(b[1] - a[1])) == 1) n2 = len(legs) - n1 mark = "OK" if ok else "X穿墙" print(f"{mark} {label}: {len(legs)} 腿(跑{n2}/走{n1}) {ms:.0f}ms") print("-" * 60) print("结论:", "全部通过 — 混合步长对所有地图有效" if all_ok else "存在失败!") return 0 if all_ok else 1 if __name__ == "__main__": sys.exit(main())