""" 演示场景工具 提供各种路径规划演示场景的创建功能 """ from typing import List, Tuple import random def create_simple_grid(rows: int, cols: int) -> List[List[int]]: """ 创建简单的空网格 Args: rows: 行数 cols: 列数 Returns: 网格数据 """ return [[0 for _ in range(cols)] for _ in range(rows)] def create_maze_grid(rows: int, cols: int) -> List[List[int]]: """ 创建迷宫网格(使用深度优先搜索算法生成) Args: rows: 行数 cols: 列数 Returns: 迷宫网格数据 """ # 确保行列数为奇数 if rows % 2 == 0: rows += 1 if cols % 2 == 0: cols += 1 # 初始化网格(全部设为墙) grid = [[1 for _ in range(cols)] for _ in range(rows)] # 使用深度优先搜索生成迷宫 stack = [] # 起点 start_row, start_col = 1, 1 grid[start_row][start_col] = 0 stack.append((start_row, start_col)) # 方向:上、右、下、左 directions = [(-2, 0), (0, 2), (2, 0), (0, -2)] while stack: current_row, current_col = stack[-1] # 获取未访问的邻居 neighbors = [] for dr, dc in directions: new_row, new_col = current_row + dr, current_col + dc if 1 <= new_row < rows - 1 and 1 <= new_col < cols - 1: if grid[new_row][new_col] == 1: neighbors.append((new_row, new_col, dr // 2, dc // 2)) if neighbors: # 随机选择一个邻居 new_row, new_col, wall_row, wall_col = random.choice(neighbors) # 打通当前单元格和选中邻居之间的墙 grid[new_row][new_col] = 0 grid[current_row + wall_row][current_col + wall_col] = 0 # 将选中的邻居加入栈 stack.append((new_row, new_col)) else: # 回溯 stack.pop() return grid def create_room_grid(rows: int, cols: int) -> List[List[int]]: """ 创建房间网格(包含多个房间和走廊) Args: rows: 行数 cols: 列数 Returns: 房间网格数据 """ grid = [[0 for _ in range(cols)] for _ in range(rows)] # 添加一些房间(用障碍物围起来的空心矩形) rooms = [ (2, 2, 5, 5), # (row, col, height, width) (2, 10, 5, 5), (10, 2, 5, 5), (10, 10, 5, 5) ] for room_row, room_col, room_height, room_width in rooms: # 创建房间的墙 for r in range(room_row, min(room_row + room_height, rows)): for c in range(room_col, min(room_col + room_width, cols)): if (r == room_row or r == room_row + room_height - 1 or c == room_col or c == room_col + room_width - 1): if 0 <= r < rows and 0 <= c < cols: grid[r][c] = 1 # 添加走廊连接房间 # 水平走廊 for c in range(7, 10): if 4 < rows: grid[4][c] = 0 # 垂直走廊 for r in range(7, 10): if 4 < cols: grid[r][4] = 0 if 12 < cols: grid[r][12] = 0 return grid def create_random_grid(rows: int, cols: int, obstacle_probability: float = 0.3) -> List[List[int]]: """ 创建随机网格 Args: rows: 行数 cols: 列数 obstacle_probability: 障碍物概率 Returns: 随机网格数据 """ grid = [] for r in range(rows): row = [] for c in range(cols): if random.random() < obstacle_probability: row.append(1) # 障碍物 else: row.append(0) # 空地 grid.append(row) return grid def create_tunnel_grid(rows: int, cols: int) -> List[List[int]]: """ 创建隧道网格(多条曲折的隧道) Args: rows: 行数 cols: 列数 Returns: 隧道网格数据 """ grid = [[1 for _ in range(cols)] for _ in range(rows)] # 全部初始化为墙 # 创建主要隧道 # 水平隧道 tunnel_row = rows // 2 for c in range(1, cols - 1): grid[tunnel_row][c] = 0 # 垂直隧道 tunnel_col = cols // 2 for r in range(1, rows - 1): grid[r][tunnel_col] = 0 # 添加一些分支隧道 branch_positions = [(tunnel_row, tunnel_col // 4), (tunnel_row, 3 * tunnel_col // 4), (tunnel_row // 4, tunnel_col), (3 * tunnel_row // 4, tunnel_col)] for br, bc in branch_positions: # 水平分支 for c in range(max(1, bc - 3), min(cols - 1, bc + 4)): grid[br][c] = 0 # 垂直分支 for r in range(max(1, br - 3), min(rows - 1, br + 4)): grid[r][bc] = 0 return grid def get_scenario_names() -> List[str]: """ 获取可用场景名称 Returns: 场景名称列表 """ return ["simple", "maze", "room", "random", "tunnel"] def create_scenario(scenario_name: str, rows: int = 20, cols: int = 20) -> List[List[int]]: """ 创建指定场景 Args: scenario_name: 场景名称 rows: 行数 cols: 列数 Returns: 网格数据 """ if scenario_name == "simple": return create_simple_grid(rows, cols) elif scenario_name == "maze": return create_maze_grid(rows, cols) elif scenario_name == "room": return create_room_grid(rows, cols) elif scenario_name == "random": return create_random_grid(rows, cols) elif scenario_name == "tunnel": return create_tunnel_grid(rows, cols) else: return create_simple_grid(rows, cols) def get_suggested_start_goal(scenario_name: str, grid: List[List[int]]) -> Tuple[Tuple[int, int], Tuple[int, int]]: """ 获取场景建议的起点和终点 Args: scenario_name: 场景名称 grid: 网格数据 Returns: (起点, 终点) 元组 """ rows = len(grid) cols = len(grid[0]) if rows > 0 else 0 if scenario_name == "simple": return (0, 0), (rows - 1, cols - 1) elif scenario_name == "maze": return (1, 1), (rows - 2, cols - 2) elif scenario_name == "room": return (0, 0), (rows - 1, cols - 1) elif scenario_name == "random": # 寻找空地作为起点和终点 start = None goal = None for r in range(rows): for c in range(cols): if grid[r][c] == 0: if start is None: start = (r, c) else: goal = (r, c) return start or (0, 0), goal or (rows - 1, cols - 1) elif scenario_name == "tunnel": return (1, 1), (rows - 2, cols - 2) else: return (0, 0), (rows - 1, cols - 1)