verify_mixed_step.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #!/usr/bin/env python3
  2. """verify_mixed_step.py — 混合步长 A*(2格跑+1格走) 全图离线验证."""
  3. from __future__ import annotations
  4. import sys
  5. import time
  6. from collections import deque
  7. sys.path.insert(0, "src")
  8. from pbot.bot.pathfind import LearnedGrid, astar, load_walls_from_map
  9. def cross_check(path, walls):
  10. pairs = list(zip(path, path[1:]))
  11. for a, b in pairs:
  12. step = max(abs(b[0] - a[0]), abs(b[1] - a[1]))
  13. if b in walls:
  14. return False
  15. if step == 2:
  16. mid = ((a[0] + b[0]) // 2, (a[1] + b[1]) // 2)
  17. if mid in walls:
  18. return False
  19. return True
  20. def farthest(start, walls, lim=1024):
  21. dq = deque([start])
  22. seen = {start}
  23. while dq:
  24. x, y = dq.popleft()
  25. for dx in (-1, 0, 1):
  26. for dy in (-1, 0, 1):
  27. n = (x + dx, y + dy)
  28. if n not in seen and n not in walls \
  29. and 0 <= n[0] < lim and 0 <= n[1] < lim:
  30. seen.add(n)
  31. dq.append(n)
  32. return max(seen, key=lambda c: abs(c[0] - start[0]) + abs(c[1] - start[1]))
  33. def main():
  34. cases = [
  35. ("d601 蜈蚣洞穴 (38,25)->(163,73) [昨晚失败场景]", "assets/maps/d601.map", (38, 25), (163, 73)),
  36. ("d401 矿区 (83,10)->(177,19) [实跑回归]", "assets/maps/d401.map", (83, 10), (177, 19)),
  37. ("d011 天然洞穴 BFS最远点", "assets/maps/d011.map", None, None),
  38. ("0139 等待图 BFS最远点", "assets/maps/0139.map", None, None),
  39. ("d022 沃玛寺庙 BFS最远点", "assets/maps/d022.map", None, None),
  40. ("d613 生死之间 BFS最远点", "assets/maps/d613.map", None, None),
  41. ("0 比奇大城 BFS最远点", "assets/maps/0.map", None, None),
  42. ("3 盟重 BFS最远点", "assets/maps/3.map", None, None),
  43. ]
  44. all_ok = True
  45. for label, mp, s, g in cases:
  46. walls = load_walls_from_map(mp)
  47. if s is None:
  48. s = next(c for c in ((x, y) for y in range(10, 200, 5)
  49. for x in range(10, 200, 5))
  50. if c not in walls)
  51. g = farthest(s, walls)
  52. grid = LearnedGrid()
  53. grid.mark_from_map(walls)
  54. t0 = time.time()
  55. path = astar(s, g, grid, max_expand=2_000_000)
  56. ms = (time.time() - t0) * 1000
  57. if path is None:
  58. print(f"X {label}: 无路!")
  59. all_ok = False
  60. continue
  61. ok = cross_check(path, walls)
  62. if not ok:
  63. all_ok = False
  64. legs = list(zip(path, path[1:]))
  65. n1 = sum(1 for a, b in legs
  66. if max(abs(b[0] - a[0]), abs(b[1] - a[1])) == 1)
  67. n2 = len(legs) - n1
  68. mark = "OK" if ok else "X穿墙"
  69. print(f"{mark} {label}: {len(legs)} 腿(跑{n2}/走{n1}) {ms:.0f}ms")
  70. print("-" * 60)
  71. print("结论:", "全部通过 — 混合步长对所有地图有效" if all_ok else "存在失败!")
  72. return 0 if all_ok else 1
  73. if __name__ == "__main__":
  74. sys.exit(main())