mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-29 17:35:14 +00:00
init-commit
This commit is contained in:
commit
18a552597a
3461 changed files with 1150579 additions and 0 deletions
0
internbootcamp/libs/maze/_init_.py
Executable file
0
internbootcamp/libs/maze/_init_.py
Executable file
229
internbootcamp/libs/maze/maze_generator.py
Executable file
229
internbootcamp/libs/maze/maze_generator.py
Executable file
|
|
@ -0,0 +1,229 @@
|
|||
import random
|
||||
from typing import List, Tuple, Optional
|
||||
from collections import deque
|
||||
|
||||
|
||||
def generate_maze(width: int, height: int, start_pos=(0, 0), end_pos=None, difficulty=1, seed=None) -> List[List[int]]:
|
||||
"""
|
||||
优化后的随机迷宫生成器
|
||||
|
||||
参数:
|
||||
width: 迷宫宽度(列数)
|
||||
height: 迷宫高度(行数)
|
||||
start_pos: 起点位置
|
||||
end_pos: 终点位置
|
||||
difficulty: 难度(1-3)
|
||||
seed: 随机种子
|
||||
"""
|
||||
if seed is not None:
|
||||
random.seed(seed)
|
||||
|
||||
# 初始化迷宫
|
||||
maze = [[1 for _ in range(width)] for _ in range(height)]
|
||||
|
||||
if end_pos is None:
|
||||
end_pos = (height - 1, width - 1)
|
||||
|
||||
start_x, start_y = start_pos
|
||||
end_x, end_y = end_pos
|
||||
|
||||
# 验证起点和终点坐标
|
||||
if not (0 <= start_x < width and 0 <= start_y < height):
|
||||
raise ValueError("起点坐标无效")
|
||||
if not (0 <= end_x < width and 0 <= end_y < height):
|
||||
raise ValueError("终点坐标无效")
|
||||
|
||||
# 增加更多方向选择,包括对角线移动用于生成过程
|
||||
directions = [
|
||||
(0, 1), (1, 0), (0, -1), (-1, 0), # 基本方向
|
||||
(1, 1), (1, -1), (-1, 1), (-1, -1) # 对角线方向
|
||||
]
|
||||
|
||||
visited = [[False for _ in range(width)] for _ in range(height)]
|
||||
|
||||
# 使用改进的生成算法
|
||||
def carve_passages(x: int, y: int, branch_chance: float):
|
||||
visited[y][x] = True
|
||||
maze[y][x] = 0
|
||||
|
||||
# 获取随机打乱的方向
|
||||
current_dirs = directions[:4] if random.random() > 0.3 else directions # 30%概率使用对角线
|
||||
random.shuffle(current_dirs)
|
||||
|
||||
for dx, dy in current_dirs:
|
||||
nx, ny = x + dx * 2, y + dy * 2
|
||||
|
||||
if 0 <= nx < width and 0 <= ny < height and not visited[ny][nx]:
|
||||
# 根据难度和分支概率决定是否开辟新路径
|
||||
if random.random() < branch_chance:
|
||||
# 在两点之间开通路径
|
||||
maze[y + dy][x + dx] = 0
|
||||
maze[ny][nx] = 0
|
||||
carve_passages(nx, ny, branch_chance * 0.95) # 随深度递减分支概率
|
||||
|
||||
# 随机创建环路
|
||||
if random.random() < 0.2: # 20%概率创建环路
|
||||
for loop_dx, loop_dy in random.sample(directions[:4], 2): # 只使用基本方向创建环路
|
||||
loop_x, loop_y = nx + loop_dx, ny + loop_dy
|
||||
if (0 <= loop_x < width and 0 <= loop_y < height and
|
||||
maze[loop_y][loop_x] == 0):
|
||||
maze[ny][nx] = 0
|
||||
break
|
||||
|
||||
# 根据难度调整分支概率
|
||||
initial_branch_chance = {
|
||||
1: 0.75, # 简单:较少分支
|
||||
2: 0.85, # 中等:适中分支
|
||||
3: 0.95 # 困难:大量分支
|
||||
}.get(difficulty, 0.85)
|
||||
|
||||
# 从起点开始生成迷宫
|
||||
carve_passages(start_x, start_y, initial_branch_chance)
|
||||
|
||||
# 添加随机特征
|
||||
add_random_features(maze, difficulty, start_pos, end_pos)
|
||||
|
||||
# 确保起点和终点是通路
|
||||
maze[start_y][start_x] = 0
|
||||
maze[end_y][end_x] = 0
|
||||
|
||||
# 如果没有路径,创建一条
|
||||
if not has_path(maze, start_pos, end_pos):
|
||||
create_enhanced_path(maze, start_pos, end_pos)
|
||||
|
||||
return maze
|
||||
|
||||
|
||||
def add_random_features(maze: List[List[int]], difficulty: int, start_pos: Tuple[int, int],
|
||||
end_pos: Tuple[int, int]):
|
||||
"""添加随机特征以增加迷宫的复杂性和随机性"""
|
||||
height, width = len(maze), len(maze[0])
|
||||
|
||||
# 根据难度确定要添加的随机特征数量
|
||||
feature_count = difficulty * (width + height) // 4
|
||||
|
||||
for _ in range(feature_count):
|
||||
feature_type = random.random()
|
||||
|
||||
if feature_type < 0.4: # 40%概率:添加或移除单个墙
|
||||
x = random.randint(1, width - 2)
|
||||
y = random.randint(1, height - 2)
|
||||
if (y, x) != start_pos and (y, x) != end_pos:
|
||||
maze[y][x] = 1 if random.random() < 0.5 else 0
|
||||
|
||||
elif feature_type < 0.7: # 30%概率:创建小房间
|
||||
room_width = random.randint(2, 4)
|
||||
room_height = random.randint(2, 4)
|
||||
x = random.randint(1, width - room_width - 1)
|
||||
y = random.randint(1, height - room_height - 1)
|
||||
|
||||
# 确保房间不会覆盖起点或终点
|
||||
if not (start_pos[1] >= y and start_pos[1] < y + room_height and
|
||||
start_pos[0] >= x and start_pos[0] < x + room_width) and \
|
||||
not (end_pos[1] >= y and end_pos[1] < y + room_height and
|
||||
end_pos[0] >= x and end_pos[0] < x + room_width):
|
||||
for i in range(room_height):
|
||||
for j in range(room_width):
|
||||
maze[y + i][x + j] = 0
|
||||
|
||||
else: # 30%概率:创建通道
|
||||
if random.random() < 0.5: # 水平通道
|
||||
y = random.randint(1, height - 2)
|
||||
for x in range(1, width - 1):
|
||||
if (y, x) != start_pos and (y, x) != end_pos:
|
||||
maze[y][x] = 0
|
||||
else: # 垂直通道
|
||||
x = random.randint(1, width - 2)
|
||||
for y in range(1, height - 1):
|
||||
if (y, x) != start_pos and (y, x) != end_pos:
|
||||
maze[y][x] = 0
|
||||
|
||||
|
||||
def has_path(maze: List[List[int]], start_pos: Tuple[int, int], end_pos: Tuple[int, int]) -> bool:
|
||||
"""
|
||||
检查迷宫是否有从起点到终点的路径
|
||||
|
||||
参数:
|
||||
maze: 迷宫二维数组
|
||||
start_pos: 起点坐标 (x, y)
|
||||
end_pos: 终点坐标 (x, y)
|
||||
|
||||
返回:
|
||||
bool: 是否存在可行路径
|
||||
"""
|
||||
width, height = len(maze[0]), len(maze)
|
||||
visited = [[False for _ in range(width)] for _ in range(height)]
|
||||
start_x, start_y = start_pos
|
||||
end_x, end_y = end_pos
|
||||
|
||||
queue = deque([(start_x, start_y)])
|
||||
visited[start_y][start_x] = True
|
||||
|
||||
# 四个基本方向:右、下、左、上
|
||||
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
|
||||
|
||||
while queue:
|
||||
x, y = queue.popleft()
|
||||
|
||||
if (x, y) == (end_x, end_y):
|
||||
return True
|
||||
|
||||
for dx, dy in directions:
|
||||
nx, ny = x + dx, y + dy
|
||||
if (0 <= nx < width and 0 <= ny < height and
|
||||
maze[ny][nx] == 0 and not visited[ny][nx]):
|
||||
visited[ny][nx] = True
|
||||
queue.append((nx, ny))
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def create_enhanced_path(maze: List[List[int]], start_pos: Tuple[int, int],
|
||||
end_pos: Tuple[int, int]):
|
||||
"""创建一条更自然的路径从起点到终点"""
|
||||
start_x, start_y = start_pos
|
||||
end_x, end_y = end_pos
|
||||
current_x, current_y = start_x, start_y
|
||||
|
||||
while (current_x, current_y) != (end_x, end_y):
|
||||
# 随机选择是先移动x还是y
|
||||
if random.random() < 0.5:
|
||||
if current_x != end_x:
|
||||
current_x += 1 if current_x < end_x else -1
|
||||
maze[current_y][current_x] = 0
|
||||
elif current_y != end_y:
|
||||
current_y += 1 if current_y < end_y else -1
|
||||
maze[current_y][current_x] = 0
|
||||
else:
|
||||
if current_y != end_y:
|
||||
current_y += 1 if current_y < end_y else -1
|
||||
maze[current_y][current_x] = 0
|
||||
elif current_x != end_x:
|
||||
current_x += 1 if current_x < end_x else -1
|
||||
maze[current_y][current_x] = 0
|
||||
|
||||
# 随机添加一些支路
|
||||
if random.random() < 0.2: # 20%概率添加支路
|
||||
dx = random.choice([-1, 1])
|
||||
dy = random.choice([-1, 1])
|
||||
nx, ny = current_x + dx, current_y + dy
|
||||
if (0 <= nx < len(maze[0]) and 0 <= ny < len(maze) and
|
||||
(ny, nx) != start_pos and (ny, nx) != end_pos):
|
||||
maze[ny][nx] = 0
|
||||
|
||||
|
||||
def print_maze(maze: List[List[int]]):
|
||||
"""
|
||||
打印迷宫(用于调试)
|
||||
|
||||
参数:
|
||||
maze: 迷宫的二维数组
|
||||
"""
|
||||
for row in maze:
|
||||
print("".join([" " if cell == 0 else "██" for cell in row]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试迷宫生成
|
||||
maze = generate_maze(15, 15, difficulty=2)
|
||||
print_maze(maze)
|
||||
142
internbootcamp/libs/maze/maze_solver.py
Executable file
142
internbootcamp/libs/maze/maze_solver.py
Executable file
|
|
@ -0,0 +1,142 @@
|
|||
from collections import deque
|
||||
|
||||
|
||||
def solve_maze(maze, start_pos=(0, 0), end_pos=None):
|
||||
"""
|
||||
使用广度优先搜索(BFS)求解迷宫
|
||||
|
||||
参数:
|
||||
maze: 迷宫的二维数组(0 表示通路,1 表示墙)
|
||||
start_pos: 起点位置,默认为(0, 0)
|
||||
end_pos: 终点位置,默认为右下角
|
||||
|
||||
返回:
|
||||
path: 从起点到终点的路径列表,如果没有路径则返回None
|
||||
output: 详细的求解过程字符串
|
||||
"""
|
||||
height = len(maze)
|
||||
width = len(maze[0]) if height > 0 else 0
|
||||
|
||||
# 如果没有指定终点,默认为右下角
|
||||
if end_pos is None:
|
||||
end_pos = (height - 1, width - 1)
|
||||
|
||||
# 确保起点和终点坐标有效
|
||||
start_x, start_y = start_pos
|
||||
end_x, end_y = end_pos
|
||||
|
||||
if not (0 <= start_x < height and 0 <= start_y < width) or maze[start_x][start_y] == 1:
|
||||
return None, "起点坐标无效或被墙壁阻挡"
|
||||
if not (0 <= end_x < height and 0 <= end_y < width) or maze[end_x][end_y] == 1:
|
||||
return None, "终点坐标无效或被墙壁阻挡"
|
||||
|
||||
# 定义移动方向:右、下、左、上
|
||||
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
|
||||
direction_names = ["右", "下", "左", "上"]
|
||||
|
||||
# 使用BFS寻找路径
|
||||
queue = deque([(start_x, start_y, [(start_x, start_y)])]) # 队列中存储当前点和路径
|
||||
visited = set([(start_x, start_y)]) # 使用集合记录已访问的位置
|
||||
|
||||
output = "开始使用广度优先搜索(BFS)求解迷宫...\n\n"
|
||||
output += f"起点: {start_pos}\n"
|
||||
output += f"终点: {end_pos}\n\n"
|
||||
|
||||
step = 0
|
||||
|
||||
while queue:
|
||||
step += 1
|
||||
x, y, path = queue.popleft()
|
||||
|
||||
output += f"步骤 {step}:\n"
|
||||
output += f"当前位置: ({x}, {y})\n"
|
||||
|
||||
if (x, y) == end_pos: # 到达终点
|
||||
output += "找到终点!\n"
|
||||
output += f"路径长度: {len(path)}\n"
|
||||
output += "完整路径:\n"
|
||||
output += str(path)
|
||||
return path, output
|
||||
|
||||
# 探索四个方向
|
||||
for i, (dx, dy) in enumerate(directions):
|
||||
nx, ny = x + dx, y + dy
|
||||
if (0 <= nx < height and 0 <= ny < width and
|
||||
maze[nx][ny] == 0 and (nx, ny) not in visited):
|
||||
visited.add((nx, ny))
|
||||
queue.append((nx, ny, path + [(nx, ny)]))
|
||||
output += f" 添加位置 ({nx}, {ny}) 到队列 (向{direction_names[i]})\n"
|
||||
|
||||
output += "\n"
|
||||
|
||||
output += "无法找到从起点到终点的路径。\n"
|
||||
return None, output
|
||||
|
||||
|
||||
def is_path_exist(maze, start_pos=(0, 0), end_pos=None):
|
||||
"""
|
||||
检查迷宫是否存在从起点到终点的路径(使用 BFS)
|
||||
|
||||
参数:
|
||||
maze: 迷宫的二维数组
|
||||
start_pos: 起点位置
|
||||
end_pos: 终点位置
|
||||
|
||||
返回:
|
||||
exists: 是否存在路径(True/False)
|
||||
"""
|
||||
height = len(maze)
|
||||
width = len(maze[0]) if height > 0 else 0
|
||||
|
||||
# 如果没有指定终点,默认为右下角
|
||||
if end_pos is None:
|
||||
end_pos = (height - 1, width - 1)
|
||||
|
||||
# 确保起点和终点坐标有效
|
||||
start_x, start_y = start_pos
|
||||
end_x, end_y = end_pos
|
||||
|
||||
if not (0 <= start_x < height and 0 <= start_y < width) or maze[start_x][start_y] == 1:
|
||||
return False
|
||||
if not (0 <= end_x < height and 0 <= end_y < width) or maze[end_x][end_y] == 1:
|
||||
return False
|
||||
|
||||
# 定义移动方向:右、下、左、上
|
||||
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
|
||||
|
||||
# 使用BFS寻找路径
|
||||
queue = deque([(start_x, start_y)])
|
||||
visited = set([(start_x, start_y)])
|
||||
|
||||
while queue:
|
||||
x, y = queue.popleft()
|
||||
|
||||
if (x, y) == end_pos: # 到达终点
|
||||
return True
|
||||
|
||||
for dx, dy in directions:
|
||||
nx, ny = x + dx, y + dy
|
||||
if (0 <= nx < height and 0 <= ny < width and
|
||||
maze[nx][ny] == 0 and (nx, ny) not in visited):
|
||||
visited.add((nx, ny))
|
||||
queue.append((nx, ny))
|
||||
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试迷宫求解
|
||||
maze = [
|
||||
[0, 1, 0, 0, 0],
|
||||
[0, 1, 0, 1, 0],
|
||||
[0, 0, 0, 1, 0],
|
||||
[1, 1, 1, 1, 0],
|
||||
[0, 0, 0, 0, 0]
|
||||
]
|
||||
|
||||
path, output = solve_maze(maze)
|
||||
print(output)
|
||||
|
||||
# 测试路径存在性检查
|
||||
exists = is_path_exist(maze)
|
||||
print(f"路径存在: {exists}")
|
||||
107
internbootcamp/libs/maze/maze_validator.py
Executable file
107
internbootcamp/libs/maze/maze_validator.py
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
def validate_maze_solution(maze, start_pos, end_pos, solution):
|
||||
"""
|
||||
验证迷宫解决方案是否有效
|
||||
|
||||
参数:
|
||||
maze: 迷宫的二维数组(0 表示通路,1 表示墙)
|
||||
start_pos: 起点位置
|
||||
end_pos: 终点位置
|
||||
solution: 解决方案路径
|
||||
|
||||
返回:
|
||||
is_valid: 解决方案是否有效
|
||||
"""
|
||||
# 检查解决方案是否为空
|
||||
if not solution:
|
||||
return False
|
||||
|
||||
# 检查起点和终点
|
||||
if solution[0] != start_pos or solution[-1] != end_pos:
|
||||
return False
|
||||
|
||||
height = len(maze)
|
||||
width = len(maze[0]) if height > 0 else 0
|
||||
|
||||
# 检查每一步是否有效
|
||||
for i, (x, y) in enumerate(solution):
|
||||
# print(f"Checking position {x}, {y}...")
|
||||
if not (0 <= x < height and 0 <= y < width):
|
||||
# print(f"Position {x}, {y} is out of bounds.")
|
||||
return False
|
||||
if maze[x][y] == 1:
|
||||
# print(f"Position {x}, {y} is a wall.")
|
||||
return False
|
||||
if i > 0:
|
||||
prev_x, prev_y = solution[i - 1]
|
||||
if not ((abs(x - prev_x) == 1 and y == prev_y) or (abs(y - prev_y) == 1 and x == prev_x)):
|
||||
# print(f"Position {x}, {y} is not adjacent to {prev_x}, {prev_y}.")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def validate_and_solve_mazes(mazes):
|
||||
"""
|
||||
批量验证和解答迷宫
|
||||
|
||||
参数:
|
||||
mazes: 迷宫列表
|
||||
|
||||
返回:
|
||||
results: 验证和解答结果列表
|
||||
"""
|
||||
from maze_solver import solve_maze, is_path_exist
|
||||
|
||||
results = []
|
||||
for maze_data in mazes:
|
||||
maze_id = maze_data["id"]
|
||||
maze_grid = maze_data["grid"]
|
||||
|
||||
# 获取起点和终点(如果有指定)
|
||||
start_pos = maze_data.get("start_pos", (0, 0))
|
||||
end_pos = maze_data.get("end_pos", (len(maze_grid) - 1, len(maze_grid[0]) - 1))
|
||||
|
||||
# 验证迷宫是否可解
|
||||
has_path = is_path_exist(maze_grid, start_pos, end_pos)
|
||||
|
||||
# 如果可解,尝试找到路径
|
||||
solution = None
|
||||
if has_path:
|
||||
solution, _ = solve_maze(maze_grid, start_pos, end_pos)
|
||||
|
||||
results.append({
|
||||
"id": maze_id,
|
||||
"has_path": has_path,
|
||||
"solution": solution
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试验证器
|
||||
maze = [
|
||||
[0, 1, 0, 0, 0],
|
||||
[0, 1, 0, 1, 0],
|
||||
[0, 0, 0, 1, 0],
|
||||
[1, 1, 1, 1, 0],
|
||||
[0, 0, 0, 0, 0]
|
||||
]
|
||||
|
||||
start_pos = (0, 0)
|
||||
end_pos = (4, 4)
|
||||
|
||||
# 有效路径
|
||||
valid_solution = [
|
||||
(0, 0), (1, 0), (2, 0), (2, 1), (2, 2),
|
||||
(3, 2), (4, 2), (4, 3), (4, 4)
|
||||
]
|
||||
|
||||
# 无效路径(不连续)
|
||||
invalid_solution = [
|
||||
(0, 0), (1, 0), (2, 0), (2, 2),
|
||||
(3, 2), (4, 2), (4, 3), (4, 4)
|
||||
]
|
||||
|
||||
print("有效路径验证结果:", validate_maze_solution(maze, start_pos, end_pos, valid_solution))
|
||||
print("无效路径验证结果:", validate_maze_solution(maze, start_pos, end_pos, invalid_solution))
|
||||
Loading…
Add table
Add a link
Reference in a new issue